Add a job to find enchanted golden apples
This commit is contained in:
parent
b723143299
commit
25ce916b43
|
@ -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
4
bot.py
|
@ -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
31
game.py
|
@ -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
|
||||||
|
|
2
items.py
2
items.py
|
@ -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
93
jobs.py
|
@ -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()
|
||||||
|
|
2
main.py
2
main.py
|
@ -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():
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user