data: switch to recovered game DB and refresh cards and charts
Publish GitHub Pages output / publish (push) Successful in 44s
Publish GitHub Pages output / publish (push) Successful in 44s
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
# 게임 데이터 원본
|
||||
|
||||
2026-09-29부터 마스터 데이터의 유일한 수집 원본은 직접 확보한 한국어 Android 게임 DB입니다.
|
||||
현재 버전은 `546b8e2e37db368c6731e148b88611cef105bbaa66ff567f5c1584711ef979a4`이며,
|
||||
379개 SQLite 파일, 233,312행의 무결성 및 protobuf 해석을 검증했습니다.
|
||||
|
||||
`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를 복호화하지 않습니다.
|
||||
|
||||
## DB만으로 대체할 수 없는 자료
|
||||
|
||||
| 자료 | 현재 원본과 처리 |
|
||||
| --- | --- |
|
||||
| 카드·스킬·보드·메모리·업적·한국어 문자열·악곡 메타데이터 | 현재 게임 DB. 영어·일본어 외부 번역을 가져오지 않음 |
|
||||
| 채보 본문·레인·노트 시각·점수 분모 | 게임 SUS 파일. DB의 난이도·노트 수·계수와 교차 검증. 외부 계산기 채보나 점수 참고표를 생성 입력으로 사용하지 않음 |
|
||||
| 과거 이벤트 기간·배율 | `src/lib/data/events.ts`의 기존 수동 기록. 당시 외부 출처 주석을 유지. 현재 DB에서 이벤트별 설정을 찾지 못함. 앱의 EventListEventInfoResponse에 일정·특효 필드가 존재하나 실제 응답은 아직 미수집 |
|
||||
| 카드 별칭·표시명 | `data/card-overrides.csv`의 사용자 편집 설정 |
|
||||
|
||||
이번 전환에서 기존 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 목록은 조사했지만 모든 번들 내부를 검사한 것은 아닙니다.
|
||||
@@ -0,0 +1,293 @@
|
||||
# 계산기 데이터와 Android 복호화 DB 비교 — 2026-09-29
|
||||
|
||||
## 결론
|
||||
|
||||
기존 카드 185개의 계산용 데이터는 일치한다. DB에는 신규 카드 4개, 곡 7개, 포스터 1개, 보드 노드 1개가 추가되어 있어 전체 데이터는 일치하지 않는다. 기존 카드 성장치와 스킬 수치가 바뀐 것은 아니다.
|
||||
|
||||
비교 대상은 현재 작업 폴더의 계산기 데이터다. 배포된 사이트의 파일은 이번 조사에서 별도 확인하지 않았다. 앱 데이터 수정·배포는 하지 않았다.
|
||||
|
||||
## 비교 기준과 검증
|
||||
|
||||
- 계산기 마스터 버전: `845cee36af22b657511ca406b5417cac7076a001208518c9601d6389a5046ddd`
|
||||
- 복호화 DB 마스터 버전: `546b8e2e37db368c6731e148b88611cef105bbaa66ff567f5c1584711ef979a4`
|
||||
- 공식 eng/kor/jpn 원격 main을 `npm run data:sync`로 fetch했다. 모두 기존 9월 26일 수집 기준과 동일했고 카드/스킬·곡·이벤트·번역·기타 시스템의 원격 추가 변경은 없었다. 세 검토 파일을 모두 확인했다.
|
||||
- 현재 Android 1.2.0 바이너리에서 Protocol Buffers 파일 정의 612개를 추출했다. 실제 DB 379개, 233,312행의 레코드를 모두 해석했고 오류나 해석되지 않은 protobuf 필드는 없었다.
|
||||
- enum 접두사와 기본값 표기를 정규화했다. DB의 보조 검색 컬럼 추가를 레코드 삭제/추가로 오인하지 않도록 기존 식별자로 비교했다. 큰 정수 client_id는 원본 JSON의 정밀도 손실을 피하도록 protobuf의 정확한 문자열 ID를 사용했다.
|
||||
- 현재 수집 코드를 조사 폴더의 격리된 출력으로 실행해 기준 원격과 DB의 계산기 요약을 각각 재생성했다. 실제 서비스 출력 경로는 변경하지 않았다.
|
||||
- 현재 card-master의 34개 표 및 저장된 번역은 기준 원격과 일치한다. 카드·보드·메모리 요약 3개 파일도 기준 원격을 재생성한 결과와 정확히 일치한다.
|
||||
- 에뮬레이터에서 확보한 번역은 한국어다. 신규 영어·일본어 번역의 최신성은 검증하지 않았다. 비교용 생성에서 이 두 언어는 기준 원격 자료를 유지했으며 한국어 화면/계산용 요약만 최신 DB와 검증했다.
|
||||
|
||||
## 카드와 스킬
|
||||
|
||||
기존 185개의 카드 원본 레코드 및 정규화된 계산기 카드 객체에 변경·삭제가 없다. 최대 레벨 능력치, 패시브/액티브/스페셜, 연결 효과, 의상 설명 등 계산기에 저장되는 기존 카드의 전체 필드가 동일하다.
|
||||
|
||||
| 신규 카드 | 속성 | 한국어 카드명 | ID |
|
||||
|---|---|---|---|
|
||||
| 호쇼 마린 | 퓨어 | 보물 독점♡워터 캐논 | `card-00023-5-uniq-0085-00` |
|
||||
| 하쿠이 코요리 | 해피 | 뒤돌아본 순간의 aventure | `card-00037-5-uniq-0086-00` |
|
||||
| 코보 카나에루 | 큐트 | 파도 사이에 흔들리는 Body & Soul | `card-03009-5-uniq-0088-00` |
|
||||
| 하코스 벨즈 | 해피 | 이게 나의 강추! | `card-04012-5-uniq-0087-00` |
|
||||
|
||||
신규 카드는 모두 ★5다. 관련 패시브/액티브/스페셜 정의는 각각 4개, 각 스킬 레벨 표는 각각 8행 추가됐다. 액티브 효과 2개가 추가됐고 기존 효과 수치는 동일하다. 의상과 SD 의상은 각각 7개 추가됐으며 의상 리더 스킬도 7개 추가됐다. 카드 레벨·한계돌파·잠재력 성장 표와 스킬 발동 조건 표는 동일하다.
|
||||
|
||||
## 곡과 채보
|
||||
|
||||
기준 마스터 204곡 → 복호화 DB 211곡. 난이도 표는 816행 → 844행이다. 현재 계산기 정확 채보 카탈로그는 200곡·800개 난이도다. 포함된 800개 모두 곡명, 난이도 레벨, 시작 시간, 가창 유형/멤버가 DB와 같고, 저장된 점수 공식의 곡 계수도 같다.
|
||||
|
||||
| 신규 곡 | ID | DB 시작 시간 (KST) | EASY / NORMAL / HARD / EXPERT |
|
||||
|---|---|---|---|
|
||||
| PARADISE! | `m0354` | 2026-09-29 11:00 | 4 / 10 / 19 / 26 |
|
||||
| Play Dice! | `m0357` | 2026-09-29 12:00 | 4 / 11 / 20 / 28 |
|
||||
| PROPOSE | `m0358` | 2026-09-29 12:00 | 3 / 10 / 18 / 25 |
|
||||
| BAKU LOVE CHEMISTRY | `m0413` | 2026-09-29 12:00 | 5 / 13 / 20 / 28 |
|
||||
| Kyapi | `m0548` | 2026-09-29 12:00 | 4 / 10 / 17 / 26 |
|
||||
| Wonky Monkey | `m0375` | 2026-10-01 00:00 | 5 / 11 / 18 / 25 |
|
||||
| KONKON Beats | `m0376` | 2026-10-05 00:00 | 5 / 12 / 18 / 26 |
|
||||
|
||||
10월 1일과 5일의 값은 DB에 선행 포함된 시작 시간이며, 실제 서비스 일정 확정이나 현재 플레이 가능을 뜻하지 않는다. 곡명은 확보한 Music.titleLangId → LangMusic_Kor 관계로 확인했다.
|
||||
|
||||
이번 신규 7곡 외에, 기준 마스터에 이미 있었지만 현재 계산기 정확 채보 카탈로그에 없는 4곡도 있다:
|
||||
|
||||
- **Glitch Through** (`m0351`), DB 시작 2026-09-21 20:00 KST
|
||||
- **64.** (`m0352`), DB 시작 2026-09-25 20:00 KST
|
||||
- **Watcha Gatcha!!!!!!!!** (`m0525`), DB 시작 2026-09-26 21:00 KST
|
||||
- **Lethal Dose Paranoid** (`m0350`), DB 시작 2026-09-23 20:00 KST
|
||||
|
||||
기존 4곡(m0349~m0352)에는 MV URL이 추가됐다. 기존 곡의 다른 Music 필드와 난이도 레벨은 동일하다. MusicDifficultyChart의 기존 816행에서는 이전 스키마의 `chartHash`, `normalNoteCount`가 사라졌고 다른 기존 필드는 동일하다. 이를 816개 채보 자체의 변경으로 판정하지 않았다.
|
||||
|
||||
실제 노트 시각·롱노트 형상·노트별 점수 가중치 등 SUS 채보 본문은 이 마스터 DB에 없으므로, 현재 채보 파일 자체의 동일성은 이번 비교에서 검증하지 않았다.
|
||||
|
||||
## 보드·메모리·업적
|
||||
|
||||
- 기존 보드 노드의 계산 수치와 조건은 동일하다. 4개 보드 모델에 `G-025`가 각 1개씩 추가되어 모델별 153 → 154개 위치가 된다.
|
||||
- 신규 G-025는 스플래시 볼 보상량 +5‰(0.5%) 효과다. 플레이어 레벨 30 조건, 포인트 3, 공용 보드 아이템 160개 비용이 포함돼 있다.
|
||||
- 기존 Y-004, Y-018, Y-022 설명이 **“전체 악곡” → “단체 악곡”**으로 수정됐다. 효과 수치/대상 조건 자체가 바뀐 것은 아니다.
|
||||
- 포스터 34 → 35개. `poster-marathon_event-normal-005-chapter-01`이 추가됐다. 수집 보너스 표는 그대로이며 보유 상한에서 적용 가능한 값이 64‰ → 65‰(6.4% → 6.5%)가 된다.
|
||||
- 홀로워크 업적의 멤버 54명별 완료 횟수 임계값은 현재 계산기와 전부 일치한다.
|
||||
|
||||
## 이벤트·번역·기타 시스템
|
||||
|
||||
- EventStory 30행, EventStoryChapter 11행은 기존과 동일하다. 신규 이벤트 관련 포스터 참조는 있지만, 이 DB에는 MarathonEvent 일정·보너스 표가 없어 현재 events.ts와 최신 이벤트 일정/배율의 일치를 확정할 수 없다.
|
||||
- 한국어 문자열은 확보된 123개 Lang 표에서 4,685행 추가, 9행 수정, 1행 삭제다. 보드 표현 수정 외에 소다팝 라군 게이트 이름/설명, 대사 오역 수정, 이벤트 보너스 안내 수정이 있다.
|
||||
- 도움말에는 “스킬 발동 빈도 UP” 해방 시 편성에 따라 유닛 스코어 표시값이 낮아질 수 있다는 설명이 추가됐다. 이는 설명 변경으로 확인했으며 계산 공식 변경의 증거로 취급하지 않았다.
|
||||
- 캐릭터 62명의 color5가 추가됐다. 소다팝 라군 관련 지역/시설, 파크 NPC·대사·위치·퀘스트, 낚시 도감/추첨/시간대, 스플래시 볼 보상 등 시스템 데이터가 추가됐다.
|
||||
- 새 DB 표 8개: `LangParkTimeTransition_Kor`, `MusicStartupNotification`, `ParkFishingFishBook`, `ParkFishingFishLottery`, `ParkFishingTimePeriod`, `ParkTimeTransition`, `SplashBallScoreReward`, `SplashBallTeamRankReward`.
|
||||
- 기준에는 있었던 LangChasePatrolSkill_Kor(4행), LangParkHighLow_Kor(1행)는 이번 DB 묶음에 없다. 관련 필드가 새 스키마에서 사라진 점은 확인했으나, 게임 기능 자체가 삭제되었다고 단정하지 않는다.
|
||||
- 여러 기타 시스템의 필드 제거·추가도 포함된다. 이름만으로 의미를 확정하기 어려운 변경은 아래 표 및 전체 필드 차이 JSON에 원문 값으로 보존했다.
|
||||
|
||||
## 전체 변경 집계
|
||||
|
||||
현재 DB 379개 중 175개는 기준과 레코드 내용이 같고, 204개는 신규 표 또는 레코드 차이가 있다. 현재 DB에 존재하는 표끼리 비교하면 45,045행 추가, 1행 삭제, 1,522행 수정이다. 별도로 기준 번역 표 2개(총 5행)가 이번 DB 묶음에 없다. 큰 변경 수에는 신규 파크 NPC·대사 등과 스키마 필드 변경이 포함되며, 계산기 수치가 그만큼 바뀌었다는 뜻은 아니다.
|
||||
|
||||
전체 전후 필드 값: `data/inspection/android-master-2026-09-29/db-comparison.json`
|
||||
실제 계산기 데이터 비교: `data/inspection/android-master-2026-09-29/app-comparison.json`
|
||||
해석된 DB JSON: `data/inspection/android-master-2026-09-29/decoded-json/`
|
||||
|
||||
| 표 | 이전 행 | DB 행 | 추가 | 삭제 | 수정 |
|
||||
|---|---:|---:|---:|---:|---:|
|
||||
| AchievementGroup | 77 | 79 | 2 | 0 | 0 |
|
||||
| AppealText | 16 | 17 | 1 | 0 | 0 |
|
||||
| Area | 8 | 9 | 1 | 0 | 0 |
|
||||
| AreaAppearance | 22 | 30 | 8 | 0 | 0 |
|
||||
| AreaGrouping | 2 | 3 | 1 | 0 | 0 |
|
||||
| AreaMap | 14 | 22 | 8 | 0 | 0 |
|
||||
| AreaSelector | 7 | 8 | 1 | 0 | 1 |
|
||||
| AreaStory | 17 | 23 | 6 | 0 | 0 |
|
||||
| AreaStoryChapter | 2 | 3 | 1 | 0 | 0 |
|
||||
| AssetEmbeddingText | 62 | 87 | 25 | 0 | 0 |
|
||||
| AssetStreamingMute | 72 | 73 | 1 | 0 | 0 |
|
||||
| Card | 185 | 189 | 4 | 0 | 0 |
|
||||
| Character | 62 | 62 | 0 | 0 | 62 |
|
||||
| CharacterLiveDialogueVoice | 6336 | 6432 | 96 | 0 | 0 |
|
||||
| CharacterVoice | 16582 | 18187 | 1605 | 0 | 0 |
|
||||
| ChasePatrolSkill | 3 | 3 | 0 | 0 | 3 |
|
||||
| ChaseSetting | 1 | 1 | 0 | 0 | 1 |
|
||||
| Cheat | 60 | 77 | 17 | 0 | 10 |
|
||||
| CircuitSetting | 1 | 1 | 0 | 0 | 1 |
|
||||
| Condition | 2267 | 2768 | 501 | 0 | 1 |
|
||||
| Costume | 193 | 200 | 7 | 0 | 0 |
|
||||
| Emblem | 949 | 987 | 38 | 0 | 39 |
|
||||
| ExchangeBooth | 294 | 304 | 10 | 0 | 0 |
|
||||
| ExchangeBoothFixedItem | 1044 | 1306 | 262 | 0 | 0 |
|
||||
| ExchangeBoothGroup | 70 | 76 | 6 | 0 | 0 |
|
||||
| Facility | 65 | 108 | 43 | 0 | 0 |
|
||||
| FacilityAppearance | 187 | 271 | 84 | 0 | 2 |
|
||||
| FacilityLevel | 30 | 51 | 21 | 0 | 0 |
|
||||
| FeatureLock | 47 | 53 | 6 | 0 | 0 |
|
||||
| Gacha | 17 | 21 | 4 | 0 | 0 |
|
||||
| GachaButton | 38 | 46 | 8 | 0 | 0 |
|
||||
| GachaPoint | 8 | 10 | 2 | 0 | 0 |
|
||||
| HelpContent | 127 | 131 | 4 | 0 | 0 |
|
||||
| InstantTips | 16 | 22 | 6 | 0 | 0 |
|
||||
| Item | 126 | 133 | 7 | 0 | 0 |
|
||||
| JumpRopePhaseGimmick | 69 | 69 | 0 | 0 | 43 |
|
||||
| JumpRopeSetting | 1 | 1 | 0 | 0 | 1 |
|
||||
| LangAchievementGroup_Kor | 77 | 79 | 2 | 0 | 0 |
|
||||
| LangAppealText_Kor | 32 | 34 | 2 | 0 | 0 |
|
||||
| LangArea_Kor | 16 | 18 | 2 | 0 | 0 |
|
||||
| LangAreaGrouping_Kor | 4 | 6 | 2 | 0 | 0 |
|
||||
| LangAreaStory_Kor | 17 | 23 | 6 | 0 | 0 |
|
||||
| LangAreaStoryChapter_Kor | 2 | 3 | 1 | 0 | 0 |
|
||||
| LangAssetEmbeddingText_Kor | 62 | 87 | 25 | 0 | 0 |
|
||||
| LangCard_Kor | 185 | 189 | 4 | 0 | 0 |
|
||||
| LangCharacterVoice_Kor | 26907 | 28813 | 1906 | 0 | 0 |
|
||||
| LangClientCommon_Kor | 3196 | 3338 | 143 | 1 | 0 |
|
||||
| LangCondition_Kor | 82 | 95 | 13 | 0 | 0 |
|
||||
| LangCostume_Kor | 193 | 200 | 7 | 0 | 0 |
|
||||
| LangEmblem_Kor | 949 | 987 | 38 | 0 | 0 |
|
||||
| LangFacility_Kor | 107 | 144 | 37 | 0 | 2 |
|
||||
| LangFacilityAppearance_Kor | 28 | 41 | 13 | 0 | 0 |
|
||||
| LangFacilityLevel_Kor | 21 | 36 | 15 | 0 | 0 |
|
||||
| LangFeatureLock_Kor | 54 | 60 | 6 | 0 | 0 |
|
||||
| LangGachaPoint_Kor | 8 | 10 | 2 | 0 | 0 |
|
||||
| LangGeneratedLiveActiveSkillEffect_Kor | 53 | 55 | 2 | 0 | 0 |
|
||||
| LangGeneratedLiveActiveSkillLevel_Kor | 373 | 381 | 8 | 0 | 0 |
|
||||
| LangGeneratedLiveLeaderSkill_Kor | 185 | 192 | 7 | 0 | 0 |
|
||||
| LangGeneratedLivePassiveSkillLevel_Kor | 370 | 378 | 8 | 0 | 0 |
|
||||
| LangGeneratedLiveSpecialSkillLevel_Kor | 370 | 378 | 8 | 0 | 0 |
|
||||
| LangGeneratedSkillTreeEffect_Kor | 121 | 122 | 1 | 0 | 2 |
|
||||
| LangGeneratedSkillTreeEffectPassiveTrigger_Kor | 81 | 81 | 0 | 0 | 1 |
|
||||
| LangHelpContent_Kor | 256 | 264 | 8 | 0 | 1 |
|
||||
| LangInstantTips_Kor | 11 | 15 | 4 | 0 | 0 |
|
||||
| LangItem_Kor | 252 | 266 | 14 | 0 | 0 |
|
||||
| LangLiveDialogueVoice_Kor | 3353 | 3405 | 52 | 0 | 0 |
|
||||
| LangLiveSkin_Kor | 87 | 89 | 2 | 0 | 0 |
|
||||
| LangLiveSkinGroup_Kor | 56 | 57 | 1 | 0 | 0 |
|
||||
| LangLoadingDisplay_Kor | 104 | 110 | 6 | 0 | 0 |
|
||||
| LangMainStory_Kor | 36 | 51 | 15 | 0 | 0 |
|
||||
| LangMainStoryChapter_Kor | 4 | 6 | 2 | 0 | 0 |
|
||||
| LangMiniGame_Kor | 20 | 24 | 4 | 0 | 0 |
|
||||
| LangMission_Kor | 1666 | 1794 | 128 | 0 | 0 |
|
||||
| LangMissionGroup_Kor | 24 | 26 | 2 | 0 | 0 |
|
||||
| LangMusic_Kor | 2096 | 2167 | 71 | 0 | 0 |
|
||||
| LangMusicMv_Kor | 154 | 157 | 3 | 0 | 0 |
|
||||
| LangParkAccessory_Kor | 163 | 217 | 54 | 0 | 0 |
|
||||
| LangParkEmotion_Kor | 918 | 1188 | 270 | 0 | 0 |
|
||||
| LangParkFishingBait_Kor | 0 | 16 | 16 | 0 | 0 |
|
||||
| LangParkFishingFish_Kor | 0 | 162 | 162 | 0 | 0 |
|
||||
| LangParkFishingFishSpecies_Kor | 0 | 4 | 4 | 0 | 0 |
|
||||
| LangParkFishingRod_Kor | 0 | 8 | 8 | 0 | 0 |
|
||||
| LangParkPermanenceAction_Kor | 3 | 9 | 6 | 0 | 0 |
|
||||
| LangParkQuest_Kor | 272 | 340 | 68 | 0 | 0 |
|
||||
| LangParkQuestChapter_Kor | 59 | 61 | 2 | 0 | 0 |
|
||||
| LangParkQuestStep_Kor | 768 | 923 | 155 | 0 | 0 |
|
||||
| LangParkTalk_Kor | 4432 | 5577 | 1145 | 0 | 1 |
|
||||
| LangParkTargetMapping_Kor | 26 | 48 | 22 | 0 | 0 |
|
||||
| LangParkTimeTransition_Kor | 0 | 12 | 12 | 0 | 0 |
|
||||
| LangPoster_Kor | 34 | 35 | 1 | 0 | 0 |
|
||||
| LangResourceObtainmentRoute_Kor | 42 | 50 | 8 | 0 | 0 |
|
||||
| LangResourceTypeDetail_Kor | 49 | 50 | 1 | 0 | 0 |
|
||||
| LangSdCostume_Kor | 301 | 308 | 7 | 0 | 0 |
|
||||
| LangSdCostumeHairAccessory_Kor | 270 | 378 | 108 | 0 | 0 |
|
||||
| LangSpecialStory_Kor | 2 | 3 | 1 | 0 | 0 |
|
||||
| LangSplashBall_Kor | 0 | 4 | 4 | 0 | 0 |
|
||||
| LangTips_Kor | 136 | 162 | 26 | 0 | 0 |
|
||||
| LangTipsDetail_Kor | 281 | 315 | 34 | 0 | 2 |
|
||||
| LangWork_Kor | 4 | 5 | 1 | 0 | 0 |
|
||||
| LiveActiveSkill | 187 | 191 | 4 | 0 | 0 |
|
||||
| LiveActiveSkillEffect | 53 | 55 | 2 | 0 | 0 |
|
||||
| LiveActiveSkillLevel | 373 | 381 | 8 | 0 | 0 |
|
||||
| LiveDialogueVoice | 3353 | 3405 | 52 | 0 | 0 |
|
||||
| LiveDialogueVoiceCharacter | 6521 | 6621 | 100 | 0 | 0 |
|
||||
| LiveLeaderSkill | 185 | 192 | 7 | 0 | 0 |
|
||||
| LivePassiveSkill | 185 | 189 | 4 | 0 | 0 |
|
||||
| LivePassiveSkillLevel | 370 | 378 | 8 | 0 | 0 |
|
||||
| LiveRewardUpStaminaEffect | 10 | 10 | 0 | 0 | 3 |
|
||||
| LiveSkin | 282 | 283 | 1 | 0 | 0 |
|
||||
| LiveSkinGroup | 56 | 57 | 1 | 0 | 0 |
|
||||
| LiveSpecialCardDialogue | 307 | 335 | 28 | 0 | 0 |
|
||||
| LiveSpecialCostumeDialogue | 307 | 335 | 28 | 0 | 0 |
|
||||
| LiveSpecialSkill | 185 | 189 | 4 | 0 | 0 |
|
||||
| LiveSpecialSkillLevel | 370 | 378 | 8 | 0 | 0 |
|
||||
| LoadingDisplay | 107 | 110 | 3 | 0 | 0 |
|
||||
| MainStory | 36 | 51 | 15 | 0 | 0 |
|
||||
| MainStoryChapter | 2 | 3 | 1 | 0 | 0 |
|
||||
| MarathonMiniGameRewardUpStaminaEffect | 12 | 15 | 3 | 0 | 0 |
|
||||
| MiniGame | 5 | 6 | 1 | 0 | 0 |
|
||||
| MiniGameMultiGame | 8 | 10 | 2 | 0 | 0 |
|
||||
| MiniGameNpcLotteryPeriod | 4 | 5 | 1 | 0 | 0 |
|
||||
| MiniGameRewardUpStaminaConversion | 1 | 2 | 1 | 0 | 0 |
|
||||
| MiniGameRewardUpStaminaEffect | 12 | 15 | 3 | 0 | 0 |
|
||||
| Mission | 1651 | 1745 | 94 | 0 | 0 |
|
||||
| MissionGroup | 27 | 30 | 3 | 0 | 0 |
|
||||
| MissionPass | 3 | 3 | 0 | 0 | 1 |
|
||||
| MissionPassLevel | 153 | 153 | 0 | 0 | 1 |
|
||||
| MissionProgress | 11420 | 11625 | 205 | 0 | 0 |
|
||||
| MissionTypeDefaultNavigation | 107 | 113 | 6 | 0 | 2 |
|
||||
| Music | 204 | 211 | 7 | 0 | 4 |
|
||||
| MusicDifficulty | 816 | 844 | 28 | 0 | 0 |
|
||||
| MusicDifficultyChart | 816 | 844 | 28 | 0 | 816 |
|
||||
| MusicMv | 288 | 294 | 6 | 0 | 0 |
|
||||
| MusicStartupNotification | 0 | 64 | 64 | 0 | 0 |
|
||||
| OctoSetting | 1 | 1 | 0 | 0 | 1 |
|
||||
| ParkAccessory | 190 | 244 | 54 | 0 | 0 |
|
||||
| ParkCall | 64 | 71 | 7 | 0 | 0 |
|
||||
| ParkCharacterShop | 4 | 5 | 1 | 0 | 0 |
|
||||
| ParkEmotion | 918 | 1188 | 270 | 0 | 0 |
|
||||
| ParkFishingBait | 0 | 8 | 8 | 0 | 0 |
|
||||
| ParkFishingFish | 0 | 81 | 81 | 0 | 0 |
|
||||
| ParkFishingFishBook | 0 | 3 | 3 | 0 | 0 |
|
||||
| ParkFishingFishIcon | 0 | 10 | 10 | 0 | 0 |
|
||||
| ParkFishingFishLottery | 0 | 2925 | 2925 | 0 | 0 |
|
||||
| ParkFishingFishSpecies | 0 | 4 | 4 | 0 | 0 |
|
||||
| ParkFishingRod | 0 | 4 | 4 | 0 | 0 |
|
||||
| ParkFishingSetting | 1 | 1 | 0 | 0 | 1 |
|
||||
| ParkFishingSpot | 0 | 12 | 12 | 0 | 0 |
|
||||
| ParkFishingTimePeriod | 0 | 2 | 2 | 0 | 0 |
|
||||
| ParkFishingTotalCaughtReward | 0 | 18 | 18 | 0 | 0 |
|
||||
| ParkFixedSymbol | 2 | 108 | 106 | 0 | 0 |
|
||||
| ParkGraph | 315 | 368 | 53 | 0 | 0 |
|
||||
| ParkHighLow | 1 | 1 | 0 | 0 | 1 |
|
||||
| ParkNotice | 17 | 21 | 4 | 0 | 0 |
|
||||
| ParkNpc | 13165 | 21317 | 8152 | 0 | 0 |
|
||||
| ParkNpcGroup | 12728 | 20843 | 8115 | 0 | 0 |
|
||||
| ParkPermanence | 115 | 149 | 34 | 0 | 0 |
|
||||
| ParkPermanenceAction | 120 | 162 | 42 | 0 | 0 |
|
||||
| ParkPosition | 802 | 1235 | 433 | 0 | 0 |
|
||||
| ParkPositionGrouping | 197 | 356 | 159 | 0 | 0 |
|
||||
| ParkPrintBoothComposition | 18 | 18 | 0 | 0 | 18 |
|
||||
| ParkQuest | 244 | 292 | 48 | 0 | 244 |
|
||||
| ParkQuestChapter | 59 | 61 | 2 | 0 | 0 |
|
||||
| ParkQuestCookingPuzzle | 14 | 14 | 0 | 0 | 14 |
|
||||
| ParkQuestLive | 130 | 144 | 14 | 0 | 0 |
|
||||
| ParkQuestLiveMusicDifficulty | 520 | 576 | 56 | 0 | 0 |
|
||||
| ParkQuestSplashBall | 0 | 2 | 2 | 0 | 0 |
|
||||
| ParkQuestStep | 766 | 921 | 155 | 0 | 0 |
|
||||
| ParkQuestStepAction | 774 | 929 | 155 | 0 | 0 |
|
||||
| ParkRandomSymbol | 198 | 296 | 98 | 0 | 0 |
|
||||
| ParkTalk | 4841 | 6056 | 1215 | 0 | 18 |
|
||||
| ParkTalkFree | 7406 | 13633 | 6227 | 0 | 174 |
|
||||
| ParkTalkFreeGrouping | 148 | 194 | 46 | 0 | 4 |
|
||||
| ParkTargetMapping | 8549 | 15328 | 6779 | 0 | 0 |
|
||||
| ParkTimeTransition | 0 | 6 | 6 | 0 | 0 |
|
||||
| ParkTreasure | 42 | 70 | 28 | 0 | 42 |
|
||||
| PlayerLevel | 50 | 70 | 20 | 0 | 0 |
|
||||
| Poster | 34 | 35 | 1 | 0 | 0 |
|
||||
| ResourceObtainmentRoute | 136 | 182 | 46 | 0 | 0 |
|
||||
| ResourceTypeDetail | 25 | 26 | 1 | 0 | 0 |
|
||||
| SdCostume | 301 | 308 | 7 | 0 | 0 |
|
||||
| SdCostumeHairAccessory | 270 | 378 | 108 | 0 | 0 |
|
||||
| Setting | 1 | 1 | 0 | 0 | 1 |
|
||||
| ShopChargeItemProduct | 141 | 153 | 12 | 0 | 0 |
|
||||
| SkillTreeEffect | 121 | 122 | 1 | 0 | 0 |
|
||||
| SkillTreeNode | 324 | 325 | 1 | 0 | 0 |
|
||||
| SkillTreeNodePosition | 612 | 616 | 4 | 0 | 0 |
|
||||
| SpecialStory | 2 | 3 | 1 | 0 | 1 |
|
||||
| SplashBall | 0 | 2 | 2 | 0 | 0 |
|
||||
| SplashBallBall | 0 | 8 | 8 | 0 | 0 |
|
||||
| SplashBallPlayerPosition | 0 | 18 | 18 | 0 | 0 |
|
||||
| SplashBallScoreReward | 0 | 10 | 10 | 0 | 0 |
|
||||
| SplashBallSetting | 1 | 1 | 0 | 0 | 1 |
|
||||
| SplashBallTeamRankReward | 0 | 3 | 3 | 0 | 0 |
|
||||
| Story | 153 | 175 | 22 | 0 | 0 |
|
||||
| SystemSound | 301 | 363 | 62 | 0 | 0 |
|
||||
| SystemVoice | 6156 | 6966 | 810 | 0 | 0 |
|
||||
| Tips | 140 | 166 | 26 | 0 | 0 |
|
||||
| TipsDetail | 288 | 329 | 41 | 0 | 2 |
|
||||
| Tutorial | 58 | 67 | 9 | 0 | 0 |
|
||||
| Work | 2040 | 2295 | 255 | 0 | 0 |
|
||||
| WorkDisplay | 2 | 3 | 1 | 0 | 0 |
|
||||
| WorkEvaluationRank | 200 | 250 | 50 | 0 | 0 |
|
||||
| WorkSlot | 4 | 5 | 1 | 0 | 0 |
|
||||
| LangChasePatrolSkill_Kor (DB 묶음에 없음) | 4 | — | — | — | — |
|
||||
| LangParkHighLow_Kor (DB 묶음에 없음) | 1 | — | — | — | — |
|
||||
@@ -0,0 +1,43 @@
|
||||
# Android 마스터 DB 열기 경로 조사
|
||||
|
||||
후속 결과: 같은 날 메모리에서 379개 파일별 키를 복구하고 전체 DB의 복호화와 SQLite 검증에 성공했다. 아래 미확인 항목은 이 최초 정적 조사 시점 기준이며, 후속 검증은 [복구 기록](android-master-recovery-2026-09-29.md)을 참고한다.
|
||||
|
||||
2026-09-29, LDPlayer 14 / Android 14 / 게임 1.2.0에서 확인했다.
|
||||
앱 파일과 프로세스는 수정하지 않았다. 테스트 계정 인증 정보 사용은 허용받았지만 이번 조사에서는 사용하지 않았다.
|
||||
|
||||
## 실행 상태에서 확인한 사실
|
||||
|
||||
- PID 4380의 파일 디스크립터에 외부 앱 저장소 `files/EB0A191797624DD3A48FA681D3061212/`의 후보 파일들이 열려 있었다.
|
||||
- 같은 프로세스가 앱의 ARM64 `libsqlcipher.so`를 로드하고 있었다.
|
||||
- 이 폴더에는 379개 파일이 있었다. 두 표본의 첫 32바이트에 일반 SQLite 헤더는 없었다.
|
||||
- 시스템 SQLite도 함께 로드되어 있으므로, 라이브러리 존재만으로 모든 파일을 SQLCipher DB라고 판정하지 않았다.
|
||||
|
||||
## 현재 Android 바이너리에서 확인한 호출 경로
|
||||
|
||||
복사한 `libil2cpp.so`와 복호화한 IL2CPP 메타데이터를 연결하고 ARM64 명령을 확인했다. 아래 주소는 이 바이너리의 RVA이며 실행 시 절대 주소가 아니다.
|
||||
|
||||
1. `MasterManagerBase<object>.CreateCryptKey` (`0xB6283A0`)는 파일 정보 인터페이스의 슬롯 3을 호출한다. 메타데이터에서 이 슬롯은 `IMasterFileInfo.get_CryptoKey`다. 앞뒤 인자를 포함한 세 문자열 연결 결과를 UTF-8 바이트로 변환한다. 앞뒤 문자열의 실제 값은 이번 기록에서 확정하지 않았다.
|
||||
2. `MasterDBConnectionPool.GetConnection` (`0xDC45458`)은 기존 연결을 찾고, 없으면 파일 경로와 키 바이트를 `CreateConnection`으로 넘긴다.
|
||||
3. `CreateConnection` (`0xDC45678`)은 URI를 만들고 `SQLite3Manager.Open`에 플래그 `0x41`을 전달한다.
|
||||
4. 키를 받는 `SQLite3Manager.Open` (`0xDC45A18`)은 내부 Open (`0xDC48138`)을 호출한 뒤 `sqlite3_key` (`0xDC48020`)에 연결과 키 바이트, 길이를 전달한다.
|
||||
5. 내부 Open은 플래그가 있는 경우 `sqlite3_open_v2`를 호출한다. `0x41`은 SQLite의 READONLY(1)와 URI(0x40) 조합이다.
|
||||
6. `CreateConnection`은 이어서 준비된 PRAGMA 목록을 `PreparedStatement.ExecuteNoQuery`로 실행한다.
|
||||
|
||||
메타데이터에는 `query_only = ON`, `journal_mode = OFF`, `locking_mode = EXCLUSIVE`, `automatic_index = 0`, `cache_size = 10`, `synchronous = 0` PRAGMA 문자열이 있다. 기본 `GetConnectionOpenPragmas`는 6개 항목 배열을 만든다. 이 문자열 각각의 배열 슬롯 연결은 아직 검증하지 않았다.
|
||||
|
||||
따라서 마스터 연결 코드는 SQLCipher에 키를 적용해 DB를 직접 읽는 구조로 확인된다. 별도의 평문 DB를 먼저 만드는 경로는 위 함수들에서 발견되지 않았다. 다른 경로의 존재를 배제한 것은 아니다.
|
||||
|
||||
## 미확인 사항
|
||||
|
||||
- 현재 각 파일에 대응하는 CryptoKey 값과 앞뒤 문자열의 실제 값.
|
||||
- 실제 실행에서의 키와 암호화 옵션, 후보 파일 전체의 테이블 구성.
|
||||
- 복사본을 독립적으로 열고 조회하는 검증은 아직 하지 않았다. 실제 마스터 복호화 성공을 의미하지 않는다.
|
||||
|
||||
## 재현 자료
|
||||
|
||||
원본 바이너리, 메타데이터, 분석 스크립트는 무시되는 `data/inspection/android-master-2026-09-29/`에 보관했다. `disasm.py`와 `open-path-assembly.txt`에 호출 근거가 있다. 덤퍼의 출력은 기존 도구 디렉터리 `data/inspection/master-direct-2026-09-26/dumper-bin/`에 생성되었으며 Android 1.2.0 분석 결과다.
|
||||
|
||||
- libil2cpp.so SHA-256: `f3c02abd02f8d0c5263e2181e712bf495fa83c80568df8c29414a61809c4fffe`
|
||||
- libsqlcipher.so SHA-256: `91060e3d9360d4ac0858633f24ed97a62b66b6cdf18c00f8ef8a1e39e72fd76f`
|
||||
|
||||
공식 HolodoriDB main은 앞선 동일 조사 세션에서 fetch했고 3개 언어 모두 9월 26일 수집 기준과 같은 커밋이었다. 계산기 데이터 수집·반영은 실행하지 않았다.
|
||||
@@ -0,0 +1,54 @@
|
||||
# Android 메모리에서 마스터 키 복구 및 DB 복호화
|
||||
|
||||
2026-09-29, LDPlayer 14 / Android 14 / 게임 1.2.0, PID 4380에서 수행했다.
|
||||
|
||||
## 결과
|
||||
|
||||
- 게임의 마스터 관리 객체에서 파일별 경로와 키 **379개**를 복구했다.
|
||||
- 원본 암호화 파일 **379개, 61,485,056바이트**를 PC로 복사했다.
|
||||
- **15,011개 페이지 전부**의 HMAC-SHA512를 검증하고 AES-256-CBC 복호화에 성공했다.
|
||||
- 복호화된 **379개 DB 전부**를 독립적인 Python 표준 SQLite로 읽기 전용으로 열었다. 모든 `PRAGMA integrity_check` 결과가 `ok`였으며, 모든 테이블을 끝까지 읽어 **233,312행**을 확인했다.
|
||||
- Card는 189행, Music은 211행, LangMusic_Kor의 Lang 테이블은 2,167행이다. 행 내부에는 BLOB이 포함되므로 계산기용 필드/JSON 변환을 완료했다는 뜻은 아니다.
|
||||
- 게임 프로세스/파일의 수정, 후킹, 재시작, 서버 요청, 계정 인증 정보 사용은 하지 않았다.
|
||||
- 계산기 서비스 데이터에는 반영하지 않았다.
|
||||
|
||||
## 확보 방법
|
||||
|
||||
1. root ADB에서 `/proc/4380/maps`를 읽고 `/proc/4380/mem`의 필요한 영역을 덤프했다. LDPlayer `su` 경유 바이너리 출력의 줄바꿈 변환을 피하기 위해 기기 쪽에서 base64로 감싼 뒤 PC에서 디코딩했다.
|
||||
2. 이전에 분석한 현재 앱의 IL2CPP 타입 정보로 `MasterManager.<>c → declaringType → MasterManagerBase<MasterManager> → static_fields → _instance`를 따라갔다.
|
||||
3. `_downloadedMasterFileInfos`의 사전과 `DownloadMasterFileInfo` 객체들을 읽어 마스터 이름, 저장 경로, 키 byte 배열, 원본 크기를 확보했다. 관련 메모리는 64KiB 단위의 제한된 청크로 저장했으며 전체 프로세스 덤프는 필요하지 않았다.
|
||||
4. 키 배열은 67바이트의 SQLCipher `x'<64 hex characters>'` 형태다. 가운데 64자리 hex는 원시 256비트 키다. 실제 키 값은 이 문서나 Git 추적 파일에 포함하지 않는다.
|
||||
5. 원본 파일을 ADB pull로 복사하고, 파일별 복구 키로 각 페이지의 HMAC를 확인한 뒤 복호화했다.
|
||||
|
||||
## 검증된 파일 형식
|
||||
|
||||
- 페이지 크기: 4,096바이트
|
||||
- 암호화: AES-256-CBC, 원시 키 32바이트
|
||||
- 파일 첫 16바이트: salt
|
||||
- 페이지 끝 reserved 영역: 80바이트 (IV 16 + HMAC 64)
|
||||
- HMAC: SHA512, 암호문과 IV 뒤에 little-endian 페이지 번호를 포함
|
||||
- HMAC 키: 원시 DB 키를 입력으로, `salt XOR 0x3A`와 PBKDF2-HMAC-SHA512 2회를 사용해 32바이트 파생
|
||||
- 첫 페이지의 평문 SQLite 헤더를 복원하고 reserved 영역은 0으로 채운 복사본을 생성했다. 페이지 헤더의 reserved 크기는 유지한다.
|
||||
|
||||
설정은 추정으로만 채택한 것이 아니라 전체 페이지 HMAC 일치 및 독립 SQLite 무결성 검사로 검증했다. 암호화와 평문 파일의 SHA-256을 파일별로 남겼다.
|
||||
|
||||
## 로컬 산출물 (Git 제외)
|
||||
|
||||
모두 `data/inspection/android-master-2026-09-29/` 아래에 있다.
|
||||
|
||||
- `master-keys.private.json`: 파일별 키, 경로, 마스터 버전 및 객체 주소. **비공개로 유지할 자료**.
|
||||
- `memory/`: 키 복구에 사용한 선택적 메모리 덤프. 계정 관련 값이 섞일 수 있으므로 비공개로 유지한다.
|
||||
- `encrypted-master/`: 암호화된 원본 복사본 379개.
|
||||
- `decrypted-master/`: 이름을 붙인 평문 SQLite DB 379개 (`Card.sqlite`, `Music.sqlite` 등).
|
||||
- `decrypt-manifest.json`: 암호 검증 페이지 수, 파일 크기 및 양쪽 SHA-256.
|
||||
- `sqlite-verification.json`: DB별 무결성 검사, 테이블 스키마와 행 수.
|
||||
- `memory.py`, `master_instance.py`, `dump_master_keys.py`: 메모리 읽기 및 키 복구 스크립트.
|
||||
- `decrypt-master.mjs`, `verify_decrypted.py`: 로컬 복사본 복호화와 독립 SQLite 검증 도구.
|
||||
|
||||
메모리 주소와 타입 레이아웃은 현재 앱 빌드/프로세스 기준이다. 앱을 재시작하거나 업데이트하면 재확인해야 한다. 확보한 키와 같은 버전의 암호화 파일 복사본은 앱 실행 없이도 로컬에서 다시 검증할 수 있다.
|
||||
|
||||
## 수집 기준 확인
|
||||
|
||||
작업 전 `npm run data:sync`를 실행하고 `latest.json`, `latest.md`, `changes.patch`를 모두 확인했다. 영문/한국어/일본어 공식 원격은 기존 9월 26일 기준 커밋과 같고, 모든 콘텐츠 분류에서 변경이 없었다. 이번 로컬 게임 스냅샷의 확보가 HolodoriDB 수집 기준을 갱신하지는 않는다.
|
||||
|
||||
참고: [SQLCipher 키 API](https://www.zetetic.net/sqlcipher/sqlcipher-api/), [SQLCipher 설계](https://www.zetetic.net/sqlcipher/design/).
|
||||
@@ -0,0 +1,13 @@
|
||||
# 이벤트 일정·보너스 설정의 확인 범위 (2026-09-29)
|
||||
|
||||
- 현재 직접 확보한 DB 379개에서 이벤트별 시작/종료와 카드·멤버·개화별 특효 설정 테이블을 확인하지 못했다. EventStory/EventStoryChapter는 존재한다.
|
||||
- 이벤트 관련 모든 값이 DB에 없는 것은 아니다. MarathonLiveRewardUpStaminaEffect, MarathonMiniGameRewardUpStaminaEffect 및 Setting.marathonRecommendDeckBonusPermilMultiply 같은 공통 설정은 DB에 존재한다. 이들은 이벤트별 특효 설정과 구분한다.
|
||||
- 공식 CDN Octo revision 93 목록 43,749개(번들 24,359개, 리소스 19,390개)를 조사했다. 이벤트·설정 관련 이름 1,580개는 이미지·연출·배경·시나리오·음성 등이었고, 이름으로 식별되는 이벤트 일정/특효 설정 파일은 확인되지 않았다. 번들의 내부를 전부 검사한 것은 아니므로 CDN에 절대 없다는 결론은 내리지 않는다.
|
||||
- 현재 앱에서 추출한 protobuf 정의에는 rpc.api.EventListEventInfoResponse가 존재한다.
|
||||
- EventInfo: start_time, end_time, exchange_end_time
|
||||
- MarathonInfo.MarathonChapter: end_time, marathon_music_score_bonuses, marathon_mini_game_marathon_score_bonuses, marathon_live_marathon_score_bonuses
|
||||
- MarathonMusicScoreBonus: music_id, character_id, card_id, card_attribute_type, card_rarity, card_potential_upgrade_count, score_up_permil_up
|
||||
- MarathonLiveMarathonScoreBonus: character_id, card_id, card_attribute_type, card_rarity, card_potential_upgrade_count, marathon_score_quantity_up_permil_up
|
||||
- 따라서 앱이 이벤트별 일정과 보너스를 서버 API 응답으로 전달받을 수 있는 구조는 확인했다. 실제 응답의 현재 값은 아직 수집하지 않았다. CDN/DB 부재를 이유로 외부 위키가 필수라고 볼 근거는 없다.
|
||||
|
||||
로컬 검증 기록: data/inspection/android-master-2026-09-29/cdn-event-catalog.json 및 event-proto-schema.json. 계정 인증 정보는 사용하지 않았다.
|
||||
Reference in New Issue
Block a user