diff --git a/bot.py b/bot.py index 2302369..8e9d8f5 100644 --- a/bot.py +++ b/bot.py @@ -20,13 +20,12 @@ from minecraft.networking.connection import Connection from minecraft.networking.packets import Packet, clientbound, serverbound from protocol.managers import DataManager, ChunksManager, ChatManager, ChunkNotLoadedException -from protocol.packets import TimeUpdatePacket, SetSlotPacket from bunch import Bunch from panda3d.core import LPoint3f, LVector3f -import packet_handlers -importlib.reload(packet_handlers) +import game +importlib.reload(game) import blocks importlib.reload(blocks) import utils @@ -135,6 +134,8 @@ def tick(global_state): packet = serverbound.play.PositionAndLookPacket(x=p.x, feet_y=p.y, z=p.z, pitch=l.pitch, yaw=l.yaw, on_ground=(not in_air)) g.connection.write_packet(packet, force=True) + g.game.tick() + def init(global_state): g = global_state @@ -149,10 +150,7 @@ def init(global_state): l.yaw = 360 l.pitch = 0 - #l.break = None - #l.break_time = 0 - #l.break_timeout = 0 - #l.break_finished_packet = None + l.breaking = None #l.jobstate = JobStates(connection, player_info) #l.jobstate.run() @@ -178,34 +176,11 @@ def bot(global_state): g.connection.connect() - def packet_wrapper(handler): - def wrapper(packet): - handler(packet, g) - return wrapper - g.chunks.register(g.connection) - def x(p): - print(p) - - h = packet_wrapper(packet_handlers.handle_block_change) - g.connection.register_packet_listener(h, clientbound.play.BlockChangePacket) - - h = packet_wrapper(packet_handlers.handle_join_game) - g.connection.register_packet_listener(h, clientbound.play.JoinGamePacket) - - h = packet_wrapper(packet_handlers.handle_position_and_look) - g.connection.register_packet_listener(h, clientbound.play.PlayerPositionAndLookPacket) - g.chat = ChatManager(g) - h = packet_wrapper(packet_handlers.handle_chat) - g.chat.set_handler(h) - h = packet_wrapper(packet_handlers.handle_time_update) - g.connection.register_packet_listener(h, TimeUpdatePacket) - - h = packet_wrapper(packet_handlers.handle_set_slot) - g.connection.register_packet_listener(h, SetSlotPacket) + g.game = game.Game(g) try: while not g.pos: diff --git a/game.py b/game.py new file mode 100644 index 0000000..bf34796 --- /dev/null +++ b/game.py @@ -0,0 +1,164 @@ +import re +import time +import importlib + +from panda3d.core import LPoint3f + +from minecraft.networking.packets import Packet, clientbound, serverbound + +from protocol.packets import TimeUpdatePacket, SetSlotPacket, PlayerDiggingPacket, BlockBreakAnimationPacket, AcknowledgePlayerDiggingPacket + +import utils +importlib.reload(utils) +import path +importlib.reload(path) + +class Game: + def __init__(self, global_state): + self.g = global_state + self.l = self.g.local_state + + register = self.g.connection.register_packet_listener + register(self.handle_block_change, clientbound.play.BlockChangePacket) + register(self.handle_join_game, clientbound.play.JoinGamePacket) + register(self.handle_position_and_look, clientbound.play.PlayerPositionAndLookPacket) + register(self.handle_time_update, TimeUpdatePacket) + register(self.handle_set_slot, SetSlotPacket) + register(self.handle_break_animation, BlockBreakAnimationPacket) + register(self.handle_break_ack, AcknowledgePlayerDiggingPacket) + + self.g.chat.set_handler(self.handle_chat) + + def handle_join_game(self, packet): + print('Connected.') + print(packet) + self.g.info = packet + self.g.eid = packet.entity_id + + def handle_block_change(self, packet): + l = self.g.local_state + + if packet.block_state_id == 3887: + try: + l.goal = LPoint3f(x=packet.location[0], y=packet.location[1], z=packet.location[2]) + print('new waypoint:', l.goal) + + start = time.time() + solution = path.Pathfinder(self.g.chunks).astar(utils.pint(self.g.pos), utils.pint(l.goal)) + if solution: + solution = list(solution) + l.path = solution + #l.jobstate.state = l.jobstate.stop + print(len(solution)) + print(solution) + print(round(time.time() - start, 3), 'seconds') + else: + print('No path found') + #say(connection, 'No path found') + + #l.y_v = 10.0 + #l.y_a = -36.0 + except BaseException as e: + import traceback + print(traceback.format_exc()) + + def handle_position_and_look(self, packet): + print('pos and look:') + print(packet) + p = LPoint3f(x=packet.x, y=packet.y, z=packet.z) + self.g.pos = p + + def handle_chat(self, message): + source, text = message + reply = None + + match = re.match(r'<(\w+)> (.*)', text) + if match: + sender, text = match.groups() + else: + return + + if text.startswith('! '): + text = text[2:] + elif text.startswith('!'): + text = text[1:] + else: + return + + if ' ' in text: + command = text.split(' ', 1)[0] + data = text.split(' ', 1)[1] + else: + command = text + + if command == 'ping': + reply = 'pong' + + if command == 'echo' and data: + reply = data + + if command == 'respawn': + packet = serverbound.play.ClientStatusPacket() + packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN + self.g.connection.write_packet(packet) + reply = 'ok' + + if command == 'pos': + reply = str(utils.pint(self.g.pos))[1:-1] + + if command == 'afk': + reply = '/afk' + + if command == 'error': + reply = 'ok' + raise + + if command == 'break': + self.break_block((616, 78, 496)) + reply = 'ok' + + if reply: + print(reply) + self.g.chat.send(reply) + + def handle_time_update(self, packet): + l = self.g.local_state + l.time = packet.time_of_day % 24000 + + def handle_set_slot(self, packet): + print(packet) + if packet.window_id == 0: + self.g.inv[packet.slot] = packet.slot_data + + def handle_break_animation(self, packet): + print(packet) + if self.l.breaking and packet.entity_id == self.g.eid: + if packet.destroy_stage >= 10: + packet = PlayerDiggingPacket() + packet.status = 2 + packet.location = self.l.breaking + packet.face = 1 + self.g.connection.write_packet(packet) + self.l.breaking = None + + def handle_break_ack(self, packet): + print(packet) + + def break_block(self, location): + if self.g.chunks.get_block_at(*location) != 0: + packet = PlayerDiggingPacket() + packet.status = 0 + packet.location = location + packet.face = 1 + self.g.connection.write_packet(packet) + + self.l.breaking = location + + def animate(self): + packet = serverbound.play.AnimationPacket() + packet.hand = packet.HAND_MAIN + self.g.connection.write_packet(packet) + + def tick(self): + if self.l.breaking: + self.animate() diff --git a/packet_handlers.py b/packet_handlers.py deleted file mode 100644 index 844ef2f..0000000 --- a/packet_handlers.py +++ /dev/null @@ -1,113 +0,0 @@ -import re -import time -import importlib - -from panda3d.core import LPoint3f - -from minecraft.networking.packets import Packet, clientbound, serverbound - -import utils -importlib.reload(utils) -import path -importlib.reload(path) -import blocks -importlib.reload(blocks) - -def handle_join_game(packet, g): - print('Connected.') - print(packet) - g.info = packet - -def handle_block_change(packet, g): - l = g.local_state - - if packet.block_state_id == blocks.SOUL_TORCH: - try: - l.goal = LPoint3f(x=packet.location[0], y=packet.location[1], z=packet.location[2]) - print('new waypoint:', l.goal) - - start = time.time() - solution = path.Pathfinder(g.chunks).astar(utils.pint(g.pos), utils.pint(l.goal)) - if solution: - solution = list(solution) - l.path = solution - #l.jobstate.state = l.jobstate.stop - print(len(solution)) - print(solution) - print(round(time.time() - start, 3), 'seconds') - else: - print('No path found') - #say(connection, 'No path found') - - #l.y_v = 10.0 - #l.y_a = -36.0 - except BaseException as e: - import traceback - print(traceback.format_exc()) - -def handle_position_and_look(packet, g): - print('pos and look:') - print(packet) - p = LPoint3f(x=packet.x, y=packet.y, z=packet.z) - g.pos = p - -def handle_chat(message, g): - source, text = message - reply = None - - match = re.match(r'<(\w+)> (.*)', text) - if match: - sender, text = match.groups() - else: - return - - if text.startswith('! '): - text = text[2:] - elif text.startswith('!'): - text = text[1:] - else: - return - - if ' ' in text: - command = text.split(' ', 1)[0] - data = text.split(' ', 1)[1] - else: - command = text - - if command == 'ping': - reply = 'pong' - - if command == 'echo' and data: - reply = data - - if command == 'respawn': - packet = serverbound.play.ClientStatusPacket() - packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN - g.connection.write_packet(packet) - reply = 'ok' - - if command == 'pos': - reply = str(utils.pint(g.pos))[1:-1] - - if command == 'afk': - reply = '/afk' - - if command == 'error': - reply = 'ok' - raise - - if reply: - print(reply) - g.chat.send(reply) - -def handle_time_update(packet, g): - l = g.local_state - l.time = packet.time_of_day % 24000 - -def handle_set_slot(packet, g): - print(packet) - if packet.window_id == 0: - g.inv[packet.slot] = packet.slot_data - - -