server/player.go
Stephen McQuay 6fd4138740 added bw calcs
unfortunately there is an issue with how these are calculated, and they don't
decrease as things quiet down. Well, the bad numbers are their for your
consumption, and should Just Work TM when appropriate changes in
bitbucket.org/smcquay/bandwith land. And they will. But I'm tired now.
2014-03-03 22:56:26 -08:00

183 lines
3.5 KiB
Go

package main
import (
"encoding/json"
"errors"
"fmt"
"log"
"bitbucket.org/smcquay/bandwidth"
"code.google.com/p/go.net/websocket"
)
const maxMessageSize = 1024
type protoTalker struct {
ws *websocket.Conn
bw *bandwidth.Bandwidth
send chan Message
buff []byte
Id string
}
func NewProtoTalker(id string, ws *websocket.Conn, bw *bandwidth.Bandwidth) *protoTalker {
return &protoTalker{
send: make(chan Message, 16),
ws: ws,
bw: bw,
Id: id,
buff: make([]byte, maxMessageSize),
}
}
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
}
n, err := pt.ws.Write(b)
pt.bw.AddTx <- n
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
}
pt.bw.AddRx <- n
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 NewPlayer(id string, ws *websocket.Conn, bw *bandwidth.Bandwidth) *player {
return &player{
Robots: []*Robot{},
protoTalker: *NewProtoTalker(id, ws, bw),
}
}
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 NewSpectator(id string, ws *websocket.Conn, bw *bandwidth.Bandwidth) *Spectator {
return &Spectator{
protoTalker: *NewProtoTalker(id, ws, bw),
}
}
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()
}