diff --git a/game.go b/game.go index d851104..d734c87 100644 --- a/game.go +++ b/game.go @@ -7,6 +7,7 @@ import ( ) type game struct { + id string players map[*player]bool projectiles map[*projectile]bool splosions map[*splosion]bool @@ -21,8 +22,9 @@ type game struct { kill chan bool } -func NewGame(width, height float64) *game { +func NewGame(id string, width, height float64) *game { return &game{ + id: id, register: make(chan *player), unregister: make(chan *player), projectiles: make(map[*projectile]bool), diff --git a/http.go b/http.go index bc1fa2d..20410b9 100644 --- a/http.go +++ b/http.go @@ -1,6 +1,10 @@ package main import ( + "code.google.com/p/go.net/websocket" + "encoding/json" + "fmt" + "log" "net/http" ) @@ -10,3 +14,81 @@ 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() + + gameLock.Lock() + games[new_game_name] = _g + gameLock.Unlock() + + w.Write([]byte(fmt.Sprintf(`{"id": "%s"}`, new_game_name))) +} + +func listGames(w http.ResponseWriter, req *http.Request) { + gameLock.RLock() + defer gameLock.RUnlock() + ids := make([]string, 0) + for id, _ := range games { + ids = append(ids, id) + } + 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 GameID + err := websocket.JSON.Receive(ws, &gid) + if err != nil { + log.Println("problem parsing the requested game id") + return + } + + gameLock.Lock() + game := games[gid.Id] + gameLock.Unlock() + log.Printf("%+v", game) + + id := "asdf" + + conf, err := Negociate(ws, id, 400, 800) + if err != nil { + websocket.JSON.Send(ws, NewFailure(err.Error())) + } + + if conf != nil { + p := &player{ + Robot: robot{ + Stats: conf.Stats, + Id: id, + Health: conf.Stats.Hp, + Scanners: make([]scanner, 0)}, + send: make(chan *boardstate), + ws: ws, + } + p.reset() + game.register <- p + defer func() { + game.unregister <- p + }() + go p.sender() + p.recv() + log.Printf("%v has been disconnect from this game\n", p.Robot.Id) + } else { + s := &Spectator{ + send: make(chan *boardstate), + ws: ws, + } + game.sregister <- s + defer func() { + game.sunregister <- s + }() + s.sender() + log.Printf("%+v has been disconnect from this game\n", s) + } +} diff --git a/main.go b/main.go index 5be1222..c5721c4 100644 --- a/main.go +++ b/main.go @@ -2,9 +2,7 @@ package main import ( "code.google.com/p/go.net/websocket" - "encoding/json" "flag" - "fmt" "log" "math/rand" "net/http" @@ -19,7 +17,6 @@ var width = flag.Float64("width", 800, "width of field") var height = flag.Float64("height", 550, "height of field") var delta float64 -var g *game var games map[string]*game var idg *IdGenerator @@ -44,68 +41,3 @@ func main() { log.Fatal("unable to start server") } } - -func startGame(w http.ResponseWriter, req *http.Request) { - new_game_name := idg.Hash() - - _g := NewGame(*width, *height) - go _g.run() - - gameLock.Lock() - games[new_game_name] = _g - gameLock.Unlock() - - w.Write([]byte(fmt.Sprintf(`{"id": "%s"}`, new_game_name))) -} - -func listGames(w http.ResponseWriter, req *http.Request) { - gameLock.RLock() - defer gameLock.RUnlock() - ids := make([]string, 0) - for id, _ := range games { - ids = append(ids, id) - } - if err := json.NewEncoder(w).Encode(ids); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - } -} - -func addPlayer(ws *websocket.Conn) { - id := fmt.Sprintf("robot%d", <-g.robot_id) - - conf, err := Negociate(ws, id, *width, *height) - if err != nil { - websocket.JSON.Send(ws, NewFailure(err.Error())) - } - - if conf != nil { - p := &player{ - Robot: robot{ - Stats: conf.Stats, - Id: id, - Health: conf.Stats.Hp, - Scanners: make([]scanner, 0)}, - send: make(chan *boardstate), - ws: ws, - } - p.reset() - g.register <- p - defer func() { - g.unregister <- p - }() - go p.sender() - p.recv() - log.Printf("%v has been disconnect from this game\n", p.Robot.Id) - } else { - s := &Spectator{ - send: make(chan *boardstate), - ws: ws, - } - g.sregister <- s - defer func() { - g.sunregister <- s - }() - s.sender() - log.Printf("%+v has been disconnect from this game\n", s) - } -} diff --git a/protocol.go b/protocol.go index c19e0df..49848f6 100644 --- a/protocol.go +++ b/protocol.go @@ -5,6 +5,10 @@ import ( "errors" ) +type GameID struct { + Id string `json:"id"` +} + // > identify type IdRequest struct { Type string `json:"type"` diff --git a/protocol_test.go b/protocol_test.go index d1d09ef..ec508b7 100644 --- a/protocol_test.go +++ b/protocol_test.go @@ -11,6 +11,7 @@ type result struct { b bool msg string } + type clientIDTest struct { clientid ClientID expected result @@ -54,7 +55,7 @@ func DummyServer() (*websocket.Conn, error) { handled = true } - g = NewGame() + g = NewGame("hello world", 400, 800) go g.run() go http.ListenAndServe(*addr, nil) @@ -66,6 +67,13 @@ func DummyServer() (*websocket.Conn, error) { func TestGoodProtocol(t *testing.T) { ws, err := DummyServer() + err = websocket.JSON.Send(ws, GameID{ + "test", + }) + if err != nil { + t.Error(err) + } + var idreq IdRequest err = websocket.JSON.Receive(ws, &idreq) if err != nil {