package common import ( "crypto/sha256" "encoding/hex" "encoding/json" "fmt" ) // CurrencyWarsReferenceNodeTemplate is the normalized grid_fight_node_template // row from the reference dump. It is configuration, never a copied run/save. type CurrencyWarsReferenceNodeTemplate struct { NodeTemplateID uint32 StageID uint32 NodeType string ParamList []uint32 PenaltyBonusRuleID uint32 BasicGoldRewardNum uint32 IsAugment uint32 } type CurrencyWarsReferenceNodes struct { Format uint32 `json:"format_version"` Client string `json:"target_client_version"` Assembly string `json:"target_assembly_sha256"` Provenance struct { Reference string `json:"reference_executable_sha256"` Excel string `json:"excel_dump_sha256"` Table string `json:"source_table"` } `json:"provenance"` Templates []CurrencyWarsReferenceNodeTemplate `json:"templates"` byID map[uint32]CurrencyWarsReferenceNodeTemplate } func LoadCurrencyWarsReferenceNodes(c *CurrencyWarsCatalog) (*CurrencyWarsReferenceNodes, error) { if c == nil { return nil, fmt.Errorf("CW reference nodes catalog missing") } raw, err := ReadResourceFile("resources/CurrencyWarsReferenceNodes.json") if err != nil { return nil, err } v := new(CurrencyWarsReferenceNodes) if err = json.Unmarshal(raw, v); err != nil { return nil, err } if v.Format != 1 || v.Client != c.ClientVersion || v.Assembly != c.Provenance.GameAssemblySHA256 || v.Provenance.Table != "grid_fight_node_template" { return nil, fmt.Errorf("CW reference node revision differs") } for _, s := range []string{v.Provenance.Reference, v.Provenance.Excel} { b, e := hex.DecodeString(s) if e != nil || len(b) != sha256.Size { return nil, fmt.Errorf("CW reference node provenance missing") } } v.byID = make(map[uint32]CurrencyWarsReferenceNodeTemplate, len(v.Templates)) for _, r := range v.Templates { if r.NodeTemplateID == 0 || r.StageID == 0 || r.NodeType == "" { return nil, fmt.Errorf("CW invalid reference node template") } if _, ok := v.byID[r.NodeTemplateID]; ok { return nil, fmt.Errorf("CW duplicate reference node template %d", r.NodeTemplateID) } v.byID[r.NodeTemplateID] = r } return v, nil } func (v *CurrencyWarsReferenceNodes) Template(id uint32) (CurrencyWarsReferenceNodeTemplate, error) { r, ok := v.byID[id] if !ok { return r, fmt.Errorf("CW reference node template %d missing", id) } r.ParamList = append([]uint32(nil), r.ParamList...) return r, nil }