Files
justthefrax/game.go
Justin C. Miller ad8e570205 Web app first pass
2024-09-03 00:55:35 -07:00

119 lines
2.6 KiB
Go

package main
import (
"fmt"
"log"
"math/rand/v2"
"strconv"
)
type Game struct {
players map[uint]*Player
hosts map[*Host]bool
playerToken uint64 // Verification token for players
hostToken uint64 // Verification token for the host
registerPlayer chan *Player // Register requests from players.
unregisterPlayer chan *Player // Unregister requests from players.
registerHost chan *Host // Register requests from hosts.
unregisterHost chan *Host // Unregister requests from hosts.
activePlayer *Player
}
func tokenize(token uint64) string {
return strconv.FormatUint(token, 36)
}
func newGame() *Game {
return &Game{
players: make(map[uint]*Player),
hosts: make(map[*Host]bool),
playerToken: rand.Uint64(),
hostToken: rand.Uint64(),
registerPlayer: make(chan *Player),
unregisterPlayer: make(chan *Player),
registerHost: make(chan *Host),
unregisterHost: make(chan *Host),
}
}
func (g *Game) checkPlayerToken(token string) bool {
return token == tokenize(g.playerToken)
}
func (g *Game) broadcastHosts(message []byte) {
for client := range g.hosts {
if !client.send(message) {
delete(g.hosts, client)
}
}
}
func (g *Game) broadcastPlayers(message []byte) {
for id := range g.players {
g.sendTo(id, message)
}
}
func (g *Game) sendTo(playerId uint, message []byte) error {
client, ok := g.players[playerId]
if !ok {
return fmt.Errorf("No Player %d", playerId)
}
if !client.send(message) {
delete(g.players, playerId)
return fmt.Errorf("Player %d disconnected", playerId)
}
return nil
}
func (g *Game) run() {
for {
select {
case player := <-g.registerPlayer:
g.players[player.Id] = player
log.Printf("Player %d (%s: %s) registered", player.Id, player.Team, player.Name)
join := makeMessage("join", player)
g.broadcastHosts(join)
case player := <-g.unregisterPlayer:
id := player.Id
if _, ok := g.players[id]; ok {
delete(g.players, id)
player.closeQueue()
}
log.Printf("Player %d (%s: %s) left", player.Id, player.Team, player.Name)
join := makeMessage("part", player)
g.broadcastHosts(join)
case host := <-g.registerHost:
g.hosts[host] = true
log.Println("Host joined")
for _, player := range g.players {
join := makeMessage("join", player)
g.broadcastHosts(join)
}
case host := <-g.unregisterHost:
if _, ok := g.hosts[host]; ok {
delete(g.hosts, host)
host.closeQueue()
}
log.Println("Host left")
}
}
}
func (g *Game) reveal(value bool) {
log.Printf("Revealing %v!", value)
reveal := makeMessage("reveal", value)
g.broadcastHosts(reveal)
}