go_games_collection/corpsestarch_save.go

91 lines
3.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"encoding/json"
"errors"
"os"
"path/filepath"
)
// ПРИМЕЧАНИЕ: сохранение реализовано только для этой игры — она
// единственная в коллекции без чёткого конца партии, поэтому жалко
// сбрасывать прогресс при каждом выходе в меню. Остальные 8 игр
// коллекции по-прежнему не сохраняются между запусками — обычно в
// них и не нужно (партия проходится за один присест).
// ErrCorpseStarchNoSave возвращается LoadCorpseStarchGame, если
// файл сохранения не найден (новая партия должна начаться с нуля).
var ErrCorpseStarchNoSave = errors.New("файл сохранения не найден")
// corpseStarchSavePath возвращает путь к файлу сохранения в
// пользовательской конфигурационной директории (например,
// ~/.config/go-games-collection/corpsestarch_save.json на Linux).
func corpseStarchSavePath() (string, error) {
dir, err := os.UserConfigDir()
if err != nil {
return "", err
}
return filepath.Join(dir, "go-games-collection", "corpsestarch_save.json"), nil
}
// SaveCorpseStarchGame сохраняет текущее состояние партии на диск,
// создавая директорию сохранения при необходимости.
func SaveCorpseStarchGame(g *CorpseStarchGameState) error {
path, err := corpseStarchSavePath()
if err != nil {
return err
}
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
return err
}
data, err := json.MarshalIndent(g, "", " ")
if err != nil {
return err
}
return os.WriteFile(path, data, 0o644)
}
// LoadCorpseStarchGame загружает сохранённую партию с диска.
// Возвращает ErrCorpseStarchNoSave, если файла сохранения нет —
// вызывающий код должен в этом случае начать новую партию.
func LoadCorpseStarchGame() (*CorpseStarchGameState, error) {
path, err := corpseStarchSavePath()
if err != nil {
return nil, err
}
data, err := os.ReadFile(path)
if err != nil {
if os.IsNotExist(err) {
return nil, ErrCorpseStarchNoSave
}
return nil, err
}
var g CorpseStarchGameState
if err := json.Unmarshal(data, &g); err != nil {
return nil, err
}
if len(g.ServitorCounts) < len(corpseStarchServitorDefs) {
grown := make([]int, len(corpseStarchServitorDefs))
copy(grown, g.ServitorCounts)
g.ServitorCounts = grown
}
if g.BonusMultiplier == 0 {
g.BonusMultiplier = 1
}
return &g, nil
}
// DeleteCorpseStarchSave удаляет файл сохранения, если он есть
// (используется для явного сброса прогресса). Отсутствие файла не
// считается ошибкой.
func DeleteCorpseStarchSave() error {
path, err := corpseStarchSavePath()
if err != nil {
return err
}
err = os.Remove(path)
if err != nil && !os.IsNotExist(err) {
return err
}
return nil
}