닉네임 타이틀·마을 불러오기·동기화 비교 버그 수정
- HUD 타이틀: 닉네임 설정 시 "{닉네임}의 마을 · 회관 LvN"
- 닉네임 모달에 "마을 불러오기" 모드: 기존 마을 이름 입력 →
1초 디바운스로 존재 확인("마을을 찾았어!") → 서버 세이브 복원
(/api/village/recover — 토큰 포함 반환, 비밀코드 보호는 추후)
- pull 비교 버그 수정: 오프라인 정산이 로컬 updatedAt을 항상 현재로
만들어 다른 기기 세이브를 절대 못 받던 문제 → 디스크에서 읽은
시점(loadedUpdatedAt) 기준으로 비교
- 모달 UX: Enter로 결정(한글 조합 중 제외), IME 간섭 제거(trim 시점 이동),
모드 전환 시 자동 재체크
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
이 커밋은 다음에 포함됨:
+11
-1
@@ -137,6 +137,7 @@ function createInitialState(): GameState {
|
||||
|
||||
let state: GameState | null = null;
|
||||
let offlineMinutes: number | null = null;
|
||||
let loadedUpdatedAt = 0; // 디스크에서 읽은 시점의 updatedAt (동기화 비교 기준)
|
||||
|
||||
function passiveSpeedMul(cat: Cat): number {
|
||||
return cat.passives.reduce((mul, key) => {
|
||||
@@ -290,7 +291,10 @@ export const engine = {
|
||||
const raw = localStorage.getItem(SAVE_KEY);
|
||||
if (raw) {
|
||||
const saved = JSON.parse(raw) as GameState;
|
||||
if (saved.version === 1) state = saved;
|
||||
if (saved.version === 1) {
|
||||
state = saved;
|
||||
loadedUpdatedAt = saved.updatedAt ?? 0;
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// 저장 데이터가 깨졌으면 새로 시작
|
||||
@@ -349,10 +353,16 @@ export const engine = {
|
||||
/** 서버 세이브로 교체 (더 최신일 때) — 마이그레이션·오프라인 정산 재수행 */
|
||||
replaceState(data: GameState) {
|
||||
state = data;
|
||||
loadedUpdatedAt = data.updatedAt ?? 0;
|
||||
this.finishLoad();
|
||||
this.save();
|
||||
},
|
||||
|
||||
/** 디스크에서 읽은 시점의 updatedAt */
|
||||
loadedUpdatedAt(): number {
|
||||
return loadedUpdatedAt;
|
||||
},
|
||||
|
||||
/** 닉네임·토큰 설정 */
|
||||
setNickname(nickname: string, token: string) {
|
||||
if (!state) return;
|
||||
|
||||
새 이슈에서 참조
사용자 차단