Add a job to find enchanted golden apples

This commit is contained in:
Tanner Collin 2020-09-25 00:03:22 -06:00
parent b723143299
commit 25ce916b43
10 changed files with 163 additions and 11 deletions

View File

@ -214,6 +214,10 @@ LEAVES = [
'dark_oak_leaves', 'dark_oak_leaves',
] ]
CHESTS = [
'chest',
]
INDEXED = [ INDEXED = [
'chest', 'chest',
] ]
@ -239,6 +243,11 @@ for block_name in LEAVES:
for state in JSON_BLOCKS['minecraft:' + block_name]['states']: for state in JSON_BLOCKS['minecraft:' + block_name]['states']:
LEAF_IDS.add(state['id']) LEAF_IDS.add(state['id'])
CHEST_IDS = set()
for block_name in CHESTS:
for state in JSON_BLOCKS['minecraft:' + block_name]['states']:
CHEST_IDS.add(state['id'])
INDEXED_IDS = set() INDEXED_IDS = set()
for block_name in INDEXED: for block_name in INDEXED:
for state in JSON_BLOCKS['minecraft:' + block_name]['states']: for state in JSON_BLOCKS['minecraft:' + block_name]['states']:

4
bot.py
View File

@ -156,6 +156,7 @@ def init(global_state):
g.dumping = None g.dumping = None
g.item_lock = False g.item_lock = False
g.command_lock = False
g.window = None g.window = None
@ -193,8 +194,7 @@ def bot(global_state):
time.sleep(utils.TICK) time.sleep(utils.TICK)
print('Player loaded.') print('Player loaded.')
x, y, z = utils.pint(g.pos) while not g.chunks.check_loaded(g.pos):
while (floor(x/16), floor(y/16), floor(z/16)) not in g.chunks.chunks:
time.sleep(utils.TICK) time.sleep(utils.TICK)
print('Chunks loaded.') print('Chunks loaded.')

31
game.py
View File

@ -249,6 +249,11 @@ class Game:
source, text = message source, text = message
reply = None reply = None
if source == 'SYSTEM':
print('unlocking command...')
self.g.command_lock = False
return
match = re.match(r'<(\w+)> (.*)', text) match = re.match(r'<(\w+)> (.*)', text)
if match: if match:
sender, text = match.groups() sender, text = match.groups()
@ -267,6 +272,7 @@ class Game:
data = text.split(' ', 1)[1] data = text.split(' ', 1)[1]
else: else:
command = text command = text
data = None
if command == 'ping': if command == 'ping':
reply = 'pong' reply = 'pong'
@ -370,6 +376,12 @@ class Game:
if command == 'loaded': if command == 'loaded':
reply = str(self.g.chunks.get_loaded_area()) reply = str(self.g.chunks.get_loaded_area())
if command == 'gapple':
self.g.job.state = self.g.job.find_gapple
if data:
self.g.job.find_gapple_states.count = int(data)
reply = 'ok'
if reply: if reply:
print(reply) print(reply)
self.g.chat.send(reply) self.g.chat.send(reply)
@ -513,13 +525,28 @@ class Game:
self.g.connection.write_packet(packet2) self.g.connection.write_packet(packet2)
def handle_spawn_object(self, packet): def handle_spawn_object(self, packet):
return
if packet.type_id != 37: return if packet.type_id != 37: return
print(packet) print(packet)
def handle_entity_metadata(self, packet): def handle_entity_metadata(self, packet):
if not packet.metadata:
return return
if packet.metadata and packet.metadata[0].index != 7: return
print(packet) if not self.g.job:
return
current_chest = self.g.job.find_gapple_states.current_chest
if not current_chest:
return
for entry in packet.metadata:
if entry.type != 6:
continue
if entry.value.item_id in items.GAPPLE_ID:
self.g.chat.send('gapple found: ' + str(current_chest)[1:-1])
def handle_spawn_living(self, packet): def handle_spawn_living(self, packet):
return return

View File

@ -32,4 +32,6 @@ for item_name, item in ITEMS.items():
CHEST_ID = set([ITEMS['minecraft:chest']['protocol_id']]) CHEST_ID = set([ITEMS['minecraft:chest']['protocol_id']])
GAPPLE_ID = set([ITEMS['minecraft:enchanted_golden_apple']['protocol_id']])
USEFUL_ITEMS = BED_IDS | CHEST_ID USEFUL_ITEMS = BED_IDS | CHEST_ID

