Add a job to find enchanted golden apples
This commit is contained in:
		@@ -214,6 +214,10 @@ LEAVES = [
 | 
			
		||||
    'dark_oak_leaves',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
CHESTS = [
 | 
			
		||||
    'chest',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
INDEXED = [
 | 
			
		||||
    'chest',
 | 
			
		||||
]
 | 
			
		||||
@@ -239,6 +243,11 @@ for block_name in LEAVES:
 | 
			
		||||
    for state in JSON_BLOCKS['minecraft:' + block_name]['states']:
 | 
			
		||||
        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()
 | 
			
		||||
for block_name in INDEXED:
 | 
			
		||||
    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.item_lock = False
 | 
			
		||||
    g.command_lock = False
 | 
			
		||||
 | 
			
		||||
    g.window = None
 | 
			
		||||
 | 
			
		||||
@@ -193,8 +194,7 @@ def bot(global_state):
 | 
			
		||||
            time.sleep(utils.TICK)
 | 
			
		||||
        print('Player loaded.')
 | 
			
		||||
 | 
			
		||||
        x, y, z = utils.pint(g.pos)
 | 
			
		||||
        while (floor(x/16), floor(y/16), floor(z/16)) not in g.chunks.chunks:
 | 
			
		||||
        while not g.chunks.check_loaded(g.pos):
 | 
			
		||||
            time.sleep(utils.TICK)
 | 
			
		||||
        print('Chunks loaded.')
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										33
									
								
								game.py
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								game.py
									
									
									
									
									
								
							@@ -249,6 +249,11 @@ class Game:
 | 
			
		||||
        source, text = message
 | 
			
		||||
        reply = None
 | 
			
		||||
 | 
			
		||||
        if source == 'SYSTEM':
 | 
			
		||||
            print('unlocking command...')
 | 
			
		||||
            self.g.command_lock = False
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        match = re.match(r'<(\w+)> (.*)', text)
 | 
			
		||||
        if match:
 | 
			
		||||
            sender, text = match.groups()
 | 
			
		||||
@@ -267,6 +272,7 @@ class Game:
 | 
			
		||||
            data = text.split(' ', 1)[1]
 | 
			
		||||
        else:
 | 
			
		||||
            command = text
 | 
			
		||||
            data = None
 | 
			
		||||
 | 
			
		||||
        if command == 'ping':
 | 
			
		||||
            reply = 'pong'
 | 
			
		||||
@@ -370,6 +376,12 @@ class Game:
 | 
			
		||||
        if command == 'loaded':
 | 
			
		||||
            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:
 | 
			
		||||
            print(reply)
 | 
			
		||||
            self.g.chat.send(reply)
 | 
			
		||||
@@ -513,13 +525,28 @@ class Game:
 | 
			
		||||
        self.g.connection.write_packet(packet2)
 | 
			
		||||
 | 
			
		||||
    def handle_spawn_object(self, packet):
 | 
			
		||||
        return
 | 
			
		||||
        if packet.type_id != 37: return
 | 
			
		||||
        print(packet)
 | 
			
		||||
 | 
			
		||||
    def handle_entity_metadata(self, packet):
 | 
			
		||||
        return
 | 
			
		||||
        if packet.metadata and packet.metadata[0].index != 7: return
 | 
			
		||||
        print(packet)
 | 
			
		||||
        if not packet.metadata:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        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):
 | 
			
		||||
        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']])
 | 
			
		||||
 | 
			
		||||
GAPPLE_ID = set([ITEMS['minecraft:enchanted_golden_apple']['protocol_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 protocol.managers import ChunkNotLoadedException
 | 
			
		||||
 | 
			
		||||
import utils
 | 
			
		||||
importlib.reload(utils)
 | 
			
		||||
import path
 | 
			
		||||
@@ -19,6 +21,85 @@ import 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:
 | 
			
		||||
    def bair(self, p):
 | 
			
		||||
        return self.g.chunks.get_block_at(*p) in blocks.NON_SOLID_IDS
 | 
			
		||||
@@ -515,6 +596,16 @@ class JobStates:
 | 
			
		||||
    def idle(self):
 | 
			
		||||
        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):
 | 
			
		||||
        s1 = self.gather_sand_states
 | 
			
		||||
        s2 = self.sleep_with_bed_states
 | 
			
		||||
@@ -570,6 +661,7 @@ class JobStates:
 | 
			
		||||
        self.gather_sand_states = GatherSandStates(self.g)
 | 
			
		||||
        self.sleep_with_bed_states = SleepWithBedStates(self.g)
 | 
			
		||||
        self.cache_items_states = CacheItemsStates(self.g)
 | 
			
		||||
        self.find_gapple_states = FindGappleStates(self.g)
 | 
			
		||||
        self.state = self.idle
 | 
			
		||||
 | 
			
		||||
    def __init__(self, global_state):
 | 
			
		||||
@@ -581,6 +673,7 @@ class JobStates:
 | 
			
		||||
        self.gather_sand_states = GatherSandStates(self.g)
 | 
			
		||||
        self.sleep_with_bed_states = SleepWithBedStates(self.g)
 | 
			
		||||
        self.cache_items_states = CacheItemsStates(self.g)
 | 
			
		||||
        self.find_gapple_states = FindGappleStates(self.g)
 | 
			
		||||
 | 
			
		||||
    def tick(self):
 | 
			
		||||
        self.state()
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								main.py
									
									
									
									
									
								
							@@ -19,6 +19,8 @@ g.connection = False
 | 
			
		||||
g.mcdata = False
 | 
			
		||||
g.pos = False
 | 
			
		||||
g.inv = {}
 | 
			
		||||
g.window = None
 | 
			
		||||
g.job = None
 | 
			
		||||
 | 
			
		||||
@app.route('/')
 | 
			
		||||
def hello_world():
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,8 @@ import json
 | 
			
		||||
from minecraft.networking.packets import clientbound, serverbound
 | 
			
		||||
from protocol import packets
 | 
			
		||||
 | 
			
		||||
import utils
 | 
			
		||||
 | 
			
		||||
class DataManager:
 | 
			
		||||
    def __init__(self, directory):
 | 
			
		||||
        self.blocks = {}
 | 
			
		||||
@@ -80,7 +82,8 @@ class ChunksManager:
 | 
			
		||||
    def get_chunk(self, x, y, z):
 | 
			
		||||
        index = (x, y, z)
 | 
			
		||||
        if not index in self.chunks:
 | 
			
		||||
            raise ChunkNotLoadedException(index)
 | 
			
		||||
            return None
 | 
			
		||||
            #raise ChunkNotLoadedException(index)
 | 
			
		||||
        return self.chunks[index]
 | 
			
		||||
 | 
			
		||||
    def get_loaded_area(self, ignore_empty=False):
 | 
			
		||||
@@ -101,12 +104,27 @@ class ChunksManager:
 | 
			
		||||
 | 
			
		||||
    def get_block_at(self, x, y, z):
 | 
			
		||||
        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)
 | 
			
		||||
 | 
			
		||||
    def set_block_at(self, x, y, z, block):
 | 
			
		||||
        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)
 | 
			
		||||
 | 
			
		||||
    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):
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
 
 | 
			
		||||
