package main import ( "bitbucket.org/hackerbots/bot" "code.google.com/p/go.net/websocket" "encoding/json" "fmt" "log" "net/http" "strings" ) type JsonHandler func(http.ResponseWriter, *http.Request) func (h JsonHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "application/json") h(w, req) } func startGame(w http.ResponseWriter, req *http.Request) { new_game_name := idg.Hash() _g := NewGame(new_game_name, *width, *height) go _g.run() games.Lock() games.m[new_game_name] = _g games.Unlock() 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() type pout struct { Name string `json:"name"` Id string `json:"id"` } type gl struct { Id string `json:"id"` Players []pout `json:"players"` } ids := make([]gl, 0) for id, g := range games.m { players := make([]pout, 0) for p, _ := range g.players { // XXX: change this to be the user-provided bot name? players = append(players, pout{ Name: p.Robot.Name, Id: p.Robot.Id, }) } ids = append(ids, gl{ Id: id, Players: players, }) } if err := json.NewEncoder(w).Encode(ids); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } func addPlayer(ws *websocket.Conn) { // route to appropriate game ... var gid bot.GameID err := websocket.JSON.Receive(ws, &gid) if err != nil { log.Println("problem parsing the requested game id") return } games.Lock() game, ok := games.m[gid.Id] games.Unlock() if !ok { log.Println("ERROR: game not found") websocket.JSON.Send(ws, bot.NewFailure("game 404")) return } id := idg.Hash() conf, err := Negociate(ws, id, game.width, game.height) if err != nil { websocket.JSON.Send(ws, bot.NewFailure(err.Error())) } if conf != nil { p := &player{ Robot: bot.Robot{ Stats: conf.Stats, Id: id, Name: conf.Name, Health: conf.Stats.Hp, Scanners: make([]bot.Scanner, 0)}, send: make(chan *bot.Boardstate), ws: ws, } p.reset() game.register <- p defer func() { game.unregister <- p }() go p.sender() p.recv() log.Printf("game %s: player %v has been disconnected from this game\n", gid.Id, p.Robot.Id) } else { s := &Spectator{ send: make(chan *bot.Boardstate), ws: ws, } game.sregister <- s defer func() { game.sunregister <- s }() s.sender() log.Printf("game %s: spectator %+v has been disconnected from this game\n", s) } }