Advertisement
Guest User

Untitled

a guest
Mar 26th, 2019
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 4.15 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "bufio"
  5.     "encoding/json"
  6.     "errors"
  7.     "fmt"
  8.     "math/rand"
  9.     "net"
  10. )
  11.  
  12. type PlayerMovement struct {
  13.     ID int `json:"id,omitempty"`
  14.     X  int `json:"x"`
  15.     Y  int `json:"y"`
  16.  
  17.     Command string `json:"cmd"`
  18. }
  19.  
  20. type PlayerJoin struct {
  21.     ID int `json:"id"`
  22.     X  int `json:"x"`
  23.     Y  int `json:"y"`
  24.     R  int `json:"r"`
  25.  
  26.     Command string `json:"cmd"`
  27. }
  28.  
  29. type PlayerInit struct {
  30.     ID int `json:"id"`
  31.     X  int `json:"x"`
  32.     Y  int `json:"y"`
  33.     R  int `json:"r"`
  34.     WW int `json:"ww"`
  35.     WH int `json:"wh"`
  36.  
  37.     Command string `json:"cmd"`
  38. }
  39.  
  40. type PlayerExit struct {
  41.     ID int `json:"id"`
  42.  
  43.     Command string `json:"cmd"`
  44. }
  45.  
  46. type Player struct {
  47.     ID int `json:"id"`
  48.     X  int `json:"x"`
  49.     Y  int `json:"y"`
  50.  
  51.     Connection net.Conn
  52.     SendChan   chan []byte
  53.     Closed     bool
  54. }
  55.  
  56. func NewPlayer(conn net.Conn, id int, x int, y int) *Player {
  57.     return &Player{
  58.         ID: id,
  59.         X:  x,
  60.         Y:  y,
  61.  
  62.         Connection: conn,
  63.         SendChan:   make(chan []byte, 128),
  64.     }
  65. }
  66.  
  67. func (player *Player) Sender() {
  68.     writer := bufio.NewWriter(player.Connection)
  69.  
  70.     for packet := range player.SendChan {
  71.         writer.Write(packet)
  72.         writer.WriteByte('\x00')
  73.         writer.Flush()
  74.     }
  75. }
  76.  
  77. func (player *Player) Send(packet []byte) error {
  78.     if player.Closed {
  79.         return errors.New("closed")
  80.     }
  81.  
  82.     select {
  83.     case player.SendChan <- packet:
  84.         return nil
  85.     default:
  86.         return errors.New("send queue full")
  87.     }
  88. }
  89.  
  90. func (player *Player) Run() {
  91.     reader := bufio.NewReader(player.Connection)
  92.  
  93.     go player.Sender()
  94.  
  95.     for {
  96.         data, err := reader.ReadSlice('\x00')
  97.  
  98.         if err == nil {
  99.             var mv PlayerMovement
  100.  
  101.             err = json.Unmarshal(data[0:len(data)-1], &mv)
  102.             if err == nil {
  103.                 mv.ID = player.ID
  104.  
  105.                 moves <- mv
  106.             } else {
  107.                 exits <- player
  108.                 break
  109.             }
  110.         } else {
  111.             exits <- player
  112.             break
  113.         }
  114.     }
  115. }
  116.  
  117. func (player *Player) Close() {
  118.     if !player.Closed {
  119.         player.Closed = true
  120.  
  121.         close(player.SendChan)
  122.         player.Connection.Close()
  123.     }
  124. }
  125.  
  126. const (
  127.     WindowWidth  = 700
  128.     WindowHeight = 500
  129.     RSize        = 30
  130. )
  131.  
  132. var (
  133.     joins = make(chan *Player)
  134.     exits = make(chan *Player)
  135.     moves = make(chan PlayerMovement)
  136. )
  137.  
  138. func netLoop() {
  139.     listener, err := net.Listen("tcp", ":5588")
  140.  
  141.     if err != nil {
  142.         panic(err)
  143.     }
  144.  
  145.     counter := 0
  146.     for {
  147.         conn, err := listener.Accept()
  148.  
  149.         if err == nil {
  150.             counter++
  151.  
  152.             joins <- NewPlayer(conn, counter, 0, 0)
  153.         }
  154.     }
  155. }
  156.  
  157. func gameLoop() {
  158.     players := make(map[int]*Player, 0)
  159.  
  160.     for {
  161.         select {
  162.         case joining := <-joins:
  163.             fmt.Println("Joining", joining.Connection.RemoteAddr())
  164.  
  165.             go joining.Run()
  166.  
  167.             joining.X = rand.Intn(500-100) + 100
  168.             joining.Y = rand.Intn(500-100) + 100
  169.  
  170.             join := PlayerJoin{
  171.                 ID: joining.ID,
  172.                 X:  joining.X,
  173.                 Y:  joining.Y,
  174.                 R:  RSize,
  175.  
  176.                 Command: "join",
  177.             }
  178.             init := PlayerInit{
  179.                 ID: joining.ID,
  180.                 X:  joining.X,
  181.                 Y:  joining.Y,
  182.                 R:  RSize,
  183.                 WW: WindowWidth,
  184.                 WH: WindowHeight,
  185.  
  186.                 Command: "init",
  187.             }
  188.  
  189.             jpacket, _ := json.Marshal(&join)
  190.             ipacket, _ := json.Marshal(&init)
  191.  
  192.             if joining.Send(ipacket) != nil {
  193.                 joining.Close()
  194.                 break
  195.             }
  196.  
  197.             for _, player := range players {
  198.                 if player.Send(jpacket) != nil {
  199.                     player.Close()
  200.                 }
  201.  
  202.                 oldJoin := PlayerJoin{
  203.                     ID: player.ID,
  204.                     X:  player.X,
  205.                     Y:  player.Y,
  206.                     R:  RSize,
  207.  
  208.                     Command: "join",
  209.                 }
  210.  
  211.                 opacket, _ := json.Marshal(oldJoin)
  212.                 if joining.Send(opacket) != nil {
  213.                     joining.Close()
  214.                     break
  215.                 }
  216.             }
  217.             players[joining.ID] = joining
  218.  
  219.         case leaving := <-exits:
  220.             fmt.Println("Leaving", leaving.Connection.RemoteAddr())
  221.             delete(players, leaving.ID)
  222.  
  223.             exit := PlayerExit{ID: leaving.ID, Command: "exit"}
  224.             packet, _ := json.Marshal(&exit)
  225.  
  226.             for _, player := range players {
  227.                 if player.Send(packet) != nil {
  228.                     player.Close()
  229.                 }
  230.             }
  231.  
  232.             leaving.Close()
  233.  
  234.         case movement := <-moves:
  235.             packet, _ := json.Marshal(&movement)
  236.  
  237.             player := players[movement.ID]
  238.             player.X = movement.X
  239.             player.Y = movement.Y
  240.  
  241.             for _, player := range players {
  242.                 if player.Send(packet) != nil {
  243.                     player.Close()
  244.                 }
  245.             }
  246.         }
  247.     }
  248. }
  249.  
  250. func main() {
  251.     go netLoop()
  252.     gameLoop()
  253. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement