diff --git a/game.go b/game.go index b49efef..ffd3162 100644 --- a/game.go +++ b/game.go @@ -7,6 +7,8 @@ import ( "time" ) +const maxPlayer = 128 + type game struct { id string players map[*player]bool @@ -26,7 +28,7 @@ func NewGame(id string, width, height float64) *game { g := &game{ id: id, register: make(chan *player), - unregister: make(chan *player), + unregister: make(chan *player, maxPlayer), projectiles: make(map[*bot.Projectile]bool), splosions: make(map[*bot.Splosion]bool), players: make(map[*player]bool), @@ -36,7 +38,7 @@ func NewGame(id string, width, height float64) *game { spectators: make(map[*Spectator]bool), sregister: make(chan *Spectator), sunregister: make(chan *Spectator), - kill: make(chan bool, 128), + kill: make(chan bool, maxPlayer), } return g } @@ -50,6 +52,9 @@ func (g *game) run() { case <-g.kill: log.Printf("game %s: received kill signal, dying gracefully", g.id) games.Lock() + for player := range g.players { + close(player.send) + } delete(games.m, g.id) games.Unlock() return diff --git a/http.go b/http.go index 21aa190..843c056 100644 --- a/http.go +++ b/http.go @@ -7,6 +7,7 @@ import ( "fmt" "log" "net/http" + "strings" ) type JsonHandler func(http.ResponseWriter, *http.Request) @@ -30,6 +31,24 @@ func startGame(w http.ResponseWriter, req *http.Request) { w.Write([]byte(fmt.Sprintf(`{"id": "%s"}`, new_game_name))) } +func stopGame(w http.ResponseWriter, req *http.Request) { + trimmed := strings.Trim(req.URL.Path, "/") + fullPath := strings.Split(trimmed, "/") + if len(fullPath) != 3 { + http.Error(w, "improperly formed url", http.StatusBadRequest) + return + } + key := fullPath[2] + games.Lock() + gameid, ok := games.m[key] + defer games.Unlock() + if !ok { + http.NotFound(w, req) + return + } + gameid.kill <- true +} + func listGames(w http.ResponseWriter, req *http.Request) { games.RLock() defer games.RUnlock() diff --git a/main.go b/main.go index 58bb4a4..377ba73 100644 --- a/main.go +++ b/main.go @@ -39,7 +39,7 @@ func main() { http.Handle("/ws/", websocket.Handler(addPlayer)) http.Handle("/game/start/", JsonHandler(startGame)) http.Handle("/game/list/", JsonHandler(listGames)) - // http.Handle("/game/stop/", stopGame) + http.HandleFunc("/game/stop/", stopGame) err := http.ListenAndServe(*addr, nil) if err != nil { diff --git a/player.go b/player.go index 9941174..647f14a 100644 --- a/player.go +++ b/player.go @@ -34,10 +34,15 @@ func (p *player) sender() { func (p *player) recv() { for { + // XXX: need to mark myself as having received something, also binding + // such action to a particular game turn ID var msg instruction err := websocket.JSON.Receive(p.ws, &msg) if err != nil { - log.Print(err) + // TODO: perhaps we could be a bit more precise in the handling of + // this 'error' by selecting on some kill signal channel and this + // json read? + log.Print("problem receiving JSON from player: ", err) break } if msg.MoveTo != nil {