package common import ( "encoding/json" "fmt" ) const aaRoundSelectionKey = "aa_round_selection" type AARoundSelection struct { PeakGroupID uint32 `json:"peak_group_id"` ClientVersion string `json:"client_version"` } func SetAARoundSelection(peakGroupID uint32) (*AARoundSelection, error) { catalog, err := LoadMonsterSettingsCatalog() if err != nil { return nil, err } valid := false for _, group := range catalog.Modes["aa"] { if group.ID == peakGroupID { valid = true break } } if !valid { return nil, fmt.Errorf("AA round %d is not present in this Client's resources", peakGroupID) } cfg, err := LoadRuntimeConfig() if err != nil { return nil, err } selection := &AARoundSelection{ PeakGroupID: peakGroupID, ClientVersion: cfg.ClientVersion, } if err := updateAARoundSelection(selection); err != nil { return nil, err } return selection, nil } // ReadAARoundSelection is read-only. The selected round remains active until // Srtool changes or clears it, or the configured Client version changes. func ReadAARoundSelection() (*AARoundSelection, error) { cfg, err := LoadRuntimeConfig() if err != nil { return nil, err } root, err := readCurrencyWarsPersistentRoot() if err != nil { return nil, err } return activeAARoundSelection(root, cfg), nil } func ClearAARoundSelection() error { persistentWriteMu.Lock() defer persistentWriteMu.Unlock() unlock, err := lockPersistentFile() if err != nil { return err } defer unlock() root, err := readCurrencyWarsPersistentRoot() if err != nil { return err } _, hasRound := root[aaRoundSelectionKey] _, hasLegacyRoom := root["aa_room_selection"] if !hasRound && !hasLegacyRoom { return nil } delete(root, aaRoundSelectionKey) delete(root, "aa_room_selection") return writeJSONAtomic("persistent", root) } func updateAARoundSelection(selection *AARoundSelection) error { raw, err := json.Marshal(selection) if err != nil { return err } persistentWriteMu.Lock() defer persistentWriteMu.Unlock() unlock, err := lockPersistentFile() if err != nil { return err } defer unlock() root, err := readCurrencyWarsPersistentRoot() if err != nil { return err } delete(root, "aa_room_selection") root[aaRoundSelectionKey] = raw return writeJSONAtomic("persistent", root) } func activeAARoundSelection(root map[string]json.RawMessage, cfg RuntimeConfig) *AARoundSelection { raw, exists := root[aaRoundSelectionKey] if !exists { return nil } var selection AARoundSelection if json.Unmarshal(raw, &selection) != nil || selection.PeakGroupID == 0 || selection.ClientVersion != cfg.ClientVersion { return nil } return &selection }