Files
GaCy-GO/internal/common/currency_wars_rewards.go
2026-10-28 18:54:43 +07:00

96 lines
3.2 KiB
Go

package common
import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
)
type CurrencyWarsOrb struct {
ID uint32 `json:"OrbID"`
Bonus uint32 `json:"BonusID"`
Type uint32 `json:"Type"`
}
type CurrencyWarsConsumable struct {
ID uint32
IfStack, IfConsume bool
ConsumableRule uint32
ConsumableParamList []uint32
}
type CurrencyWarsForge struct {
ID, FuncType, EquipNum, EquipCategory uint32
ParamList []uint32
}
type CurrencyWarsCombination struct {
ID uint32 `json:"BonusID"`
Pools []uint32 `json:"CombinationBonusList"`
Counts []uint32 `json:"BonusNumberList"`
}
type CurrencyWarsRewards struct {
Orbs map[uint32]CurrencyWarsOrb
Consumables map[uint32]CurrencyWarsConsumable
Forges map[uint32]CurrencyWarsForge
Combinations map[uint32]CurrencyWarsCombination
}
// Tables are complete flat-table captures for the recorded Client revision.
// Bonus-pool resolution and item-effect execution are separate prerequisites.
func LoadCurrencyWarsRewards(c *CurrencyWarsCatalog) (*CurrencyWarsRewards, error) {
raw, err := ReadResourceFile("resources/CurrencyWarsRewards.json")
if err != nil {
return nil, err
}
var r struct {
Format uint32 `json:"format_version"`
Client string `json:"target_client_version"`
Assembly string `json:"target_assembly_sha256"`
Capture string `json:"source_capture_sha256"`
Tables struct {
Orbs []CurrencyWarsOrb `json:"orb"`
Consumables []CurrencyWarsConsumable `json:"consumable"`
Forges []CurrencyWarsForge `json:"forge"`
Combinations []CurrencyWarsCombination `json:"combination"`
} `json:"tables"`
}
if err = json.Unmarshal(raw, &r); err != nil {
return nil, err
}
if c == nil || r.Format != 1 || r.Client != c.ClientVersion || r.Assembly != c.Provenance.GameAssemblySHA256 {
return nil, fmt.Errorf("CW reward table revision differs")
}
hash, e := hex.DecodeString(r.Capture)
if e != nil || len(hash) != sha256.Size {
return nil, fmt.Errorf("CW reward capture provenance missing")
}
out := &CurrencyWarsRewards{Orbs: map[uint32]CurrencyWarsOrb{}, Consumables: map[uint32]CurrencyWarsConsumable{}, Forges: map[uint32]CurrencyWarsForge{}, Combinations: map[uint32]CurrencyWarsCombination{}}
for _, v := range r.Tables.Orbs {
if _, ok := out.Orbs[v.ID]; v.ID == 0 || v.Bonus == 0 || ok {
return nil, fmt.Errorf("CW Orb identity invalid")
}
out.Orbs[v.ID] = v
}
for _, v := range r.Tables.Consumables {
if _, ok := out.Consumables[v.ID]; v.ID == 0 || ok {
return nil, fmt.Errorf("CW consumable identity invalid")
}
out.Consumables[v.ID] = v
}
for _, v := range r.Tables.Forges {
if _, ok := out.Forges[v.ID]; v.ID == 0 || v.EquipNum == 0 || ok {
return nil, fmt.Errorf("CW forge identity invalid")
}
out.Forges[v.ID] = v
}
for _, v := range r.Tables.Combinations {
if _, ok := out.Combinations[v.ID]; v.ID == 0 || len(v.Pools) != len(v.Counts) || ok {
return nil, fmt.Errorf("CW combination identity invalid")
}
out.Combinations[v.ID] = v
}
if len(out.Orbs) == 0 || len(out.Consumables) == 0 || len(out.Forges) == 0 || len(out.Combinations) == 0 {
return nil, fmt.Errorf("CW reward tables incomplete")
}
return out, nil
}