diff --git a/hwe/sammo/API/Message/GetOldMessage.php b/hwe/sammo/API/Message/GetOldMessage.php new file mode 100644 index 00000000..36bbe2a2 --- /dev/null +++ b/hwe/sammo/API/Message/GetOldMessage.php @@ -0,0 +1,143 @@ +args); + $v->rule('required', [ + 'sequence', + 'type', + ])->rule('int', 'to') + ->rule('string', 'type'); + if (!$v->validate()) { + return $v->errorStr(); + } + $this->args['to'] = (int)($this->args['to'] ?? 0); + return null; + } + + public function getRequiredSessionMode(): int + { + return static::REQ_GAME_LOGIN; + } + + private function delayFrequentCall(Session $session): void + { + $lastMsgGet = Json::decode($session->lastMsgGet) ?? []; + $now = new \DateTimeImmutable(); + $delayTime = false; + + if (count($lastMsgGet) >= 10) { + try { + if (!is_string($lastMsgGet[0])) { + throw new \Exception('Why not string?'); + } + $first = new \DateTimeImmutable($lastMsgGet[0]); + $diffSec = TimeUtil::DateIntervalToSeconds($first->diff($now)); + if ($diffSec < 1) { + $delayTime = true; + } + array_shift($lastMsgGet); + } catch (\Exception $e) { + $lastMsgGet = []; + } + } + $lastMsgGet[] = TimeUtil::format($now, true); + $session->lastMsgGet = Json::encode($lastMsgGet); + + if ($delayTime) { + usleep(200); + } + } + + public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag) + { + $this->delayFrequentCall($session); + $session->setReadOnly(); + $userID = $session->getUserID(); + + + + $db = DB::db(); + $me = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`con`,`picture`,`imgsvr`,penalty,permission FROM general WHERE `owner`=%i', $userID); + + if ($me === null) { + return '장수가 사망했습니다.'; + } + + [$generalID, $nationID, $generalName] = [$me['no'], $me['nation'], $me['name']]; + $permission = checkSecretPermission($me, false); + $reqTo = $this->args['reqTo']; + + $result = [ + MessageType::private->value => [], + MessageType::public->value => [], + MessageType::national->value => [], + MessageType::diplomacy->value => [], + 'result' => true, + 'keepRecent' => true, + 'sequence' => 0, + 'nationID' => $nationID, + 'generalName' => $generalName, + ]; + $result['result'] = true; + + $nextSequence = $reqTo; + $reqType = MessageType::tryFrom($this->args['type']); + if ($reqType === null) { + return '잘못된 요청입니다.'; + } + + if ($reqType === MessageType::private) { + $result[MessageType::private->value] = array_map(function (Message $msg) use (&$nextSequence) { + if ($msg->id > $nextSequence) { + $nextSequence = $msg->id; + } + return $msg->toArray(); + }, Message::getMessagesFromMailBoxOld($generalID, MessageType::private, $reqTo, 15)); + } else if ($reqType === MessageType::public) { + $result[MessageType::public->value] = array_map(function (Message $msg) use (&$nextSequence) { + if ($msg->id > $nextSequence) { + $nextSequence = $msg->id; + } + return $msg->toArray(); + }, Message::getMessagesFromMailBoxOld(Message::MAILBOX_PUBLIC, MessageType::public, $reqTo, 15)); + } else if ($reqType === MessageType::national) { + $result[MessageType::national->value] = array_map(function (Message $msg) use (&$nextSequence) { + if ($msg->id > $nextSequence) { + $nextSequence = $msg->id; + } + return $msg->toArray(); + }, Message::getMessagesFromMailBoxOld(Message::MAILBOX_NATIONAL + $nationID, MessageType::national, $reqTo, 15)); + } else { + $result[MessageType::diplomacy->value] = array_map(function (Message $msg) use (&$nextSequence, $permission) { + if ($msg->id > $nextSequence) { + $nextSequence = $msg->id; + } + $values = $msg->toArray(); + if ($msg->dest->nationID != 0 && $permission < 3) { + $values['text'] = '(외교 메시지입니다)'; //TODO: 외교서신이라 읽을 수 없음을 보여줘야함 + $values['option']['invalid'] = true; + } + return $values; + }, Message::getMessagesFromMailBoxOld(Message::MAILBOX_NATIONAL + $nationID, MessageType::diplomacy, $reqTo, 15)); + } + + return $result; + } +} diff --git a/hwe/ts/SammoAPI.ts b/hwe/ts/SammoAPI.ts index 189523bd..3d361ce9 100644 --- a/hwe/ts/SammoAPI.ts +++ b/hwe/ts/SammoAPI.ts @@ -32,7 +32,7 @@ GetRecentRecordResponse, import type { CachedMapResult, GeneralListResponse, ItemTypeKey, MapResult } from "./defs"; import type { VoteDetailResult, VoteListResult } from "./defs/API/Vote"; import type { ActiveResourceAuctionList, OpenAuctionResponse, UniqueItemAuctionDetail, UniqueItemAuctionList } from "./defs/API/Auction"; -import type { MsgResponse } from "./defs/API/Message"; +import type { MsgResponse, MsgType } from "./defs/API/Message"; const apiRealPath = { Auction: { @@ -175,6 +175,10 @@ const apiRealPath = { GetRecentMessage: GET as APICallT<{ sequence?: number; }, MsgResponse>, + GetOldMessage: GET as APICallT<{ + to: number; + type: MsgType; + }, MsgResponse>, }, Misc: { UploadImage: POST as APICallT< diff --git a/hwe/ts/defs/API/Message.ts b/hwe/ts/defs/API/Message.ts index b7c91efa..05725661 100644 --- a/hwe/ts/defs/API/Message.ts +++ b/hwe/ts/defs/API/Message.ts @@ -1,5 +1,3 @@ -import type { ValidResponse } from "@/util/callSammoAPI"; - export type MsgType = "private" | "public" | "national" | "diplomacy"; export const minMsgSeq: Record = {