Guest User

Untitled

a guest
Jul 15th, 2018
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.47 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4. "encoding/binary"
  5. "image/color"
  6. "io"
  7. "log"
  8. "net"
  9. "sync"
  10. "time"
  11. )
  12.  
  13. var colors = []color.RGBA{
  14. {253, 255, 252, 255},
  15. {46, 196, 182, 255},
  16. {231, 29, 54, 255},
  17. {255, 159, 28, 255},
  18. }
  19.  
  20. type Player struct {
  21. Id byte
  22. conn net.Conn
  23. in chan []byte
  24. out chan []byte
  25. }
  26.  
  27. type Event struct {
  28. Time time.Time
  29. Msg []byte
  30. }
  31.  
  32. type Board struct {
  33. playerId byte
  34. players []*Player
  35. playersMu sync.Mutex
  36.  
  37. history []Event
  38. historyMu sync.Mutex
  39. }
  40.  
  41. func NewBoard() *Board {
  42. return &Board{}
  43. }
  44.  
  45. func (b *Board) HandleConn(conn net.Conn) error {
  46. // Register player.
  47. b.playersMu.Lock()
  48. b.playerId++
  49. player := &Player{
  50. Id: b.playerId,
  51. conn: conn,
  52. out: make(chan []byte, 32),
  53. }
  54. b.players = append(b.players, player)
  55. b.playersMu.Unlock()
  56.  
  57. defer func() {
  58. // Remove player.
  59. b.playersMu.Lock()
  60. defer b.playersMu.Unlock()
  61. index := -1
  62. for i, p := range b.players {
  63. if p.Id == player.Id {
  64. index = i
  65. break
  66. }
  67. }
  68. b.players = append(b.players[:index], b.players[index+1:]...)
  69. }()
  70.  
  71. // Replay history.
  72. history := append([]Event{}, b.history...)
  73. previous := time.Now()
  74. for _, event := range history {
  75. dur := event.Time.Sub(previous)
  76. if dur.Seconds() > 1 {
  77. dur = time.Second
  78. }
  79. time.Sleep(dur)
  80. previous = event.Time
  81.  
  82. sz := make([]byte, 2)
  83. binary.LittleEndian.PutUint16(sz, uint16(len(event.Msg)))
  84. _, err := conn.Write(sz)
  85. if err != nil {
  86. return err
  87. }
  88. _, err = conn.Write(event.Msg)
  89. if err != nil {
  90. return err
  91. }
  92. }
  93.  
  94. go func() {
  95. for data := range player.out {
  96. _, err := player.conn.Write(data)
  97. if err != nil {
  98. log.Printf("p.conn.Write: %v", err)
  99. }
  100. }
  101. }()
  102.  
  103. // Send WelcomeMessage.
  104. color := colors[int(player.Id)%len(colors)]
  105. _, err := conn.Write([]byte{6, 0, 2, b.playerId, color.R, color.G, color.B, color.A})
  106. if err != nil {
  107. return err
  108. }
  109.  
  110. buf := make([]byte, 128*1024)
  111. for {
  112. // Receive message from player.
  113. _, err := io.ReadFull(conn, buf[:2])
  114. if err != nil {
  115. return err
  116. }
  117. size := binary.LittleEndian.Uint16(buf[:2])
  118. log.Printf("reading %d bytes", size)
  119. n, err := io.ReadFull(conn, buf[:size])
  120. if err != nil {
  121. return err
  122. }
  123. if n != int(size) {
  124. log.Printf("expected to get %d bytes, but got %d", size, n)
  125. continue
  126. }
  127. log.Printf("got message: %v", buf[:size])
  128.  
  129. // Broadcast the message to all players except the one who sent it.
  130. msg := make([]byte, size)
  131. copy(msg, buf[:size])
  132. b.Broadcast(msg, player)
  133.  
  134. // Save message to history.
  135. b.historyMu.Lock()
  136. if msg[0] == 3 {
  137. // Reset history on clear.
  138. b.history = nil
  139. } else {
  140. b.history = append(b.history, Event{
  141. Time: time.Now(),
  142. Msg: msg,
  143. })
  144. }
  145. b.historyMu.Unlock()
  146. }
  147. }
  148.  
  149. func (b *Board) Broadcast(msg []byte, except *Player) {
  150. b.playersMu.Lock()
  151. defer b.playersMu.Unlock()
  152. data := make([]byte, 2+len(msg))
  153. binary.LittleEndian.PutUint16(data, uint16(len(msg)))
  154. copy(data[2:], msg)
  155. for _, p := range b.players {
  156. if p.Id != except.Id {
  157. log.Printf("sending msg to from %d to %d", except.Id, p.Id)
  158. p.out <- data
  159. }
  160. }
  161.  
  162. // Calculate FPS.
  163. fps := 0
  164. min := time.Now().Add(-time.Second)
  165. for _, e := range b.history {
  166. if e.Time.After(min) {
  167. fps++
  168. }
  169. }
  170. log.Printf("fps is %d", fps)
  171. }
  172.  
  173. func main() {
  174. b := NewBoard()
  175.  
  176. l, err := net.Listen("tcp", ":3939")
  177. if err != nil {
  178. log.Fatal(err)
  179. }
  180. for {
  181. conn, err := l.Accept()
  182. if err != nil {
  183. log.Printf("Accept: %v", err)
  184. continue
  185. }
  186. go func() {
  187. if err := b.HandleConn(conn); err != nil {
  188. log.Printf("HandleConn: %v", err)
  189. }
  190. }()
  191. }
  192. }
Add Comment
Please, Sign In to add comment