Add job for farming trees and object physics
This commit is contained in:
		
							
								
								
									
										20
									
								
								blocks.py
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								blocks.py
									
									
									
									
									
								
							@@ -194,6 +194,12 @@ NON_SOLID = [
 | 
				
			|||||||
    'cave_air',
 | 
					    'cave_air',
 | 
				
			||||||
    'lantern',
 | 
					    'lantern',
 | 
				
			||||||
    'soul_torch',
 | 
					    'soul_torch',
 | 
				
			||||||
 | 
					    #'oak_sapling',       # saplings can grow up and hurt
 | 
				
			||||||
 | 
					    #'spruce_sapling',
 | 
				
			||||||
 | 
					    #'birch_sapling',
 | 
				
			||||||
 | 
					    #'jungle_sapling',
 | 
				
			||||||
 | 
					    #'acacia_sapling',
 | 
				
			||||||
 | 
					    #'dark_oak_sapling',
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LOGS = [
 | 
					LOGS = [
 | 
				
			||||||
@@ -214,6 +220,15 @@ LEAVES = [
 | 
				
			|||||||
    'dark_oak_leaves',
 | 
					    'dark_oak_leaves',
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SAPLINGS = [
 | 
				
			||||||
 | 
					    'oak_sapling',
 | 
				
			||||||
 | 
					    'spruce_sapling',
 | 
				
			||||||
 | 
					    'birch_sapling',
 | 
				
			||||||
 | 
					    'jungle_sapling',
 | 
				
			||||||
 | 
					    'acacia_sapling',
 | 
				
			||||||
 | 
					    'dark_oak_sapling',
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CHESTS = [
 | 
					CHESTS = [
 | 
				
			||||||
    'chest',
 | 
					    'chest',
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
@@ -253,6 +268,11 @@ for block_name in INDEXED:
 | 
				
			|||||||
    for state in JSON_BLOCKS['minecraft:' + block_name]['states']:
 | 
					    for state in JSON_BLOCKS['minecraft:' + block_name]['states']:
 | 
				
			||||||
        INDEXED_IDS.add(state['id'])
 | 
					        INDEXED_IDS.add(state['id'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SAPLING_IDS = set()
 | 
				
			||||||
 | 
					for block_name in SAPLINGS:
 | 
				
			||||||
 | 
					    for state in JSON_BLOCKS['minecraft:' + block_name]['states']:
 | 
				
			||||||
 | 
					        SAPLING_IDS.add(state['id'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get(bid):
 | 
					def get(bid):
 | 
				
			||||||
    name = BLOCKS[bid]
 | 
					    name = BLOCKS[bid]
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										34
									
								
								bot.py
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								bot.py
									
									
									
									
									
								
							@@ -22,7 +22,7 @@ from minecraft.networking.packets import Packet, clientbound, serverbound
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
from protocol.managers import DataManager, ChunksManager, ChatManager, ChunkNotLoadedException
 | 
					from protocol.managers import DataManager, ChunksManager, ChatManager, ChunkNotLoadedException
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from bunch import Bunch
 | 
					from munch import Munch
 | 
				
			||||||
from panda3d.core import LPoint3f, LVector3f
 | 
					from panda3d.core import LPoint3f, LVector3f
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import game
 | 
					import game
 | 
				
			||||||
@@ -59,6 +59,37 @@ def tick(global_state):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    g.chunks.unload_chunks(p)
 | 
					    g.chunks.unload_chunks(p)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ########## object physics ##########
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for eid, obj in g.objects.items():
 | 
				
			||||||
 | 
					        start_x = obj.x
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if obj.velocity_x:
 | 
				
			||||||
 | 
					            obj.x += obj.velocity_x / 8000
 | 
				
			||||||
 | 
					        if obj.velocity_y:
 | 
				
			||||||
 | 
					            obj.y += obj.velocity_y / 8000
 | 
				
			||||||
 | 
					        if obj.velocity_z:
 | 
				
			||||||
 | 
					            obj.z += obj.velocity_z / 8000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        block_below = g.chunks.get_block_at(floor(obj.x), int(obj.y-0.20), floor(obj.z))
 | 
				
			||||||
 | 
					        in_air = block_below in blocks.NON_SOLID_IDS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if in_air:
 | 
				
			||||||
 | 
					            obj.velocity_x *= 0.988
 | 
				
			||||||
 | 
					            obj.velocity_y -= 390
 | 
				
			||||||
 | 
					            obj.velocity_z *= 0.988
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            obj.y = int(obj.y-0.20)+1
 | 
				
			||||||
 | 
					            obj.velocity_x *= 0.5
 | 
				
			||||||
 | 
					            obj.velocity_y = 0
 | 
				
			||||||
 | 
					            obj.velocity_z *= 0.5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if abs(obj.velocity_x) < 1: obj.velocity_x = 0
 | 
				
			||||||
 | 
					        if abs(obj.velocity_z) < 1: obj.velocity_z = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ########## player physics ##########
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if g.path and len(g.path):
 | 
					    if g.path and len(g.path):
 | 
				
			||||||
        target = LPoint3f(g.path[0])
 | 
					        target = LPoint3f(g.path[0])
 | 
				
			||||||
        target.x += 0.5
 | 
					        target.x += 0.5
 | 
				
			||||||
@@ -162,6 +193,7 @@ def init(global_state):
 | 
				
			|||||||
    g.window = None
 | 
					    g.window = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    g.job = jobs.JobStates(g)
 | 
					    g.job = jobs.JobStates(g)
 | 
				
			||||||
 | 
					    g.chopped_tree = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def bot(global_state):
 | 
					def bot(global_state):
 | 
				
			||||||
    g = global_state
 | 
					    g = global_state
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										124
									
								
								game.py
									
									
									
									
									
								
							
							
						
						
									
										124
									
								
								game.py
									
									
									
									
									
								
							@@ -1,9 +1,10 @@
 | 
				
			|||||||
import re
 | 
					import re
 | 
				
			||||||
import time
 | 
					import time
 | 
				
			||||||
import importlib
 | 
					import importlib
 | 
				
			||||||
 | 
					import random
 | 
				
			||||||
from math import hypot
 | 
					from math import hypot
 | 
				
			||||||
from itertools import count
 | 
					from itertools import count
 | 
				
			||||||
from bunch import Bunch
 | 
					from munch import Munch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from panda3d.core import LPoint3f
 | 
					from panda3d.core import LPoint3f
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -17,8 +18,7 @@ from protocol.packets import (
 | 
				
			|||||||
    ClickWindowPacket, CloseWindowPacket, ServerWindowConfirmationPacket,
 | 
					    ClickWindowPacket, CloseWindowPacket, ServerWindowConfirmationPacket,
 | 
				
			||||||
    ClientWindowConfirmationPacket, EntityMetadataPacket,
 | 
					    ClientWindowConfirmationPacket, EntityMetadataPacket,
 | 
				
			||||||
    SpawnLivingEntityPacket, EntityPositionPacket,
 | 
					    SpawnLivingEntityPacket, EntityPositionPacket,
 | 
				
			||||||
    EntityPositionRotationPacket,
 | 
					    EntityPositionRotationPacket, DestroyEntitiesPacket, EntityVelocityPacket,
 | 
				
			||||||
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from protocol.types import Slot
 | 
					from protocol.types import Slot
 | 
				
			||||||
@@ -93,7 +93,7 @@ class MCWorld:
 | 
				
			|||||||
        result = []
 | 
					        result = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # TODO: make sure only non-solid and leaves between
 | 
					        # TODO: make sure only non-solid and leaves between
 | 
				
			||||||
        # make sure traversable too
 | 
					        # make sure traversable too and non-avoid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for distance in range(5):
 | 
					        for distance in range(5):
 | 
				
			||||||
            for direction in path.CHECK_DIRECTIONS:
 | 
					            for direction in path.CHECK_DIRECTIONS:
 | 
				
			||||||
@@ -203,6 +203,8 @@ class Game:
 | 
				
			|||||||
        register(self.handle_spawn_living, SpawnLivingEntityPacket)
 | 
					        register(self.handle_spawn_living, SpawnLivingEntityPacket)
 | 
				
			||||||
        register(self.handle_entity_position, EntityPositionPacket)
 | 
					        register(self.handle_entity_position, EntityPositionPacket)
 | 
				
			||||||
        register(self.handle_entity_position_rotation, EntityPositionRotationPacket)
 | 
					        register(self.handle_entity_position_rotation, EntityPositionRotationPacket)
 | 
				
			||||||
 | 
					        register(self.handle_destroy_entities, DestroyEntitiesPacket)
 | 
				
			||||||
 | 
					        register(self.handle_entity_velocity, EntityVelocityPacket)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #register(self.handle_packet, Packet, early=True)
 | 
					        #register(self.handle_packet, Packet, early=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -224,8 +226,8 @@ class Game:
 | 
				
			|||||||
                solution = path.Pathfinder(self.g.chunks).astar(utils.pint(self.g.pos), utils.pint(self.g.goal))
 | 
					                solution = path.Pathfinder(self.g.chunks).astar(utils.pint(self.g.pos), utils.pint(self.g.goal))
 | 
				
			||||||
                if solution:
 | 
					                if solution:
 | 
				
			||||||
                    solution = list(solution)
 | 
					                    solution = list(solution)
 | 
				
			||||||
                    #self.g.path = solution
 | 
					                    self.g.path = solution
 | 
				
			||||||
                    #self.g.job.state = self.g.job.stop
 | 
					                    self.g.job.state = self.g.job.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')
 | 
				
			||||||
@@ -320,6 +322,19 @@ class Game:
 | 
				
			|||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    reply += ', I need a bed'
 | 
					                    reply += ', I need a bed'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if command == 'farm' and data:
 | 
				
			||||||
 | 
					            if data == 'wood':
 | 
				
			||||||
 | 
					                self.g.job.state = self.g.job.farm_wood
 | 
				
			||||||
 | 
					                reply = 'ok'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if reply:
 | 
				
			||||||
 | 
					                for i in self.g.inv.values():
 | 
				
			||||||
 | 
					                    print(i.item_id)
 | 
				
			||||||
 | 
					                    if i.item_id in items.BED_IDS:
 | 
				
			||||||
 | 
					                        break
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    reply += ', I need a bed'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if command == 'stop':
 | 
					        if command == 'stop':
 | 
				
			||||||
            self.g.job.state = self.g.job.stop
 | 
					            self.g.job.state = self.g.job.stop
 | 
				
			||||||
            reply = 'ok'
 | 
					            reply = 'ok'
 | 
				
			||||||
@@ -386,6 +401,11 @@ class Game:
 | 
				
			|||||||
                self.g.job.find_gapple_states.count = int(data)
 | 
					                self.g.job.find_gapple_states.count = int(data)
 | 
				
			||||||
            reply = 'ok'
 | 
					            reply = 'ok'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if command == 'objects':
 | 
				
			||||||
 | 
					            for k, v in self.g.objects.items():
 | 
				
			||||||
 | 
					                if data and v.item_id != int(data): continue
 | 
				
			||||||
 | 
					                print(str(k) + ':', v)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if reply:
 | 
					        if reply:
 | 
				
			||||||
            print(reply)
 | 
					            print(reply)
 | 
				
			||||||
            self.g.chat.send(reply)
 | 
					            self.g.chat.send(reply)
 | 
				
			||||||
@@ -483,6 +503,23 @@ class Game:
 | 
				
			|||||||
        else:  #for
 | 
					        else:  #for
 | 
				
			||||||
            return False
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def select_random_item(self, items):
 | 
				
			||||||
 | 
					        # select a random match from items of inv
 | 
				
			||||||
 | 
					        # this is random per item type
 | 
				
			||||||
 | 
					        # example: 5 stacks wood, 1 stack glass
 | 
				
			||||||
 | 
					        # -> still 50/50 chance between them
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        matches = set()
 | 
				
			||||||
 | 
					        for slot, item in self.g.inv.items():
 | 
				
			||||||
 | 
					            if item.item_id in items:
 | 
				
			||||||
 | 
					                matches.add(item.item_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if matches:
 | 
				
			||||||
 | 
					            return self.select_item([random.choice(list(matches))])
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def drop_stack(self):
 | 
					    def drop_stack(self):
 | 
				
			||||||
        packet = PlayerDiggingPacket()
 | 
					        packet = PlayerDiggingPacket()
 | 
				
			||||||
        packet.status = 3
 | 
					        packet.status = 3
 | 
				
			||||||
@@ -497,7 +534,7 @@ class Game:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def handle_window(self, packet):
 | 
					    def handle_window(self, packet):
 | 
				
			||||||
        print(packet)
 | 
					        print(packet)
 | 
				
			||||||
        self.g.window = Bunch(data=packet, contents=dict(), count=0)
 | 
					        self.g.window = Munch(data=packet, contents=dict(), count=0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def click_window(self, slot, button, mode, item):
 | 
					    def click_window(self, slot, button, mode, item):
 | 
				
			||||||
        w = self.g.window
 | 
					        w = self.g.window
 | 
				
			||||||
@@ -529,41 +566,76 @@ 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
 | 
					        #return
 | 
				
			||||||
        if packet.type_id != 37: return
 | 
					        if packet.type_id != 37: return
 | 
				
			||||||
        print(packet)
 | 
					        print(packet)
 | 
				
			||||||
 | 
					        self.g.objects[packet.entity_id] = Munch(
 | 
				
			||||||
 | 
					            x=packet.x,
 | 
				
			||||||
 | 
					            y=packet.y,
 | 
				
			||||||
 | 
					            z=packet.z,
 | 
				
			||||||
 | 
					            velocity_x=packet.velocity_x,
 | 
				
			||||||
 | 
					            velocity_y=packet.velocity_y,
 | 
				
			||||||
 | 
					            velocity_z=packet.velocity_z,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def check_gapple(self, packet):
 | 
				
			||||||
 | 
					        if not self.g.job:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        current_gapple_chest = self.g.job.find_gapple_states.current_chest
 | 
				
			||||||
 | 
					        if current_gapple_chest:
 | 
				
			||||||
 | 
					            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_gapple_chest)[1:-1])
 | 
				
			||||||
 | 
					                    print('gapple found:', str(current_gapple_chest)[1:-1])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle_entity_metadata(self, packet):
 | 
					    def handle_entity_metadata(self, packet):
 | 
				
			||||||
        if not packet.metadata:
 | 
					        if not packet.metadata:
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not self.g.job:
 | 
					        self.check_gapple(packet)
 | 
				
			||||||
            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])
 | 
					 | 
				
			||||||
                print('gapple found:', str(current_chest)[1:-1])
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        obj = self.g.objects.get(packet.entity_id, None)
 | 
				
			||||||
 | 
					        if obj:
 | 
				
			||||||
 | 
					            for entry in packet.metadata:
 | 
				
			||||||
 | 
					                if entry.type != 6:
 | 
				
			||||||
 | 
					                    continue
 | 
				
			||||||
 | 
					                obj.item_id = entry.value.item_id
 | 
				
			||||||
 | 
					                obj.item_count = entry.value.item_count
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle_spawn_living(self, packet):
 | 
					    def handle_spawn_living(self, packet):
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
        print(packet)
 | 
					        print(packet)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle_entity_position(self, packet):
 | 
					    def handle_entity_position(self, packet):
 | 
				
			||||||
        return
 | 
					        obj = self.g.objects.get(packet.entity_id, None)
 | 
				
			||||||
        print(packet)
 | 
					        if obj:
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					            #obj.x += packet.delta_x
 | 
				
			||||||
 | 
					            #obj.y += packet.delta_y
 | 
				
			||||||
 | 
					            #obj.z += packet.delta_z
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle_entity_position_rotation(self, packet):
 | 
					    def handle_entity_position_rotation(self, packet):
 | 
				
			||||||
        return
 | 
					        obj = self.g.objects.get(packet.entity_id, None)
 | 
				
			||||||
        print(packet)
 | 
					        if obj:
 | 
				
			||||||
 | 
					            print('object rotation found:', packet)
 | 
				
			||||||
 | 
					            raise
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def handle_entity_velocity(self, packet):
 | 
				
			||||||
 | 
					        obj = self.g.objects.get(packet.entity_id, None)
 | 
				
			||||||
 | 
					        if obj:
 | 
				
			||||||
 | 
					            print(packet)
 | 
				
			||||||
 | 
					            #obj.velocity_x = packet.velocity_x
 | 
				
			||||||
 | 
					            #obj.velocity_y = packet.velocity_y
 | 
				
			||||||
 | 
					            #obj.velocity_z = packet.velocity_z
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def handle_destroy_entities(self, packet):
 | 
				
			||||||
 | 
					        for eid in packet.entity_ids:
 | 
				
			||||||
 | 
					            if eid in self.g.objects:
 | 
				
			||||||
 | 
					                del self.g.objects[eid]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def tick(self):
 | 
					    def tick(self):
 | 
				
			||||||
        if self.g.breaking:
 | 
					        if self.g.breaking:
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										13
									
								
								items.py
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								items.py
									
									
									
									
									
								
							@@ -22,10 +22,23 @@ BEDS = [
 | 
				
			|||||||
    'black_bed',
 | 
					    'black_bed',
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SAPLINGS = [
 | 
				
			||||||
 | 
					    'oak_sapling',
 | 
				
			||||||
 | 
					    'spruce_sapling',
 | 
				
			||||||
 | 
					    'birch_sapling',
 | 
				
			||||||
 | 
					    'jungle_sapling',
 | 
				
			||||||
 | 
					    'acacia_sapling',
 | 
				
			||||||
 | 
					    'dark_oak_sapling',
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BED_IDS = set()
 | 
					BED_IDS = set()
 | 
				
			||||||
for item_name in BEDS:
 | 
					for item_name in BEDS:
 | 
				
			||||||
    BED_IDS.add(ITEMS['minecraft:'+item_name]['protocol_id'])
 | 
					    BED_IDS.add(ITEMS['minecraft:'+item_name]['protocol_id'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SAPLING_IDS = set()
 | 
				
			||||||
 | 
					for item_name in SAPLINGS:
 | 
				
			||||||
 | 
					    SAPLING_IDS.add(ITEMS['minecraft:'+item_name]['protocol_id'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ITEM_NAMES = {}
 | 
					ITEM_NAMES = {}
 | 
				
			||||||
for item_name, item in ITEMS.items():
 | 
					for item_name, item in ITEMS.items():
 | 
				
			||||||
    ITEM_NAMES[ITEMS[item_name]['protocol_id']] = item_name.replace('minecraft:', '')
 | 
					    ITEM_NAMES[ITEMS[item_name]['protocol_id']] = item_name.replace('minecraft:', '')
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										165
									
								
								jobs.py
									
									
									
									
									
								
							
							
						
						
									
										165
									
								
								jobs.py
									
									
									
									
									
								
							@@ -131,6 +131,7 @@ class GatherWoodStates:
 | 
				
			|||||||
        return None
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def init(self):
 | 
					    def init(self):
 | 
				
			||||||
 | 
					        self.g.chopped_tree = False
 | 
				
			||||||
        self.state = self.find_new_tree
 | 
					        self.state = self.find_new_tree
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def find_new_tree(self):
 | 
					    def find_new_tree(self):
 | 
				
			||||||
@@ -141,9 +142,14 @@ class GatherWoodStates:
 | 
				
			|||||||
        trees = w.find_trees(p, 100)
 | 
					        trees = w.find_trees(p, 100)
 | 
				
			||||||
        print('Found trees:', trees)
 | 
					        print('Found trees:', trees)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        while trees[0] in self.bad_trees:
 | 
					        try:
 | 
				
			||||||
            trees.pop(0)
 | 
					            while trees[0] in self.bad_trees:
 | 
				
			||||||
        self.tree = trees[0]
 | 
					                trees.pop(0)
 | 
				
			||||||
 | 
					            self.tree = trees[0]
 | 
				
			||||||
 | 
					        except IndexError:
 | 
				
			||||||
 | 
					            print('No good tress left, aborting.')
 | 
				
			||||||
 | 
					            self.state = self.cleanup
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.openings = w.find_tree_openings(self.tree)
 | 
					        self.openings = w.find_tree_openings(self.tree)
 | 
				
			||||||
        self.state = self.choose_opening
 | 
					        self.state = self.choose_opening
 | 
				
			||||||
@@ -241,6 +247,7 @@ class GatherWoodStates:
 | 
				
			|||||||
        if self.wait_time > 0:
 | 
					        if self.wait_time > 0:
 | 
				
			||||||
            self.wait_time -= utils.TICK
 | 
					            self.wait_time -= utils.TICK
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
 | 
					            self.g.chopped_tree = True
 | 
				
			||||||
            self.state = self.cleanup
 | 
					            self.state = self.cleanup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def cleanup(self):
 | 
					    def cleanup(self):
 | 
				
			||||||
@@ -428,7 +435,8 @@ class SleepWithBedStates:
 | 
				
			|||||||
        if self.g.time >= 12542:
 | 
					        if self.g.time >= 12542:
 | 
				
			||||||
            print('Sleeping')
 | 
					            print('Sleeping')
 | 
				
			||||||
            self.g.game.place_block(self.area, BlockFace.TOP)
 | 
					            self.g.game.place_block(self.area, BlockFace.TOP)
 | 
				
			||||||
            self.g.chat.send('zzz')
 | 
					            if not self.silent:
 | 
				
			||||||
 | 
					                self.g.chat.send('zzz')
 | 
				
			||||||
            self.state = self.sleep_bed
 | 
					            self.state = self.sleep_bed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def sleep_bed(self):
 | 
					    def sleep_bed(self):
 | 
				
			||||||
@@ -465,6 +473,8 @@ class SleepWithBedStates:
 | 
				
			|||||||
        self.g = global_state
 | 
					        self.g = global_state
 | 
				
			||||||
        self.state = self.idle
 | 
					        self.state = self.idle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.silent = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.area = None
 | 
					        self.area = None
 | 
				
			||||||
        self.opening = None
 | 
					        self.opening = None
 | 
				
			||||||
        self.bad_areas = []
 | 
					        self.bad_areas = []
 | 
				
			||||||
@@ -507,7 +517,7 @@ class CacheItemsStates:
 | 
				
			|||||||
            self.state = self.cleanup
 | 
					            self.state = self.cleanup
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        openings = w.find_bed_openings(self.area)
 | 
					        openings = w.find_cache_openings(self.area)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for o in openings:
 | 
					        for o in openings:
 | 
				
			||||||
            navpath = w.path_to_place(p, o)
 | 
					            navpath = w.path_to_place(p, o)
 | 
				
			||||||
@@ -612,6 +622,115 @@ class CacheItemsStates:
 | 
				
			|||||||
        self.state()
 | 
					        self.state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PlantTreeStates:
 | 
				
			||||||
 | 
					    def idle(self):
 | 
				
			||||||
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # TODO: maybe add a "plant deficit" so we know when to plant or not
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def init(self):
 | 
				
			||||||
 | 
					        if self.g.chopped_tree:
 | 
				
			||||||
 | 
					            self.state = self.check_feet
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            print('Aborting planting, did not plant')
 | 
				
			||||||
 | 
					            self.state = self.cleanup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def check_feet(self):
 | 
				
			||||||
 | 
					        p = utils.pint(self.g.pos)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # check for air at feet
 | 
				
			||||||
 | 
					        if self.g.chunks.get_block_at(*p) in [0]:
 | 
				
			||||||
 | 
					            self.state = self.select_sapling
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            print('Aborting planting, feet not air')
 | 
				
			||||||
 | 
					            self.state = self.cleanup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def select_sapling(self):
 | 
				
			||||||
 | 
					        p = utils.pint(self.g.pos)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self.g.game.select_random_item(items.SAPLING_IDS):
 | 
				
			||||||
 | 
					            self.g.look_at = utils.padd(p, path.BLOCK_BELOW)
 | 
				
			||||||
 | 
					            self.state = self.wait_select
 | 
				
			||||||
 | 
					            self.wait_time = 1
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            print('Aborting planting, no saplings')
 | 
				
			||||||
 | 
					            self.state = self.cleanup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def wait_select(self):
 | 
				
			||||||
 | 
					        # wait a bit to look down
 | 
				
			||||||
 | 
					        if self.wait_time > 0:
 | 
				
			||||||
 | 
					            self.wait_time -= utils.TICK
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self.state = self.place_sapling
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def place_sapling(self):
 | 
				
			||||||
 | 
					        p = utils.pint(self.g.pos)
 | 
				
			||||||
 | 
					        self.g.game.place_block(p, BlockFace.TOP)
 | 
				
			||||||
 | 
					        print('Placed sapling')
 | 
				
			||||||
 | 
					        self.state = self.wait_place
 | 
				
			||||||
 | 
					        self.wait_time = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def wait_place(self):
 | 
				
			||||||
 | 
					        # wait a bit for chunk data to update
 | 
				
			||||||
 | 
					        if self.wait_time > 0:
 | 
				
			||||||
 | 
					            self.wait_time -= utils.TICK
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self.state = self.find_open_spot
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def find_open_spot(self):
 | 
				
			||||||
 | 
					        print('Finding an open spot to stand...')
 | 
				
			||||||
 | 
					        w = self.g.world
 | 
				
			||||||
 | 
					        p = utils.pint(self.g.pos)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        areas = w.find_cache_areas(p, 20)
 | 
				
			||||||
 | 
					        print('Found areas:', areas)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            while areas[0] in self.bad_areas:
 | 
				
			||||||
 | 
					                areas.pop(0)
 | 
				
			||||||
 | 
					            self.area = areas[0]
 | 
				
			||||||
 | 
					        except IndexError:
 | 
				
			||||||
 | 
					            print('No good areas left, aborting.')
 | 
				
			||||||
 | 
					            self.bad_areas = []
 | 
				
			||||||
 | 
					            self.state = self.cleanup
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        navpath = w.path_to_place(p, self.area)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not navpath:
 | 
				
			||||||
 | 
					            print('Unable to get to open area', self.area)
 | 
				
			||||||
 | 
					            self.bad_areas.append(self.area)
 | 
				
			||||||
 | 
					            self.state = self.cleanup
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.g.path = navpath
 | 
				
			||||||
 | 
					        self.state = self.going_to_area
 | 
				
			||||||
 | 
					        print('Going to area', self.area)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def going_to_area(self):
 | 
				
			||||||
 | 
					        if utils.pint(self.g.pos) == self.area:
 | 
				
			||||||
 | 
					            self.state = self.cleanup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def cleanup(self):
 | 
				
			||||||
 | 
					        self.g.look_at = None
 | 
				
			||||||
 | 
					        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.wait_time = 0
 | 
				
			||||||
 | 
					        self.area = None
 | 
				
			||||||
 | 
					        self.bad_areas = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def run(self):
 | 
				
			||||||
 | 
					        self.state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class JobStates:
 | 
					class JobStates:
 | 
				
			||||||
    def idle(self):
 | 
					    def idle(self):
 | 
				
			||||||
        return None
 | 
					        return None
 | 
				
			||||||
@@ -676,12 +795,47 @@ class JobStates:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        s1.run()
 | 
					        s1.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def farm_wood(self):
 | 
				
			||||||
 | 
					        self.sleep_with_bed_states.silent = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        s1 = self.gather_wood_states
 | 
				
			||||||
 | 
					        s2 = self.plant_tree_states
 | 
				
			||||||
 | 
					        s3 = self.sleep_with_bed_states
 | 
				
			||||||
 | 
					        s4 = self.cache_items_states
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if s1.state == s1.idle:
 | 
				
			||||||
 | 
					            s1.state = s1.init
 | 
				
			||||||
 | 
					            s2.state = s2.init
 | 
				
			||||||
 | 
					            s3.state = s3.init
 | 
				
			||||||
 | 
					            s4.state = s4.init
 | 
				
			||||||
 | 
					        elif s1.state == s1.done:
 | 
				
			||||||
 | 
					            if s2.state != s2.done:
 | 
				
			||||||
 | 
					                s2.run()
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if s3.state != s3.done:
 | 
				
			||||||
 | 
					                s3.run()
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if s4.state != s4.done:
 | 
				
			||||||
 | 
					                s4.run()
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            s1.state = s1.init
 | 
				
			||||||
 | 
					            s2.state = s2.init
 | 
				
			||||||
 | 
					            s3.state = s3.init
 | 
				
			||||||
 | 
					            s4.state = s4.init
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        s1.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def stop(self):
 | 
					    def stop(self):
 | 
				
			||||||
        self.gather_wood_states = GatherWoodStates(self.g)
 | 
					        self.gather_wood_states = GatherWoodStates(self.g)
 | 
				
			||||||
        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.find_gapple_states = FindGappleStates(self.g)
 | 
				
			||||||
 | 
					        self.plant_tree_states = PlantTreeStates(self.g)
 | 
				
			||||||
        self.state = self.idle
 | 
					        self.state = self.idle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, global_state):
 | 
					    def __init__(self, global_state):
 | 
				
			||||||
@@ -694,6 +848,7 @@ class JobStates:
 | 
				
			|||||||
        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.find_gapple_states = FindGappleStates(self.g)
 | 
				
			||||||
 | 
					        self.plant_tree_states = PlantTreeStates(self.g)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def tick(self):
 | 
					    def tick(self):
 | 
				
			||||||
        self.state()
 | 
					        self.state()
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										5
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								main.py
									
									
									
									
									
								
							@@ -7,18 +7,19 @@ import json
 | 
				
			|||||||
from flask import Flask
 | 
					from flask import Flask
 | 
				
			||||||
app = Flask(__name__)
 | 
					app = Flask(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from bunch import Bunch
 | 
					from munch import Munch
 | 
				
			||||||
from watchdog.observers import Observer
 | 
					from watchdog.observers import Observer
 | 
				
			||||||
from watchdog.events import PatternMatchingEventHandler
 | 
					from watchdog.events import PatternMatchingEventHandler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import bot
 | 
					import bot
 | 
				
			||||||
 | 
					
 | 
				
			||||||
global_state = Bunch()
 | 
					global_state = Munch()
 | 
				
			||||||
g = global_state
 | 
					g = global_state
 | 
				
			||||||
g.connection = False
 | 
					g.connection = False
 | 
				
			||||||
g.mcdata = False
 | 
					g.mcdata = False
 | 
				
			||||||
g.pos = False
 | 
					g.pos = False
 | 
				
			||||||
g.inv = {}
 | 
					g.inv = {}
 | 
				
			||||||
 | 
					g.objects = {}
 | 
				
			||||||
g.window = None
 | 
					g.window = None
 | 
				
			||||||
g.job = None
 | 
					g.job = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,8 @@ def get_packets(old_get_packets):
 | 
				
			|||||||
        mc_packets.add(packets.SpawnLivingEntityPacket)
 | 
					        mc_packets.add(packets.SpawnLivingEntityPacket)
 | 
				
			||||||
        mc_packets.add(packets.EntityPositionPacket)
 | 
					        mc_packets.add(packets.EntityPositionPacket)
 | 
				
			||||||
        mc_packets.add(packets.EntityPositionRotationPacket)
 | 
					        mc_packets.add(packets.EntityPositionRotationPacket)
 | 
				
			||||||
 | 
					        mc_packets.add(packets.DestroyEntitiesPacket)
 | 
				
			||||||
 | 
					        mc_packets.add(packets.EntityVelocityPacket)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return mc_packets
 | 
					        return mc_packets
 | 
				
			||||||
    return lambda x: wrapper(old_get_packets, x)
 | 
					    return lambda x: wrapper(old_get_packets, x)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -334,9 +334,9 @@ class SpawnLivingEntityPacket(Packet):
 | 
				
			|||||||
        {'yaw': Angle},
 | 
					        {'yaw': Angle},
 | 
				
			||||||
        {'pitch': Angle},
 | 
					        {'pitch': Angle},
 | 
				
			||||||
        {'head_pitch': Angle},
 | 
					        {'head_pitch': Angle},
 | 
				
			||||||
        {'x_velocity': Short},
 | 
					        {'velocity_x': Short},
 | 
				
			||||||
        {'y_velocity': Short},
 | 
					        {'velocity_y': Short},
 | 
				
			||||||
        {'z_velocity': Short},
 | 
					        {'velocity_z': Short},
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class EntityPositionPacket(Packet):
 | 
					class EntityPositionPacket(Packet):
 | 
				
			||||||
@@ -370,3 +370,32 @@ class EntityPositionRotationPacket(Packet):
 | 
				
			|||||||
        {'pitch': Angle},
 | 
					        {'pitch': Angle},
 | 
				
			||||||
        {'on_ground': Boolean},
 | 
					        {'on_ground': Boolean},
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DestroyEntitiesPacket(Packet):
 | 
				
			||||||
 | 
					    # Sent by the server when a list of entities is to be destroyed on the client
 | 
				
			||||||
 | 
					    # https://wiki.vg/Protocol#Destroy_Entities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    id = 0x36
 | 
				
			||||||
 | 
					    packet_name = 'destroy entities'
 | 
				
			||||||
 | 
					    fields = 'count', 'entity_ids'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def read(self, file_object):
 | 
				
			||||||
 | 
					        self.count = VarInt.read(file_object)
 | 
				
			||||||
 | 
					        self.entity_ids = []
 | 
				
			||||||
 | 
					        for _ in range(self.count):
 | 
				
			||||||
 | 
					            eid = VarInt.read(file_object)
 | 
				
			||||||
 | 
					            self.entity_ids.append(eid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class EntityVelocityPacket(Packet):
 | 
				
			||||||
 | 
					    # Sent to update entity's velocity
 | 
				
			||||||
 | 
					    # https://wiki.vg/Protocol#Entity_Velocity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    id = 0x46
 | 
				
			||||||
 | 
					    packet_name = 'entity velocity'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    definition = [
 | 
				
			||||||
 | 
					        {'entity_id': VarInt},
 | 
				
			||||||
 | 
					        {'velocity_x': Short},
 | 
				
			||||||
 | 
					        {'velocity_y': Short},
 | 
				
			||||||
 | 
					        {'velocity_z': Short},
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,4 @@
 | 
				
			|||||||
astar==0.92
 | 
					astar==0.92
 | 
				
			||||||
bunch==1.0.1
 | 
					 | 
				
			||||||
certifi==2020.6.20
 | 
					certifi==2020.6.20
 | 
				
			||||||
cffi==1.14.2
 | 
					cffi==1.14.2
 | 
				
			||||||
chardet==3.0.4
 | 
					chardet==3.0.4
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user