93
jobs.py
View File

@ -7,6 +7,8 @@ from panda3d.core import LPoint3f
from minecraft.networking.types import BlockFace from minecraft.networking.types import BlockFace
from protocol.managers import ChunkNotLoadedException
import utils import utils
importlib.reload(utils) importlib.reload(utils)
import path import path
@ -19,6 +21,85 @@ import data
importlib.reload(data) importlib.reload(data)
class FindGappleStates:
def idle(self):
return None
def init(self):
self.state = self.go_spectator
def go_spectator(self):
print('Going spectator...')
self.g.chat.send('/gamemode spectator')
self.state = self.tp_to_coord
def tp_to_coord(self):
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))
print('count:', self.count, 'teleporting to:', self.coord)
self.g.chat.send('/tp {} {} {}'.format(*self.coord))
self.state = self.wait_for_load
def wait_for_load(self):
if self.g.chunks.check_loaded(self.g.pos):
print('chunks have been loaded')
self.state = self.pick_chest
def pick_chest(self):
chest_list = []
for chest_id in blocks.CHEST_IDS:
chest_list.extend(self.g.chunks.index.get(chest_id, []))
for chest in chest_list:
if chest in self.checked_chests: continue
self.current_chest = chest
self.state = self.break_chest
break
else: # for
print('exhausted chest list')
self.state = self.cleanup
def break_chest(self):
print('Breaking chest', self.current_chest)
self.g.command_lock = True
self.g.chat.send('/setblock {} {} {} air destroy'.format(*self.current_chest))
self.checked_chests.append(self.current_chest)
self.state = self.wait_for_items
def wait_for_items(self):
if not self.g.command_lock:
print('done waiting for items')
self.state = self.pick_chest
def cleanup(self):
self.count += 1
self.state = self.done
def done(self):
# never gets ran, placeholder
return None
def __init__(self, global_state):
self.g = global_state
self.state = self.idle
self.origin = utils.pint(self.g.pos)
self.count = 0
self.coord = None
self.current_chest = None
self.checked_chests = []
def run(self):
self.state()
class LumberjackStates: class LumberjackStates:
def bair(self, p): def bair(self, p):
return self.g.chunks.get_block_at(*p) in blocks.NON_SOLID_IDS return self.g.chunks.get_block_at(*p) in blocks.NON_SOLID_IDS
@ -515,6 +596,16 @@ class JobStates:
def idle(self): def idle(self):
return None return None
def find_gapple(self):
s1 = self.find_gapple_states
if s1.state == s1.idle:
s1.state = s1.init
elif s1.state == s1.done:
s1.state = s1.init
s1.run()
def gather_sand(self): def gather_sand(self):
s1 = self.gather_sand_states s1 = self.gather_sand_states
s2 = self.sleep_with_bed_states s2 = self.sleep_with_bed_states
@ -570,6 +661,7 @@ class JobStates:
self.gather_sand_states = GatherSandStates(self.g) self.gather_sand_states = GatherSandStates(self.g)
self.sleep_with_bed_states = SleepWithBedStates(self.g) self.sleep_with_bed_states = SleepWithBedStates(self.g)
self.cache_items_states = CacheItemsStates(self.g) self.cache_items_states = CacheItemsStates(self.g)
self.find_gapple_states = FindGappleStates(self.g)
self.state = self.idle self.state = self.idle
def __init__(self, global_state): def __init__(self, global_state):
@ -581,6 +673,7 @@ class JobStates:
self.gather_sand_states = GatherSandStates(self.g) self.gather_sand_states = GatherSandStates(self.g)
self.sleep_with_bed_states = SleepWithBedStates(self.g) self.sleep_with_bed_states = SleepWithBedStates(self.g)
self.cache_items_states = CacheItemsStates(self.g) self.cache_items_states = CacheItemsStates(self.g)
self.find_gapple_states = FindGappleStates(self.g)
def tick(self): def tick(self):
self.state() self.state()

View File

