91 lines
1.8 KiB
Go
91 lines
1.8 KiB
Go
package player
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// Session holds an authenticated player's session state.
|
|
type Session struct {
|
|
Token string
|
|
PlayerID uint64
|
|
PlayerName string
|
|
CreatedAt time.Time
|
|
LastActive time.Time
|
|
}
|
|
|
|
// SessionManager manages active sessions.
|
|
type SessionManager struct {
|
|
mu sync.RWMutex
|
|
sessions map[string]*Session // token -> session
|
|
}
|
|
|
|
// NewSessionManager creates a new session manager.
|
|
func NewSessionManager() *SessionManager {
|
|
return &SessionManager{
|
|
sessions: make(map[string]*Session),
|
|
}
|
|
}
|
|
|
|
// Create generates a new session for the given player.
|
|
func (sm *SessionManager) Create(playerID uint64, playerName string) *Session {
|
|
token := generateToken()
|
|
now := time.Now()
|
|
|
|
s := &Session{
|
|
Token: token,
|
|
PlayerID: playerID,
|
|
PlayerName: playerName,
|
|
CreatedAt: now,
|
|
LastActive: now,
|
|
}
|
|
|
|
sm.mu.Lock()
|
|
sm.sessions[token] = s
|
|
sm.mu.Unlock()
|
|
|
|
return s
|
|
}
|
|
|
|
// Get retrieves a session by token. Returns nil if not found.
|
|
func (sm *SessionManager) Get(token string) *Session {
|
|
sm.mu.RLock()
|
|
defer sm.mu.RUnlock()
|
|
s := sm.sessions[token]
|
|
if s != nil {
|
|
s.LastActive = time.Now()
|
|
}
|
|
return s
|
|
}
|
|
|
|
// Remove deletes a session.
|
|
func (sm *SessionManager) Remove(token string) {
|
|
sm.mu.Lock()
|
|
delete(sm.sessions, token)
|
|
sm.mu.Unlock()
|
|
}
|
|
|
|
// CleanupExpired removes sessions inactive for longer than the given duration.
|
|
func (sm *SessionManager) CleanupExpired(maxIdle time.Duration) int {
|
|
sm.mu.Lock()
|
|
defer sm.mu.Unlock()
|
|
|
|
cutoff := time.Now().Add(-maxIdle)
|
|
removed := 0
|
|
for token, s := range sm.sessions {
|
|
if s.LastActive.Before(cutoff) {
|
|
delete(sm.sessions, token)
|
|
removed++
|
|
}
|
|
}
|
|
return removed
|
|
}
|
|
|
|
func generateToken() string {
|
|
b := make([]byte, 32)
|
|
_, _ = rand.Read(b)
|
|
return hex.EncodeToString(b)
|
|
}
|