No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

player.go 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. package botserv
  2. import (
  3. "encoding/gob"
  4. "encoding/json"
  5. "log"
  6. "bitbucket.org/smcquay/bandwidth"
  7. "code.google.com/p/go.net/websocket"
  8. )
  9. const maxMessageSize = 1024
  10. type encoder interface {
  11. Encode(v interface{}) error
  12. }
  13. type decoder interface {
  14. Decode(v interface{}) error
  15. }
  16. type streamCounter struct {
  17. ws *websocket.Conn
  18. bw *bandwidth.Bandwidth
  19. }
  20. func (sc *streamCounter) Read(p []byte) (n int, err error) {
  21. n, err = sc.ws.Read(p)
  22. sc.bw.AddRx <- n
  23. return n, err
  24. }
  25. func (sc *streamCounter) Write(p []byte) (n int, err error) {
  26. n, err = sc.ws.Write(p)
  27. sc.bw.AddTx <- n
  28. return n, err
  29. }
  30. func (sc *streamCounter) Close() error {
  31. return sc.ws.Close()
  32. }
  33. type protoTalker struct {
  34. enc encoder
  35. dec decoder
  36. counter *streamCounter
  37. send chan Message
  38. Id string
  39. }
  40. func NewProtoTalker(id string, ws *websocket.Conn, bw *bandwidth.Bandwidth, encoding string) *protoTalker {
  41. var enc encoder
  42. var dec decoder
  43. comptroller := &streamCounter{
  44. ws: ws,
  45. bw: bw,
  46. }
  47. if encoding == "json" {
  48. enc = json.NewEncoder(comptroller)
  49. dec = json.NewDecoder(comptroller)
  50. } else {
  51. enc = gob.NewEncoder(comptroller)
  52. dec = gob.NewDecoder(comptroller)
  53. }
  54. return &protoTalker{
  55. send: make(chan Message, 16),
  56. enc: enc,
  57. dec: dec,
  58. counter: comptroller,
  59. Id: id,
  60. }
  61. }
  62. func (pt *protoTalker) sender() {
  63. log.Printf("%s: client launched", pt.Id)
  64. for things := range pt.send {
  65. err := pt.enc.Encode(things)
  66. if err != nil {
  67. break
  68. }
  69. }
  70. pt.counter.Close()
  71. log.Printf("%s: spectator sender close", pt.Id)
  72. }
  73. type player struct {
  74. Robots []*Robot
  75. Instruction Instruction
  76. protoTalker
  77. }
  78. func NewPlayer(id string, ws *websocket.Conn, bw *bandwidth.Bandwidth, encoding string) *player {
  79. return &player{
  80. Robots: []*Robot{},
  81. protoTalker: *NewProtoTalker(id, ws, bw, encoding),
  82. }
  83. }
  84. func (p *player) recv() {
  85. for {
  86. var msgs map[string]Instruction
  87. err := p.dec.Decode(&msgs)
  88. if err != nil {
  89. log.Printf("%s: %s", p.Id, err)
  90. break
  91. }
  92. for _, r := range p.Robots {
  93. msg, ok := msgs[r.Id]
  94. if !ok {
  95. continue
  96. }
  97. if msg.Repair != nil && *msg.Repair == true {
  98. r.ActiveScan = false
  99. r.TargetSpeed = 0
  100. r.FireAt = nil
  101. r.MoveTo = nil
  102. if r.RepairCounter <= 0 {
  103. r.RepairCounter = 3.0
  104. }
  105. } else if msg.Scan != nil && *msg.Scan == true {
  106. r.RepairCounter = 0
  107. r.TargetSpeed = 0
  108. r.FireAt = nil
  109. r.MoveTo = nil
  110. r.ActiveScan = true
  111. } else {
  112. r.RepairCounter = 0
  113. r.ActiveScan = false
  114. // Reapiring halts all other activity
  115. if msg.MoveTo != nil {
  116. r.MoveTo = msg.MoveTo
  117. }
  118. if msg.Heading != nil {
  119. r.DesiredHeading = msg.Heading
  120. }
  121. if msg.FireAt != nil {
  122. r.FireAt = msg.FireAt
  123. } else {
  124. r.FireAt = nil
  125. }
  126. if msg.TargetSpeed != nil {
  127. r.TargetSpeed = float32(*msg.TargetSpeed)
  128. } else {
  129. r.TargetSpeed = r.Stats.Speed
  130. }
  131. }
  132. if msg.Probe != nil {
  133. r.Probe = msg.Probe
  134. r.ProbeResult = nil
  135. } else {
  136. r.Probe = nil
  137. }
  138. if msg.Message != nil {
  139. r.Message = *msg.Message
  140. }
  141. }
  142. }
  143. log.Printf("%s: recv close", p.Id)
  144. p.counter.Close()
  145. }
  146. type Spectator struct {
  147. protoTalker
  148. }
  149. func NewSpectator(id string, ws *websocket.Conn, bw *bandwidth.Bandwidth, encoding string) *Spectator {
  150. return &Spectator{
  151. protoTalker: *NewProtoTalker(id, ws, bw, encoding),
  152. }
  153. }
  154. func (s *Spectator) recv() {
  155. for {
  156. var msgs interface{}
  157. err := s.dec.Decode(&msgs)
  158. if err != nil {
  159. log.Printf("%s: %s", s.Id, err)
  160. break
  161. }
  162. // After the first bit of handshaking, the rest of the messages should
  163. // only be "{}" for spectators, and the following could hold true:
  164. //
  165. // if string(buff[:n]) != "{}" {
  166. // log.Printf("protocol breach!!")
  167. // break
  168. // }
  169. }
  170. log.Printf("%s: recv close", s.Id)
  171. s.counter.Close()
  172. }