Advertisement
Guest User

Untitled

a guest
Apr 21st, 2017
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 5.61 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "bufio"
  5.     "bytes"
  6.     "fmt"
  7.     "log"
  8.     "math"
  9.     "net"
  10.     "regexp"
  11.     "strconv"
  12.     "time"
  13. )
  14.  
  15. const (
  16.     SERVER_USER         = "100 LOGIN\r\n"        // Výzva k zadání uživatelského jména
  17.     SERVER_PASSWORD     = "101 PASSWORD\r\n"     // Výzva k zadání uživatelského hesla
  18.     SERVER_MOVE         = "102 MOVE\r\n"         // Příkaz pro pohyb o jedno pole vpřed
  19.     SERVER_TURN_LEFT    = "103 TURN LEFT\r\n"    // Příkaz pro otočení doleva
  20.     SERVER_TURN_RIGHT   = "104 TURN RIGHT\r\n"   // Příkaz pro otočení doprava
  21.     SERVER_PICK_UP      = "105 GET MESSAGE\r\n"  // Příkaz pro vyzvednutí zprávy
  22.     SERVER_OK           = "200 OK\r\n"           // Kladné potvrzení
  23.     SERVER_LOGIN_FAILED = "300 LOGIN FAILED\r\n" // Chybné heslo
  24.     SERVER_SYNTAX_ERROR = "301 SYNTAX ERROR\r\n" // Chybná syntaxe zprávy
  25.     SERVER_LOGIC_ERROR  = "302 LOGIC ERROR\r\n"  // Zpráva odeslaná ve špatné situaci
  26. )
  27.  
  28. const (
  29.     TIMEOUT            = 1
  30.     TIMEOUT_RECHARGING = 5
  31. )
  32.  
  33. var (
  34.     CLIENT_PASSWORD   = regexp.MustCompile(`^[1-9][0-9]{0,4}\r\n$`)
  35.     CLIENT_CONFIRM    = regexp.MustCompile(`^OK -?[0-9]+ -?[0-9]+\r\n$`)
  36.     CLIENT_RECHARGING = regexp.MustCompile(`^RECHARGING\r\n$`)
  37.     CLIENT_FULL_POWER = regexp.MustCompile(`^FULL POWER\r\n$`)
  38. )
  39.  
  40. type Bot struct {
  41.     *net.TCPConn
  42.     *bufio.Reader
  43.  
  44.     recharging   bool
  45.     posX, posY   int
  46.     prevX, prevY int
  47.     dirX, dirY   int
  48. }
  49.  
  50. func NewBot(conn *net.TCPConn) *Bot {
  51.     log.Println("NEW BOT :: ", conn.RemoteAddr())
  52.  
  53.     b := new(Bot)
  54.     b.TCPConn = conn
  55.     b.Reader = bufio.NewReader(conn)
  56.  
  57.     b.prevX, b.prevY = math.MaxInt64, math.MaxInt64
  58.  
  59.     return b
  60. }
  61.  
  62. func (b *Bot) Auth() {
  63.     b.SendMessage(SERVER_USER)
  64.     username := b.ReceiveMessage()
  65.  
  66.     b.SendMessage(SERVER_PASSWORD)
  67.     password := b.ReceiveMessage()
  68.     if !CLIENT_PASSWORD.MatchString(password) {
  69.         panic(SERVER_SYNTAX_ERROR)
  70.     }
  71.  
  72.     checkSum := 0
  73.     for _, v := range username[:len(username)-2] {
  74.         checkSum += int(v)
  75.     }
  76.  
  77.     pass, err := strconv.Atoi(password[:len(password)-2])
  78.     if err != nil {
  79.         panic(SERVER_SYNTAX_ERROR)
  80.     }
  81.  
  82.     if checkSum != pass {
  83.         panic(SERVER_LOGIN_FAILED)
  84.     }
  85. }
  86.  
  87. func (b *Bot) Navigate() {
  88.     b.SendMessage(SERVER_TURN_LEFT) // initial move to get bots position
  89.  
  90.     for {
  91.         msg := b.ReceiveMessage()
  92.  
  93.         if CLIENT_CONFIRM.MatchString(msg) {
  94.             b.CheckCoords(msg)
  95.         } else {
  96.             panic(SERVER_SYNTAX_ERROR)
  97.         }
  98.  
  99.         if b.posX == 0 && b.posY == 0 {
  100.             log.Println("Bot is on the [0:0] coords")
  101.             b.SendMessage(SERVER_PICK_UP)
  102.             msg := b.ReceiveMessage()
  103.             fmt.Print("Secret message: ", msg)
  104.             b.SendMessage(SERVER_OK)
  105.             return
  106.         } else {
  107.             if b.dirX == 0 && b.dirY == 0 {
  108.                 b.SendMessage(SERVER_MOVE) // initial move to get direction of bot
  109.             } else {
  110.                 if math.Abs(float64(b.posX+b.dirX)) < math.Abs(float64(b.posX)) { // if bot moves it moves to closer position
  111.                     b.SendMessage(SERVER_MOVE)
  112.                 } else if math.Abs(float64(b.posY+b.dirY)) < math.Abs(float64(b.posY)) { // if bot moves it moves to closer position
  113.                     b.SendMessage(SERVER_MOVE)
  114.                 } else if b.posX == 0 {
  115.                     if (b.posY > 0 && b.dirX == -1) || (b.posY < 0 && b.dirX == 1) { // bot in top-right or bottom-left quadrant
  116.                         b.SendMessage(SERVER_TURN_LEFT)
  117.                     } else if (b.posY > 0 && b.dirX == 1) || (b.posY < 0 && b.dirX == -1) { // bot in top-left or bottom-right quadrant
  118.                         b.SendMessage(SERVER_TURN_RIGHT)
  119.                     }
  120.                 } else {
  121.                     b.SendMessage(SERVER_TURN_LEFT) // bot in bad position. try turning left
  122.                 }
  123.             }
  124.         }
  125.     }
  126. }
  127.  
  128. func (b *Bot) CheckCoords(msg string) {
  129.     if b.prevX != math.MaxInt64 && b.prevY != math.MaxInt64 {
  130.         b.prevX, b.prevY = b.posX, b.posY
  131.     }
  132.  
  133.     _, err := fmt.Sscanf(msg, "OK %d %d\r\n", &b.posX, &b.posY)
  134.     if err != nil {
  135.         panic(SERVER_SYNTAX_ERROR)
  136.     }
  137.  
  138.     if b.prevX == math.MaxInt64 && b.prevY == math.MaxInt64 {
  139.         b.prevX, b.prevY = b.posX, b.posY
  140.     }
  141.  
  142.     b.dirX = b.posX - b.prevX
  143.     b.dirY = b.posY - b.prevY
  144. }
  145.  
  146. func (b *Bot) ReceiveMessage() string {
  147.     var buf bytes.Buffer
  148.  
  149.     isR := false
  150.     for {
  151.         data, err := b.ReadByte()
  152.         if err != nil {
  153.             panic(SERVER_SYNTAX_ERROR)
  154.         }
  155.  
  156.         b.TCPConn.SetDeadline(time.Now().Add(TIMEOUT * time.Second))
  157.  
  158.         buf.WriteByte(data)
  159.         if data == '\n' && isR {
  160.             break
  161.         }
  162.  
  163.         if buf.Len() == 100 {
  164.             panic(SERVER_SYNTAX_ERROR)
  165.         }
  166.  
  167.         // jesus man WTF :O
  168.         if len(buf.String()) > 2 && buf.String()[:2] == "OK" && isR && data == '\r' {
  169.             panic(SERVER_SYNTAX_ERROR)
  170.         }
  171.  
  172.         isR = data == '\r'
  173.     }
  174.  
  175.     msg := buf.String()
  176.     log.Printf("RECV :: %#v", msg)
  177.  
  178.     if CLIENT_RECHARGING.MatchString(msg) {
  179.         b.recharging = true
  180.         b.TCPConn.SetDeadline(time.Now().Add(TIMEOUT_RECHARGING * time.Second))
  181.  
  182.         str := b.ReceiveMessage()
  183.         if CLIENT_FULL_POWER.MatchString(str) {
  184.             if b.recharging == false {
  185.                 panic(SERVER_LOGIC_ERROR)
  186.             }
  187.         } else {
  188.             panic(SERVER_LOGIC_ERROR)
  189.         }
  190.  
  191.         msg = b.ReceiveMessage()
  192.     }
  193.  
  194.     return msg
  195. }
  196.  
  197. func (b *Bot) SendMessage(msg string) {
  198.     log.Printf("SEND :: %#v", msg)
  199.     fmt.Fprint(b, msg)
  200.     b.SetDeadline(time.Now().Add(TIMEOUT * time.Second))
  201. }
  202.  
  203. func (b *Bot) Run() {
  204.     b.Auth()
  205.     b.SendMessage(SERVER_OK)
  206.     b.Navigate()
  207. }
  208.  
  209. func main() {
  210.     address, _ := net.ResolveTCPAddr("tcp", ":3999")
  211.     listener, _ := net.ListenTCP("tcp", address)
  212.  
  213.     for {
  214.         conn, _ := listener.AcceptTCP()
  215.  
  216.         go func(c *net.TCPConn) {
  217.             log.Println("ACCEPT :: ", c.RemoteAddr())
  218.  
  219.             defer func() {
  220.                 err := recover()
  221.                 switch err.(type) {
  222.                 case string:
  223.                     log.Print("PANIC :: ", err.(string))
  224.                     fmt.Fprint(c, err.(string))
  225.                 case nil:
  226.                     log.Println("BOT SUCCESSFUL")
  227.                 }
  228.  
  229.                 log.Println("CLOSE :: ", c.RemoteAddr())
  230.                 c.Close()
  231.             }()
  232.  
  233.             b := NewBot(c)
  234.             b.Run()
  235.         }(conn)
  236.     }
  237. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement