- package main
-
- import (
- "code.google.com/p/go.net/websocket"
- "encoding/json"
- "errors"
- "fmt"
- "log"
- )
-
- const maxMessageSize = 1024
-
- type protoTalker struct {
- ws *websocket.Conn
- send chan Message
- Id string
- }
-
- 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 = pt.ws.Write(b)
- if err != nil {
- break
- }
- }
- 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() {
- for {
- msgs, err := p.readJSON(p.buff)
- if err != nil {
- log.Printf("%s: %s", p.Id, err)
- break
- }
-
- for _, r := range p.Robots {
-
- msg, ok := msgs[r.Id]
-
- if !ok {
- continue
- }
-
- if msg.Repair != nil && *msg.Repair == true {
- r.ActiveScan = false
- r.TargetSpeed = 0
- r.FireAt = nil
- r.MoveTo = nil
- if r.RepairCounter <= 0 {
- r.RepairCounter = 3.0
- }
- } else if msg.Scan != nil && *msg.Scan == true {
- r.RepairCounter = 0
- r.TargetSpeed = 0
- r.FireAt = nil
- r.MoveTo = nil
- r.ActiveScan = true
- } else {
- r.RepairCounter = 0
- r.ActiveScan = false
-
- // Reapiring halts all other activity
- if msg.MoveTo != nil {
- r.MoveTo = msg.MoveTo
- }
- if msg.Heading != nil {
- r.DesiredHeading = msg.Heading
- }
- if msg.FireAt != nil {
- r.FireAt = msg.FireAt
- } else {
- r.FireAt = nil
- }
-
- if msg.TargetSpeed != nil {
- r.TargetSpeed = float32(*msg.TargetSpeed)
- } else {
- r.TargetSpeed = r.Stats.Speed
- }
- }
-
- if msg.Probe != nil {
- r.Probe = msg.Probe
- r.ProbeResult = nil
- } else {
- r.Probe = nil
- }
-
- if msg.Message != nil {
- r.Message = *msg.Message
- }
- }
- }
-
- log.Printf("%s: recv close", p.Id)
- p.ws.Close()
- }
-
- type Spectator struct {
- protoTalker
- }
-
- func (s *Spectator) recv() {
- for {
- _, err := s.readJSON(s.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()
- }
|