From 9206b74500dbb8c12a39c29463f9b2ad27da7fcf Mon Sep 17 00:00:00 2001 From: Hide_D Date: Sat, 25 Mar 2023 02:09:23 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=9D=B4=EB=AF=B8=20=EC=9D=BD=EC=9D=80?= =?UTF-8?q?=20=EB=A9=94=EC=8B=9C=EC=A7=80=EB=A5=BC=20DB=EC=97=90=EC=84=9C?= =?UTF-8?q?=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hwe/sammo/API/Message/GetRecentMessage.php | 12 +++++ hwe/sammo/API/Message/ReadLatestMessage.php | 52 +++++++++++++++++++++ hwe/sammo/Enums/GeneralStorKey.php | 7 +++ hwe/ts/SammoAPI.ts | 16 ++++--- hwe/ts/components/MessagePanel.vue | 45 ++++++++++++------ hwe/ts/defs/API/Message.ts | 4 ++ 6 files changed, 115 insertions(+), 21 deletions(-) create mode 100644 hwe/sammo/API/Message/ReadLatestMessage.php create mode 100644 hwe/sammo/Enums/GeneralStorKey.php diff --git a/hwe/sammo/API/Message/GetRecentMessage.php b/hwe/sammo/API/Message/GetRecentMessage.php index 43bcf716..ae535db0 100644 --- a/hwe/sammo/API/Message/GetRecentMessage.php +++ b/hwe/sammo/API/Message/GetRecentMessage.php @@ -6,8 +6,10 @@ use sammo\Session; use DateTimeInterface; use sammo\DB; use sammo\Enums\APIRecoveryType; +use sammo\Enums\GeneralStorKey; use sammo\Enums\MessageType; use sammo\Json; +use sammo\KVStorage; use sammo\Message; use sammo\TimeUtil; use sammo\Util; @@ -140,9 +142,19 @@ class GetRecentMessage extends \sammo\BaseAPI array_pop($result[$lastType]); } + $generalStor = KVStorage::getStorage($db, "general_{$generalID}"); + [$latestReadDiplomacyMsg, $latestReadPrivateMsg] = $generalStor->getValuesAsArray([ + GeneralStorKey::latestReadDiplomacyMsg, + GeneralStorKey::latestReadPrivateMsg + ]); + $result['sequence'] = $nextSequence; $result['nationID'] = $nationID; $result['generalName'] = $generalName; + $result['latestRead'] = [ + 'diplomacy' => $latestReadDiplomacyMsg ?? 0, + 'private' => $latestReadPrivateMsg ?? 0, + ]; return $result; } diff --git a/hwe/sammo/API/Message/ReadLatestMessage.php b/hwe/sammo/API/Message/ReadLatestMessage.php new file mode 100644 index 00000000..85bbd11a --- /dev/null +++ b/hwe/sammo/API/Message/ReadLatestMessage.php @@ -0,0 +1,52 @@ +args); + $v->rule('required', ['type', 'msgID']) + ->rule('in', 'type', [MessageType::private->value, MessageType::diplomacy->value]) + ->rule('int', 'msgID'); + if (!$v->validate()) { + return $v->errorStr(); + } + return null; + } + + public function getRequiredSessionMode(): int + { + return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY; + } + + public function launch(Session $session, ?\DateTimeInterface $modifiedSince, ?string $reqEtag): null | string | array | APIRecoveryType + { + $db = DB::db(); + $generalID = $session->generalID; + $generalStor = KVStorage::getStorage($db, "general_{$generalID}"); + $type = MessageType::from($this->args['type']); + $msgID = $this->args['msgID']; + + $storKey = GeneralStorKey::latestReadPrivateMsg; + if($type == MessageType::diplomacy){ + $storKey = GeneralStorKey::latestReadDiplomacyMsg; + } + $oldValue = $generalStor->getValue($storKey); + if($oldValue === null || $oldValue < $msgID){ + $generalStor->setValue($storKey, $msgID); + } + + return null; + } +} diff --git a/hwe/sammo/Enums/GeneralStorKey.php b/hwe/sammo/Enums/GeneralStorKey.php new file mode 100644 index 00000000..ae265a9e --- /dev/null +++ b/hwe/sammo/Enums/GeneralStorKey.php @@ -0,0 +1,7 @@ +, GetUniqueItemAuctionDetail: GET as APICallT<{ - auctionID: number; + auctionID: number; }, UniqueItemAuctionDetail>, GetUniqueItemAuctionList: GET as APICallT, OpenUniqueAuction: POST as APICallT<{ - itemID: string, - amount: number, + itemID: string, + amount: number, }, OpenAuctionResponse>, }, Betting: { @@ -199,7 +199,11 @@ const apiRealPath = { SendMessage: POST as APICallT<{ mailbox: number; text: string; - }, ValidResponse & {msgID: number, msgType: MsgType}> + }, ValidResponse & { msgID: number, msgType: MsgType }>, + ReadLatestMessage: PATCH as APICallT<{ + type: 'diplomacy' | 'private'; + msgID: number; + }> }, Misc: { UploadImage: POST as APICallT< @@ -273,7 +277,7 @@ const apiRealPath = { troopID: number; troopName: string; }>, - GetNationInfo: GET as APICallT<{full?: boolean}, NationInfoResponse>, + GetNationInfo: GET as APICallT<{ full?: boolean }, NationInfoResponse>, }, Troop: { NewTroop: POST as APICallT<{ diff --git a/hwe/ts/components/MessagePanel.vue b/hwe/ts/components/MessagePanel.vue index da1dd289..9d1001d5 100644 --- a/hwe/ts/components/MessagePanel.vue +++ b/hwe/ts/components/MessagePanel.vue @@ -255,21 +255,8 @@ const messageIndexedList: Record> = { diplomacy: messageDiplomacy, }; -function generateLatestMsgState(msgType: MsgType) { - const storageKey = `state.${serverID}.latestReadMsg.${msgType}`; - const latestReadMsgID = parseInt(localStorage.getItem(storageKey) ?? "0"); - const obj = ref<[string | undefined, number, number]>([undefined, latestReadMsgID, latestReadMsgID]); - watch(obj, ([, newMsgID], [, oldMsgID]) => { - if (newMsgID == oldMsgID) { - return; - } - localStorage.setItem(storageKey, newMsgID.toString()); - }); - return obj; -} - -const latestPrivateMsgToastInfo = generateLatestMsgState("private"); -const latestDiplomacyMsgToastInfo = generateLatestMsgState("diplomacy"); +const latestPrivateMsgToastInfo = ref<[string | undefined, number, number]>([undefined, 0, 0]); +const latestDiplomacyMsgToastInfo = ref<[string | undefined, number, number]>([undefined, 0, 0]); function readLatestMsg(msgType: MsgType) { const targetMap = { @@ -288,6 +275,13 @@ function readLatestMsg(msgType: MsgType) { if (toastID) { toasts.remove(toastID); } + + if(msgType == "private" || msgType == "diplomacy"){ + void SammoAPI.Message.ReadLatestMessage({ + type: msgType, + msgID: lastestReceivedID, + }); + } target.value = [undefined, lastestReceivedID, lastestReceivedID]; } @@ -403,6 +397,27 @@ function updateMsgResponse(response: MsgResponse) { return; } + if(response.latestRead){ + const newDiplomacyIdx = response.latestRead.diplomacy; + const [diplomacyToastID, diplomacyLatestMsgID] = latestDiplomacyMsgToastInfo.value; + if(diplomacyLatestMsgID < newDiplomacyIdx){ + if(diplomacyToastID){ + toasts.remove(diplomacyToastID); + } + latestDiplomacyMsgToastInfo.value = [undefined, newDiplomacyIdx, newDiplomacyIdx]; + } + + const newPrivateIdx = response.latestRead.private; + const [privateToastID, privateLatestMsgID] = latestPrivateMsgToastInfo.value; + if(privateLatestMsgID < newPrivateIdx){ + if(privateToastID){ + toasts.remove(privateToastID); + } + latestPrivateMsgToastInfo.value = [undefined, newPrivateIdx, newPrivateIdx]; + } + } + + lastSequence.value = Math.max(lastSequence.value, response.sequence); for (const msgType of Object.keys(messageIndexedList) as (keyof typeof messageIndexedList)[]) { diff --git a/hwe/ts/defs/API/Message.ts b/hwe/ts/defs/API/Message.ts index fc996e62..b583bc8f 100644 --- a/hwe/ts/defs/API/Message.ts +++ b/hwe/ts/defs/API/Message.ts @@ -58,6 +58,10 @@ export type MsgResponse = { nationID: number; generalName: string; sequence: number; + latestRead?: { + private: number; + diplomacy: number; + } }; export type MailboxItem = {