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