Files
HolodoriCalc/docs/game-data-source.md
dal4segno a9e140fa85
Publish GitHub Pages output / publish (push) Successful in 38s
feat: copy song lists with jackets and simplify song rows
2026-10-07 21:58:31 +09:00

63 lines
7.7 KiB
Markdown

# 게임 데이터 원본
2026-09-29부터 마스터 데이터의 유일한 수집 원본은 직접 확보한 한국어 Android 게임 DB입니다.
최신 확보 버전은 `65badf8533aacbc04382f97f0f5f56740e761e6f5be6172d8440ae9061deebe7`이며,
2026-10-06 Android 앱 1.2.1에서 379개 SQLite 파일, 234,333행의 무결성 및 protobuf 해석을 검증했습니다.
서비스 적용 버전은 `applied.json`에 기록된 `65badf8533aacbc04382f97f0f5f56740e761e6f5be6172d8440ae9061deebe7`입니다.
새 수집본 등록은 서비스 데이터 반영이나 수집 기준 갱신을 의미하지 않습니다.
`data/game-db/current.json`이 버전별 `snapshots/<version>/manifest.json`을 SHA-256으로 고정합니다.
스냅샷에는 전체 테이블의 압축 JSON과 DB/JSON 해시만 저장하며, 복호화 키·메모리 덤프·계정 인증은 포함하지 않습니다.
`data/holodoridb/`와 과거 연구 기록은 이전 수집의 기록으로만 남으며 현재 수집기가 읽지 않습니다.
## 갱신
1. 게임의 새 DB를 확보·복호화합니다. 복구 디렉터리에 `decrypted-master/`, `decrypt-manifest.json`, 해당 앱 버전의 `descriptors.json`이 필요합니다.
2. protobuf가 설치된 Python으로 `python scripts/import-game-db.py <복구 디렉터리>`를 실행합니다. SQLite 해시·무결성·알 수 없는 protobuf 필드를 검사한 뒤 전체 스냅샷을 등록합니다. 같은 버전의 내용 교체는 거부합니다.
3. `npm run data:sync`로 전체 테이블을 마지막 적용 스냅샷과 비교합니다. `data/game-db/review/latest.json`의 전체 변경 전후 값과 `latest.md`를 검토하고 한국어로 변경 의미를 보고합니다. 첫 등록은 전체 스냅샷 등록으로 표시하며 모든 행을 신규 콘텐츠로 간주하지 않습니다.
4. `npm run data:apply`로 카드·보드·메모리·홀로워크 업적을 생성합니다. 검토와 같은 스냅샷만 허용하며 성공 후에만 `applied.json`을 갱신합니다.
5. 채보를 갱신할 때는 별도 게임 SUS 파일을 `data/raw/sus/`에 확보합니다. `npm run data:download-charts`는 공식 게임 CDN에 직접 접속합니다. `npm run data:collect-charts`는 로컬 SUS와 DB를 검증한 뒤 공개 시각이 지난 곡만 생성합니다. `-- --existing`은 기존 카탈로그만 재생성합니다. 이어 `npm run data:collect-chart-visuals`로 동일 SUS의 표시 데이터를 만듭니다.
수집 실패·누락·해시 불일치 시 다른 사이트나 예전 DB로 대체하지 않습니다. 지금 가진 스냅샷은 캡처 당시 버전이며, 게임의 다음 업데이트는 새로 확보해야 합니다.
실행 중인 게임에서 DB를 복구하는 과정은 아직 별도 작업입니다. 스냅샷 등록 명령이 자동으로 게임 업데이트를 감지하거나 DB를 복호화하지 않습니다.
### 2026-10-07 카드·악곡 공개 시각 분리
2026-10-06 Android 앱 1.2.1에서 확보한 전체 379개 테이블·234,333행을 비교하여 59개 변경 테이블을 검토했습니다.
사용자의 수정 지시에 따라 신규 ★5 카드 3종은 10월 7일 11:00 KST, 신곡 3곡·12채보 및 표시 데이터와 메모리 최대 개수 35→36은 12:00 KST에 반영합니다.
공식 Octo revision 97의 SUS를 DB 노트 수·점수 분모·타임라인·표시 데이터와 대조했습니다.
10월 10일·13일 공개 악곡 2곡과 다음 이벤트 포스터 normal-007은 앱 생성물에서 제외합니다. 이벤트 API 설정은 이번 반영 범위에서 제외합니다.
12:00 악곡 반영본은 11:00 카드 반영본에 신곡 3곡·12채보 및 표시 데이터를 추가하고 메모리 최대 개수를 36개로 늘립니다. 총 214곡·856채보가 되며 Pages 정책은 2026-10-07T03:00:00Z 이전 게시를 차단합니다.
## DB만으로 대체할 수 없는 자료
| 자료 | 현재 원본과 처리 |
| --- | --- |
| 카드·스킬·보드·메모리·업적·한국어 문자열·악곡 메타데이터 | 현재 게임 DB. 영어·일본어 외부 번역을 가져오지 않음 |
| 채보 본문·레인·노트 시각·점수 분모 | 게임 SUS 파일. DB의 난이도·노트 수·계수와 교차 검증. 외부 계산기 채보나 점수 참고표를 생성 입력으로 사용하지 않음 |
| 과거 이벤트 기간·배율 | `src/lib/data/events.ts`의 기존 수동 기록. 당시 외부 출처 주석을 유지. 현재 DB에서 이벤트별 설정을 찾지 못함. 기존 기록의 기간·배율은 그대로 보존 |
| 카드 별칭·표시명 | `data/card-overrides.csv`의 사용자 편집 설정 |
### 악곡 재킷 이미지
`src/lib/data/song-jackets.json`은 현재 앱 악곡 카탈로그의 곡 ID를 해시가 고정된 Android `Music.json`의 `jacketAssetId`에 연결합니다. 이미지는 별도 공식 게임 CDN의 `img_music_jacket_<jacketAssetId>` 번들에서 추출했으며, DB에서 추출한 이미지로 표시하지 않습니다.
2026-10-07 Octo revision 97에서 앱에 포함된 214곡의 번들 MD5를 확인하고 Texture2D를 최대 128px WebP로 변환했습니다. `static/images/song-jackets/`에 저장하고, 메타데이터에 번들 이름·MD5와 생성 이미지 SHA-256을 기록합니다. 재킷 추가·변경 시 현재 앱 카탈로그와 같은 DB 스냅샷의 매핑 및 공식 CDN 번들 해시를 다시 확인해야 합니다. 미래 공개 악곡과 카탈로그 밖의 자산은 포함하지 않습니다.
이번 전환에서 기존 200곡/800채보를 로컬 게임 파일로 다시 생성하고, 공식 게임 CDN의 Octo revision 93에서 신규·누락 9곡의 SUS 36개를 확보했습니다. 현재 공개된 209곡/836채보를 생성했습니다. 아직 공개되지 않은 2곡은 DB 스냅샷에만 보관합니다.
공식 게임 자산과 서버의 이벤트 설정까지 DB 하나에 들어 있는 것은 아닙니다. HolodoriDB 원격 저장소나 다른 계산기 사이트 접속은 기본 수집 과정에서 필요하지 않습니다.
첫 전환의 기존 데이터 비교는 [DB 비교 기록](research/android-master-comparison-2026-09-29.md)을 참고합니다.
기존 외부 점수 참고표와 달랐던 m0337(Pretty Guardian Matsulimit Zero)의 분모는 공식 게임 CDN revision 93에서 재확인했습니다. Hard는 544300 → 539500, Expert는 874750 → 884700이며, 같은 노트 수라도 비가시·제어점 가중치가 포함되는 분모는 별도로 검증해야 합니다. 검증용 게임 SUS는 scripts/fixtures/game-sus/에 보관합니다.
이벤트 설정의 DB·CDN 조사 범위와 서버 API 스키마 확인 결과는 [이벤트 설정 원본 조사](research/event-config-source-2026-09-29.md)를 참고합니다. CDN 목록은 조사했지만 모든 번들 내부를 검사한 것은 아닙니다.
## 게임 API 이벤트 반영
신규 이벤트의 직접 원본은 `data/game-events/2026-09-29.json`이다. 실제 앱이 받은 이벤트 응답을 메모리에서 추출·검증하고 계정별 필드를 제외했다. 마스터 DB 및 과거 수동 이벤트 기록과 출처를 구분한다.
`data/game-events/current.json`에서 적용할 이벤트 ID와 원본 파일의 SHA-256을 지정한 뒤 `npm run data:collect-events`를 실행한다. 검증한 일정·라이브 Pt·과제곡 스코어 보너스를 `src/lib/data/events-api.json`으로 생성하며 이벤트명은 DB의 포스터 이름으로 확인한다. 기존 PT·스코어 화면은 이 파일을 읽는다. 지원하지 않는 배율 조건이나 여러 챕터가 있으면 변환을 중단한다.
현재 적용 대상은 `marathon_event-normal-005`이다. 직전 릴레이 이벤트는 수동 기록을 유지하고, 미니게임 환산 계수와 보너스는 API 원본에 보관한다. 이 명령은 네트워크 수집이나 마스터 DB 갱신을 실행하지 않는다.