배경
처음엔 T-126으로 만들었으나 창고 일감(T-126)이 먼저 그 번호를 써서 T-128로 옮겼다(2026-10-06). 첫 커밋 메시지의
(T-126)은 이 일감이다.
이슈 #48(클라 요청 · T-106).
경매 만료 · 거래소 전일 평균 · 받은 우편 7일 삭제 · 전체 우편 기간을 진짜로 기다리지 않고는 시험할 수 없었다.
서버의 "지금"이 핸들러마다 DateTime.UtcNow, 경매장은 따로 TimeProvider라 한 번에 넘길 자리가 없었다.
결정 (진우, 2026-10-06)
- 채취는 쌓이지 않는다 — 넘기는 순간 슬롯 기준 시각도 같이 민다. 보상이 크게 튀지 않게
- 오프셋은 저장하지 않는다 — 재시작하면 0
할 일
- [x]
GameClock(실제 시각 + 오프셋) — 핸들러·채취 스케줄러·경매 릴레이·로그인/종료 시각을 이 시계로. 세션 감시·gRPC 기한·로그·구매 ID는 실제 시간 그대로 - [x] 경매장
GameTimeProvider+SetClockOffsetRPC — 메인 릴레이가 바퀴(1초)마다 보낸다(경매장 재시작에도 다시 맞는다). 청소 타이머는 실제 시간 - [x] 우편 시각 — 이미 코드가
now를 넘겨 저장하고 있었다(received_at·claimed_at·ends_at). 바꿀 것 없음 - [x]
S_ServerTimeResponse { ServerNowUnixMs }(69) — 로그인 직후(S_LoginResponse바로 뒤) · 시간 치트 직후. UnityServerTimeReceived이벤트 · 더미 클라 핸들러 - [x] 치트 —
AdvanceTime = 12(초, 1~365일, 누적) ·ResetTime = 13. 이슈에 적힌 11은SetTraitLevel(T-115)이 먼저 써서 12·13 - [x]
TokenBucket— 시계가 뒤로 가면(ResetTime) 기준을 당긴다. 두면 넘겼던 만큼 검색이 막힌다 - [x] 테스트 —
GameClockTest·UserCheatTimeTest(채취 안 쌓임 · 다른 접속자 · 릴레이 깨움 · 초기화) · 릴레이 오프셋 동기화 ·TokenBucket역행 · 경매장GameTimeProvider·gRPC 만료 — 메인 770(1 건너뜀) · 경매장 112 통과 - [x] 문서 —
치트.md2장 · 5장(게임 시계) ·경매장.md5장 ·Server/CLAUDE.md서버 작업 규칙("지금"은 게임 시계에서만) - [ ] 실측 — 더미 클라 또는 클라 치트 창(T-106)으로 경매 등록 →
AdvanceTime 172800→ 만료 우편 · 우편 받기 →AdvanceTime 604800→ 재접속 시 삭제
완료 조건
AdvanceTime으로 시간을 넘기면 경매 만료·전일 평균·우편 삭제가 그 시각으로 판정되고, 채취는 넘긴 만큼 쌓이지 않는다.
막고 있는 것 / 선행 일감
- 없음
관련 커밋
- 487f50d — 게임 시계와 시간 조작 치트를 추가한다