Files
GaCy-GO/internal/gameserver/peak_scene_overrides.go
T

91 lines
3.1 KiB
Go
Raw Normal View History

2026-10-28 18:54:43 +07:00
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))
}