@ -19,6 +19,8 @@ g.connection = False
g.mcdata = False g.mcdata = False
g.pos = False g.pos = False
g.inv = {} g.inv = {}
g.window = None
g.job = None
@app.route('/') @app.route('/')
def hello_world(): def hello_world():

View File

@ -5,6 +5,8 @@ import json
from minecraft.networking.packets import clientbound, serverbound from minecraft.networking.packets import clientbound, serverbound
from protocol import packets from protocol import packets
import utils
class DataManager: class DataManager:
def __init__(self, directory): def __init__(self, directory):
self.blocks = {} self.blocks = {}
@ -80,7 +82,8 @@ class ChunksManager:
def get_chunk(self, x, y, z): def get_chunk(self, x, y, z):
index = (x, y, z) index = (x, y, z)
if not index in self.chunks: if not index in self.chunks:
raise ChunkNotLoadedException(index) return None
#raise ChunkNotLoadedException(index)
return self.chunks[index] return self.chunks[index]
def get_loaded_area(self, ignore_empty=False): def get_loaded_area(self, ignore_empty=False):
@ -101,12 +104,27 @@ class ChunksManager:
def get_block_at(self, x, y, z): def get_block_at(self, x, y, z):
c = self.get_chunk(floor(x/16), floor(y/16), floor(z/16)) c = self.get_chunk(floor(x/16), floor(y/16), floor(z/16))
if not c: return None
return c.get_block_at(x%16, y%16, z%16) return c.get_block_at(x%16, y%16, z%16)
def set_block_at(self, x, y, z, block): def set_block_at(self, x, y, z, block):
c = self.get_chunk(floor(x/16), floor(y/16), floor(z/16)) c = self.get_chunk(floor(x/16), floor(y/16), floor(z/16))
if not c: return None
c.set_block_at(x%16, y%16, z%16, block) 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?
x, y, z = utils.pint(position)
player_chunk = (x//16, 1, z//16)
for i in range(121): # TODO: base off render_distance?
offset = utils.spiral(i)
check = utils.padd(player_chunk, offset)
if check not in self.chunks:
return False
return True
class ChunkNotLoadedException(Exception): class ChunkNotLoadedException(Exception):
def __str__(self): def __str__(self):

View File

@ -312,7 +312,7 @@ class EntityMetadataPacket(Packet):
self.entity_id = VarInt.read(file_object) self.entity_id = VarInt.read(file_object)
self.metadata = [] self.metadata = []
for _ in range(99): for _ in range(99):
entry = Entry.read(file_object) entry = Entry.read(file_object, self.context)
if not entry: break if not entry: break
self.metadata.append(entry) self.metadata.append(entry)

View File

@ -133,7 +133,7 @@ class Slot(Type):
Boolean.send(value.present, socket) Boolean.send(value.present, socket)
VarInt.send(value.item_id, socket) VarInt.send(value.item_id, socket)
Byte.send(value.item_count, socket) Byte.send(value.item_count, socket)
TrailingByteArray.send(value.nbt, socket) Byte.send(0x00, socket)
class Entry(Type): class Entry(Type):
@ -157,16 +157,18 @@ class Entry(Type):
def __str__(self): def __str__(self):
return str(self.__dict__) return str(self.__dict__)
def __repr__(self): def __repr__(self):
return 'Entry(index={}, type={}, value={}'.format( return 'Entry(index={}, type={}, value={})'.format(
self.index, self.type, self.value) self.index, self.type, self.value)
@staticmethod @staticmethod
def read(file_object): def read(file_object, context):
index = UnsignedByte.read(file_object) index = UnsignedByte.read(file_object)
if index == 0xff: return None if index == 0xff: return None
type = VarInt.read(file_object) type = VarInt.read(file_object)
try: try:
value = Entry.types[type].read(file_object) value = Entry.types[type].read(file_object)
except TypeError:
value = Entry.types[type].read_with_context(file_object, context)
except KeyError: except KeyError:
return None return None
return Entry(index, type, value) return Entry(index, type, value)

View File

@ -90,4 +90,3 @@ def break_time(block_id, held_item=0, in_water=False, on_ground=True, enchantmen
if not on_ground: time *= 5.0 if not on_ground: time *= 5.0
return time return time