@@ -312,7 +312,7 @@ class EntityMetadataPacket(Packet):
 | 
			
		||||
        self.entity_id = VarInt.read(file_object)
 | 
			
		||||
        self.metadata = []
 | 
			
		||||
        for _ in range(99):
 | 
			
		||||
            entry = Entry.read(file_object)
 | 
			
		||||
            entry = Entry.read(file_object, self.context)
 | 
			
		||||
            if not entry: break
 | 
			
		||||
            self.metadata.append(entry)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -133,7 +133,7 @@ class Slot(Type):
 | 
			
		||||
        Boolean.send(value.present, socket)
 | 
			
		||||
        VarInt.send(value.item_id, socket)
 | 
			
		||||
        Byte.send(value.item_count, socket)
 | 
			
		||||
        TrailingByteArray.send(value.nbt, socket)
 | 
			
		||||
        Byte.send(0x00, socket)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Entry(Type):
 | 
			
		||||
@@ -157,16 +157,18 @@ class Entry(Type):
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return str(self.__dict__)
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        return 'Entry(index={}, type={}, value={}'.format(
 | 
			
		||||
        return 'Entry(index={}, type={}, value={})'.format(
 | 
			
		||||
            self.index, self.type, self.value)
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def read(file_object):
 | 
			
		||||
    def read(file_object, context):
 | 
			
		||||
        index = UnsignedByte.read(file_object)
 | 
			
		||||
        if index == 0xff: return None
 | 
			
		||||
        type = VarInt.read(file_object)
 | 
			
		||||
        try:
 | 
			
		||||
            value = Entry.types[type].read(file_object)
 | 
			
		||||
        except TypeError:
 | 
			
		||||
            value = Entry.types[type].read_with_context(file_object, context)
 | 
			
		||||
        except KeyError:
 | 
			
		||||
            return None
 | 
			
		||||
        return Entry(index, type, value)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user