package gameserver import ( "encoding/hex" "encoding/json" "fmt" "strconv" "gac-hkrpg-go/internal/common" ) // These are adventure actor/placement identifiers, not battle wave monsters. // Their reference binary provenance is retained in the editable resource. // Applying the overlay never changes an existing session/run or a save file. func applyPeakSceneOverrides(data *ChallengeDataConfig) { var catalog struct { SourceKind string `json:"source_kind"` BinaryHash string `json:"binary_sha256"` Offset string `json:"source_file_offset"` Length uint32 `json:"decoded_byte_length"` Data struct { Groups []struct { GroupID uint32 `json:"group_id"` Stages map[string]struct { NPC uint32 `json:"npc_monster_id"` Entrance uint32 `json:"map_entrance_id"` Group uint32 `json:"maze_group_id"` } `json:"stages"` } `json:"challenge_peak_extra_data"` } `json:"data"` } markAll := func(err error) { for id, stage := range data.Peak { stage.SceneResourceError = err.Error() data.Peak[id] = stage } Log("[PEAK] scene override rejected: " + err.Error()) } raw, err := common.ReadResourceFile("resources/ChallengePeakSceneOverrides.json") if err != nil { markAll(err) return } if err := json.Unmarshal(raw, &catalog); err != nil { markAll(err) return } digest, err := hex.DecodeString(catalog.BinaryHash) _, offsetErr := strconv.ParseUint(catalog.Offset, 0, 64) if err != nil || len(digest) != 32 || offsetErr != nil || catalog.Length == 0 || catalog.SourceKind != "reference-server-embedded-data" { markAll(fmt.Errorf("Peak scene override provenance is incomplete")) return } res, err := common.GameRes() if err != nil { markAll(err) return } seen := make(map[string]bool) for _, group := range catalog.Data.Groups { for id, row := range group.Stages { stage, exists := data.Peak[id] if !exists || seen[id] || group.GroupID == 0 || stage.GroupID != group.GroupID { markAll(fmt.Errorf("Peak scene override has unknown, duplicate or mismatched stage %s", id)) return } seen[id] = true stage.SceneResourceError = "" if row.NPC == 0 || row.Entrance == 0 || row.Group == 0 { stage.SceneResourceError = "Peak scene override has an empty actor/placement identifier" } else if scenes := res.LevelOutputConfigs[row.Entrance]; len(scenes) == 0 { stage.SceneResourceError = fmt.Sprintf("Peak entrance %d has no resource scene", row.Entrance) } else { _, scene, _ := firstSceneOfEntry(res, row.Entrance) placement, ok := scene.Scenes[row.Group] if !ok || len(placement.Monsters) == 0 { stage.SceneResourceError = fmt.Sprintf("Peak entrance %d group %d has no resource monster placement", row.Entrance, row.Group) } } stage.Entrance, stage.Group, stage.MonsterID = row.Entrance, row.Group, row.NPC data.Peak[id] = stage } } for id, stage := range data.Peak { if !seen[id] { stage.SceneResourceError = "Peak stage is missing from the scene override resource" data.Peak[id] = stage } } Log(fmt.Sprintf("[PEAK] scene override loaded stages=%d reference_sha256=%s; Client acceptance unverified", len(seen), catalog.BinaryHash)) }