package main import ( "sync" "time" "github.com/panjf2000/gnet/v2" "zombiezen.com/go/sqlite/sqlitex" ) type WorldServer struct { ID uint32 Name string Address string Port uint16 Status uint8 Players uint32 MaxPlayers uint32 Locked bool LastUpdate time.Time conn gnet.Conn mu sync.RWMutex } type WorldManager struct { worlds map[uint32]*WorldServer db *sqlitex.Pool mu sync.RWMutex } func NewWorldManager(db *sqlitex.Pool) *WorldManager { return &WorldManager{ worlds: make(map[uint32]*WorldServer), db: db, } } func (wm *WorldManager) AddWorld(world *WorldServer) { wm.mu.Lock() defer wm.mu.Unlock() wm.worlds[world.ID] = world } func (wm *WorldManager) RemoveWorld(id uint32) { wm.mu.Lock() defer wm.mu.Unlock() delete(wm.worlds, id) } func (wm *WorldManager) GetWorld(id uint32) *WorldServer { wm.mu.RLock() defer wm.mu.RUnlock() return wm.worlds[id] } func (wm *WorldManager) GetWorldList() []*WorldInfo { wm.mu.RLock() defer wm.mu.RUnlock() worlds := make([]*WorldInfo, 0, len(wm.worlds)) for _, world := range wm.worlds { worlds = append(worlds, &WorldInfo{ ID: world.ID, Name: world.Name, Status: world.Status, Players: world.Players, MaxPlayers: world.MaxPlayers, Address: world.Address, Port: world.Port, Locked: world.Locked, }) } return worlds } func (wm *WorldManager) UpdateStats() { wm.mu.Lock() defer wm.mu.Unlock() cutoff := time.Now().Add(-5 * time.Minute) for _, world := range wm.worlds { if world.LastUpdate.Before(cutoff) { world.Status = 0 // Offline } } } func (wm *WorldManager) GetStats() (int, int) { wm.mu.RLock() defer wm.mu.RUnlock() total := len(wm.worlds) online := 0 for _, world := range wm.worlds { if world.Status == 1 { online++ } } return total, online }