wip: 메인 페이지 갱신 버튼 작동 시작

This commit is contained in:
2023-03-09 02:20:10 +09:00
parent cea00133d2
commit 6d00966d15
3 changed files with 169 additions and 61 deletions
+22 -25
View File
@@ -16,13 +16,13 @@ class GetRecentRecord extends \sammo\BaseAPI
public function validateArgs(): ?string public function validateArgs(): ?string
{ {
$v = new Validator($this->args); $v = new Validator($this->args);
$v->rule('int', 'lastGeneralRecordID') $v->rule('integer', 'lastGeneralRecordID')
->rule('int', 'lastWorldHistoryID'); ->rule('integer', 'lastWorldHistoryID');
if (!$v->validate()) { if (!$v->validate()) {
return $v->errorStr(); return $v->errorStr();
} }
$this->args['lastGeneralRecordID'] = (int)($this->args['lastGeneralRecordID']??0); $this->args['lastGeneralRecordID'] = (int)($this->args['lastGeneralRecordID'] ?? 0);
$this->args['lastWorldHistoryID'] = (int)($this->args['lastWorldHistoryID']??0); $this->args['lastWorldHistoryID'] = (int)($this->args['lastWorldHistoryID'] ?? 0);
return null; return null;
} }
@@ -81,48 +81,45 @@ class GetRecentRecord extends \sammo\BaseAPI
$globalRecord = $this->getGlobalRecord($lastRecordID); $globalRecord = $this->getGlobalRecord($lastRecordID);
$generalRecord = $this->getGeneralRecord($session->generalID, $lastRecordID); $generalRecord = $this->getGeneralRecord($session->generalID, $lastRecordID);
$flushHistory = true; $flushHistory = false;
$flushGlobalRecord = true; $flushGlobalRecord = false;
$flushGeneralRecord = true; $flushGeneralRecord = false;
if($history){ if (!$history) {
if(Util::array_last($history)[0] == $lastHistoryID){ $flushHistory = false;
} else if (Util::array_last($history)[0] <= $lastHistoryID) {
$flushHistory = false; $flushHistory = false;
array_pop($history); array_pop($history);
} } else if (count($history) > static::ROW_LIMIT) {
else if(count($history) > static::ROW_LIMIT){
array_pop($history); array_pop($history);
} }
}
if($globalRecord){ if (!$globalRecord) {
if(Util::array_last($globalRecord)[0] == $lastRecordID){ $flushGlobalRecord = false;
} else if (Util::array_last($globalRecord)[0] == $lastRecordID) {
$flushGlobalRecord = false; $flushGlobalRecord = false;
array_pop($globalRecord); array_pop($globalRecord);
} } else if (count($globalRecord) > static::ROW_LIMIT) {
else if(count($globalRecord) > static::ROW_LIMIT){
array_pop($globalRecord); array_pop($globalRecord);
} }
}
if($generalRecord){ if (!$generalRecord) {
if(Util::array_last($generalRecord)[0] == $lastRecordID){ $flushGeneralRecord = false;
} else if (Util::array_last($generalRecord)[0] == $lastRecordID) {
$flushGeneralRecord = false; $flushGeneralRecord = false;
array_pop($generalRecord); array_pop($generalRecord);
} } else if (count($generalRecord) > static::ROW_LIMIT) {
else if(count($generalRecord) > static::ROW_LIMIT){
array_pop($generalRecord); array_pop($generalRecord);
} }
}
return [ return [
'result' => true, 'result' => true,
'history' => $history, 'history' => $history,
'global' => $globalRecord, 'global' => $globalRecord,
'general' => $generalRecord, 'general' => $generalRecord,
'flushHistory' => $flushHistory?1:0, 'flushHistory' => $flushHistory ? 1 : 0,
'flushGlobal' => $flushGlobalRecord?1:0, 'flushGlobal' => $flushGlobalRecord ? 1 : 0,
'flushGeneral' => $flushGeneralRecord?1:0, 'flushGeneral' => $flushGeneralRecord ? 1 : 0,
]; ];
} }
} }
+138 -21
View File
@@ -21,6 +21,7 @@
<div class="gameInfo2">접속중인</div> <div class="gameInfo2">접속중인</div>
<div class="nationNotice">국방</div> <div class="nationNotice">국방</div>
<div>접속자</div> <div>접속자</div>
<div class="d-grid"><BButton @click="tryRefresh">갱신</BButton></div>
<!-- TODO: 운영자 툴바는 어디에?--> <!-- TODO: 운영자 툴바는 어디에?-->
<div class="mapView">지도</div> <div class="mapView">지도</div>
<div class="reservedCommandZone">예턴</div> <div class="reservedCommandZone">예턴</div>
@@ -29,9 +30,27 @@
<div class="generalInfo">장수 정보</div> <div class="generalInfo">장수 정보</div>
<div class="generalCommandToolbar">국가 툴바</div> <div class="generalCommandToolbar">국가 툴바</div>
<div class="actionMiniPlate">갱신/로비 버튼</div> <div class="actionMiniPlate">갱신/로비 버튼</div>
<div class="PublicRecord">장수 동향</div> <div class="PublicRecord">
<div class="GeneralLog">개인 기록</div> <div class="title">장수 동향</div>
<div class="WorldHistory">중원 정세</div> <template v-for="[idx, rawText] of globalRecords.toArray()" :key="idx">
<!-- eslint-disable-next-line vue/no-v-html -->
<div :v-data-idx="idx" v-html="formatLog(rawText)" />
</template>
</div>
<div class="GeneralLog">
<div class="title">개인 기록</div>
<template v-for="[idx, rawText] of generalRecords.toArray()" :key="idx">
<!-- eslint-disable-next-line vue/no-v-html -->
<div :v-data-idx="idx" v-html="formatLog(rawText)" />
</template>
</div>
<div class="WorldHistory">
<div class="title">중원 정세</div>
<template v-for="[idx, rawText] of worldHistory.toArray()" :key="idx">
<!-- eslint-disable-next-line vue/no-v-html -->
<div :v-data-idx="idx" v-html="formatLog(rawText)" />
</template>
</div>
<div class="commonToolbar">툴바?</div> <div class="commonToolbar">툴바?</div>
<div class="MessageInputForm">메시지 입력</div> <div class="MessageInputForm">메시지 입력</div>
<div class="PublicTalk">전체 메시지</div> <div class="PublicTalk">전체 메시지</div>
@@ -41,9 +60,7 @@
<div class="commonToolbar">툴바?</div> <div class="commonToolbar">툴바?</div>
</main> </main>
</BContainer> </BContainer>
<div v-else> <div v-else>서버 갱신 중입니다.</div>
서버 갱신 중입니다.
</div>
</div> </div>
<nav id="mobileBottomBar"> <nav id="mobileBottomBar">
<BButton>하단 </BButton> <BButton>하단 </BButton>
@@ -62,13 +79,17 @@ declare const staticValues: {
}; };
</script> </script>
<script lang="ts" setup> <script lang="ts" setup>
import { BContainer, useToast } from "bootstrap-vue-3"; import { BContainer, BButton, useToast } from "bootstrap-vue-3";
import { isString } from "lodash"; import { isString } from "lodash";
import { provide, ref } from "vue"; import { provide, ref, watch } from "vue";
import { GameConstStore, getGameConstStore } from "./GameConstStore"; import { GameConstStore, getGameConstStore } from "./GameConstStore";
import { SammoAPI } from "./SammoAPI"; import { SammoAPI, type InvalidResponse } from "./SammoAPI";
import { parseTime } from "./util/parseTime"; import { parseTime } from "./util/parseTime";
import { unwrap } from "./util/unwrap"; import { unwrap } from "./util/unwrap";
import Denque from "denque";
import { formatLog } from "@/utilGame/formatLog";
import type { ExecuteResponse } from "./defs/API/Global";
import { delay } from "./util/delay";
const { serverName, serverNick, serverCnt, serverID } = staticValues; const { serverName, serverNick, serverCnt, serverID } = staticValues;
@@ -83,18 +104,46 @@ const lastExecuted = ref<Date>(parseTime("2022-08-15 00:00:00"));
const serverLocked = ref(true); const serverLocked = ref(true);
const refreshCounter = ref(0); const refreshCounter = ref(0);
const storeP = getGameConstStore().then((store) => { const storeP = getGameConstStore().then((store) => {
gameConstStore.value = store; gameConstStore.value = store;
}); });
const responseP = ref<
Promise<
| ExecuteResponse
| (InvalidResponse & {
reqRefresh?: boolean;
})
>
>();
async function tryRefresh() { async function tryRefresh() {
if (responseP.value !== undefined) {
return;
}
try { try {
const responseP = SammoAPI.Global.ExecuteEngine({ serverID }, true); responseP.value = SammoAPI.Global.ExecuteEngine({ serverID }, true).then(
(response) => {
if (response.result) {
lastExecuted.value = parseTime(response.lastExecuted);
serverLocked.value = response.locked;
}
return response;
}
);
//TODO: 갱신 알림 띄우기 //TODO: 갱신 알림 띄우기
const response = await responseP; const response = await Promise.race([delay(3000), responseP.value]);
responseP.value = undefined;
if(response === undefined){
//timeout이지만 일단 갱신한다.
refreshCounter.value += 1;
return;
}
if (!response.result) { if (!response.result) {
if(response.reqRefresh){ if (response.reqRefresh) {
alert(`갱신이 필요합니다: ${response.reason}`); alert(`갱신이 필요합니다: ${response.reason}`);
window.location.reload(); window.location.reload();
return; return;
@@ -103,22 +152,18 @@ async function tryRefresh() {
console.error(response.reason); console.error(response.reason);
if (!asyncReady.value) { if (!asyncReady.value) {
throw response.reason; throw response.reason;
} }
toasts.danger({ toasts.danger({
title: '갱신 실패', title: "갱신 실패",
body: response.reason, body: response.reason,
}) });
return; return;
} }
lastExecuted.value = parseTime(response.lastExecuted);
serverLocked.value = response.locked;
refreshCounter.value += 1; refreshCounter.value += 1;
//TODO: 서버와 클라이언트 버전이 다르다면 갱신 필요 //TODO: 서버와 클라이언트 버전이 다르다면 갱신 필요
} } catch (e) {
catch (e) {
//매우 심각한 버그 //매우 심각한 버그
console.error(e); console.error(e);
alert(`서버 갱신 실패: ${e}`); alert(`서버 갱신 실패: ${e}`);
@@ -130,9 +175,81 @@ void Promise.all([storeP, tryRefresh()]).then(() => {
asyncReady.value = true; asyncReady.value = true;
}); });
const lastGeneralRecordID = ref(0);
const lastWorldHistoryID = ref(0);
const generalRecords = ref(new Denque<[number, string]>());
const globalRecords = ref(new Denque<[number, string]>());
const worldHistory = ref(new Denque<[number, string]>());
watch(refreshCounter, async () => {
try {
const response = await SammoAPI.Global.GetRecentRecord({
lastGeneralRecordID: lastGeneralRecordID.value,
lastWorldHistoryID: lastWorldHistoryID.value,
});
if (response.flushGeneral) {
generalRecords.value = new Denque<[number, string]>();
}
if (response.flushGlobal) {
globalRecords.value = new Denque<[number, string]>();
}
if (response.flushHistory) {
worldHistory.value = new Denque<[number, string]>();
}
if (response.general.length) {
lastGeneralRecordID.value = Math.max(lastGeneralRecordID.value, response.general[0][0]);
}
if (response.global.length) {
lastGeneralRecordID.value = Math.max(lastGeneralRecordID.value, response.global[0][0]);
}
if (response.history.length) {
lastWorldHistoryID.value = Math.max(lastWorldHistoryID.value, response.history[0][0]);
}
while (response.general.length) {
const [id, record] = unwrap(response.general.pop());
if (!generalRecords.value.isEmpty() && id <= unwrap(generalRecords.value.get(0))[0]) {
continue;
}
if(generalRecords.value.length >= 15) {
generalRecords.value.pop();
}
generalRecords.value.unshift([id, record]);
}
while (response.global.length) {
const [id, record] = unwrap(response.global.pop());
if (!globalRecords.value.isEmpty() && id <= unwrap(globalRecords.value.get(0))[0]) {
continue;
}
if(globalRecords.value.length >= 15) {
globalRecords.value.pop();
}
globalRecords.value.unshift([id, record]);
}
while (response.history.length) {
const [id, record] = unwrap(response.history.pop());
if (!worldHistory.value.isEmpty() && id <= unwrap(worldHistory.value.get(0))[0]) {
continue;
}
if(worldHistory.value.length >= 15) {
worldHistory.value.pop();
}
worldHistory.value.unshift([id, record]);
}
} catch (e) {
console.error(e);
toasts.danger({
title: "최근 기록 갱신 실패",
body: `${e}`,
});
}
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import "@scss/common/break_500px.scss"; @import "@scss/common/break_500px.scss";
@@ -168,7 +285,7 @@ void Promise.all([storeP, tryRefresh()]).then(() => {
#container { #container {
width: 500px; width: 500px;
>main>div { > main > div {
min-height: 100px; min-height: 100px;
/* 테스트 */ /* 테스트 */
} }
-6
View File
@@ -5,8 +5,6 @@ namespace sammo;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
//로그인 검사 //로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
$userID = Session::getUserID();
//턴 실행 대기 및 갱신 증가는 API에서 //턴 실행 대기 및 갱신 증가는 API에서
@@ -20,10 +18,6 @@ $userID = Session::getUserID();
//TODO: 시나리오 정보는 gameConst 받아올때 가져오기 //TODO: 시나리오 정보는 gameConst 받아올때 가져오기
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$generalID = $session->generalID;
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>