198 lines
4.7 KiB
Go
198 lines
4.7 KiB
Go
package achievements
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
)
|
|
|
|
// MasterList manages the global list of all achievements
|
|
type MasterList struct {
|
|
achievements map[uint32]*Achievement
|
|
mutex sync.RWMutex
|
|
}
|
|
|
|
// NewMasterList creates a new master achievement list
|
|
func NewMasterList() *MasterList {
|
|
return &MasterList{
|
|
achievements: make(map[uint32]*Achievement),
|
|
}
|
|
}
|
|
|
|
// AddAchievement adds an achievement to the master list
|
|
// Returns false if achievement with same ID already exists
|
|
func (m *MasterList) AddAchievement(achievement *Achievement) bool {
|
|
if achievement == nil {
|
|
return false
|
|
}
|
|
|
|
m.mutex.Lock()
|
|
defer m.mutex.Unlock()
|
|
|
|
if _, exists := m.achievements[achievement.ID]; exists {
|
|
return false
|
|
}
|
|
|
|
m.achievements[achievement.ID] = achievement
|
|
return true
|
|
}
|
|
|
|
// GetAchievement retrieves an achievement by ID
|
|
// Returns nil if not found
|
|
func (m *MasterList) GetAchievement(id uint32) *Achievement {
|
|
m.mutex.RLock()
|
|
defer m.mutex.RUnlock()
|
|
|
|
return m.achievements[id]
|
|
}
|
|
|
|
// GetAchievementClone retrieves a cloned copy of an achievement by ID
|
|
// Returns nil if not found. Safe for modification without affecting master list
|
|
func (m *MasterList) GetAchievementClone(id uint32) *Achievement {
|
|
m.mutex.RLock()
|
|
achievement := m.achievements[id]
|
|
m.mutex.RUnlock()
|
|
|
|
if achievement == nil {
|
|
return nil
|
|
}
|
|
|
|
return achievement.Clone()
|
|
}
|
|
|
|
// GetAllAchievements returns a map of all achievements (read-only access)
|
|
// The returned map should not be modified
|
|
func (m *MasterList) GetAllAchievements() map[uint32]*Achievement {
|
|
m.mutex.RLock()
|
|
defer m.mutex.RUnlock()
|
|
|
|
// Return copy of map to prevent external modification
|
|
result := make(map[uint32]*Achievement, len(m.achievements))
|
|
for id, achievement := range m.achievements {
|
|
result[id] = achievement
|
|
}
|
|
return result
|
|
}
|
|
|
|
// GetAchievementsByCategory returns achievements filtered by category
|
|
func (m *MasterList) GetAchievementsByCategory(category string) []*Achievement {
|
|
m.mutex.RLock()
|
|
defer m.mutex.RUnlock()
|
|
|
|
var result []*Achievement
|
|
for _, achievement := range m.achievements {
|
|
if achievement.Category == category {
|
|
result = append(result, achievement)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
// GetAchievementsByExpansion returns achievements filtered by expansion
|
|
func (m *MasterList) GetAchievementsByExpansion(expansion string) []*Achievement {
|
|
m.mutex.RLock()
|
|
defer m.mutex.RUnlock()
|
|
|
|
var result []*Achievement
|
|
for _, achievement := range m.achievements {
|
|
if achievement.Expansion == expansion {
|
|
result = append(result, achievement)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
// RemoveAchievement removes an achievement from the master list
|
|
// Returns true if achievement was found and removed
|
|
func (m *MasterList) RemoveAchievement(id uint32) bool {
|
|
m.mutex.Lock()
|
|
defer m.mutex.Unlock()
|
|
|
|
if _, exists := m.achievements[id]; !exists {
|
|
return false
|
|
}
|
|
|
|
delete(m.achievements, id)
|
|
return true
|
|
}
|
|
|
|
// UpdateAchievement updates an existing achievement
|
|
// Returns error if achievement doesn't exist
|
|
func (m *MasterList) UpdateAchievement(achievement *Achievement) error {
|
|
if achievement == nil {
|
|
return fmt.Errorf("achievement cannot be nil")
|
|
}
|
|
|
|
m.mutex.Lock()
|
|
defer m.mutex.Unlock()
|
|
|
|
if _, exists := m.achievements[achievement.ID]; !exists {
|
|
return fmt.Errorf("achievement with ID %d does not exist", achievement.ID)
|
|
}
|
|
|
|
m.achievements[achievement.ID] = achievement
|
|
return nil
|
|
}
|
|
|
|
// Clear removes all achievements from the master list
|
|
func (m *MasterList) Clear() {
|
|
m.mutex.Lock()
|
|
defer m.mutex.Unlock()
|
|
|
|
m.achievements = make(map[uint32]*Achievement)
|
|
}
|
|
|
|
// Size returns the number of achievements in the master list
|
|
func (m *MasterList) Size() int {
|
|
m.mutex.RLock()
|
|
defer m.mutex.RUnlock()
|
|
|
|
return len(m.achievements)
|
|
}
|
|
|
|
// Exists checks if an achievement with given ID exists
|
|
func (m *MasterList) Exists(id uint32) bool {
|
|
m.mutex.RLock()
|
|
defer m.mutex.RUnlock()
|
|
|
|
_, exists := m.achievements[id]
|
|
return exists
|
|
}
|
|
|
|
// GetCategories returns all unique categories
|
|
func (m *MasterList) GetCategories() []string {
|
|
m.mutex.RLock()
|
|
defer m.mutex.RUnlock()
|
|
|
|
categories := make(map[string]bool)
|
|
for _, achievement := range m.achievements {
|
|
if achievement.Category != "" {
|
|
categories[achievement.Category] = true
|
|
}
|
|
}
|
|
|
|
result := make([]string, 0, len(categories))
|
|
for category := range categories {
|
|
result = append(result, category)
|
|
}
|
|
return result
|
|
}
|
|
|
|
// GetExpansions returns all unique expansions
|
|
func (m *MasterList) GetExpansions() []string {
|
|
m.mutex.RLock()
|
|
defer m.mutex.RUnlock()
|
|
|
|
expansions := make(map[string]bool)
|
|
for _, achievement := range m.achievements {
|
|
if achievement.Expansion != "" {
|
|
expansions[achievement.Expansion] = true
|
|
}
|
|
}
|
|
|
|
result := make([]string, 0, len(expansions))
|
|
for expansion := range expansions {
|
|
result = append(result, expansion)
|
|
}
|
|
return result
|
|
}
|