View difference between Paste ID: u13H9MYe and nqkTWRt4
SHOW: | | - or go back to the newest paste.
1
import net, json, strutils, sequtils, sugar, PlayerInput
2
3
4
type Bot* = object
5
    name*: string
6
    rootsocket*: Socket
7
    inputs*: PlayerInputs
8
9
type PlayerInputs* = object
10
    steer*: float
11
    throttle*: float
12-
    result = %[("steer", %inputs.steer), 
12+
    roll*: float
13
    pitch*: float
14
    yaw*: float
15
    jump*: bool
16
    boost*: bool
17
    use_item*: bool
18
    chat*: int
19
20-
    ("chat", %inputs.chat)]
20+
21
proc tojson(inputs: PlayerInputs): JsonNode =
22
    ## Quick wrapper around the generic JObject constructor.
23
    result = %[
24
    ("steer", %inputs.steer), 
25
    ("throttle", %inputs.throttle), 
26
    ("roll", %inputs.roll), 
27
    ("pitch", %inputs.pitch), 
28
    ("yaw", %inputs.yaw), 
29
    ("jump", %inputs.jump), 
30
    ("boost", %inputs.boost), 
31
    ("use_item", %inputs.use_item), 
32
    ("chat", %inputs.chat)
33
    ]
34
    return result
35
36
37
proc unrollBytes(n : uint16) : string =
38
    let shifts : seq[uint16] = @[0'u16, 8'u16]
39
    # shift each byte right by a certain amount and mask off the least-significant byte
40
    map(shifts, shift => $char((n shr shift) and 0x000000ff)).join
41
    
42
    
43
proc rollBytes(bs : string) : uint16 =
44
    let shifts : seq[uint16] = @[0'u16, 8'u16]
45
    var n : uint16
46
    for pair in zip(shifts, bs):
47
        n = n or pair.b.uint16 shl pair.a
48
    return n
49
50
proc try_connect(bot: Bot, add: string = "localhost", port: Port) =
51
    bot.rootsocket.connect(add, port)
52
    echo("Bot: ", bot.name, " connected to server on address: localhost, on port: ", port)
53
54
proc get_inputs(inputs: var PlayerInputs, game_info: JsonNode) =
55
    var 
56
        steer: float = 0.0
57
        throttle: float = 0.0
58
        roll: float = 0.0
59
        pitch: float = 0.0
60
        yaw: float = 0.0
61
        jump: bool = false
62
        boost: bool = false
63
        use_item: bool = false
64-
    #echo(recieved, "     |     ", recieved[2..^1], "     |     ", rollBytes(recieved[2..^2]), "     |     ", recieved.toHex()[2..3], recieved.toHex()[0..1])
64+
65
66
    inputs = PlayerInputs(steer: steer, 
67
                    throttle: throttle, 
68-
    #echo(full_length, ", ", header, ", ", len(recieved).uint16)
68+
69-
    #echo("reciving data...  data recived so far: ", len(recived), "  data to recive: ", fromHex[int16](header), " collecting: ", fromHex[int16](header) - len(recived) - 4, " bytes")
69+
70
                    yaw: yaw, 
71
                    jump: jump, 
72
                    boost: boost, 
73-
    echo("data recived: ")
73+
74-
    echo(packet)
74+
75
76
proc recievePacket(bot: Bot): JsonNode =
77
    var recieved: string = bot.rootsocket.recv(1024)
78
    echo(recieved)#, "     |     ", recieved[2..^1], "     |     ", rollBytes(recieved[2..^2]), "     |     ", recieved.toHex()[2..3], recieved.toHex()[0..1])
79
    #var full_length: int = len("""[{"type":"Game","frame":0,"score":[0,0],"ball":{"position":[0.0,0.0,0.0],"velocity":[0.0,0.0,0.0],"euler_angles":[0.0,0.0,0.0],"angular_velocity":[0.0,0.0,0.0],"damage":0.0,"shape":0,"radius":-1.0,"height":-1.0},"cars":[{"position":[0.0,0.0,0.0],"velocity":[0.0,0.0,0.0],"euler_angles":[0.0,0.0,0.0],"angular_velocity":[0.0,0.0,0.0],"boost":0.0,"on_ground":true,"jumped":false,"double_jumped":false,"demolished":false,"is_bot":true,"team":-1,"name":"","body_type":0,"hitbox_offset":[0.0,0.0,0.0],"hitbox_dimensions":[0.0,0.0,0.0]},{"position":[0.0,0.0,0.0],"velocity":[0.0,0.0,0.0],"euler_angles":[0.0,0.0,0.0],"angular_velocity":[0.0,0.0,0.0],"boost":0.0,"on_ground":true,"jumped":false,"double_jumped":false,"demolished":false,"is_bot":true,"team":-1,"name":"","body_type":0,"hitbox_offset":[0.0,0.0,0.0],"hitbox_dimensions":[0.0,0.0,0.0]}],"goals":[],"pads":[],"time_left":0.0,"time_elapsed":0.0,"is_overtime":true,"is_round_active":true,"is_kickoff_paused":false,"is_match_ended":false,"is_unlimited_time":false,"gravity":0.0,"map":0,"mode":0}]""")
80
    let header: uint16 = rollBytes(recieved[0..2])
81
    recieved = recieved[2..^1]
82
    #echo(header, ", ", len(recieved).uint16)
83
    #echo("reciving data...  data recieved so far: ", len(recieved), "  data to recieve: ", header, " collecting: ", header.int - len(recieved) - 4, " bytes")
84
    recieved.add(bot.rootsocket.recv(header.int - len(recieved)))#((header2.parseHexInt() - len(recieved)) - 1))
85
86
    let packet: JsonNode = json.parseJson("{\"Game\":" & recieved & "}")
87
    #echo("data recieved: ")
88
    #echo(packet)
89
    return packet
90
91
92
var Mybot: Bot = Bot(name: "Nimbot")
93
var port: Port = Port(8085)
94
Mybot.rootsocket = newSocket(AF_INET, SOCK_STREAM)
95
MyBot.inputs = PlayerInputs(steer: 0.0, 
96
                            throttle: 0.0, 
97
                            roll: 0.0, 
98
                            pitch: 0.0, 
99
                            yaw: 0.0, 
100
                            jump: false, 
101-
proc recive_and_respond(bot: Bot) =
101+
102
                            use_item: false, 
103-
    echo(game_info)
103+
104
105
106
proc send_inputs(bot: Bot, game_info: JsonNode) =
107
    var inputs = bot.inputs
108
    inputs.get_inputs(game_info)
109
    let strinputs: string = $tojson(inputs)
110
    let header: string = (strinputs.len + 2).uint16.unrollBytes
111
    let buffer: string = header & strinputs
112
    echo(buffer, "    |    ", len(strinputs), "    |    ", header, "    |    ")
113
    bot.rootsocket.send(buffer)
114-
    Mybot.recive_and_respond()
114+
115
proc recieve_and_respond(bot: Bot) =
116
    let game_info: JsonNode = recievePacket(bot)
117
    #echo(game_info)
118
    if game_info["Game"][0]["is_match_ended"].getBool() == true:
119
        raise newException(Exception, "Match Eneded")
120
    else:
121
        bot.send_inputs(game_info)
122
123
124
Mybot.try_connect(port = port)
125
var i: int = 0
126
while true:
127
    echo(i)
128
    Mybot.recieve_and_respond()
129
    inc(i)