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.

155 lines
2.9 KiB

7 years ago
  1. package main
  2. import (
  3. "code.google.com/p/go.net/websocket"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "log"
  8. )
  9. const maxMessageSize = 1024
  10. type protoTalker struct {
  11. ws *websocket.Conn
  12. send chan Message
  13. Id string
  14. }
  15. func (pt *protoTalker) sender() {
  16. log.Printf("%s: client launched", pt.Id)
  17. for things := range pt.send {
  18. b, err := json.Marshal(things)
  19. if err != nil {
  20. break
  21. }
  22. // XXX: send the count to our bandwidth analyzer ...
  23. _, err = pt.ws.Write(b)
  24. if err != nil {
  25. break
  26. }
  27. }
  28. pt.ws.Close()
  29. log.Printf("%s: spectator sender close", pt.Id)
  30. }
  31. func (pt *protoTalker) readJSON(buff []byte) (map[string]Instruction, error) {
  32. msg := map[string]Instruction{}
  33. n, err := pt.ws.Read(buff)
  34. if err != nil {
  35. log.Printf("%s: problem reading from player: %s", pt.Id, err)
  36. return nil, err
  37. }
  38. // XXX: send n to our bandwidth analyzer ...
  39. if n == len(buff) {
  40. errMsg := fmt.Sprintf("%s: read buffer overfull: %s", pt.Id, string(buff))
  41. log.Printf(errMsg)
  42. return msg, errors.New(errMsg)
  43. }
  44. err = json.Unmarshal(buff[:n], &msg)
  45. if err != nil {
  46. log.Printf("%s: problem reading from player: %s", pt.Id, err)
  47. return nil, err
  48. }
  49. return msg, nil
  50. }
  51. type player struct {
  52. Robots []*Robot
  53. Instruction Instruction
  54. protoTalker
  55. }
  56. func (p *player) recv() {
  57. for {
  58. msgs, err := p.readJSON(p.buff)
  59. if err != nil {
  60. log.Printf("%s: %s", p.Id, err)
  61. break
  62. }
  63. for _, r := range p.Robots {
  64. msg, ok := msgs[r.Id]
  65. if !ok {
  66. continue
  67. }
  68. if msg.Repair != nil && *msg.Repair == true {
  69. r.ActiveScan = false
  70. r.TargetSpeed = 0
  71. r.FireAt = nil
  72. r.MoveTo = nil
  73. if r.RepairCounter <= 0 {
  74. r.RepairCounter = 3.0
  75. }
  76. } else if msg.Scan != nil && *msg.Scan == true {
  77. r.RepairCounter = 0
  78. r.TargetSpeed = 0
  79. r.FireAt = nil
  80. r.MoveTo = nil
  81. r.ActiveScan = true
  82. } else {
  83. r.RepairCounter = 0
  84. r.ActiveScan = false
  85. // Reapiring halts all other activity
  86. if msg.MoveTo != nil {
  87. r.MoveTo = msg.MoveTo
  88. }
  89. if msg.Heading != nil {
  90. r.DesiredHeading = msg.Heading
  91. }
  92. if msg.FireAt != nil {
  93. r.FireAt = msg.FireAt
  94. } else {
  95. r.FireAt = nil
  96. }
  97. if msg.TargetSpeed != nil {
  98. r.TargetSpeed = float32(*msg.TargetSpeed)
  99. } else {
  100. r.TargetSpeed = r.Stats.Speed
  101. }
  102. }
  103. if msg.Probe != nil {
  104. r.Probe = msg.Probe
  105. r.ProbeResult = nil
  106. } else {
  107. r.Probe = nil
  108. }
  109. if msg.Message != nil {
  110. r.Message = *msg.Message
  111. }
  112. }
  113. }
  114. log.Printf("%s: recv close", p.Id)
  115. p.ws.Close()
  116. }
  117. type Spectator struct {
  118. protoTalker
  119. }
  120. func (s *Spectator) recv() {
  121. for {
  122. _, err := s.readJSON(s.buff)
  123. if err != nil {
  124. log.Printf("%s: %s", s.Id, err)
  125. break
  126. }
  127. // After the first bit of handshaking, the rest of the messages should
  128. // only be "{}" for spectators, and the following could hold true:
  129. //
  130. // if string(buff[:n]) != "{}" {
  131. // log.Printf("protocol breach!!")
  132. // break
  133. // }
  134. }
  135. log.Printf("%s: recv close", s.Id)
  136. s.ws.Close()
  137. }