fix: 가오픈 빙의 후보 시간을 논리 시계에 맞춤
This commit is contained in:
@@ -18,6 +18,7 @@ const mode = computed({
|
||||
},
|
||||
});
|
||||
const sample = shallowRef<ReturnType<typeof sampleServerClock>>(null);
|
||||
const preopenLogicalSample = shallowRef<ReturnType<typeof sampleServerClock>>(null);
|
||||
const now = ref(Date.now());
|
||||
const engineRunning = ref<boolean | null>(null);
|
||||
const haltedAt = ref<number | null>(null);
|
||||
@@ -32,6 +33,9 @@ export const receiveClockSample = (
|
||||
): void => {
|
||||
if (!input.serverTime) return;
|
||||
const wallTime = input.serverWallTime ? new Date(input.serverWallTime).getTime() : undefined;
|
||||
const startsAt = input.clockStartsAt ? new Date(input.clockStartsAt).getTime() : NaN;
|
||||
const isPreopenSample =
|
||||
input.clockMode === 'realtime' && wallTime !== undefined && Number.isFinite(startsAt) && wallTime < startsAt;
|
||||
// 메인 화면의 이전 표본을 heartbeat가 재전달해도 더 최신 lobby 표본을 되감지 않는다.
|
||||
if (
|
||||
wallTime !== undefined &&
|
||||
@@ -44,14 +48,20 @@ export const receiveClockSample = (
|
||||
wallTime !== undefined &&
|
||||
wallTime === sample.value.serverWallTimeMs &&
|
||||
new Date(input.serverTime).getTime() === sample.value.serverTimeMs &&
|
||||
input.turnEngineRunning === engineRunning.value
|
||||
input.turnEngineRunning === engineRunning.value &&
|
||||
isPreopenSample === (preopenLogicalSample.value !== null)
|
||||
)
|
||||
return;
|
||||
const sampledAt = Date.now();
|
||||
// PREOPEN's displayed clock is intentionally frozen. Its negative logical tick
|
||||
// still advances, so candidate deadlines need the unpaused server sample.
|
||||
preopenLogicalSample.value = isPreopenSample ? sampleServerClock(input, sampledAt) : null;
|
||||
receiveClockEngineState(input.turnEngineRunning ?? null);
|
||||
sample.value = sampleServerClock(
|
||||
input.turnEngineRunning === false ? { ...input, clockRunning: false, clockStartsAt: null } : input
|
||||
input.turnEngineRunning === false ? { ...input, clockRunning: false, clockStartsAt: null } : input,
|
||||
sampledAt
|
||||
);
|
||||
now.value = Date.now();
|
||||
now.value = sampledAt;
|
||||
};
|
||||
|
||||
export const advanceClockDisplay = (): void => {
|
||||
@@ -64,7 +74,13 @@ const projection = computed(() =>
|
||||
sample.value ? projectServerClock(sample.value, haltedAt.value ?? now.value) : null
|
||||
);
|
||||
// 마감 판정은 표시 모드와 무관하게 서버가 투영한 GAME 시각을 사용한다.
|
||||
const gameTime = computed(() => projection.value?.time ?? null);
|
||||
const gameTime = computed(() => {
|
||||
const preopen = preopenLogicalSample.value;
|
||||
if (preopen) {
|
||||
return new Date(preopen.serverTimeMs + Math.max(0, now.value - preopen.sampledClientTimeMs));
|
||||
}
|
||||
return projection.value?.time ?? null;
|
||||
});
|
||||
const accelerated = computed(() => projection.value?.rate === 2 && engineRunning.value !== false);
|
||||
const label = computed(() => (mode.value === 'real' ? '실제 시간 기준' : '게임 시간 기준'));
|
||||
const time = computed(() => {
|
||||
|
||||
Reference in New Issue
Block a user