package common import ( "crypto/sha256" "encoding/hex" "fmt" ) type CurrencyWarsChapter struct { ID uint32 `json:"ChapterID"` HealNum uint32 `json:"HealNum"` } type CurrencyWarsNodeType struct { Name string `json:"name"` Value uint32 `json:"value"` } func (c *CurrencyWarsCatalog) validateNodeRules() error { c.chapterByID = make(map[uint32]CurrencyWarsChapter) c.nodeTypeByID = make(map[uint32]string) if len(c.Chapters) == 0 && len(c.NodeTypes) == 0 && c.Provenance.ChaptersSHA256 == "" && c.Provenance.NodeTypesSHA256 == "" { return nil } for _, hash := range []string{c.Provenance.ChaptersSHA256, c.Provenance.NodeTypesSHA256} { digest, err := hex.DecodeString(hash) if err != nil || len(digest) != sha256.Size { return fmt.Errorf("CW chapter/node enum capture provenance is missing") } } needed := make(map[uint32]bool) for _, row := range c.StageRoutes { needed[row.ChapterID] = true } for _, row := range c.Chapters { if !needed[row.ID] { return fmt.Errorf("CW chapter %d is not in captured routes", row.ID) } if _, duplicate := c.chapterByID[row.ID]; duplicate { return fmt.Errorf("duplicate CW chapter %d", row.ID) } c.chapterByID[row.ID] = row } if len(c.chapterByID) != len(needed) { return fmt.Errorf("CW chapter rules do not cover every route chapter") } names := make(map[string]bool) for _, row := range c.NodeTypes { if row.Name == "" || names[row.Name] { return fmt.Errorf("invalid/duplicate CW node enum name") } if _, duplicate := c.nodeTypeByID[row.Value]; duplicate { return fmt.Errorf("duplicate CW node enum value %d", row.Value) } c.nodeTypeByID[row.Value] = row.Name names[row.Name] = true } if len(c.nodeTypeByID) == 0 { return fmt.Errorf("CW node enum is empty") } return nil } func (c *CurrencyWarsCatalog) Chapter(id uint32) (CurrencyWarsChapter, error) { row, exists := c.chapterByID[id] if !exists { return CurrencyWarsChapter{}, fmt.Errorf("CW chapter %d has not been captured", id) } return row, nil } func (c *CurrencyWarsCatalog) NodeTypeName(value uint32) (string, error) { name, exists := c.nodeTypeByID[value] if !exists { return "", fmt.Errorf("CW node type %d has not been captured", value) } return name, nil }