interface to any

This commit is contained in:
Sky Johnson 2025-08-07 11:21:56 -05:00
parent 41f80008c9
commit 5cb4b5b56c
11 changed files with 808 additions and 809 deletions

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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,
})
}

View File

@ -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

View File

@ -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

View File

@ -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{}

View File

@ -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
}

View File

@ -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",

View File

@ -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

View File

@ -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