|
|
|
@ -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) |
|
|
|
|