package common import ( "encoding/json" "fmt" "math" ) type AhaHelpLevel struct { BuffID uint32 `json:"BuffID"` ProgressPercent float64 `json:"ProgressPercent"` BuffLevel uint32 `json:"BuffLevel"` } // The supplied table selects the support buff; progress thresholds are metadata, // not a fabricated dynamic-value key sent to the Client. func LoadAhaHelpLevels() ([]AhaHelpLevel, error) { raw, err := ReadResourceFile("resources/AhaHelpConfig.json") if err != nil { return nil, err } var config struct { Source string `json:"source"` Levels []AhaHelpLevel `json:"levels"` } if err = json.Unmarshal(raw, &config); err != nil { return nil, err } if config.Source == "" || len(config.Levels) == 0 { return nil, fmt.Errorf("Aha help table has no provenance or levels") } seen := map[uint32]bool{} for _, level := range config.Levels { if level.BuffID == 0 || level.BuffLevel == 0 || seen[level.BuffLevel] || math.IsNaN(level.ProgressPercent) || level.ProgressPercent < 0 || level.ProgressPercent > 1 { return nil, fmt.Errorf("invalid Aha help level") } seen[level.BuffLevel] = true } return config.Levels, nil } // nil preserves the existing FreeSR switch. Explicit zero means disabled. func ReadAhaHelpLevel() (*uint32, error) { root, err := readCurrencyWarsPersistentRoot() if err != nil { return nil, err } raw, ok := root["aha_help_level"] if !ok { return nil, nil } var level *uint32 if err = json.Unmarshal(raw, &level); err != nil { return nil, err } return level, nil } func SaveAhaHelpLevel(level *uint32) error { levels, err := LoadAhaHelpLevels() if err != nil { return err } if level != nil && *level != 0 { found := false for _, row := range levels { found = found || row.BuffLevel == *level } if !found { return fmt.Errorf("Aha help level is not in the configured table") } } persistentWriteMu.Lock() defer persistentWriteMu.Unlock() unlock, err := lockPersistentFile() if err != nil { return err } defer unlock() root, err := readCurrencyWarsPersistentRoot() if err != nil { return err } if level == nil { delete(root, "aha_help_level") } else { root["aha_help_level"], err = json.Marshal(*level) } if err != nil { return err } return writeJSONAtomic("persistent", root) }