92 lines
3.1 KiB
Go
92 lines
3.1 KiB
Go
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))
|
|
}
|