interface to any
This commit is contained in:
parent
41f80008c9
commit
5cb4b5b56c
@ -27,10 +27,10 @@ type Config struct {
|
||||
|
||||
// Database wraps the SQL database connection
|
||||
type Database struct {
|
||||
db *sql.DB
|
||||
pool *sqlitex.Pool // For achievements system compatibility (SQLite only)
|
||||
config Config
|
||||
mutex sync.RWMutex
|
||||
db *sql.DB
|
||||
pool *sqlitex.Pool // For achievements system compatibility (SQLite only)
|
||||
config Config
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
// New creates a new database connection with the provided configuration
|
||||
@ -101,19 +101,18 @@ func (d *Database) GetPool() *sqlitex.Pool {
|
||||
return d.pool
|
||||
}
|
||||
|
||||
|
||||
// Query executes a query that returns rows
|
||||
func (d *Database) Query(query string, args ...interface{}) (*sql.Rows, error) {
|
||||
func (d *Database) Query(query string, args ...any) (*sql.Rows, error) {
|
||||
return d.db.Query(query, args...)
|
||||
}
|
||||
|
||||
// QueryRow executes a query that returns a single row
|
||||
func (d *Database) QueryRow(query string, args ...interface{}) *sql.Row {
|
||||
func (d *Database) QueryRow(query string, args ...any) *sql.Row {
|
||||
return d.db.QueryRow(query, args...)
|
||||
}
|
||||
|
||||
// Exec executes a query that doesn't return rows
|
||||
func (d *Database) Exec(query string, args ...interface{}) (sql.Result, error) {
|
||||
func (d *Database) Exec(query string, args ...any) (sql.Result, error) {
|
||||
return d.db.Exec(query, args...)
|
||||
}
|
||||
|
||||
@ -174,7 +173,7 @@ func NewMySQL(dsn string) (*Database, error) {
|
||||
}
|
||||
|
||||
// GetZones retrieves all zones from the database
|
||||
func (d *Database) GetZones() ([]map[string]interface{}, error) {
|
||||
func (d *Database) GetZones() ([]map[string]any, error) {
|
||||
rows, err := d.Query(`
|
||||
SELECT id, name, file, description, motd, min_level, max_level,
|
||||
min_version, xp_modifier, city_zone, weather_allowed,
|
||||
@ -187,10 +186,10 @@ func (d *Database) GetZones() ([]map[string]interface{}, error) {
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var zones []map[string]interface{}
|
||||
var zones []map[string]any
|
||||
|
||||
for rows.Next() {
|
||||
zone := make(map[string]interface{})
|
||||
zone := make(map[string]any)
|
||||
var id, minLevel, maxLevel, minVersion int
|
||||
var name, file, description, motd string
|
||||
var xpModifier, safeX, safeY, safeZ, safeHeading float64
|
||||
|
@ -43,8 +43,8 @@ type WorldInterface interface {
|
||||
|
||||
// DatabaseInterface defines database operations needed by packet handlers
|
||||
type DatabaseInterface interface {
|
||||
GetCharacter(characterID int32) (map[string]interface{}, error)
|
||||
SaveCharacter(characterID int32, data map[string]interface{}) error
|
||||
GetCharacter(characterID int32) (map[string]any, error)
|
||||
SaveCharacter(characterID int32, data map[string]any) error
|
||||
// Add more database methods as needed
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@ func (phr *PacketHandlerRegistry) GetRegisteredOpcodes() []InternalOpcode {
|
||||
|
||||
// PacketProcessor combines opcode management and handler dispatch
|
||||
type PacketProcessor struct {
|
||||
opcodeManager *OpcodeManager
|
||||
opcodeManager *OpcodeManager
|
||||
handlerRegistry *PacketHandlerRegistry
|
||||
}
|
||||
|
||||
|
@ -212,7 +212,7 @@ All server data is persisted to SQLite:
|
||||
func (d *Database) LoadRules() (map[string]map[string]string, error)
|
||||
|
||||
// Zone management
|
||||
func (d *Database) GetZones() ([]map[string]interface{}, error)
|
||||
func (d *Database) GetZones() ([]map[string]any, error)
|
||||
|
||||
// Character persistence (planned)
|
||||
func (d *Database) SaveCharacter(character *Character) error
|
||||
|
@ -80,7 +80,7 @@ const (
|
||||
type AchievementEvent struct {
|
||||
Type AchievementEventType
|
||||
CharacterID int32
|
||||
Data map[string]interface{}
|
||||
Data map[string]any
|
||||
Timestamp int64
|
||||
}
|
||||
|
||||
@ -355,7 +355,7 @@ func (aeh *AchievementEventHandler) handleGenericEvent(event *AchievementEvent,
|
||||
}
|
||||
|
||||
// TriggerEvent is a convenience method for triggering achievement events
|
||||
func (w *World) TriggerAchievementEvent(eventType AchievementEventType, characterID int32, data map[string]interface{}) {
|
||||
func (w *World) TriggerAchievementEvent(eventType AchievementEventType, characterID int32, data map[string]any) {
|
||||
if w.achievementMgr == nil {
|
||||
return // Achievement system not initialized
|
||||
}
|
||||
@ -379,7 +379,7 @@ func (w *World) TriggerAchievementEvent(eventType AchievementEventType, characte
|
||||
|
||||
// OnNPCKill triggers an NPC kill achievement event
|
||||
func (w *World) OnNPCKill(characterID int32, npcID int32, npcLevel int32) {
|
||||
w.TriggerAchievementEvent(EventNPCKill, characterID, map[string]interface{}{
|
||||
w.TriggerAchievementEvent(EventNPCKill, characterID, map[string]any{
|
||||
"npc_id": npcID,
|
||||
"level": npcLevel,
|
||||
})
|
||||
@ -387,21 +387,21 @@ func (w *World) OnNPCKill(characterID int32, npcID int32, npcLevel int32) {
|
||||
|
||||
// OnQuestComplete triggers a quest completion achievement event
|
||||
func (w *World) OnQuestComplete(characterID int32, questID int32) {
|
||||
w.TriggerAchievementEvent(EventQuestCompleted, characterID, map[string]interface{}{
|
||||
w.TriggerAchievementEvent(EventQuestCompleted, characterID, map[string]any{
|
||||
"quest_id": questID,
|
||||
})
|
||||
}
|
||||
|
||||
// OnLevelGain triggers a level gain achievement event
|
||||
func (w *World) OnLevelGain(characterID int32, newLevel int32) {
|
||||
w.TriggerAchievementEvent(EventLevelGain, characterID, map[string]interface{}{
|
||||
w.TriggerAchievementEvent(EventLevelGain, characterID, map[string]any{
|
||||
"level": newLevel,
|
||||
})
|
||||
}
|
||||
|
||||
// OnItemDiscovered triggers an item discovery achievement event
|
||||
func (w *World) OnItemDiscovered(characterID int32, itemID int32, rarity string) {
|
||||
w.TriggerAchievementEvent(EventItemDiscovered, characterID, map[string]interface{}{
|
||||
w.TriggerAchievementEvent(EventItemDiscovered, characterID, map[string]any{
|
||||
"item_id": itemID,
|
||||
"rarity": rarity,
|
||||
})
|
||||
@ -409,7 +409,7 @@ func (w *World) OnItemDiscovered(characterID int32, itemID int32, rarity string)
|
||||
|
||||
// OnZoneDiscovered triggers a zone discovery achievement event
|
||||
func (w *World) OnZoneDiscovered(characterID int32, zoneID int32) {
|
||||
w.TriggerAchievementEvent(EventZoneDiscovered, characterID, map[string]interface{}{
|
||||
w.TriggerAchievementEvent(EventZoneDiscovered, characterID, map[string]any{
|
||||
"zone_id": zoneID,
|
||||
})
|
||||
}
|
@ -10,12 +10,12 @@ import (
|
||||
|
||||
// AchievementManager manages achievements for the world server
|
||||
type AchievementManager struct {
|
||||
masterList *achievements.MasterList
|
||||
playerManagers map[int32]*achievements.PlayerManager // CharacterID -> PlayerManager
|
||||
database *database.Database
|
||||
world *World // Reference to world server for notifications
|
||||
masterList *achievements.MasterList
|
||||
playerManagers map[int32]*achievements.PlayerManager // CharacterID -> PlayerManager
|
||||
database *database.Database
|
||||
world *World // Reference to world server for notifications
|
||||
|
||||
mutex sync.RWMutex
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
// NewAchievementManager creates a new achievement manager
|
||||
@ -289,15 +289,15 @@ func (am *AchievementManager) RemovePlayerManager(characterID int32) {
|
||||
}
|
||||
|
||||
// GetStatistics returns achievement system statistics
|
||||
func (am *AchievementManager) GetStatistics() map[string]interface{} {
|
||||
func (am *AchievementManager) GetStatistics() map[string]any {
|
||||
am.mutex.RLock()
|
||||
defer am.mutex.RUnlock()
|
||||
|
||||
stats := map[string]interface{}{
|
||||
"total_achievements": am.masterList.Size(),
|
||||
"online_players": len(am.playerManagers),
|
||||
"categories": am.masterList.GetCategories(),
|
||||
"expansions": am.masterList.GetExpansions(),
|
||||
stats := map[string]any{
|
||||
"total_achievements": am.masterList.Size(),
|
||||
"online_players": len(am.playerManagers),
|
||||
"categories": am.masterList.GetCategories(),
|
||||
"expansions": am.masterList.GetExpansions(),
|
||||
}
|
||||
|
||||
return stats
|
||||
|
@ -15,64 +15,64 @@ import (
|
||||
// Client represents a connected player client
|
||||
type Client struct {
|
||||
// Account information
|
||||
AccountID int32
|
||||
AccountName string
|
||||
AdminLevel int
|
||||
AccountID int32
|
||||
AccountName string
|
||||
AdminLevel int
|
||||
|
||||
// Character information
|
||||
CharacterID int32
|
||||
CharacterName string
|
||||
Player *entity.Entity
|
||||
CharacterID int32
|
||||
CharacterName string
|
||||
Player *entity.Entity
|
||||
|
||||
// Connection information
|
||||
Connection interface{} // TODO: Will be *udp.Connection
|
||||
IPAddress string
|
||||
ConnectedTime time.Time
|
||||
LastActivity time.Time
|
||||
ClientVersion int32 // EQ2 client version
|
||||
Connection any // TODO: Will be *udp.Connection
|
||||
IPAddress string
|
||||
ConnectedTime time.Time
|
||||
LastActivity time.Time
|
||||
ClientVersion int32 // EQ2 client version
|
||||
|
||||
// Zone information
|
||||
CurrentZone *ZoneServer
|
||||
ZoneID int32
|
||||
CurrentZone *ZoneServer
|
||||
ZoneID int32
|
||||
|
||||
// State flags
|
||||
IsConnected bool
|
||||
IsLinkdead bool
|
||||
IsAFK bool
|
||||
IsAnonymous bool
|
||||
IsLFG bool
|
||||
IsConnected bool
|
||||
IsLinkdead bool
|
||||
IsAFK bool
|
||||
IsAnonymous bool
|
||||
IsLFG bool
|
||||
|
||||
// Chat state
|
||||
LastTellFrom string
|
||||
IgnoreList map[string]bool
|
||||
LastTellFrom string
|
||||
IgnoreList map[string]bool
|
||||
|
||||
// Group/Guild
|
||||
GroupID int32
|
||||
GuildID int32
|
||||
GroupID int32
|
||||
GuildID int32
|
||||
|
||||
// Pending operations
|
||||
PendingZone *ZoneChangeDetails
|
||||
PendingZone *ZoneChangeDetails
|
||||
|
||||
mutex sync.RWMutex
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
// ZoneChangeDetails holds information about a zone change
|
||||
type ZoneChangeDetails struct {
|
||||
ZoneID int32
|
||||
InstanceID int32
|
||||
X float32
|
||||
Y float32
|
||||
Z float32
|
||||
Heading float32
|
||||
ZoneID int32
|
||||
InstanceID int32
|
||||
X float32
|
||||
Y float32
|
||||
Z float32
|
||||
Heading float32
|
||||
}
|
||||
|
||||
// ClientList manages all connected clients
|
||||
type ClientList struct {
|
||||
clients map[int32]*Client // CharacterID -> Client
|
||||
clientsByName map[string]*Client // Lowercase name -> Client
|
||||
clientsByAcct map[int32][]*Client // AccountID -> Clients
|
||||
clients map[int32]*Client // CharacterID -> Client
|
||||
clientsByName map[string]*Client // Lowercase name -> Client
|
||||
clientsByAcct map[int32][]*Client // AccountID -> Clients
|
||||
|
||||
mutex sync.RWMutex
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
// NewClientList creates a new client list
|
||||
|
@ -10,17 +10,17 @@ import (
|
||||
|
||||
// ItemManager manages items for the world server
|
||||
type ItemManager struct {
|
||||
masterItemList *items.MasterItemList
|
||||
masterItemList *items.MasterItemList
|
||||
itemSystemAdapter *items.ItemSystemAdapter
|
||||
database *database.Database
|
||||
world *World // Reference to world server
|
||||
database *database.Database
|
||||
world *World // Reference to world server
|
||||
|
||||
// World-specific item tracking
|
||||
playerInventories map[uint32]*items.PlayerItemList // Player ID -> Inventory
|
||||
playerEquipment map[uint32]*items.EquipmentItemList // Player ID -> Equipment
|
||||
worldDrops map[int32][]*items.Item // Zone ID -> Ground items
|
||||
playerInventories map[uint32]*items.PlayerItemList // Player ID -> Inventory
|
||||
playerEquipment map[uint32]*items.EquipmentItemList // Player ID -> Equipment
|
||||
worldDrops map[int32][]*items.Item // Zone ID -> Ground items
|
||||
|
||||
mutex sync.RWMutex
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
// NewItemManager creates a new item manager for the world server
|
||||
@ -61,7 +61,7 @@ func NewItemManager(db *database.Database) *ItemManager {
|
||||
return &ItemManager{
|
||||
masterItemList: masterList,
|
||||
itemSystemAdapter: systemAdapter,
|
||||
database: db,
|
||||
database: db,
|
||||
playerInventories: make(map[uint32]*items.PlayerItemList),
|
||||
playerEquipment: make(map[uint32]*items.EquipmentItemList),
|
||||
worldDrops: make(map[int32][]*items.Item),
|
||||
@ -272,7 +272,7 @@ func (im *ItemManager) SearchItems(name string, maxResults int32) []*items.Item
|
||||
}
|
||||
|
||||
// GetStatistics returns item system statistics
|
||||
func (im *ItemManager) GetStatistics() map[string]interface{} {
|
||||
func (im *ItemManager) GetStatistics() map[string]any {
|
||||
im.mutex.RLock()
|
||||
defer im.mutex.RUnlock()
|
||||
|
||||
@ -284,7 +284,7 @@ func (im *ItemManager) GetStatistics() map[string]interface{} {
|
||||
totalWorldDrops += len(drops)
|
||||
}
|
||||
|
||||
result := make(map[string]interface{})
|
||||
result := make(map[string]any)
|
||||
for k, v := range systemStats {
|
||||
result[k] = v
|
||||
}
|
||||
@ -434,12 +434,12 @@ func (wdb *WorldItemDatabaseAdapter) LoadItemStats() (map[string]int32, map[int3
|
||||
fmt.Println("Loading item stats - using placeholder data")
|
||||
|
||||
statsStrings := map[string]int32{
|
||||
"health": 1,
|
||||
"power": 2,
|
||||
"strength": 3,
|
||||
"stamina": 4,
|
||||
"agility": 5,
|
||||
"wisdom": 6,
|
||||
"health": 1,
|
||||
"power": 2,
|
||||
"strength": 3,
|
||||
"stamina": 4,
|
||||
"agility": 5,
|
||||
"wisdom": 6,
|
||||
"intelligence": 7,
|
||||
}
|
||||
|
||||
@ -601,14 +601,14 @@ type MockPlayer struct {
|
||||
alignment int8
|
||||
}
|
||||
|
||||
func (mp *MockPlayer) GetID() uint32 { return mp.id }
|
||||
func (mp *MockPlayer) GetName() string { return mp.name }
|
||||
func (mp *MockPlayer) GetLevel() int16 { return mp.level }
|
||||
func (mp *MockPlayer) GetAdventureClass() int8 { return mp.adventureClass }
|
||||
func (mp *MockPlayer) GetTradeskillClass() int8 { return mp.tradeskillClass }
|
||||
func (mp *MockPlayer) GetRace() int8 { return mp.race }
|
||||
func (mp *MockPlayer) GetGender() int8 { return mp.gender }
|
||||
func (mp *MockPlayer) GetAlignment() int8 { return mp.alignment }
|
||||
func (mp *MockPlayer) GetID() uint32 { return mp.id }
|
||||
func (mp *MockPlayer) GetName() string { return mp.name }
|
||||
func (mp *MockPlayer) GetLevel() int16 { return mp.level }
|
||||
func (mp *MockPlayer) GetAdventureClass() int8 { return mp.adventureClass }
|
||||
func (mp *MockPlayer) GetTradeskillClass() int8 { return mp.tradeskillClass }
|
||||
func (mp *MockPlayer) GetRace() int8 { return mp.race }
|
||||
func (mp *MockPlayer) GetGender() int8 { return mp.gender }
|
||||
func (mp *MockPlayer) GetAlignment() int8 { return mp.alignment }
|
||||
|
||||
// MockItemQuestAdapter provides mock quest functionality
|
||||
type MockItemQuestAdapter struct{}
|
||||
|
@ -4,23 +4,23 @@ import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"eq2emu/internal/database"
|
||||
"eq2emu/internal/npc"
|
||||
"eq2emu/internal/npc/ai"
|
||||
"eq2emu/internal/database"
|
||||
)
|
||||
|
||||
// NPCManager manages NPCs for the world server
|
||||
type NPCManager struct {
|
||||
npcManager *npc.Manager
|
||||
aiManager *ai.AIManager
|
||||
database *database.Database
|
||||
world *World // Reference to world server
|
||||
npcManager *npc.Manager
|
||||
aiManager *ai.AIManager
|
||||
database *database.Database
|
||||
world *World // Reference to world server
|
||||
|
||||
// World-specific NPC tracking
|
||||
npcsByZone map[int32][]*npc.NPC // Zone ID -> NPCs
|
||||
activeCombat map[int32]bool // NPC ID -> in combat
|
||||
npcsByZone map[int32][]*npc.NPC // Zone ID -> NPCs
|
||||
activeCombat map[int32]bool // NPC ID -> in combat
|
||||
|
||||
mutex sync.RWMutex
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
// NewNPCManager creates a new NPC manager for the world server
|
||||
@ -412,7 +412,7 @@ func (nm *NPCManager) RemoveNPCFromZone(zoneID int32, npcID int32) {
|
||||
}
|
||||
|
||||
// GetStatistics returns NPC system statistics
|
||||
func (nm *NPCManager) GetStatistics() map[string]interface{} {
|
||||
func (nm *NPCManager) GetStatistics() map[string]any {
|
||||
nm.mutex.RLock()
|
||||
defer nm.mutex.RUnlock()
|
||||
|
||||
@ -423,17 +423,17 @@ func (nm *NPCManager) GetStatistics() map[string]interface{} {
|
||||
totalZones := len(nm.npcsByZone)
|
||||
totalInCombat := len(nm.activeCombat)
|
||||
|
||||
result := map[string]interface{}{
|
||||
"total_npcs": stats.TotalNPCs,
|
||||
"npcs_in_combat": stats.NPCsInCombat,
|
||||
"npcs_with_spells": stats.NPCsWithSpells,
|
||||
"npcs_with_skills": stats.NPCsWithSkills,
|
||||
"spell_cast_count": stats.SpellCastCount,
|
||||
"skill_usage_count": stats.SkillUsageCount,
|
||||
"runback_count": stats.RunbackCount,
|
||||
result := map[string]any{
|
||||
"total_npcs": stats.TotalNPCs,
|
||||
"npcs_in_combat": stats.NPCsInCombat,
|
||||
"npcs_with_spells": stats.NPCsWithSpells,
|
||||
"npcs_with_skills": stats.NPCsWithSkills,
|
||||
"spell_cast_count": stats.SpellCastCount,
|
||||
"skill_usage_count": stats.SkillUsageCount,
|
||||
"runback_count": stats.RunbackCount,
|
||||
"average_aggro_radius": stats.AverageAggroRadius,
|
||||
"ai_strategy_counts": stats.AIStrategyCounts,
|
||||
"zones_with_npcs": totalZones,
|
||||
"ai_strategy_counts": stats.AIStrategyCounts,
|
||||
"zones_with_npcs": totalZones,
|
||||
"world_npcs_in_combat": totalInCombat,
|
||||
}
|
||||
|
||||
@ -459,9 +459,9 @@ func (nm *NPCManager) Shutdown() {
|
||||
|
||||
// NPCInfo represents basic information about an NPC
|
||||
type NPCInfo struct {
|
||||
ID int32
|
||||
Name string
|
||||
Level int8
|
||||
ID int32
|
||||
Name string
|
||||
Level int8
|
||||
ZoneID int32
|
||||
}
|
||||
|
||||
|
@ -304,14 +304,14 @@ func (w *World) SendCharacterAchievements(client *Client) {
|
||||
|
||||
// Get all achievements with player progress
|
||||
allAchievements := w.achievementMgr.masterList.GetAllAchievements()
|
||||
characterData := make(map[string]interface{})
|
||||
characterData := make(map[string]any)
|
||||
|
||||
for achievementID, achievement := range allAchievements {
|
||||
progress := w.achievementMgr.GetPlayerProgress(characterID, achievementID)
|
||||
completed := w.achievementMgr.IsPlayerCompleted(characterID, achievementID)
|
||||
percentage := w.achievementMgr.GetCompletionPercentage(characterID, achievementID)
|
||||
|
||||
characterData[fmt.Sprintf("achievement_%d", achievementID)] = map[string]interface{}{
|
||||
characterData[fmt.Sprintf("achievement_%d", achievementID)] = map[string]any{
|
||||
"id": achievementID,
|
||||
"title": achievement.Title,
|
||||
"description": achievement.UncompletedText,
|
||||
@ -564,7 +564,7 @@ func (w *World) SendNPCInfo(client *Client, npcID int32) {
|
||||
}
|
||||
|
||||
// SendNPCUpdate sends NPC update to clients in range
|
||||
func (w *World) SendNPCUpdate(npcID int32, updateType string, data map[string]interface{}) {
|
||||
func (w *World) SendNPCUpdate(npcID int32, updateType string, data map[string]any) {
|
||||
// TODO: Implement NPC update broadcasting
|
||||
// This would send updates to all clients in range of the NPC
|
||||
|
||||
@ -604,13 +604,13 @@ type WorldDatabaseAdapter struct {
|
||||
}
|
||||
|
||||
// GetCharacter implements packets.DatabaseInterface
|
||||
func (wda *WorldDatabaseAdapter) GetCharacter(characterID int32) (map[string]interface{}, error) {
|
||||
func (wda *WorldDatabaseAdapter) GetCharacter(characterID int32) (map[string]any, error) {
|
||||
// TODO: Implement character loading from database
|
||||
return nil, fmt.Errorf("character loading not yet implemented")
|
||||
}
|
||||
|
||||
// SaveCharacter implements packets.DatabaseInterface
|
||||
func (wda *WorldDatabaseAdapter) SaveCharacter(characterID int32, data map[string]interface{}) error {
|
||||
func (wda *WorldDatabaseAdapter) SaveCharacter(characterID int32, data map[string]any) error {
|
||||
// TODO: Implement character saving to database
|
||||
return fmt.Errorf("character saving not yet implemented")
|
||||
}
|
||||
@ -902,7 +902,7 @@ func (w *World) HandleItemUpdate(ctx *packets.PacketContext, packet *packets.Pac
|
||||
}
|
||||
|
||||
// SendItemDetails sends detailed item information to a client
|
||||
func (w *World) SendItemDetails(client *Client, item interface{}) {
|
||||
func (w *World) SendItemDetails(client *Client, item any) {
|
||||
if w.itemMgr == nil {
|
||||
return
|
||||
}
|
||||
@ -947,7 +947,7 @@ func (w *World) SendPlayerInventory(client *Client) {
|
||||
}
|
||||
|
||||
// SendItemUpdate sends item update to client
|
||||
func (w *World) SendItemUpdate(client *Client, updateType string, itemData map[string]interface{}) {
|
||||
func (w *World) SendItemUpdate(client *Client, updateType string, itemData map[string]any) {
|
||||
if w.itemMgr == nil {
|
||||
return
|
||||
}
|
||||
@ -961,7 +961,7 @@ func (w *World) SendItemUpdate(client *Client, updateType string, itemData map[s
|
||||
}
|
||||
|
||||
// BroadcastItemUpdate broadcasts item updates to nearby players
|
||||
func (w *World) BroadcastItemUpdate(sourcePlayerID uint32, updateType string, itemData map[string]interface{}) {
|
||||
func (w *World) BroadcastItemUpdate(sourcePlayerID uint32, updateType string, itemData map[string]any) {
|
||||
// TODO: Implement item update broadcasting (for things like equipment changes visible to others)
|
||||
|
||||
fmt.Printf("Broadcasting item update from player %d: %s - %v\n",
|
||||
|
@ -4,17 +4,17 @@ import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"eq2emu/internal/titles"
|
||||
"eq2emu/internal/database"
|
||||
"eq2emu/internal/titles"
|
||||
)
|
||||
|
||||
// TitleManager manages titles for the world server
|
||||
type TitleManager struct {
|
||||
titleManager *titles.TitleManager
|
||||
integrationMgr *titles.IntegrationManager
|
||||
database *database.Database
|
||||
titleManager *titles.TitleManager
|
||||
integrationMgr *titles.IntegrationManager
|
||||
database *database.Database
|
||||
|
||||
mutex sync.RWMutex
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
// NewTitleManager creates a new title manager for the world server
|
||||
@ -198,7 +198,7 @@ func (tm *TitleManager) ProcessAchievementCompletion(playerID int32, achievement
|
||||
}
|
||||
|
||||
// GetStatistics returns title system statistics
|
||||
func (tm *TitleManager) GetStatistics() map[string]interface{} {
|
||||
func (tm *TitleManager) GetStatistics() map[string]any {
|
||||
tm.mutex.RLock()
|
||||
defer tm.mutex.RUnlock()
|
||||
|
||||
@ -206,8 +206,8 @@ func (tm *TitleManager) GetStatistics() map[string]interface{} {
|
||||
titleManagerStats := tm.titleManager.GetStatistics()
|
||||
|
||||
// Combine with our own statistics
|
||||
stats := map[string]interface{}{
|
||||
"total_titles": tm.titleManager.GetMasterList().GetTitleCount(),
|
||||
stats := map[string]any{
|
||||
"total_titles": tm.titleManager.GetMasterList().GetTitleCount(),
|
||||
}
|
||||
|
||||
// Add statistics from the title manager
|
||||
|
@ -16,87 +16,87 @@ import (
|
||||
// World represents the main world server instance
|
||||
type World struct {
|
||||
// Core components
|
||||
db *database.Database
|
||||
commandManager *commands.CommandManager
|
||||
rulesManager *rules.RuleManager
|
||||
db *database.Database
|
||||
commandManager *commands.CommandManager
|
||||
rulesManager *rules.RuleManager
|
||||
|
||||
// Server configuration
|
||||
config *WorldConfig
|
||||
startTime time.Time
|
||||
shutdownTime *time.Time
|
||||
shutdownReason string
|
||||
config *WorldConfig
|
||||
startTime time.Time
|
||||
shutdownTime *time.Time
|
||||
shutdownReason string
|
||||
|
||||
// World time management
|
||||
worldTime *WorldTime
|
||||
worldTimeTicker *time.Ticker
|
||||
|
||||
// Zones management
|
||||
zones *ZoneList
|
||||
zones *ZoneList
|
||||
|
||||
// Client management
|
||||
clients *ClientList
|
||||
clients *ClientList
|
||||
|
||||
// Achievement system
|
||||
achievementMgr *AchievementManager
|
||||
achievementMgr *AchievementManager
|
||||
|
||||
// Title system
|
||||
titleMgr *TitleManager
|
||||
titleMgr *TitleManager
|
||||
|
||||
// NPC system
|
||||
npcMgr *NPCManager
|
||||
npcMgr *NPCManager
|
||||
|
||||
// Item system
|
||||
itemMgr *ItemManager
|
||||
itemMgr *ItemManager
|
||||
|
||||
// Master lists (singletons)
|
||||
masterSpells interface{} // TODO: implement spell manager
|
||||
masterQuests interface{} // TODO: implement quest manager
|
||||
masterSkills interface{} // TODO: implement skill manager
|
||||
masterFactions interface{} // TODO: implement faction manager
|
||||
masterSpells any // TODO: implement spell manager
|
||||
masterQuests any // TODO: implement quest manager
|
||||
masterSkills any // TODO: implement skill manager
|
||||
masterFactions any // TODO: implement faction manager
|
||||
|
||||
// Server statistics
|
||||
stats *ServerStatistics
|
||||
stats *ServerStatistics
|
||||
|
||||
// Synchronization
|
||||
mutex sync.RWMutex
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
wg sync.WaitGroup
|
||||
mutex sync.RWMutex
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
// WorldConfig holds world server configuration
|
||||
type WorldConfig struct {
|
||||
// Network settings
|
||||
ListenAddr string `json:"listen_addr"`
|
||||
ListenPort int `json:"listen_port"`
|
||||
MaxClients int `json:"max_clients"`
|
||||
ListenAddr string `json:"listen_addr"`
|
||||
ListenPort int `json:"listen_port"`
|
||||
MaxClients int `json:"max_clients"`
|
||||
|
||||
// Web interface settings
|
||||
WebAddr string `json:"web_addr"`
|
||||
WebPort int `json:"web_port"`
|
||||
WebCertFile string `json:"web_cert_file"`
|
||||
WebKeyFile string `json:"web_key_file"`
|
||||
WebKeyPassword string `json:"web_key_password"`
|
||||
WebAddr string `json:"web_addr"`
|
||||
WebPort int `json:"web_port"`
|
||||
WebCertFile string `json:"web_cert_file"`
|
||||
WebKeyFile string `json:"web_key_file"`
|
||||
WebKeyPassword string `json:"web_key_password"`
|
||||
|
||||
// Database settings
|
||||
DatabaseType string `json:"database_type"` // "sqlite" or "mysql"
|
||||
DatabasePath string `json:"database_path"` // For SQLite: file path
|
||||
DatabaseHost string `json:"database_host"` // For MySQL: hostname
|
||||
DatabasePort int `json:"database_port"` // For MySQL: port
|
||||
DatabaseName string `json:"database_name"` // For MySQL: database name
|
||||
DatabaseUser string `json:"database_user"` // For MySQL: username
|
||||
DatabasePass string `json:"database_pass"` // For MySQL: password
|
||||
DatabaseType string `json:"database_type"` // "sqlite" or "mysql"
|
||||
DatabasePath string `json:"database_path"` // For SQLite: file path
|
||||
DatabaseHost string `json:"database_host"` // For MySQL: hostname
|
||||
DatabasePort int `json:"database_port"` // For MySQL: port
|
||||
DatabaseName string `json:"database_name"` // For MySQL: database name
|
||||
DatabaseUser string `json:"database_user"` // For MySQL: username
|
||||
DatabasePass string `json:"database_pass"` // For MySQL: password
|
||||
|
||||
// Server settings
|
||||
ServerName string `json:"server_name"`
|
||||
ServerMOTD string `json:"server_motd"`
|
||||
LogLevel string `json:"log_level"`
|
||||
ServerName string `json:"server_name"`
|
||||
ServerMOTD string `json:"server_motd"`
|
||||
LogLevel string `json:"log_level"`
|
||||
|
||||
// Game settings
|
||||
XPRate float32 `json:"xp_rate"`
|
||||
TSXPRate float32 `json:"ts_xp_rate"`
|
||||
CoinRate float32 `json:"coin_rate"`
|
||||
LootRate float32 `json:"loot_rate"`
|
||||
XPRate float32 `json:"xp_rate"`
|
||||
TSXPRate float32 `json:"ts_xp_rate"`
|
||||
CoinRate float32 `json:"coin_rate"`
|
||||
LootRate float32 `json:"loot_rate"`
|
||||
|
||||
// Login server settings
|
||||
LoginServerAddr string `json:"login_server_addr"`
|
||||
@ -117,29 +117,29 @@ type WorldTime struct {
|
||||
// ServerStatistics tracks server metrics
|
||||
type ServerStatistics struct {
|
||||
// Server info
|
||||
ServerCreated time.Time
|
||||
ServerStartTime time.Time
|
||||
ServerCreated time.Time
|
||||
ServerStartTime time.Time
|
||||
|
||||
// Connection stats
|
||||
TotalConnections int64
|
||||
CurrentConnections int32
|
||||
MaxConnections int32
|
||||
TotalConnections int64
|
||||
CurrentConnections int32
|
||||
MaxConnections int32
|
||||
|
||||
// Character stats
|
||||
TotalAccounts int32
|
||||
TotalCharacters int32
|
||||
AverageCharLevel float32
|
||||
TotalAccounts int32
|
||||
TotalCharacters int32
|
||||
AverageCharLevel float32
|
||||
|
||||
// Zone stats
|
||||
ActiveZones int32
|
||||
ActiveInstances int32
|
||||
ActiveZones int32
|
||||
ActiveInstances int32
|
||||
|
||||
// Performance stats
|
||||
CPUUsage float32
|
||||
MemoryUsage int64
|
||||
PeakMemoryUsage int64
|
||||
CPUUsage float32
|
||||
MemoryUsage int64
|
||||
PeakMemoryUsage int64
|
||||
|
||||
mutex sync.RWMutex
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
// NewWorld creates a new world server instance
|
||||
@ -205,11 +205,11 @@ func NewWorld(config *WorldConfig) (*World, error) {
|
||||
worldTime: &WorldTime{Year: 3721, Month: 1, Day: 1, Hour: 12, Minute: 0},
|
||||
zones: NewZoneList(),
|
||||
clients: NewClientList(),
|
||||
stats: &ServerStatistics{
|
||||
stats: &ServerStatistics{
|
||||
ServerStartTime: time.Now(),
|
||||
},
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
}
|
||||
|
||||
// Set world references for cross-system communication
|
||||
|
Loading…
x
Reference in New Issue
Block a user