diff options
Diffstat (limited to 'internal/player/store.go')
| -rw-r--r-- | internal/player/store.go | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/internal/player/store.go b/internal/player/store.go new file mode 100644 index 0000000..c19d9fb --- /dev/null +++ b/internal/player/store.go @@ -0,0 +1,136 @@ +package player + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "thirdcollapse/internal/object" + "gopkg.in/yaml.v3" +) + +type AccountStore struct { + dataDir string +} + +func NewAccountStore(dataDir string) *AccountStore { + return &AccountStore{dataDir: dataDir} +} + +func (s *AccountStore) AccountPath(name string) string { + return filepath.Join(s.dataDir, "players", "accounts", name+".yaml") +} + +func (s *AccountStore) LoadAccount(name string) (*Account, error) { + path := s.AccountPath(name) + data, err := os.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("account not found: %s", name) + } + var acc Account + if err := yaml.Unmarshal(data, &acc); err != nil { + return nil, fmt.Errorf("parse account: %w", err) + } + return &acc, nil +} + +func (s *AccountStore) SaveAccount(acc *Account) error { + path := s.AccountPath(acc.Name) + data, err := yaml.Marshal(acc) + if err != nil { + return err + } + return os.WriteFile(path, data, 0644) +} + +func (s *AccountStore) AccountExists(name string) bool { + _, err := s.FindAccount(name) + return err == nil +} + +func (s *AccountStore) FindAccount(name string) (string, error) { + path := s.AccountPath(name) + if _, err := os.Stat(path); err == nil { + return name, nil + } + dir := filepath.Join(s.dataDir, "players", "accounts") + entries, err := os.ReadDir(dir) + if err != nil { + return "", fmt.Errorf("account not found: %s", name) + } + lower := strings.ToLower(name) + for _, e := range entries { + if e.IsDir() { + continue + } + base := strings.TrimSuffix(e.Name(), ".yaml") + if strings.ToLower(base) == lower { + return base, nil + } + } + return "", fmt.Errorf("account not found: %s", name) +} + +func (s *AccountStore) CharPath(name string) string { + return filepath.Join(s.dataDir, "players", "characters", name+".yaml") +} + +func (s *AccountStore) LoadCharacter(name string) (*Player, error) { + path := s.CharPath(name) + data, err := os.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("character not found: %s", name) + } + var p Player + if err := yaml.Unmarshal(data, &p); err != nil { + return nil, fmt.Errorf("parse character: %w", err) + } + if p.Skills == nil { + p.Skills = make(map[SkillName]int) + } + if p.Equipment == nil { + p.Equipment = make(map[object.EquipSlot]string) + } + if p.Inventory == nil { + p.Inventory = make(map[int]*InventorySlot) + } + return &p, nil +} + +func (s *AccountStore) SaveCharacter(p *Player) error { + path := s.CharPath(p.Name) + data, err := yaml.Marshal(p) + if err != nil { + return err + } + return os.WriteFile(path, data, 0644) +} + +func (s *AccountStore) CharacterExists(name string) bool { + _, err := s.FindCharacter(name) + return err == nil +} + +func (s *AccountStore) FindCharacter(name string) (string, error) { + path := s.CharPath(name) + if _, err := os.Stat(path); err == nil { + return name, nil + } + dir := filepath.Join(s.dataDir, "players", "characters") + entries, err := os.ReadDir(dir) + if err != nil { + return "", fmt.Errorf("character not found: %s", name) + } + lower := strings.ToLower(name) + for _, e := range entries { + if e.IsDir() { + continue + } + base := strings.TrimSuffix(e.Name(), ".yaml") + if strings.ToLower(base) == lower { + return base, nil + } + } + return "", fmt.Errorf("character not found: %s", name) +} |
