Add window slot packet and item info

This commit is contained in:
Tanner Collin 2020-05-27 17:47:36 -06:00
parent 9ce9a47493
commit ebc9c5ef1a
6 changed files with 10173 additions and 77 deletions

View File

@ -41,7 +41,6 @@ AVOID = [
] ]
NON_SOLID = [ NON_SOLID = [
'minecraft:air', 'minecraft:air',
'minecraft:oak_sapling', 'minecraft:oak_sapling',
@ -183,7 +182,6 @@ NON_SOLID = [
] ]
SINGLE_SNOW = 3919 SINGLE_SNOW = 3919
LOGS = [ LOGS = [
'minecraft:oak_log', 'minecraft:oak_log',
'minecraft:spruce_log', 'minecraft:spruce_log',
@ -202,6 +200,7 @@ LEAVES = [
'minecraft:dark_oak_leaves', 'minecraft:dark_oak_leaves',
] ]
NON_SOLID_IDS = set([SINGLE_SNOW]) NON_SOLID_IDS = set([SINGLE_SNOW])
for block_name in NON_SOLID: for block_name in NON_SOLID:
for state in BLOCKS[block_name]['states']: for state in BLOCKS[block_name]['states']:

146
bot.py
View File

@ -6,6 +6,7 @@ from itertools import count
import blocks import blocks
import items
import custom_packets import custom_packets
from minecraft import authentication from minecraft import authentication
@ -379,6 +380,11 @@ def break_block(connection, coords, time):
s['break_time'] = time s['break_time'] = time
s['break_timeout'] = 0.25 s['break_timeout'] = 0.25
def say(connection, message):
packet = serverbound.play.ChatPacket()
packet.message = message
connection.write_packet(packet)
BLOCK_ABOVE = (0, +1, 0) BLOCK_ABOVE = (0, +1, 0)
BLOCK_BELOW = (0, -1, 0) BLOCK_BELOW = (0, -1, 0)
@ -491,6 +497,9 @@ class LumberjackStates:
def idle(self): def idle(self):
return None return None
def init(self):
self.state = self.find_new_tree
def find_new_tree(self): def find_new_tree(self):
print('Finding new tree...') print('Finding new tree...')
w = MCWorld(self.player_info.chunks) w = MCWorld(self.player_info.chunks)
@ -512,7 +521,7 @@ class LumberjackStates:
else: # for else: # for
print('Unable to get to tree', self.tree) print('Unable to get to tree', self.tree)
self.bad_trees.append(self.tree) self.bad_trees.append(self.tree)
self.state = self.finished self.state = self.done
return return
s['path'] = path s['path'] = path
@ -588,9 +597,9 @@ class LumberjackStates:
if self.wait_time > 0: if self.wait_time > 0:
self.wait_time -= TICK self.wait_time -= TICK
else: else:
self.state = self.finished self.state = self.done
def finished(self): def done(self):
return None return None
@ -617,17 +626,23 @@ class JobStates:
def lumberjack(self): def lumberjack(self):
l = self.lumberjack_states l = self.lumberjack_states
if l.state == l.idle: if l.state == l.idle:
l.state = l.find_new_tree l.state = l.init
elif l.state == l.finished: elif l.state == l.done:
# check time, etc # check time, etc
l.state = l.find_new_tree l.state = l.init
l.run() l.run()
def __init__(self, player_info): def stop(self):
self.lumberjack_states = LumberjackStates(self.player_info)
self.state = self.idle
def __init__(self, connection, player_info):
self.connection = connection
self.player_info = player_info self.player_info = player_info
self.state = self.idle self.state = self.idle
self.lumberjack_states = LumberjackStates(player_info) self.lumberjack_states = LumberjackStates(self.player_info)
self.survive = False
def run(self): def run(self):
self.state() self.state()
@ -785,7 +800,7 @@ def init(connection, player_info):
s['break_timeout'] = 0 s['break_timeout'] = 0
s['break_finished_packet'] = None s['break_finished_packet'] = None
s['jobstate'] = JobStates(player_info) s['jobstate'] = JobStates(connection, player_info)
s['jobstate'].run() s['jobstate'].run()
def main(connection, player_info): def main(connection, player_info):
@ -819,13 +834,12 @@ def main(connection, player_info):
if solution: if solution:
solution = list(solution) solution = list(solution)
s['path'] = solution s['path'] = solution
s['jobstate'].state = s['jobstate'].stop
print(len(solution)) print(len(solution))
print(solution) print(solution)
print(round(time.time() - start, 3), 'seconds') print(round(time.time() - start, 3), 'seconds')
else: else:
packet = serverbound.play.ChatPacket() say(connection, 'No path found')
packet.message = 'No path found'
connection.write_packet(packet)
#s['y_v'] = 10.0 #s['y_v'] = 10.0
#s['y_a'] = -36.0 #s['y_a'] = -36.0
@ -842,37 +856,37 @@ def main(connection, player_info):
#connection.register_packet_listener( #connection.register_packet_listener(
# y, AcknowledgePlayerDiggingPacket) # y, AcknowledgePlayerDiggingPacket)
def z(p): def handle_set_slot(p):
print(p) print(p)
if p.window_id == 0:
player_info.inv[p.slot] = p.slot_data
connection.register_packet_listener( connection.register_packet_listener(
z, custom_packets.BlockBreakAnimationPacket) handle_set_slot, custom_packets.SetSlotPacket)
def print_chat(chat_packet): def print_chat(chat_packet):
print("Message (%s): %s" % ( try:
chat_packet.field_string('position'), chat_packet.json_data)) print("Message (%s): %s" % (
chat_packet.field_string('position'), chat_packet.json_data))
if '!reload' in chat_packet.json_data: if '!reload' in chat_packet.json_data:
global running global running
running = False running = False
elif '!afk' in chat_packet.json_data: elif '!afk' in chat_packet.json_data:
packet = serverbound.play.ChatPacket() say(connection, '/afk')
packet.message = '/afk' elif '!respawn' in chat_packet.json_data:
connection.write_packet(packet) packet = serverbound.play.ClientStatusPacket()
elif '!respawn' in chat_packet.json_data: packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN
packet = serverbound.play.ClientStatusPacket() connection.write_packet(packet)
packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN elif '!chunk' in chat_packet.json_data:
connection.write_packet(packet) print(len(player_info.chunks.chunks.keys()))
elif '!chunk' in chat_packet.json_data: print(player_info.chunks.chunks[(38, 4, 33)].__dict__)
print(len(player_info.chunks.chunks.keys())) elif '!block' in chat_packet.json_data:
print(player_info.chunks.chunks[(38, 4, 33)].__dict__) block = player_info.chunks.get_block_at(616, 78, 496)
elif '!block' in chat_packet.json_data: packet = serverbound.play.ChatPacket()
block = player_info.chunks.get_block_at(616, 78, 496) packet.message = str(block)
packet = serverbound.play.ChatPacket() connection.write_packet(packet)
packet.message = str(block) elif '!path' in chat_packet.json_data:
connection.write_packet(packet)
elif '!path' in chat_packet.json_data:
try:
s['goal'] = LPoint3f(655, 86, 341) s['goal'] = LPoint3f(655, 86, 341)
print('new waypoint:', s['goal']) print('new waypoint:', s['goal'])
start = time.time() start = time.time()
@ -881,11 +895,7 @@ def main(connection, player_info):
s['path'] = solution s['path'] = solution
print(len(solution)) print(len(solution))
print(round(time.time() - start, 3), 'seconds') print(round(time.time() - start, 3), 'seconds')
except BaseException as e: elif '!tree' in chat_packet.json_data:
import traceback
print(traceback.format_exc())
elif '!tree' in chat_packet.json_data:
try:
mc_world = MCWorld(player_info.chunks) mc_world = MCWorld(player_info.chunks)
start = time.time() start = time.time()
coords = mc_world.find_tree(pint(player_info.pos), 100) coords = mc_world.find_tree(pint(player_info.pos), 100)
@ -895,40 +905,44 @@ def main(connection, player_info):
path = mc_world.navigate_to_opening(pint(player_info.pos), openings[0]) path = mc_world.navigate_to_opening(pint(player_info.pos), openings[0])
print(path) print(path)
print(round(time.time() - start, 3), 'seconds') print(round(time.time() - start, 3), 'seconds')
except BaseException as e: elif '!break' in chat_packet.json_data:
import traceback
print(traceback.format_exc())
elif '!break' in chat_packet.json_data:
try:
coords = pint(player_info.pos) coords = pint(player_info.pos)
coords = padd(coords, CHECK_NORTH) coords = padd(coords, CHECK_NORTH)
break_block(connection, coords, 2.5) break_block(connection, coords, 2.5)
#break_block(connection, coords, 0.35) #break_block(connection, coords, 0.35)
except BaseException as e: elif '!pick' in chat_packet.json_data:
import traceback
print(traceback.format_exc())
elif '!pick' in chat_packet.json_data:
try:
packet = custom_packets.PickItemPacket() packet = custom_packets.PickItemPacket()
packet.slot_to_use = 1 packet.slot_to_use = 1
connection.write_packet(packet) connection.write_packet(packet)
except BaseException as e: elif '!inv' in chat_packet.json_data:
import traceback for i in player_info.inv.values():
print(traceback.format_exc()) if i.present:
elif '!echo' in chat_packet.json_data: print(items.ITEM_NAMES[i.item_id], 'x', i.item_count)
try: elif '!echo' in chat_packet.json_data:
parts = chat_packet.json_data.split('\'') parts = chat_packet.json_data.split('\'')
packet = serverbound.play.ChatPacket() say(connection, parts[1])
packet.message = parts[1] elif 'get wood and survive' in chat_packet.json_data:
connection.write_packet(packet) for i in player_info.inv.values():
except BaseException as e: if i.item_id in items.BED_IDS:
import traceback break
print(traceback.format_exc()) else: # for
elif 'get wood' in chat_packet.json_data: say(connection, 'I need a bed')
print('setting job state to lumberjack') return
s['jobstate'].state = s['jobstate'].lumberjack
s['jobstate'].state = s['jobstate'].lumberjack
s['jobstate'].survive = True
elif 'get wood' in chat_packet.json_data:
s['jobstate'].state = s['jobstate'].lumberjack
elif 'stop job' in chat_packet.json_data:
say(connection, 'ok')
s['jobstate'].state = s['jobstate'].stop
elif 'where are you' in chat_packet.json_data:
say(connection, str(pint(player_info.pos))[1:-1])
except BaseException as e:
import traceback
print(traceback.format_exc())

View File

@ -1,7 +1,8 @@
import minecraft.networking.packets import minecraft.networking.packets
from minecraft.networking.packets import Packet from minecraft.networking.packets import Packet
from minecraft.networking.types import BlockFace, VarInt, Position, Boolean, Byte from minecraft.networking.types import BlockFace, VarInt, Position, Boolean, Byte, UnsignedByte, Short, TrailingByteArray
from minecraft.networking.types.basic import Type
#def qot(x): #def qot(x):
# print('qot.') # print('qot.')
@ -11,10 +12,7 @@ from minecraft.networking.types import BlockFace, VarInt, Position, Boolean, Byt
class AcknowledgePlayerDiggingPacket(Packet): class AcknowledgePlayerDiggingPacket(Packet):
@staticmethod id = 0x08
def get_id(context):
return 0x08
packet_name = 'acknowledge player digging' packet_name = 'acknowledge player digging'
definition = [ definition = [
{'status': VarInt}, {'status': VarInt},
@ -24,10 +22,7 @@ class AcknowledgePlayerDiggingPacket(Packet):
] ]
class BlockBreakAnimationPacket(Packet): class BlockBreakAnimationPacket(Packet):
@staticmethod id = 0x09
def get_id(context):
return 0x09
packet_name = 'block break animation' packet_name = 'block break animation'
definition = [ definition = [
{'entity_id': VarInt}, {'entity_id': VarInt},
@ -35,12 +30,69 @@ class BlockBreakAnimationPacket(Packet):
{'destroy_stage': Byte}, {'destroy_stage': Byte},
] ]
#class WindowItemsPacket(Packet):
# id = 0x15
# packet_name = 'window items'
# definition = [
# {'window_id': UnsignedByte},
# {'count': Short},
# {'destroy_stage': Byte},
# ]
class Slot(Type):
def __init__(self, present, item_id, item_count, nbt):
self.present = present
self.item_id = item_id
self.item_count = item_count
self.nbt = nbt
def __str__(self):
return str(self.__dict__)
def __repr__(self):
return 'Slot(present={}, item_id={}, item_count={}, nbt={}'.format(
self.present, self.item_id, self.item_count, self.nbt)
@staticmethod
def read(file_object):
present = Boolean.read(file_object)
item_id = VarInt.read(file_object) if present else None
item_count = Byte.read(file_object) if present else None
nbt = TrailingByteArray.read(file_object) if present else None
return Slot(present, item_id, item_count, nbt)
#a = {}
#a['present'] = Boolean.read(file_object)
#a['item_id'] = VarInt.read(file_object) if a['present'] else None
#a['item_count'] = Byte.read(file_object) if a['present'] else None
#a['nbt'] = TrailingByteArray.read(file_object) if a['present'] else None
#return a
@staticmethod
def send(value, socket):
# TODO
pass
class SetSlotPacket(Packet):
id = 0x17
packet_name = 'set slot'
definition = [
{'window_id': Byte},
{'slot': Short},
{'slot_data': Slot},
]
def get_packets(old_get_packets): def get_packets(old_get_packets):
def wrapper(func, context): def wrapper(func, context):
print('Monkey-patched.') print('Monkey-patched.')
packets = func(context) packets = func(context)
packets.add(AcknowledgePlayerDiggingPacket) packets.add(AcknowledgePlayerDiggingPacket)
packets.add(BlockBreakAnimationPacket) packets.add(BlockBreakAnimationPacket)
packets.add(SetSlotPacket)
return packets return packets
return lambda x: wrapper(old_get_packets, x) return lambda x: wrapper(old_get_packets, x)

31
items.py Normal file
View File

@ -0,0 +1,31 @@
import json
with open('registries.json') as f:
ITEMS = json.load(f)['minecraft:item']['entries']
BEDS = [
'minecraft:white_bed',
'minecraft:orange_bed',
'minecraft:magenta_bed',
'minecraft:light_blue_bed',
'minecraft:yellow_bed',
'minecraft:lime_bed',
'minecraft:pink_bed',
'minecraft:gray_bed',
'minecraft:light_gray_bed',
'minecraft:cyan_bed',
'minecraft:purple_bed',
'minecraft:blue_bed',
'minecraft:brown_bed',
'minecraft:green_bed',
'minecraft:red_bed',
'minecraft:black_bed',
]
BED_IDS = set()
for item_name in BEDS:
BED_IDS.add(ITEMS[item_name]['protocol_id'])
ITEM_NAMES = {}
for item_name, item in ITEMS.items():
ITEM_NAMES[ITEMS[item_name]['protocol_id']] = item_name

9999
registries.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,7 @@ get_mod_time = lambda: os.path.getmtime('bot.py')
class PlayerInfo: class PlayerInfo:
eid = None eid = None
pos = None pos = None
inv = {}
mcdata = None mcdata = None
chunks = None chunks = None