From fa9d597483ad6329de3589980c4944ff17857144 Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Fri, 25 Sep 2020 15:51:36 -0600 Subject: [PATCH] Fix gapple bugs and unload far chunks --- bot.py | 11 ++++++----- game.py | 6 +++++- jobs.py | 32 ++++++++++++++++++++++++++------ protocol/managers.py | 24 +++++++++++++++++++++--- utils.py | 4 ++++ 5 files changed, 62 insertions(+), 15 deletions(-) diff --git a/bot.py b/bot.py index a92ec90..95cb976 100644 --- a/bot.py +++ b/bot.py @@ -51,12 +51,13 @@ def tick(global_state): target = None - try: - g.chunks.get_block_at(*utils.pint(p)) - except ChunkNotLoadedException: + # make sure current chunks are loaded for physics + if not g.chunks.check_loaded(p, 9): + packet = serverbound.play.PositionAndLookPacket(x=p.x, feet_y=p.y, z=p.z, pitch=0, yaw=0, on_ground=True) + g.connection.write_packet(packet, force=True) return - #g.jobstate.run() + g.chunks.unload_chunks(p) if g.path and len(g.path): target = LPoint3f(g.path[0]) @@ -194,7 +195,7 @@ def bot(global_state): time.sleep(utils.TICK) print('Player loaded.') - while not g.chunks.check_loaded(g.pos): + while not g.chunks.check_loaded(g.pos, 529): time.sleep(utils.TICK) print('Chunks loaded.') diff --git a/game.py b/game.py index d8c35ba..7e2e2fc 100644 --- a/game.py +++ b/game.py @@ -240,11 +240,15 @@ class Game: 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 + confirm_packet = serverbound.play.TeleportConfirmPacket() + confirm_packet.teleport_id = packet.teleport_id + self.g.connection.write_packet(confirm_packet) + + def handle_chat(self, message): source, text = message reply = None diff --git a/jobs.py b/jobs.py index dff40d3..8696475 100644 --- a/jobs.py +++ b/jobs.py @@ -38,15 +38,19 @@ class FindGappleStates: step = utils.spiral(self.count) step_scaled = utils.pmul(step, 192) self.coord = utils.padd(self.origin, step_scaled) - self.coord = utils.padd(self.coord, (0, 50, 0)) + self.coord = (self.coord[0], 50, self.coord[2]) print('count:', self.count, 'teleporting to:', self.coord) self.g.chat.send('/tp {} {} {}'.format(*self.coord)) + self.g.command_lock = True self.state = self.wait_for_load def wait_for_load(self): - if self.g.chunks.check_loaded(self.g.pos): + if self.g.command_lock: + return + + if self.g.chunks.check_loaded(self.g.pos, 169): print('chunks have been loaded') self.state = self.pick_chest @@ -56,9 +60,16 @@ class FindGappleStates: chest_list.extend(self.g.chunks.index.get(chest_id, [])) for chest in chest_list: - if chest in self.checked_chests: continue + if chest in self.checked_chests: + # slow but simple + continue + + if utils.phyp_king(self.coord, chest) > 96: + # skip because we can't detect item drops + continue self.current_chest = chest + self.checked_chests.append(self.current_chest) self.state = self.break_chest break else: # for @@ -68,13 +79,21 @@ class FindGappleStates: def break_chest(self): print('Breaking chest', self.current_chest) self.g.command_lock = True + self.g.item_lock = True self.g.chat.send('/setblock {} {} {} air destroy'.format(*self.current_chest)) - self.checked_chests.append(self.current_chest) + self.wait_time = 0.5 self.state = self.wait_for_items def wait_for_items(self): - if not self.g.command_lock: + # wait for command to execute + if self.g.command_lock: + return + + # wait for items to drop + if self.wait_time > 0: + self.wait_time -= utils.TICK + else: print('done waiting for items') self.state = self.pick_chest @@ -95,6 +114,7 @@ class FindGappleStates: self.coord = None self.current_chest = None self.checked_chests = [] + self.wait_time = 0 def run(self): self.state() @@ -602,7 +622,7 @@ class JobStates: if s1.state == s1.idle: s1.state = s1.init elif s1.state == s1.done: - s1.state = s1.init + s1.state = s1.tp_to_coord s1.run() diff --git a/protocol/managers.py b/protocol/managers.py index 4cc4d1e..6c3282f 100644 --- a/protocol/managers.py +++ b/protocol/managers.py @@ -1,6 +1,7 @@ import os from math import floor import json +import time from minecraft.networking.packets import clientbound, serverbound from protocol import packets @@ -112,11 +113,10 @@ class ChunksManager: if not c: return None c.set_block_at(x%16, y%16, z%16, block) - def check_loaded(self, position): - #for i in range(441): # TODO: base off render_distance? + def check_loaded(self, position, steps): x, y, z = utils.pint(position) player_chunk = (x//16, 1, z//16) - for i in range(121): # TODO: base off render_distance? + for i in range(steps): # TODO: base off render_distance? offset = utils.spiral(i) check = utils.padd(player_chunk, offset) @@ -125,6 +125,24 @@ class ChunksManager: return True + def unload_chunks(self, position): + start = time.time() + x, y, z = utils.pint(position) + player_chunk = (x//16, 0, z//16) + + loaded_chunks = list(self.chunks.keys()) + count = 0 + + for chunk in loaded_chunks: + check = (chunk[0], 0, chunk[2]) + if utils.phyp_king(player_chunk, check) > 16: + del self.chunks[chunk] + count += 1 + + if count: + print('unloaded', count, 'chunks in', time.time()-start, 's') + + class ChunkNotLoadedException(Exception): def __str__(self): diff --git a/utils.py b/utils.py index a5fec16..b68343d 100644 --- a/utils.py +++ b/utils.py @@ -25,6 +25,10 @@ def phyp_bias(p1, p2, origin): height_diff = height_diff*8 if height_diff < 0 else height_diff*0.5 return hypot(p1[0] - p2[0], height_diff, p1[2] - p2[2]) + origin_distance*0.5 +def phyp_king(p1, p2): + # calculates the Chebyshev distance + return max(abs(p1[0] - p2[0]), abs(p1[1] - p2[1]), abs(p1[2] - p2[2])) + def pint(p): return (floor(p[0]), floor(p[1]), floor(p[2]))