Update GaCy-GO
This commit is contained in:
1 parent
da8a32f60d
commit
0cbe460e49
345 files changed
+98202
-77559
No files matched your search
@@ -0,0 +1,115 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// LoadCurrencyWarsGuideMissions returns only the native CW panel's declared
|
||||
// FinishMainMission prerequisites for the server's existing freeplay policy.
|
||||
// It does not finish all imported missions, change a save or force Client UI
|
||||
// state. The current condition capture is an explicit overlay of the older CW
|
||||
// catalog, not a claim that every CW table was recaptured for that assembly.
|
||||
func LoadCurrencyWarsGuideMissions() ([]uint32, error) {
|
||||
catalog, err := LoadCurrencyWarsCatalog()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
raw, err := ReadResourceFile("resources/CurrencyWarsActivityConditions.json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var overlay struct {
|
||||
Format uint32 `json:"format_version"`
|
||||
Source string `json:"source_assembly_sha256"`
|
||||
Target string `json:"target_assembly_sha256"`
|
||||
Capture string `json:"capture_sha256"`
|
||||
Policy string `json:"guide_policy"`
|
||||
Types map[string]uint32 `json:"condition_types"`
|
||||
Rows []struct {
|
||||
PanelID uint32
|
||||
GuideConditions []struct {
|
||||
Type uint32
|
||||
Param string
|
||||
}
|
||||
} `json:"rows"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &overlay); err != nil {
|
||||
return nil, fmt.Errorf("decode CW activity conditions: %w", err)
|
||||
}
|
||||
if overlay.Format != 1 || overlay.Source != catalog.Provenance.GameAssemblySHA256 || overlay.Policy != "complete_declared_guide_finish_main_missions" {
|
||||
return nil, fmt.Errorf("CW activity condition source/policy differs")
|
||||
}
|
||||
for _, digest := range []string{overlay.Target, overlay.Capture} {
|
||||
value, e := hex.DecodeString(digest)
|
||||
if e != nil || len(value) != 32 {
|
||||
return nil, fmt.Errorf("CW activity condition evidence missing")
|
||||
}
|
||||
}
|
||||
// The independently captured current activity catalog provides the target
|
||||
// assembly identity; a configured version label is not an identity check.
|
||||
current, err := ReadResourceFile("resources/PreviewGameplayCatalog.json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var identity struct {
|
||||
Assembly string `json:"client_assembly_sha256"`
|
||||
}
|
||||
if err := json.Unmarshal(current, &identity); err != nil || identity.Assembly != overlay.Target {
|
||||
return nil, fmt.Errorf("CW activity condition target differs from current activity capture")
|
||||
}
|
||||
finishType := overlay.Types["FinishMainMission"]
|
||||
if finishType == 0 || len(overlay.Rows) == 0 {
|
||||
return nil, fmt.Errorf("CW guide condition enum/rows missing")
|
||||
}
|
||||
mainData, err := ReadResourceFile("resources/MainMission.json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var main struct {
|
||||
Rows []struct {
|
||||
ID uint32 `json:"MainMissionID"`
|
||||
} `json:"main_mission_config"`
|
||||
}
|
||||
if err := json.Unmarshal(mainData, &main); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
known := make(map[uint32]bool, len(main.Rows))
|
||||
for _, mission := range main.Rows {
|
||||
known[mission.ID] = true
|
||||
}
|
||||
panels := map[uint32]bool{}
|
||||
for _, schedule := range catalog.ActivitySchedules() {
|
||||
panels[schedule.ActivityID] = true
|
||||
}
|
||||
seenPanels, seenMissions := map[uint32]bool{}, map[uint32]bool{}
|
||||
var result []uint32
|
||||
for _, row := range overlay.Rows {
|
||||
if row.PanelID == 0 || !panels[row.PanelID] || seenPanels[row.PanelID] {
|
||||
return nil, fmt.Errorf("CW guide condition panel is not an active unique CW panel")
|
||||
}
|
||||
seenPanels[row.PanelID] = true
|
||||
for _, condition := range row.GuideConditions {
|
||||
// An unimplemented condition cannot silently be treated as finished.
|
||||
if condition.Type != finishType {
|
||||
return nil, fmt.Errorf("CW guide condition kind %d is not implemented", condition.Type)
|
||||
}
|
||||
id, err := strconv.ParseUint(condition.Param, 10, 32)
|
||||
if err != nil || id == 0 || !known[uint32(id)] {
|
||||
return nil, fmt.Errorf("CW guide mission is not present in the mission resource")
|
||||
}
|
||||
if !seenMissions[uint32(id)] {
|
||||
seenMissions[uint32(id)] = true
|
||||
result = append(result, uint32(id))
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(result) == 0 {
|
||||
return nil, fmt.Errorf("CW guide condition mission list is empty")
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool { return result[i] < result[j] })
|
||||
return result, nil
|
||||
}
|
||||
Reference in new issue
Block a user