From 104a039bc0610b764d7c2f9398cb780382a0adca Mon Sep 17 00:00:00 2001 From: Sky Johnson Date: Thu, 7 Aug 2025 12:17:10 -0500 Subject: [PATCH] remove legacyachievement type --- CLAUDE.md | 24 +----- internal/achievements/achievement.go | 20 +++-- internal/achievements/achievements_test.go | 89 ++++------------------ internal/achievements/doc.go | 2 +- internal/achievements/master.go | 33 ++++---- internal/achievements/types.go | 65 ---------------- 6 files changed, 47 insertions(+), 186 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 1c63ca7..025b408 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,26 +2,6 @@ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. -## Code Quality Requirements - -**Function Documentation**: All functions must have thorough documentation explaining their purpose, parameters, return values, and any important behavior. Do NOT follow the standard Go convention of starting comments with the function name - instead, write clear explanations of what the function does. - -**Examples:** - -Good: -```go -// Creates a new UDP server instance with the specified address and packet handler. -// The server will listen on the given address and route incoming packets to the handler. -// Returns an error if the address is invalid or the socket cannot be bound. -func NewServer(addr string, handler PacketHandler, config ...Config) (*Server, error) { -``` - -Poor (standard Go convention - avoid this): -```go -// NewServer creates a new UDP server instance with the specified address and packet handler. -func NewServer(addr string, handler PacketHandler, config ...Config) (*Server, error) { -``` - **Additional Documentation Requirements:** - Document all public types, constants, and variables - Include examples in documentation for complex functions @@ -48,7 +28,7 @@ go fmt ./...; go mod tidy ## Architecture Overview -**Login Server** - Client authentication, character management, world server coordination +**Login Server** - Client authentication, character management, world server coordination **World Server** - Game simulation engine, zones, NPCs, combat, quests, web admin interface **Core Systems:** @@ -105,4 +85,4 @@ go fmt ./...; go mod tidy **Architecture Transition**: Converted from C++ EQ2EMu codebase maintaining protocol compatibility while modernizing implementation. -**Testing**: Focus on UDP protocol and packet parsing for client compatibility. All systems include comprehensive test suites with concurrency testing. \ No newline at end of file +**Testing**: Focus on UDP protocol and packet parsing for client compatibility. All systems include comprehensive test suites with concurrency testing. diff --git a/internal/achievements/achievement.go b/internal/achievements/achievement.go index e6d6695..6f4317d 100644 --- a/internal/achievements/achievement.go +++ b/internal/achievements/achievement.go @@ -257,10 +257,11 @@ func (a *Achievement) GetID() uint32 { return a.AchievementID } -// ToLegacy converts to legacy achievement format for master list compatibility -func (a *Achievement) ToLegacy() *LegacyAchievement { - return &LegacyAchievement{ - ID: a.AchievementID, // Use AchievementID as legacy ID +// Clone creates a deep copy of the achievement +func (a *Achievement) Clone() *Achievement { + clone := &Achievement{ + ID: a.ID, + AchievementID: a.AchievementID, Title: a.Title, UncompletedText: a.UncompletedText, CompletedText: a.CompletedText, @@ -272,9 +273,16 @@ func (a *Achievement) ToLegacy() *LegacyAchievement { Hide: a.Hide, Unknown3A: a.Unknown3A, Unknown3B: a.Unknown3B, - Requirements: a.Requirements, - Rewards: a.Rewards, + MaxVersion: a.MaxVersion, + Requirements: make([]Requirement, len(a.Requirements)), + Rewards: make([]Reward, len(a.Rewards)), + db: a.db, + isNew: false, } + + copy(clone.Requirements, a.Requirements) + copy(clone.Rewards, a.Rewards) + return clone } // Private helper methods diff --git a/internal/achievements/achievements_test.go b/internal/achievements/achievements_test.go index c4d127c..4be9da0 100644 --- a/internal/achievements/achievements_test.go +++ b/internal/achievements/achievements_test.go @@ -45,18 +45,18 @@ func TestSimpleAchievement(t *testing.T) { t.Errorf("Expected 1 reward, got %d", len(achievement.Rewards)) } - // Test ToLegacy conversion - legacy := achievement.ToLegacy() - if legacy == nil { - t.Fatal("ToLegacy returned nil") + // Test Clone + clone := achievement.Clone() + if clone == nil { + t.Fatal("Clone returned nil") } - if legacy.ID != achievement.AchievementID { - t.Errorf("Expected legacy ID %d, got %d", achievement.AchievementID, legacy.ID) + if clone.AchievementID != achievement.AchievementID { + t.Errorf("Expected clone ID %d, got %d", achievement.AchievementID, clone.AchievementID) } - if legacy.Title != achievement.Title { - t.Errorf("Expected legacy title %s, got %s", achievement.Title, legacy.Title) + if clone.Title != achievement.Title { + t.Errorf("Expected clone title %s, got %s", achievement.Title, clone.Title) } } @@ -72,9 +72,12 @@ func TestMasterListWithGeneric(t *testing.T) { t.Errorf("Expected size 0, got %d", masterList.Size()) } - // Create a legacy achievement - achievement := NewLegacyAchievement() - achievement.ID = 1001 + // Create an achievement (need database for new pattern) + db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared") + defer db.Close() + + achievement := New(db) + achievement.AchievementID = 1001 achievement.Title = "Test Achievement" achievement.Category = "Testing" @@ -103,67 +106,3 @@ func TestMasterListWithGeneric(t *testing.T) { t.Errorf("Expected 1 achievement in Testing category, got %d", len(achievements)) } } - -// TestLegacyTypes tests the basic legacy types functionality -func TestLegacyTypes(t *testing.T) { - // Test NewLegacyAchievement - achievement := NewLegacyAchievement() - if achievement == nil { - t.Fatal("NewLegacyAchievement returned nil") - } - - if achievement.Requirements == nil { - t.Error("Requirements slice should not be nil") - } - - if achievement.Rewards == nil { - t.Error("Rewards slice should not be nil") - } - - // Test GetID - achievement.ID = 1001 - if achievement.GetID() != 1001 { - t.Errorf("Expected GetID() to return 1001, got %d", achievement.GetID()) - } - - // Test AddRequirement - req := Requirement{ - AchievementID: 1001, - Name: "test_requirement", - QtyRequired: 5, - } - achievement.AddRequirement(req) - - if len(achievement.Requirements) != 1 { - t.Errorf("Expected 1 requirement, got %d", len(achievement.Requirements)) - } - - // Test AddReward - reward := Reward{ - AchievementID: 1001, - Reward: "test_reward", - } - achievement.AddReward(reward) - - if len(achievement.Rewards) != 1 { - t.Errorf("Expected 1 reward, got %d", len(achievement.Rewards)) - } - - // Test Clone - clone := achievement.Clone() - if clone == nil { - t.Fatal("Clone returned nil") - } - - if clone == achievement { - t.Error("Clone returned same instance") - } - - if clone.ID != achievement.ID { - t.Error("Clone ID mismatch") - } - - if clone.Title != achievement.Title { - t.Error("Clone Title mismatch") - } -} diff --git a/internal/achievements/doc.go b/internal/achievements/doc.go index 57829a2..bc0a64f 100644 --- a/internal/achievements/doc.go +++ b/internal/achievements/doc.go @@ -44,7 +44,7 @@ // // Load all achievements from database // allAchievements, _ := achievements.LoadAll(db) // for _, ach := range allAchievements { -// masterList.AddAchievement(ach.ToLegacy()) +// masterList.AddAchievement(ach) // } // // // Get achievements by category diff --git a/internal/achievements/master.go b/internal/achievements/master.go index b95700f..b149f8d 100644 --- a/internal/achievements/master.go +++ b/internal/achievements/master.go @@ -7,21 +7,20 @@ import ( ) // MasterList manages the global list of all achievements -// Now uses the generic MasterList with achievement-specific extensions type MasterList struct { - *common.MasterList[uint32, *LegacyAchievement] + *common.MasterList[uint32, *Achievement] } // NewMasterList creates a new master achievement list func NewMasterList() *MasterList { return &MasterList{ - MasterList: common.NewMasterList[uint32, *LegacyAchievement](), + MasterList: common.NewMasterList[uint32, *Achievement](), } } // AddAchievement adds an achievement to the master list // Returns false if achievement with same ID already exists -func (m *MasterList) AddAchievement(achievement *LegacyAchievement) bool { +func (m *MasterList) AddAchievement(achievement *Achievement) bool { if achievement == nil { return false } @@ -30,13 +29,13 @@ func (m *MasterList) AddAchievement(achievement *LegacyAchievement) bool { // GetAchievement retrieves an achievement by ID // Returns nil if not found -func (m *MasterList) GetAchievement(id uint32) *LegacyAchievement { +func (m *MasterList) GetAchievement(id uint32) *Achievement { return m.MasterList.Get(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) *LegacyAchievement { +func (m *MasterList) GetAchievementClone(id uint32) *Achievement { achievement := m.MasterList.Get(id) if achievement == nil { return nil @@ -46,25 +45,25 @@ func (m *MasterList) GetAchievementClone(id uint32) *LegacyAchievement { // GetAllAchievements returns a map of all achievements (read-only access) // The returned map should not be modified -func (m *MasterList) GetAllAchievements() map[uint32]*LegacyAchievement { +func (m *MasterList) GetAllAchievements() map[uint32]*Achievement { return m.MasterList.GetAll() } // GetAchievementsByCategory returns achievements filtered by category -func (m *MasterList) GetAchievementsByCategory(category string) []*LegacyAchievement { - return m.MasterList.Filter(func(achievement *LegacyAchievement) bool { +func (m *MasterList) GetAchievementsByCategory(category string) []*Achievement { + return m.MasterList.Filter(func(achievement *Achievement) bool { return achievement.Category == category }) } // GetAchievementsByExpansion returns achievements filtered by expansion -func (m *MasterList) GetAchievementsByExpansion(expansion string) []*LegacyAchievement { - return m.MasterList.Filter(func(achievement *LegacyAchievement) bool { +func (m *MasterList) GetAchievementsByExpansion(expansion string) []*Achievement { + return m.MasterList.Filter(func(achievement *Achievement) bool { return achievement.Expansion == expansion }) } -// RemoveAchievement removes an achievement from the master list +// Removes an achievement from the master list // Returns true if achievement was found and removed func (m *MasterList) RemoveAchievement(id uint32) bool { return m.MasterList.Remove(id) @@ -72,18 +71,18 @@ func (m *MasterList) RemoveAchievement(id uint32) bool { // UpdateAchievement updates an existing achievement // Returns error if achievement doesn't exist -func (m *MasterList) UpdateAchievement(achievement *LegacyAchievement) error { +func (m *MasterList) UpdateAchievement(achievement *Achievement) error { if achievement == nil { return fmt.Errorf("achievement cannot be nil") } return m.MasterList.Update(achievement) } -// GetCategories returns all unique categories +// Returns all unique categories func (m *MasterList) GetCategories() []string { categories := make(map[string]bool) - m.MasterList.ForEach(func(_ uint32, achievement *LegacyAchievement) { + m.MasterList.ForEach(func(_ uint32, achievement *Achievement) { if achievement.Category != "" { categories[achievement.Category] = true } @@ -96,11 +95,11 @@ func (m *MasterList) GetCategories() []string { return result } -// GetExpansions returns all unique expansions +// Returns all unique expansions func (m *MasterList) GetExpansions() []string { expansions := make(map[string]bool) - m.MasterList.ForEach(func(_ uint32, achievement *LegacyAchievement) { + m.MasterList.ForEach(func(_ uint32, achievement *Achievement) { if achievement.Expansion != "" { expansions[achievement.Expansion] = true } diff --git a/internal/achievements/types.go b/internal/achievements/types.go index 371c750..2fea7d5 100644 --- a/internal/achievements/types.go +++ b/internal/achievements/types.go @@ -15,24 +15,6 @@ type Reward struct { Reward string `json:"reward"` } -// LegacyAchievement represents the old achievement definition for master list compatibility -type LegacyAchievement struct { - ID uint32 `json:"id"` - Title string `json:"title"` - UncompletedText string `json:"uncompleted_text"` - CompletedText string `json:"completed_text"` - Category string `json:"category"` - Expansion string `json:"expansion"` - Icon uint16 `json:"icon"` - PointValue uint32 `json:"point_value"` - QtyRequired uint32 `json:"qty_required"` - Hide bool `json:"hide"` - Unknown3A uint32 `json:"unknown3a"` - Unknown3B uint32 `json:"unknown3b"` - Requirements []Requirement `json:"requirements"` - Rewards []Reward `json:"rewards"` -} - // UpdateItem represents a single achievement progress update type UpdateItem struct { AchievementID uint32 `json:"achievement_id"` @@ -46,19 +28,6 @@ type Update struct { UpdateItems []UpdateItem `json:"update_items"` } -// GetID returns the achievement ID (implements common.Identifiable interface) -func (a *LegacyAchievement) GetID() uint32 { - return a.ID -} - -// NewLegacyAchievement creates a new legacy achievement with empty slices -func NewLegacyAchievement() *LegacyAchievement { - return &LegacyAchievement{ - Requirements: make([]Requirement, 0), - Rewards: make([]Reward, 0), - } -} - // NewUpdate creates a new achievement update with empty slices func NewUpdate() *Update { return &Update{ @@ -66,45 +35,11 @@ func NewUpdate() *Update { } } -// AddRequirement adds a requirement to the legacy achievement -func (a *LegacyAchievement) AddRequirement(req Requirement) { - a.Requirements = append(a.Requirements, req) -} - -// AddReward adds a reward to the legacy achievement -func (a *LegacyAchievement) AddReward(reward Reward) { - a.Rewards = append(a.Rewards, reward) -} - // AddUpdateItem adds an update item to the achievement update func (u *Update) AddUpdateItem(item UpdateItem) { u.UpdateItems = append(u.UpdateItems, item) } -// Clone creates a deep copy of the legacy achievement -func (a *LegacyAchievement) Clone() *LegacyAchievement { - clone := &LegacyAchievement{ - ID: a.ID, - Title: a.Title, - UncompletedText: a.UncompletedText, - CompletedText: a.CompletedText, - Category: a.Category, - Expansion: a.Expansion, - Icon: a.Icon, - PointValue: a.PointValue, - QtyRequired: a.QtyRequired, - Hide: a.Hide, - Unknown3A: a.Unknown3A, - Unknown3B: a.Unknown3B, - Requirements: make([]Requirement, len(a.Requirements)), - Rewards: make([]Reward, len(a.Rewards)), - } - - copy(clone.Requirements, a.Requirements) - copy(clone.Rewards, a.Rewards) - return clone -} - // Clone creates a deep copy of the achievement update func (u *Update) Clone() *Update { clone := &Update{