feat: online player tracking and count display in lobby
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -28,13 +28,60 @@ type LobbyRoom struct {
|
|||||||
Session *GameSession
|
Session *GameSession
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OnlinePlayer struct {
|
||||||
|
Name string
|
||||||
|
Fingerprint string
|
||||||
|
InRoom string // room code, empty if in lobby
|
||||||
|
}
|
||||||
|
|
||||||
type Lobby struct {
|
type Lobby struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
rooms map[string]*LobbyRoom
|
rooms map[string]*LobbyRoom
|
||||||
|
online map[string]*OnlinePlayer // fingerprint -> player
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLobby() *Lobby {
|
func NewLobby() *Lobby {
|
||||||
return &Lobby{rooms: make(map[string]*LobbyRoom)}
|
return &Lobby{
|
||||||
|
rooms: make(map[string]*LobbyRoom),
|
||||||
|
online: make(map[string]*OnlinePlayer),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Lobby) PlayerOnline(fingerprint, name string) {
|
||||||
|
l.mu.Lock()
|
||||||
|
defer l.mu.Unlock()
|
||||||
|
l.online[fingerprint] = &OnlinePlayer{Name: name, Fingerprint: fingerprint}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Lobby) PlayerOffline(fingerprint string) {
|
||||||
|
l.mu.Lock()
|
||||||
|
defer l.mu.Unlock()
|
||||||
|
delete(l.online, fingerprint)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Lobby) ListOnline() []*OnlinePlayer {
|
||||||
|
l.mu.RLock()
|
||||||
|
defer l.mu.RUnlock()
|
||||||
|
result := make([]*OnlinePlayer, 0, len(l.online))
|
||||||
|
for _, p := range l.online {
|
||||||
|
result = append(result, p)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Lobby) InvitePlayer(roomCode, fingerprint string) error {
|
||||||
|
l.mu.Lock()
|
||||||
|
defer l.mu.Unlock()
|
||||||
|
p, ok := l.online[fingerprint]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("player not online")
|
||||||
|
}
|
||||||
|
if p.InRoom != "" {
|
||||||
|
return fmt.Errorf("player already in a room")
|
||||||
|
}
|
||||||
|
// Store the invite as a pending field
|
||||||
|
p.InRoom = "invited:" + roomCode
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Lobby) CreateRoom(name string) string {
|
func (l *Lobby) CreateRoom(name string) string {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ type lobbyState struct {
|
|||||||
roomName string
|
roomName string
|
||||||
joining bool
|
joining bool
|
||||||
codeInput string
|
codeInput string
|
||||||
|
online int
|
||||||
}
|
}
|
||||||
|
|
||||||
type roomInfo struct {
|
type roomInfo struct {
|
||||||
@@ -39,7 +40,7 @@ func renderLobby(state lobbyState, width, height int) string {
|
|||||||
Border(lipgloss.RoundedBorder()).
|
Border(lipgloss.RoundedBorder()).
|
||||||
Padding(0, 1)
|
Padding(0, 1)
|
||||||
|
|
||||||
header := headerStyle.Render("── Lobby ──")
|
header := headerStyle.Render(fmt.Sprintf("── Lobby ── %d online ──", state.online))
|
||||||
menu := "[C] Create Room [J] Join by Code [Up/Down] Select [Enter] Join [Q] Back"
|
menu := "[C] Create Room [J] Join by Code [Up/Down] Select [Enter] Join [Q] Back"
|
||||||
|
|
||||||
roomList := ""
|
roomList := ""
|
||||||
|
|||||||
Reference in New Issue
Block a user