package gameserver import ( "battlecamp-go/game" "battlecamp-go/player" "battlecamp-go/stomp" "encoding/json" "log" "net/http" "runtime/pprof" "strconv" "github.com/julienschmidt/httprouter" ) var gameServer *GameServer func newUrlRouter(gs *GameServer) *httprouter.Router { gameServer = gs router := httprouter.New() router.GET("/", showIndex) router.GET("/games", listGames) router.PUT("/games", createGame) router.PUT("/games/:rows/:cols", createGame) router.POST("/games/:gameid/join", joinGame) // API says PUT... zuch. router.GET("/games/:gameid", showGame) router.GET("/games/:gameid/:boardid", proxyHandler) router.GET("/games/:gameid/:boardid/:playerid", showPlayer) router.POST("/games/:gameid/move/:playerid/:direction", movePlayer) router.GET("/debug/profiledump", profileDump) return router } func showIndex(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { log.Println("Go battlecamp!") w.Write([]byte("Go battlecamp!")) } func proxyHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { if ps.ByName("gameid") == "asciiboard" { showAsciiBoard(w, r, ps) } else if ps.ByName("gameid") == "board" { showBoard(w, r, ps) } else if ps.ByName("boardid") == "join" { joinGame(w, r, ps) } else { listPlayers(w, r, ps) } } func listGames(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { e := json.NewEncoder(w) e.Encode(gameServer.ListGames()) } func createGame(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { widthString := ps.ByName("cols") heightString := ps.ByName("rows") var game *game.Game log.Printf("Creating new game %vx%v", widthString, heightString) if widthString != "" && heightString != "" { width, _ := strconv.Atoi(widthString) height, _ := strconv.Atoi(heightString) game = gameServer.AddGame(width, height) } else { game = gameServer.AddGame(56, 35) } w.WriteHeader(http.StatusCreated) e := json.NewEncoder(w) e.Encode(game) log.Printf("Created game %v", game.Id) } func joinGame(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { w.Header().Set("Content-Type", "application/json") gameId, _ := strconv.ParseInt(ps.ByName("gameid"), 10, 64) d := json.NewDecoder(r.Body) var p player.Player d.Decode(&p) game := gameServer.GetGame(gameId) game.Join(&p) e := json.NewEncoder(w) e.Encode(&p) stomp.SendJsonPlayerJoin("update", p) log.Printf("Player %v joined game %v", p.Id, game.Id) } func showGame(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { w.Header().Set("Content-Type", "application/json") id, _ := strconv.ParseInt(ps.ByName("gameid"), 10, 64) e := json.NewEncoder(w) e.Encode(gameServer.GetGame(id)) } func listPlayers(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { w.Header().Set("Content-Type", "application/json") gameId, _ := strconv.ParseInt(ps.ByName("gameid"), 10, 64) e := json.NewEncoder(w) e.Encode(gameServer.GetGame(gameId).Players) } func showPlayer(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { w.Header().Set("Content-Type", "application/json") gameId, _ := strconv.ParseInt(ps.ByName("gameid"), 10, 64) playerId := ps.ByName("playerid") g := gameServer.GetGame(gameId) p := g.GetPlayer(playerId) e := json.NewEncoder(w) e.Encode(p) } func movePlayer(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { w.Header().Set("Content-Type", "application/json") idString := ps.ByName("gameid") gameId, _ := strconv.ParseInt(idString, 10, 64) playerId := ps.ByName("playerid") g := gameServer.GetGame(gameId) p := g.GetPlayer(playerId) w.Header().Set("Content-Type", "application/json") direction := ps.ByName("direction") result := g.Move(p, direction) if !result { http.Error(w, "Bad request", http.StatusBadRequest) } e := json.NewEncoder(w) e.Encode(p.Pos) log.Printf("Player %v moved in direction %v\n", p.Id, direction) } // Request params: x={x}&y={y}&rows={rows}&cols={cols} func showBoard(w http.ResponseWriter, req *http.Request, ps httprouter.Params) { w.Header().Set("Content-Type", "application/json") xString := req.FormValue("x") yString := req.FormValue("y") widthString := req.FormValue("cols") heightString := req.FormValue("rows") id, _ := strconv.ParseInt(ps.ByName("boardid"), 10, 64) b := gameServer.GetGame(id).Board if xString != "" && yString != "" && widthString != "" && heightString != "" { x, _ := strconv.Atoi(xString) y, _ := strconv.Atoi(yString) width, _ := strconv.Atoi(widthString) height, _ := strconv.Atoi(heightString) b.WriteJSON(w, x, y, width, height) } else if xString != "" || yString != "" || widthString != "" || heightString != "" { http.Error(w, "Bad request", http.StatusBadRequest) } else { b.WriteJSON(w, 0, 0, b.Width, b.Height) } } func showAsciiBoard(w http.ResponseWriter, req *http.Request, ps httprouter.Params) { w.Header().Set("Content-Type", "text/plain;charset=utf-8") id, _ := strconv.ParseInt(ps.ByName("boardid"), 10, 64) b := gameServer.GetGame(id).Board.String() w.Write([]byte(b)) } func profileDump(w http.ResponseWriter, req *http.Request, ps httprouter.Params) { log.Println("Dumping cpu profile") pprof.StopCPUProfile() }