diff --git a/README.md b/README.md index ce3b94f..db9043b 100644 --- a/README.md +++ b/README.md @@ -33,78 +33,108 @@ Talking to bot (All commands can be found in "game.py" under "public commands", Use prefix (in this case, "1") to call to attention before giving command. (EX. 1ping, 1here, etc.) -# ping -Will respond "pong" if active and listening -# pos -Will respond with current position +### Public Commands -# afk -Will afk (if not already) +These can be ran by anyone, all bots will reply -# unafk -Will unafk (if afk) +!ping - replies with "pong" -# error ---- +!echo [data] - replies with "data" -# inv -Will list inventory (in terminal) +!pos - replies with position and dimension +!afk - goes AFK with /afk -# time ---- +!unafk - goes not AFK with /afk -# count ---- +!error - raises an error -# loaded ---- +!inv - prints current inventory -# players ---- +!time - replies with Minecraft world time -# objects ---- +!count [id] - counts the number of items with that id -# mobs ---- +!loaded - replies with the current loaded area -# monsters ---- +!players - prints the current players -# villagers ---- +!players clear - clears the current player list -# threats ---- +!objects - prints the current items on ground -# spiral ---- +!objects clear - clears the current object list -# sand slice ---- +!mobs - prints the current mobs -# zzz -Will afk if in overworld, and if not already afk +!mobs clear - clears the current mob list -# tree ---- +!monsters - prints the current monsters -# block ---- +!villagers - prints the current villagers -# +!threats - prints the dangerous monsters within 20 blocks +!threats [num] - prints the dangerous monsters within num blocks +"zzz" or !zzz - bot does /afk to let others sleep +!tree - replies with the closest tree +!block x y z - replies what block is at (x, y, z) +### Bot-specific Commands -## temporary workarounds +These will only run for the bot they are addressed to -# Add "?" to line 457, which is "match1 = re.match(r'<(\w+)> (.*)', text)" -It should now look like this "match1 = re.match(r' (.*)', text)" -This allows the bot to react to commands made by someone else than the creator of code (Tanner6) +1respawn - respawns the bot if it's dead +1gather wood - gathers wood from the world + +1gather sand - gathers sand from the world + +1farm wood - farms wood from a certain area + +1farm sand - farms sand from a certain area + +1farm wart - farms netherwart from a certain area + +1farm crop - farms mature crops from a certain area + +1loiter - stands still but eats, sleeps, and flees + +1trade - sells items to villagers to get emeralds + +1stop - stops the current job and resets bot + +1drop - drops the current stack its holding + +1select [id] - moves item with id into main hand + +1dump [id] - drops all items matching id + +1drain - drops all items in inventory + +1fill [x] [y] [z] [x] [y] [z] - fills the cuboid with the block at the first coordinate + +1here - bot comes to your location + +1goto [x] [y] [z] - sends the bot to coordinate (x, y, z) + +1close - closes the current Minecraft window + +1click [slot] [button] [mode] - clicks the current window + +1use - use the item it's currently holding + +1interact [entity id] - interacts with that entity + +### Authorized Commands + +These dangerous commands can only be ran by the bot owner + +1print [expression] - replies with Python eval(expression) + +1exit - exits the program diff --git a/game.py b/game.py index cda3081..ebe2520 100644 --- a/game.py +++ b/game.py @@ -491,29 +491,37 @@ class Game: try: - ################# Public commands ######################## + ## ### Public Commands + ## These can be ran by anyone, all bots will reply + ## !ping - replies with "pong" if command == 'ping': reply = 'pong' + ## !echo [data] - replies with "data" if command == 'echo' and data: reply = data + ## !pos - replies with position and dimension if command == 'pos': reply = str(utils.pint(self.g.pos))[1:-1] + ', ' + self.g.dimension + ## !afk - goes AFK with /afk if command == 'afk': if not self.g.afk: reply = '/afk' + ## !unafk - goes not AFK with /afk if command == 'unafk': if self.g.afk: reply = '/afk' + ## !error - raises an error if command == 'error': reply = 'ok' raise + ## !inv - prints current inventory if command == 'inv': inv_list = [] for i in self.g.inv.values(): @@ -523,16 +531,21 @@ class Game: result = '\n'.join(inv_list) print(result or 'Empty') + ## !time - replies with Minecraft world time if command == 'time': reply = str(self.g.time) + ## !count [id] - counts the number of items with that id if command == 'count' and data: item = int(data) reply = str(self.count_items([item])) + ## !loaded - replies with the current loaded area if command == 'loaded': reply = str(self.g.chunks.get_loaded_area()) + ## !players - prints the current players + ## !players clear - clears the current player list if command == 'players': if data == 'clear': self.g.players = {} @@ -541,6 +554,8 @@ class Game: for k, v in self.g.players.items(): print(str(k) + ':', v, self.g.player_names[v.player_uuid]) + ## !objects - prints the current items on ground + ## !objects clear - clears the current object list if command == 'objects': if data == 'clear': self.g.objects = {} @@ -550,6 +565,8 @@ class Game: if data and v.item_id != int(data): continue print(str(k) + ':', v, items.ITEM_NAMES[v.item_id]) + ## !mobs - prints the current mobs + ## !mobs clear - clears the current mob list if command == 'mobs': if data == 'clear': self.g.mobs = {} @@ -561,6 +578,7 @@ class Game: print(str(k) + ':', v, mobs.MOB_NAMES[v.type]) reply = str(len(all_mobs)) + ' mobs' + ## !monsters - prints the current monsters if command == 'monsters': monsters = sorted(list(self.g.mobs.items()), key=lambda x: x[1].type) count = 0 @@ -571,6 +589,7 @@ class Game: print(str(k) + ':', v, mobs.MOB_NAMES[v.type]) reply = str(count) + ' monsters' + ## !villagers - prints the current villagers if command == 'villagers': all_mobs = sorted(list(self.g.mobs.items()), key=lambda x: x[1].type) count = 0 @@ -581,6 +600,8 @@ class Game: print(str(k) + ':', v, type_name) reply = str(count) + ' villagers' + ## !threats - prints the dangerous monsters within 20 blocks + ## !threats [num] - prints the dangerous monsters within num blocks if command == 'threats': distance = int(data) if data else 20 p = utils.pint(self.g.pos) @@ -598,16 +619,19 @@ class Game: result = self.g.world.find_sand_slice(utils.pint(self.g.pos), 50) reply = str(result) + ## "zzz" or !zzz - bot does /afk to let others sleep if command == 'zzz': if not self.g.afk and self.g.dimension == 'overworld': reply = '/afk' self.g.afk_timeout = 5.0 + ## !tree - replies with the closest tree if command == 'tree': pos = utils.pint(self.g.pos) tree = next(self.g.world.find_trees(pos, 50)) reply = str(tree)[1:-1] + ## !block x y z - replies what block is at (x, y, z) if command == 'block': try: data = data.replace('(', ' ').replace(')', ' ').replace(',', ' ') @@ -627,15 +651,22 @@ class Game: ################# Specific commands ########################## + + ## ### Bot-specific Commands + ## These will only run for the bot they are addressed to + if for_me: pass + ## 1respawn - respawns the bot if it's dead if command == 'respawn': packet = serverbound.play.ClientStatusPacket() packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN self.g.connection.write_packet(packet) reply = 'ok' + ## 1gather wood - gathers wood from the world + ## 1gather sand - gathers sand from the world if command == 'gather' and data: if data == 'wood': self.g.job.state = self.g.job.gather_wood @@ -652,6 +683,10 @@ class Game: else: reply += ', I need a bed' + ## 1farm wood - farms wood from a certain area + ## 1farm sand - farms sand from a certain area + ## 1farm wart - farms netherwart from a certain area + ## 1farm crop - farms mature crops from a certain area if command == 'farm' and data: if data == 'wood': self.g.job.state = self.g.job.farm_wood @@ -673,22 +708,27 @@ class Game: else: reply += ', I need a bed' + ## 1loiter - stands still but eats, sleeps, and flees if command == 'loiter': self.g.job.state = self.g.job.loiter reply = 'ok' + ## 1trade - sells items to villagers to get emeralds if command == 'trade': self.g.job.state = self.g.job.trade reply = 'ok' + ## 1stop - stops the current job and resets bot if command == 'stop': self.close_window() bot.init(self.g) reply = 'ok' + ## 1drop - drops the current stack its holding if command == 'drop': self.drop_stack() + ## 1select [id] - moves item with id into main hand if command == 'select' and data: item = int(data) if self.select_item([item]): @@ -696,6 +736,7 @@ class Game: else: reply = 'not found' + ## 1dump [id] - drops all items matching id if command == 'dump' and data: item = int(data) if self.count_items([item]): @@ -704,6 +745,7 @@ class Game: else: reply = 'not found' + ## 1drain - drops all items in inventory if command == 'drain': self.g.draining = True reply = 'ok' @@ -720,6 +762,8 @@ class Game: self.g.job.cache_items_states.silent = True reply = 'ok' + + ## 1fill [x] [y] [z] [x] [y] [z] - fills the cuboid with the block at the first coordinate if command == 'fill': try: data = data.replace('(', ' ').replace(')', ' ').replace(',', ' ') @@ -746,6 +790,7 @@ class Game: self.g.job.state = self.g.job.fill_blocks reply = 'filling ' + str(utils.pvolume(coord1, coord2)) + ' with ' + blocks.BLOCKS[block] + ## 1here - bot comes to your location if command == 'here': try: sender_uuid = self.g.player_names[sender] @@ -780,6 +825,7 @@ class Game: else: reply = 'no path' + ## 1goto [x] [y] [z] - sends the bot to coordinate (x, y, z) if command == 'goto': try: data = data.replace('(', ' ').replace(')', ' ').replace(',', ' ') @@ -814,6 +860,7 @@ class Game: if command == 'open': self.open_container(blocks.TEST_BLOCK) + ## 1close - closes the current Minecraft window if command == 'close': if self.g.window: self.close_window() @@ -821,6 +868,7 @@ class Game: else: reply = 'nothing open' + ## 1click [slot] [button] [mode] - clicks the current window if command == 'click' and data: if self.g.window: slot, button, mode = [int(x) for x in data.split(' ')] @@ -833,9 +881,11 @@ class Game: else: reply = 'nothing open' + ## 1use - use the item it's currently holding if command == 'use': self.use_item(0) + ## 1interact [entity id] - interacts with that entity if command == 'interact' and data: self.interact(int(data)) @@ -845,12 +895,18 @@ class Game: print(r) ################# Authorized commands ########################## + + ## ### Authorized Commands + ## These dangerous commands can only be ran by the bot owner + if authed: + ## 1print [expression] - replies with Python eval(expression) if command == 'print': data = data.replace('`', '.') reply = str(eval(data)) + ## 1exit - exits the program if command == 'exit': import os os._exit(0) diff --git a/print_help.py b/print_help.py new file mode 100644 index 0000000..79bb22d --- /dev/null +++ b/print_help.py @@ -0,0 +1,13 @@ + +HELP_LINES = [] + +with open('game.py', 'r') as f: + for line in f.readlines(): + if line.strip().startswith('## '): + HELP_LINES.append(line.strip()[3:]) + + +for line in HELP_LINES: + print(line) + print() +