diff --git a/player.go b/player.go index c7c655c..1187e9a 100644 --- a/player.go +++ b/player.go @@ -3,53 +3,69 @@ package main import ( "code.google.com/p/go.net/websocket" "encoding/json" + "errors" + "fmt" "log" ) const maxMessageSize = 1024 -type player struct { - ws *websocket.Conn - Robots []*Robot - send chan Message - Instruction Instruction - Id string +type protoTalker struct { + ws *websocket.Conn + send chan Message + Id string } -func (p *player) sender() { - log.Printf("%s: sender launched", p.Id) - for things := range p.send { +func (pt *protoTalker) sender() { + log.Printf("%s: client launched", pt.Id) + for things := range pt.send { b, err := json.Marshal(things) if err != nil { break } // XXX: send the count to our bandwidth analyzer ... - _, err = p.ws.Write(b) + _, err = pt.ws.Write(b) if err != nil { break } } - p.ws.Close() - log.Printf("%s: robot (%s) sender close", p.Id, p.Robots[0].Id) + pt.ws.Close() + log.Printf("%s: spectator sender close", pt.Id) +} + +func (pt *protoTalker) readJSON(buff []byte) (map[string]Instruction, error) { + msg := map[string]Instruction{} + n, err := pt.ws.Read(buff) + if err != nil { + log.Printf("%s: problem reading from player: %s", pt.Id, err) + return nil, err + } + // XXX: send n to our bandwidth analyzer ... + if n == len(buff) { + errMsg := fmt.Sprintf("%s: read buffer overfull: %s", pt.Id, string(buff)) + log.Printf(errMsg) + return msg, errors.New(errMsg) + } + err = json.Unmarshal(buff[:n], &msg) + if err != nil { + log.Printf("%s: problem reading from player: %s", pt.Id, err) + return nil, err + } + return msg, nil +} + +type player struct { + Robots []*Robot + Instruction Instruction + protoTalker } func (p *player) recv() { buff := make([]byte, maxMessageSize) - var msgs map[string]Instruction for { - n, err := p.ws.Read(buff) + msgs, err := p.readJSON(buff) if err != nil { - log.Printf("%s: problem reading from player: %s", p.Id, err) - break - } - // XXX: send n to our bandwidth analyzer ... - if n == len(buff) { - log.Printf("%s: read buffer overfull: %s", p.Id, string(buff)) - break - } - err = json.Unmarshal(buff[:n], &msgs) - if err != nil { - log.Printf("%s: problem reading from player: %s", p.Id, err) + log.Printf("%s: %s", p.Id, err) break } @@ -115,3 +131,28 @@ func (p *player) recv() { log.Printf("%s: recv close", p.Id) p.ws.Close() } + +type Spectator struct { + protoTalker +} + +func (s *Spectator) recv() { + // TODO: move this to a NewSpectator func + buff := make([]byte, maxMessageSize) + for { + _, err := s.readJSON(buff) + if err != nil { + log.Printf("%s: %s", s.Id, err) + break + } + // After the first bit of handshaking, the rest of the messages should + // only be "{}" for spectators, and the following could hold true: + // + // if string(buff[:n]) != "{}" { + // log.Printf("protocol breach!!") + // break + // } + } + log.Printf("%s: recv close", s.Id) + s.ws.Close() +} diff --git a/protocol.go b/protocol.go index fa0274e..d303bc4 100644 --- a/protocol.go +++ b/protocol.go @@ -232,9 +232,11 @@ func addPlayer(ws *websocket.Conn) { p := &player{ Robots: []*Robot{}, - send: make(chan Message, 16), - ws: ws, - Id: player_id, + protoTalker: protoTalker{ + send: make(chan Message, 16), + ws: ws, + Id: player_id, + }, } log.Printf("%s: made a player: %s", gid.Id, p.Id) @@ -291,9 +293,11 @@ func addPlayer(ws *websocket.Conn) { ) case "spectator": s := &Spectator{ - send: make(chan Message, 16), - ws: ws, - Id: player_id, + protoTalker{ + send: make(chan Message, 16), + ws: ws, + Id: player_id, + }, } log.Printf("%s, %s: about to register this spectator", gid.Id, s.Id) game.sregister <- s diff --git a/spectator.go b/spectator.go deleted file mode 100644 index 30ac598..0000000 --- a/spectator.go +++ /dev/null @@ -1,63 +0,0 @@ -package main - -import ( - "code.google.com/p/go.net/websocket" - "encoding/json" - "log" -) - -type Spectator struct { - ws *websocket.Conn - send chan Message - Id string -} - -func (s *Spectator) sender() { - log.Printf("%s: sender launched", s.Id) - for things := range s.send { - b, err := json.Marshal(things) - if err != nil { - break - } - // XXX: send the count to our bandwidth analyzer ... - _, err = s.ws.Write(b) - if err != nil { - break - } - } - s.ws.Close() - log.Printf("%s: spectator sender close", s.Id) -} - -func (s *Spectator) recv() { - var msg interface{} - buff := make([]byte, maxMessageSize) - for { - n, err := s.ws.Read(buff) - if err != nil { - log.Printf("%s: problem reading from player: %s", s.Id, err) - break - } - // XXX: send n to our bandwidth analyzer ... - log.Println(string(buff[:n])) - if n == len(buff) { - log.Printf("%s: read buffer overfull: %s", s.Id, string(buff)) - break - } - err = json.Unmarshal(buff[:n], &msg) - log.Println(n) - if err != nil { - log.Printf("%s: problem reading from player: %s", s.Id, err) - break - } - // After the first bit of handshaking, the rest of the messages should - // only be "{}" for spectators, and the following could hold true: - // - // if string(buff[:n]) != "{}" { - // log.Printf("protocol breach!!") - // break - // } - } - log.Printf("%s: recv close", s.Id) - s.ws.Close() -}