SHOW:
|
|
- or go back to the newest paste.
| 1 | - | pastebin/gist |
| 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 | ||
| 10 | proc tojson(inputs: PlayerInputs): JsonNode = | |
| 11 | ## Quick wrapper around the generic JObject constructor. | |
| 12 | result = %[("steer", %inputs.steer),
| |
| 13 | ("throttle", %inputs.throttle),
| |
| 14 | ("roll", %inputs.roll),
| |
| 15 | ("pitch", %inputs.pitch),
| |
| 16 | ("yaw", %inputs.yaw),
| |
| 17 | ("jump", %inputs.jump),
| |
| 18 | ("boost", %inputs.boost),
| |
| 19 | ("use_item", %inputs.use_item),
| |
| 20 | ("chat", %inputs.chat)]
| |
| 21 | ||
| 22 | ||
| 23 | proc unrollBytes(n : uint16) : string = | |
| 24 | let shifts : seq[uint16] = @[0'u16, 8'u16] | |
| 25 | # shift each byte right by a certain amount and mask off the least-significant byte | |
| 26 | map(shifts, shift => $char((n shr shift) and 0x000000ff)).join | |
| 27 | ||
| 28 | ||
| 29 | proc rollBytes(bs : string) : uint16 = | |
| 30 | let shifts : seq[uint16] = @[0'u16, 8'u16] | |
| 31 | var n : uint16 | |
| 32 | for pair in zip(shifts, bs): | |
| 33 | n = n or pair.b.uint16 shl pair.a | |
| 34 | return n | |
| 35 | ||
| 36 | proc try_connect(bot: Bot, add: string = "localhost", port: Port) = | |
| 37 | bot.rootsocket.connect(add, port) | |
| 38 | echo("Bot: ", bot.name, " connected to server on address: localhost, on port: ", port)
| |
| 39 | ||
| 40 | proc get_inputs(inputs: var PlayerInputs, game_info: JsonNode) = | |
| 41 | var | |
| 42 | steer: float = 0.0 | |
| 43 | throttle: float = 0.0 | |
| 44 | roll: float = 0.0 | |
| 45 | pitch: float = 0.0 | |
| 46 | yaw: float = 0.0 | |
| 47 | jump: bool = false | |
| 48 | boost: bool = false | |
| 49 | use_item: bool = false | |
| 50 | chat: int = 0 | |
| 51 | ||
| 52 | inputs = PlayerInputs(steer: steer, | |
| 53 | throttle: throttle, | |
| 54 | roll: roll, | |
| 55 | pitch: pitch, | |
| 56 | yaw: yaw, | |
| 57 | jump: jump, | |
| 58 | boost: boost, | |
| 59 | use_item: use_item, | |
| 60 | chat: chat) | |
| 61 | ||
| 62 | proc recievePacket(bot: Bot): JsonNode = | |
| 63 | var recieved: string = bot.rootsocket.recv(1024) | |
| 64 | #echo(recieved, " | ", recieved[2..^1], " | ", rollBytes(recieved[2..^2]), " | ", recieved.toHex()[2..3], recieved.toHex()[0..1]) | |
| 65 | #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}]""")
| |
| 66 | let header: uint16 = rollBytes(recieved[0..2]) | |
| 67 | recieved = recieved[2..^1] | |
| 68 | #echo(full_length, ", ", header, ", ", len(recieved).uint16) | |
| 69 | #echo("reciving data... data recived so far: ", len(recived), " data to recive: ", fromHex[int16](header), " collecting: ", fromHex[int16](header) - len(recived) - 4, " bytes")
| |
| 70 | recieved.add(bot.rootsocket.recv(header.int - len(recieved)))#((header2.parseHexInt() - len(recieved)) - 1)) | |
| 71 | ||
| 72 | let packet: JsonNode = json.parseJson("{\"Game\":" & recieved & "}")
| |
| 73 | echo("data recived: ")
| |
| 74 | echo(packet) | |
| 75 | return packet | |
| 76 | ||
| 77 | ||
| 78 | var Mybot: Bot = Bot(name: "Nimbot") | |
| 79 | var port: Port = Port(8085) | |
| 80 | Mybot.rootsocket = newSocket(AF_INET, SOCK_STREAM) | |
| 81 | MyBot.inputs = PlayerInputs(steer: 0.0, | |
| 82 | throttle: 0.0, | |
| 83 | roll: 0.0, | |
| 84 | pitch: 0.0, | |
| 85 | yaw: 0.0, | |
| 86 | jump: false, | |
| 87 | boost: false, | |
| 88 | use_item: false, | |
| 89 | chat: 0) | |
| 90 | ||
| 91 | ||
| 92 | proc send_inputs(bot: Bot, game_info: JsonNode) = | |
| 93 | var inputs = bot.inputs | |
| 94 | inputs.get_inputs(game_info) | |
| 95 | let strinputs: string = $tojson(inputs) | |
| 96 | let header: string = (strinputs.len + 2).uint16.unrollBytes | |
| 97 | let buffer: string = header & strinputs | |
| 98 | echo(buffer, " | ", len(strinputs), " | ", header, " | ") | |
| 99 | bot.rootsocket.send(buffer) | |
| 100 | ||
| 101 | proc recive_and_respond(bot: Bot) = | |
| 102 | let game_info: JsonNode = recievePacket(bot) | |
| 103 | echo(game_info) | |
| 104 | if game_info["Game"][0]["is_match_ended"].getBool() == true: | |
| 105 | raise newException(Exception, "Match Eneded") | |
| 106 | else: | |
| 107 | bot.send_inputs(game_info) | |
| 108 | ||
| 109 | ||
| 110 | Mybot.try_connect(port = port) | |
| 111 | var i: int = 0 | |
| 112 | while true: | |
| 113 | echo(i) | |
| 114 | Mybot.recive_and_respond() | |
| 115 | inc(i) |