1
0
EQ2Emu/cmd/loginServer/clients.go
2025-07-02 13:14:42 -05:00

91 lines
1.5 KiB
Go

package main
import (
"sync"
"time"
"github.com/panjf2000/gnet/v2"
"zombiezen.com/go/sqlite/sqlitex"
)
type ClientState int
const (
StateConnected ClientState = iota
StateAuthenticated
StateCharacterSelect
StateDisconnected
)
type Client struct {
conn gnet.Conn
address string
connected time.Time
lastActive time.Time
state ClientState
accountID uint32
accountName string
version int16
mu sync.RWMutex
}
type ClientManager struct {
clients map[int]*Client
db *sqlitex.Pool
mu sync.RWMutex
}
func NewClientManager(db *sqlitex.Pool) *ClientManager {
return &ClientManager{
clients: make(map[int]*Client),
db: db,
}
}
func (cm *ClientManager) AddClient(fd int, client *Client) {
cm.mu.Lock()
defer cm.mu.Unlock()
cm.clients[fd] = client
}
func (cm *ClientManager) RemoveClient(fd int) {
cm.mu.Lock()
defer cm.mu.Unlock()
delete(cm.clients, fd)
}
func (cm *ClientManager) GetClient(fd int) *Client {
cm.mu.RLock()
defer cm.mu.RUnlock()
return cm.clients[fd]
}
func (cm *ClientManager) CleanupExpired() {
cm.mu.Lock()
defer cm.mu.Unlock()
cutoff := time.Now().Add(-30 * time.Minute)
for fd, client := range cm.clients {
if client.lastActive.Before(cutoff) {
client.conn.Close()
delete(cm.clients, fd)
}
}
}
func (cm *ClientManager) GetStats() (int, int) {
cm.mu.RLock()
defer cm.mu.RUnlock()
total := len(cm.clients)
authenticated := 0
for _, client := range cm.clients {
if client.state == StateAuthenticated {
authenticated++
}
}
return total, authenticated
}