diff --git a/hwe/index.php b/hwe/index.php index 9dcdf126..0de377b2 100644 --- a/hwe/index.php +++ b/hwe/index.php @@ -303,15 +303,20 @@ else if($session->userGrade == 4){
전체 메시지(최고99자)
-
+
+ +
개인 메시지(최고99자)
-
+
+ +
-
국가 메시지(최고99자)
-
+
+ +
diff --git a/hwe/j_msg_get_old.php b/hwe/j_msg_get_old.php new file mode 100644 index 00000000..0f806c67 --- /dev/null +++ b/hwe/j_msg_get_old.php @@ -0,0 +1,107 @@ +false, + 'reason'=>'올바르지 않은 범위 입니다.' + ]); +} +if($reqType === null || !in_array($reqType, ['private', 'public', 'national'])){ + Json::die([ + 'result'=>false, + 'reason'=>'올바르지 않은 타입입니다.' + ]); +} + +$lastMsgGet = Json::decode($session->lastMsgGet)??[]; +$now = new \DateTime(); +$delayTime = false; +if(count($lastMsgGet) >= 10){ + try{ + if($lastMsgGet[0] !== 'string'){ + throw new \Exception('Why not string?'); + } + $first = new \DateTime($lastMsgGet[0]); + $diff = $first->diff($now); + if($diff->days == 0 && $diff->h > 0 && $diff->i == 0 && $diff->s <= 1){ + $delayTime = true; + } + array_shift($lastMsgGet); + } + catch(\Exception $e){ + $lastMsgGet = []; + } +} +$lastMsgGet[] = $now; +$session->lastMsgGet = Json::encode($lastMsgGet); +$session->setReadOnly(); + +if($delayTime){ + sleep(1); +} + +list($generalID, $nationID, $generalName) = DB::db()->queryFirstList( + 'select `no`, `nation`, `name` from `general` where owner = %i', + $userID +); + + + +if($nationID === null){ + Json::die([ + 'result'=>false, + 'reason'=>'장수가 사망했습니다.' + ]); +} + +$result = [ + 'private'=>[], + 'public'=>[], + 'national'=>[], + 'diplomacy'=>[], + 'result'=>true, + 'keepRecent'=>true, + 'sequence'=>0, + 'nationID'=>$nationID, + 'generalName'=>$generalName, +]; +$result['result'] = true; + +$nextSequence = $reqTo; + +if($reqType == 'private'){ + $result['private'] = array_map(function(Message $msg) use (&$nextSequence){ + if($msg->id > $nextSequence){ + $nextSequence = $msg->id; + } + return $msg->toArray(); + }, Message::getMessagesFromMailBoxOld($generalID, Message::MSGTYPE_PRIVATE, $reqTo, 20)); +} +else if($reqType == 'public'){ + $result['public'] = array_map(function(Message $msg)use (&$nextSequence){ + if($msg->id > $nextSequence){ + $nextSequence = $msg->id; + } + return $msg->toArray(); + }, Message::getMessagesFromMailBoxOld(Message::MAILBOX_PUBLIC, Message::MSGTYPE_PUBLIC, $reqTo, 20)); +} +else{ + $result['national'] = array_map(function(Message $msg)use (&$nextSequence){ + if($msg->id > $nextSequence){ + $nextSequence = $msg->id; + } + return $msg->toArray(); + }, Message::getMessagesFromMailBoxOld(Message::MAILBOX_NATIONAL + $nationID, Message::MSGTYPE_NATIONAL, $reqTo, 40)); +} + +Json::die($result); \ No newline at end of file diff --git a/hwe/j_msg_get_recent.php b/hwe/j_msg_get_recent.php index 0ff1f231..c088f128 100644 --- a/hwe/j_msg_get_recent.php +++ b/hwe/j_msg_get_recent.php @@ -4,10 +4,37 @@ namespace sammo; include('lib.php'); include('func.php'); -$session = Session::requireGameLogin([])->setReadOnly(); +$session = Session::requireGameLogin([]); $userID = Session::getUserID(); -$reqSequence = Util::getReq('sequence', 'int', 0); +$reqSequence = Util::getReq('sequence', 'int', -1); + +$lastMsgGet = Json::decode($session->lastMsgGet)??[]; +$now = new \DateTime(); +$delayTime = false; +if(count($lastMsgGet) >= 10){ + try{ + if($lastMsgGet[0] !== 'string'){ + throw new \Exception('Why not string?'); + } + $first = new \DateTime($lastMsgGet[0]); + $diff = $first->diff($now); + if($diff->days == 0 && $diff->h > 0 && $diff->i == 0 && $diff->s <= 1){ + $delayTime = true; + } + array_shift($lastMsgGet); + } + catch(\Exception $e){ + $lastMsgGet = []; + } +} +$lastMsgGet[] = $now; +$session->lastMsgGet = Json::encode($lastMsgGet); +$session->setReadOnly(); + +if($delayTime){ + sleep(0.1); +} list($generalID, $nationID, $generalName) = DB::db()->queryFirstList( @@ -25,37 +52,59 @@ if($nationID === null){ $result = []; $result['result'] = true; - +$result['keepRecent'] = false; $nextSequence = $reqSequence; +$minSequence = $reqSequence; +$lastType = null; -$result['private'] = array_map(function(Message $msg) use (&$nextSequence){ +$result['private'] = array_map(function(Message $msg) use (&$nextSequence, &$minSequence, &$lastType){ if($msg->id > $nextSequence){ $nextSequence = $msg->id; } + if($msg->id <= $minSequence){ + $minSequence = $msg->id; + $lastType = 'private'; + } return $msg->toArray(); -}, Message::getMessagesFromMailBox($generalID, Message::MSGTYPE_PRIVATE, 10, $reqSequence)); +}, Message::getMessagesFromMailBox($generalID, Message::MSGTYPE_PRIVATE, 20, $reqSequence)); -$result['public'] = array_map(function(Message $msg)use (&$nextSequence){ +$result['public'] = array_map(function(Message $msg)use (&$nextSequence, &$minSequence, &$lastType){ if($msg->id > $nextSequence){ $nextSequence = $msg->id; } + if($msg->id <= $minSequence){ + $minSequence = $msg->id; + $lastType = 'public'; + } return $msg->toArray(); -}, Message::getMessagesFromMailBox(Message::MAILBOX_PUBLIC, Message::MSGTYPE_PUBLIC, 10, $reqSequence)); +}, Message::getMessagesFromMailBox(Message::MAILBOX_PUBLIC, Message::MSGTYPE_PUBLIC, 20, $reqSequence)); -$result['national'] = array_map(function(Message $msg)use (&$nextSequence){ +$result['national'] = array_map(function(Message $msg)use (&$nextSequence, &$minSequence, &$lastType){ if($msg->id > $nextSequence){ $nextSequence = $msg->id; } + if($msg->id <= $minSequence){ + $minSequence = $msg->id; + $lastType = 'national'; + } return $msg->toArray(); -}, Message::getMessagesFromMailBox(Message::MAILBOX_NATIONAL + $nationID, Message::MSGTYPE_NATIONAL, 20, $reqSequence)); +}, Message::getMessagesFromMailBox(Message::MAILBOX_NATIONAL + $nationID, Message::MSGTYPE_NATIONAL, 40, $reqSequence)); -$result['diplomacy']= array_map(function(Message $msg)use (&$nextSequence){ +$result['diplomacy']= array_map(function(Message $msg)use (&$nextSequence, &$minSequence, &$lastType){ if($msg->id > $nextSequence){ $nextSequence = $msg->id; } return $msg->toArray(); }, Message::getMessagesFromMailBox(Message::MAILBOX_NATIONAL + $nationID, Message::MSGTYPE_DIPLOMACY, 10, 0)); +if($lastType !== null){ + array_pop($result[$lastType]); + $result['keepRecent'] = true; +} +else if($reqSequence <= 0){ + $result['keepRecent'] = true; +} + $result['sequence'] = $nextSequence; $result['nationID'] = $nationID; $result['generalName'] = $generalName; diff --git a/hwe/js/msg.js b/hwe/js/msg.js index 06936ca6..5759f2a9 100644 --- a/hwe/js/msg.js +++ b/hwe/js/msg.js @@ -23,9 +23,13 @@ function isBrightColor(color){ var messageTemplate = ''; var myGeneralID=null; var isChief = false; -var sequence =null; +var lastSequence = 0; var myNation = null; -var lastMsg = null; +var minMsgSeq = { + 'private':0x7fffffff, + 'public':0x7fffffff, + 'national':0x7fffffff, +} var generalList = {}; @@ -47,28 +51,62 @@ function refreshMsg(result){ if(result && !result.result){ alert(result.reason); } - return redrawMsg(fetchMsg()); + return redrawMsg(fetchRecentMsg(), true); } -function fetchMsg(){ +function fetchRecentMsg(){ return $.ajax({ url: 'j_msg_get_recent.php', type: 'post', dataType:'json', data: { - sequence:sequence + sequence:lastSequence } }); } -function redrawMsg(deferred){ +function showOldMsg(msgType){ + var oldMsg = $.ajax({ + url: 'j_msg_get_old.php', + type: 'post', + dataType:'json', + data: { + to:minMsgSeq[msgType], + type:msgType, + } + }); + redrawMsg(oldMsg, false); +} +function redrawMsg(deferred, addFront){ + function checkClear(obj){ + if(!obj.keepRecent){ + var t = $.Deferred(); + $('.msg_plate').detach(); + lastSequence = null; + console.log('refresh!'); + redrawMsg(fetchRecentMsg(), true); + t.reject(); + return t; + } + return obj; + } function registerSequence(obj){ if(!obj.result){ - deferred.reject(); - return; + var t = $.Deferred(); + t.reject(); + return t; } - sequence = obj.sequence; + lastSequence = Math.max(lastSequence, obj.sequence); + $.each(['public', 'private', 'national'], function (_, msgType) { + var msgList = obj[msgType]; + if(msgList === undefined || msgList.length == 0){ + return true; + } + var lastMsg = msgList[msgList.length - 1]; + console.log(msgType, lastMsg.id); + minMsgSeq[msgType] = Math.min(minMsgSeq[msgType], lastMsg.id); + }); return obj; } @@ -198,12 +236,19 @@ function redrawMsg(deferred){ }); - $msgBoard.prepend($msgs); + if(addFront){ + $msgBoard.prepend($msgs); + } + else{ + $msgBoard.find('.load_old_message').before($msgs); + } + }); } deferred + .then(checkClear) .then(registerSequence) .then(refineMessageObjs) .then(printTemplate); @@ -353,9 +398,6 @@ function registerGlobal(basicInfo){ 'color':'#000000', 'nation':'재야' }; - window.lastMsg = { - id : basicInfo.lastContact - }; window.myGeneralID = basicInfo.generalID; window.isChief = basicInfo.isChief; window.myGeneralLevel = basicInfo.generalLevel; @@ -430,7 +472,7 @@ jQuery(function($){ dataType:'json', }); - var MessageList = fetchMsg(); + var MessageList = fetchRecentMsg(); senderList = $.when(senderList, basicInfo) .then(refreshMailboxList) @@ -438,6 +480,12 @@ jQuery(function($){ $.when(MessageList, getTemplate, basicInfo, senderList) .then(function(){ - redrawMsg(MessageList); + redrawMsg(MessageList, true); + }).then(function(){ + $('.load_old_message').click(function(){ + var $this = $(this); + var msgType = $this.data('msg_type'); + showOldMsg(msgType); + }) }); }); \ No newline at end of file diff --git a/hwe/sammo/Message.php b/hwe/sammo/Message.php index 793bb918..2bef1b1e 100644 --- a/hwe/sammo/Message.php +++ b/hwe/sammo/Message.php @@ -217,7 +217,7 @@ class Message $where->add('type = %s', $msgType); $where->add('valid_until > %s', $date); if ($fromSeq > 0) { - $where->add('id > %i', $fromSeq); + $where->add('id >= %i', $fromSeq); } if ($limit > 0) { @@ -231,6 +231,40 @@ class Message }, $db->query('SELECT * FROM `message` WHERE %l ORDER BY id DESC %? ', $where, $limitSql)); } + /** + * @param int $mailbox 메일 사서함. + * @param string $msgType 메일 타입. MSGTYPE 중 하나. + * @param int $toSeq 가져오고자 하는 위치. $toSeq보다 '작은' seq만 가져온다. + * @param int $limit 가져오고자 하는 수. + * @return Message[] + */ + public static function getMessagesFromMailBoxOld(int $mailbox, string $msgType, int $toSeq, int $limit = 20) + { + $db = DB::db(); + + if (!static::isValidMsgType($msgType)) { + throw new \InvalidArgumentException('올바르지 않은 $msgType'); + } + + $date = (new \DateTime())->format('Y-m-d H:i:s'); + + $where = new \WhereClause('and'); + $where->add('mailbox = %i', $mailbox); + $where->add('type = %s', $msgType); + $where->add('valid_until > %s', $date); + $where->add('id < %i', $toSeq); + + if ($limit > 0) { + $limitSql = $db->sqleval('LIMIT %i', $limit); + } else { + $limitSql = new \MeekroDBEval(''); + } + + return array_map(function ($row) { + return static::buildFromArray($row); + }, $db->query('SELECT * FROM `message` WHERE %l ORDER BY id DESC %? ', $where, $limitSql)); + } + protected function sendRaw(int $mailbox):array{ //NOTE:: 여기선 검증하지 않는다.