Compare commits
No commits in common. "6c4aaf8d7db0e08f747bc658858aff7c6d2cf41b" and "83132ab2bbe84f7d9fea19f45df7605f02256463" have entirely different histories.
6c4aaf8d7d
...
83132ab2bb
20
blocks.py
20
blocks.py
|
@ -194,12 +194,6 @@ 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 = [
|
||||||
|
@ -220,15 +214,6 @@ 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',
|
||||||
]
|
]
|
||||||
|
@ -268,11 +253,6 @@ 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]
|
||||||
|
|
35
bot.py
35
bot.py
|
@ -6,7 +6,6 @@ import os
|
||||||
import time
|
import time
|
||||||
import importlib
|
import importlib
|
||||||
from math import floor, ceil
|
from math import floor, ceil
|
||||||
from copy import copy
|
|
||||||
|
|
||||||
USERNAME = os.environ['USERNAME']
|
USERNAME = os.environ['USERNAME']
|
||||||
PASSWORD = os.environ['PASSWORD']
|
PASSWORD = os.environ['PASSWORD']
|
||||||
|
@ -23,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 munch import Munch
|
from bunch import Bunch
|
||||||
from panda3d.core import LPoint3f, LVector3f
|
from panda3d.core import LPoint3f, LVector3f
|
||||||
|
|
||||||
import game
|
import game
|
||||||
|
@ -60,37 +59,6 @@ def tick(global_state):
|
||||||
|
|
||||||
g.chunks.unload_chunks(p)
|
g.chunks.unload_chunks(p)
|
||||||
|
|
||||||
########## object physics ##########
|
|
||||||
|
|
||||||
for eid, obj in copy(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
|
||||||
|
@ -194,7 +162,6 @@ 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
|
||||||
|
|
157
game.py
157
game.py
|
@ -1,11 +1,9 @@
|
||||||
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 munch import Munch
|
from bunch import Bunch
|
||||||
from copy import copy
|
|
||||||
|
|
||||||
from panda3d.core import LPoint3f
|
from panda3d.core import LPoint3f
|
||||||
|
|
||||||
|
@ -13,12 +11,14 @@ from minecraft.networking.packets import Packet, clientbound, serverbound
|
||||||
from minecraft.networking.types import BlockFace
|
from minecraft.networking.types import BlockFace
|
||||||
|
|
||||||
from protocol.packets import (
|
from protocol.packets import (
|
||||||
SetSlotPacket, PlayerDiggingPacket,
|
TimeUpdatePacket, SetSlotPacket, PlayerDiggingPacket,
|
||||||
BlockBreakAnimationPacket, AcknowledgePlayerDiggingPacket,
|
BlockBreakAnimationPacket, AcknowledgePlayerDiggingPacket,
|
||||||
HeldItemChangePacket, PickItemPacket, OpenWindowPacket,
|
HeldItemChangePacket, PickItemPacket, OpenWindowPacket,
|
||||||
ClickWindowPacket, CloseWindowPacket, ServerWindowConfirmationPacket,
|
ClickWindowPacket, CloseWindowPacket, ServerWindowConfirmationPacket,
|
||||||
ClientWindowConfirmationPacket, EntityMetadataPacket,
|
ClientWindowConfirmationPacket, EntityMetadataPacket,
|
||||||
SpawnLivingEntityPacket, EntityPositionRotationPacket, DestroyEntitiesPacket,
|
SpawnLivingEntityPacket, EntityPositionPacket,
|
||||||
|
EntityPositionRotationPacket,
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
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 and non-avoid
|
# make sure traversable too
|
||||||
|
|
||||||
for distance in range(5):
|
for distance in range(5):
|
||||||
for direction in path.CHECK_DIRECTIONS:
|
for direction in path.CHECK_DIRECTIONS:
|
||||||
|
@ -115,23 +115,20 @@ class MCWorld:
|
||||||
air = []
|
air = []
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
check = utils.padd(center, utils.alternate(i, 1))
|
check = utils.padd(center, utils.alternate(i, 1))
|
||||||
air.extend(self.find_blocks(check, distance, [0], 0))
|
air.extend(self.find_blocks(check, distance, [0], 200))
|
||||||
|
|
||||||
bed_clearance = 25 # 5x5 area
|
|
||||||
clear_distance = 3
|
|
||||||
|
|
||||||
areas = []
|
areas = []
|
||||||
for a in air:
|
for a in air:
|
||||||
# check for air around the area
|
# check for ground around the area
|
||||||
if len(self.find_blocks(a, clear_distance, [0], bed_clearance)) < bed_clearance:
|
if len(self.find_blocks(utils.padd(a, path.BLOCK_BELOW), 2, blocks.NON_SOLID_IDS, 9)):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# check for ground around the area
|
# check for air around the area
|
||||||
if len(self.find_blocks(utils.padd(a, path.BLOCK_BELOW), clear_distance, blocks.NON_SOLID_IDS, bed_clearance)):
|
if len(self.find_blocks(a, 2, [0], 9)) < 9:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# check for air above the area
|
# check for air above the area
|
||||||
if len(self.find_blocks(utils.padd(a, path.BLOCK_ABOVE), clear_distance, [0], bed_clearance)) < bed_clearance:
|
if len(self.find_blocks(utils.padd(a, path.BLOCK_ABOVE), 2, [0], 9)) < 9:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
areas.append(a)
|
areas.append(a)
|
||||||
|
@ -186,13 +183,6 @@ class MCWorld:
|
||||||
def find_cache_openings(self, area):
|
def find_cache_openings(self, area):
|
||||||
return self.find_bed_openings(area)
|
return self.find_bed_openings(area)
|
||||||
|
|
||||||
def find_objects(self, object_ids):
|
|
||||||
result = []
|
|
||||||
for eid, obj in copy(self.g.objects).items():
|
|
||||||
if obj.get('item_id', None) in object_ids:
|
|
||||||
result.append(obj)
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
class Game:
|
class Game:
|
||||||
def __init__(self, global_state):
|
def __init__(self, global_state):
|
||||||
|
@ -202,7 +192,7 @@ class Game:
|
||||||
register(self.handle_block_change, clientbound.play.BlockChangePacket)
|
register(self.handle_block_change, clientbound.play.BlockChangePacket)
|
||||||
register(self.handle_join_game, clientbound.play.JoinGamePacket)
|
register(self.handle_join_game, clientbound.play.JoinGamePacket)
|
||||||
register(self.handle_position_and_look, clientbound.play.PlayerPositionAndLookPacket)
|
register(self.handle_position_and_look, clientbound.play.PlayerPositionAndLookPacket)
|
||||||
register(self.handle_time_update, clientbound.play.TimeUpdatePacket)
|
register(self.handle_time_update, TimeUpdatePacket)
|
||||||
register(self.handle_set_slot, SetSlotPacket)
|
register(self.handle_set_slot, SetSlotPacket)
|
||||||
register(self.handle_break_animation, BlockBreakAnimationPacket)
|
register(self.handle_break_animation, BlockBreakAnimationPacket)
|
||||||
register(self.handle_break_ack, AcknowledgePlayerDiggingPacket)
|
register(self.handle_break_ack, AcknowledgePlayerDiggingPacket)
|
||||||
|
@ -211,10 +201,8 @@ class Game:
|
||||||
register(self.handle_spawn_object, clientbound.play.SpawnObjectPacket)
|
register(self.handle_spawn_object, clientbound.play.SpawnObjectPacket)
|
||||||
register(self.handle_entity_metadata, EntityMetadataPacket)
|
register(self.handle_entity_metadata, EntityMetadataPacket)
|
||||||
register(self.handle_spawn_living, SpawnLivingEntityPacket)
|
register(self.handle_spawn_living, SpawnLivingEntityPacket)
|
||||||
register(self.handle_entity_position, clientbound.play.EntityPositionDeltaPacket)
|
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, clientbound.play.EntityVelocityPacket)
|
|
||||||
|
|
||||||
#register(self.handle_packet, Packet, early=True)
|
#register(self.handle_packet, Packet, early=True)
|
||||||
|
|
||||||
|
@ -236,8 +224,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')
|
||||||
|
@ -318,7 +306,7 @@ class Game:
|
||||||
|
|
||||||
if command == 'gather' and data:
|
if command == 'gather' and data:
|
||||||
if data == 'wood':
|
if data == 'wood':
|
||||||
self.g.job.state = self.g.job.gather_wood
|
self.g.job.state = self.g.job.lumberjack
|
||||||
reply = 'ok'
|
reply = 'ok'
|
||||||
elif data == 'sand':
|
elif data == 'sand':
|
||||||
self.g.job.state = self.g.job.gather_sand
|
self.g.job.state = self.g.job.gather_sand
|
||||||
|
@ -332,19 +320,6 @@ 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'
|
||||||
|
@ -411,11 +386,6 @@ 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)
|
||||||
|
@ -513,23 +483,6 @@ 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
|
||||||
|
@ -544,7 +497,7 @@ class Game:
|
||||||
|
|
||||||
def handle_window(self, packet):
|
def handle_window(self, packet):
|
||||||
print(packet)
|
print(packet)
|
||||||
self.g.window = Munch(data=packet, contents=dict(), count=0)
|
self.g.window = Bunch(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
|
||||||
|
@ -576,77 +529,41 @@ 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(
|
|
||||||
entity_id=packet.entity_id,
|
|
||||||
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
|
||||||
|
|
||||||
self.check_gapple(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])
|
||||||
|
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):
|
||||||
obj = self.g.objects.get(packet.entity_id, None)
|
return
|
||||||
if obj:
|
print(packet)
|
||||||
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):
|
||||||
obj = self.g.objects.get(packet.entity_id, None)
|
return
|
||||||
if obj:
|
print(packet)
|
||||||
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,23 +22,10 @@ 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:', '')
|
||||||
|
|
252
jobs.py
252
jobs.py
|
@ -1,7 +1,6 @@
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
import importlib
|
import importlib
|
||||||
import random
|
|
||||||
from math import hypot
|
from math import hypot
|
||||||
|
|
||||||
from panda3d.core import LPoint3f
|
from panda3d.core import LPoint3f
|
||||||
|
@ -121,7 +120,7 @@ class FindGappleStates:
|
||||||
self.state()
|
self.state()
|
||||||
|
|
||||||
|
|
||||||
class GatherWoodStates:
|
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
|
||||||
|
|
||||||
|
@ -132,7 +131,6 @@ 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):
|
||||||
|
@ -143,14 +141,9 @@ class GatherWoodStates:
|
||||||
trees = w.find_trees(p, 100)
|
trees = w.find_trees(p, 100)
|
||||||
print('Found trees:', trees)
|
print('Found trees:', trees)
|
||||||
|
|
||||||
try:
|
while trees[0] in self.bad_trees:
|
||||||
while trees[0] in self.bad_trees:
|
trees.pop(0)
|
||||||
trees.pop(0)
|
self.tree = trees[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
|
||||||
|
@ -248,7 +241,6 @@ 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):
|
||||||
|
@ -436,8 +428,7 @@ 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)
|
||||||
if not self.silent:
|
self.g.chat.send('zzz')
|
||||||
self.g.chat.send('zzz')
|
|
||||||
self.state = self.sleep_bed
|
self.state = self.sleep_bed
|
||||||
|
|
||||||
def sleep_bed(self):
|
def sleep_bed(self):
|
||||||
|
@ -474,8 +465,6 @@ 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 = []
|
||||||
|
@ -518,7 +507,7 @@ class CacheItemsStates:
|
||||||
self.state = self.cleanup
|
self.state = self.cleanup
|
||||||
return
|
return
|
||||||
|
|
||||||
openings = w.find_cache_openings(self.area)
|
openings = w.find_bed_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)
|
||||||
|
@ -623,182 +612,6 @@ class CacheItemsStates:
|
||||||
self.state()
|
self.state()
|
||||||
|
|
||||||
|
|
||||||
class PlantTreeStates:
|
|
||||||
def idle(self):
|
|
||||||
return None
|
|
||||||
|
|
||||||
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 GrabSaplingStates:
|
|
||||||
def idle(self):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def init(self):
|
|
||||||
self.state = self.find_saplings
|
|
||||||
print('Trying to grab a sapling')
|
|
||||||
|
|
||||||
def find_saplings(self):
|
|
||||||
w = self.g.world
|
|
||||||
|
|
||||||
saplings = w.find_objects(items.SAPLING_IDS)
|
|
||||||
|
|
||||||
if not saplings:
|
|
||||||
print('No saplings objects found, aborting')
|
|
||||||
self.state = self.cleanup
|
|
||||||
return
|
|
||||||
|
|
||||||
random.shuffle(saplings)
|
|
||||||
|
|
||||||
for s in saplings:
|
|
||||||
p = utils.pint(self.g.pos)
|
|
||||||
s_pos = utils.pint((s.x, s.y, s.z))
|
|
||||||
|
|
||||||
check = utils.padd(s_pos, path.BLOCK_BELOW)
|
|
||||||
|
|
||||||
if s.entity_id in self.eid_blacklist:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# slip if the sapling is floating
|
|
||||||
if self.g.chunks.get_block_at(*check) in blocks.LEAF_IDS | {0}:
|
|
||||||
continue
|
|
||||||
|
|
||||||
navpath = w.path_to_place(p, s_pos)
|
|
||||||
|
|
||||||
if navpath:
|
|
||||||
self.g.path = navpath
|
|
||||||
self.state = self.going_to_sapling
|
|
||||||
self.sapling = s_pos
|
|
||||||
self.eid_blacklist.append(s.entity_id)
|
|
||||||
print('Going to sapling', self.sapling)
|
|
||||||
return
|
|
||||||
|
|
||||||
print('Cant get to any saplings, aborting')
|
|
||||||
self.state = self.cleanup
|
|
||||||
|
|
||||||
def going_to_sapling(self):
|
|
||||||
if utils.pint(self.g.pos) == self.sapling:
|
|
||||||
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.sapling = None
|
|
||||||
self.eid_blacklist = []
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self.state()
|
|
||||||
|
|
||||||
|
|
||||||
class JobStates:
|
class JobStates:
|
||||||
def idle(self):
|
def idle(self):
|
||||||
return None
|
return None
|
||||||
|
@ -838,8 +651,8 @@ class JobStates:
|
||||||
|
|
||||||
s1.run()
|
s1.run()
|
||||||
|
|
||||||
def gather_wood(self):
|
def lumberjack(self):
|
||||||
s1 = self.gather_wood_states
|
s1 = self.lumberjack_states
|
||||||
s2 = self.sleep_with_bed_states
|
s2 = self.sleep_with_bed_states
|
||||||
s3 = self.cache_items_states
|
s3 = self.cache_items_states
|
||||||
|
|
||||||
|
@ -863,55 +676,12 @@ 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
|
|
||||||
s5 = self.grab_sapling_states
|
|
||||||
|
|
||||||
if s1.state == s1.idle:
|
|
||||||
s1.state = s1.init
|
|
||||||
s2.state = s2.init
|
|
||||||
s3.state = s3.init
|
|
||||||
s4.state = s4.init
|
|
||||||
s5.state = s5.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
|
|
||||||
|
|
||||||
if s5.state != s5.done:
|
|
||||||
s5.run()
|
|
||||||
return
|
|
||||||
|
|
||||||
s1.state = s1.init
|
|
||||||
s2.state = s2.init
|
|
||||||
s3.state = s3.init
|
|
||||||
s4.state = s4.init
|
|
||||||
s5.state = s5.init
|
|
||||||
return
|
|
||||||
|
|
||||||
s1.run()
|
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.gather_wood_states = GatherWoodStates(self.g)
|
self.lumberjack_states = LumberjackStates(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.grab_sapling_states = GrabSaplingStates(self.g)
|
|
||||||
self.state = self.idle
|
self.state = self.idle
|
||||||
|
|
||||||
def __init__(self, global_state):
|
def __init__(self, global_state):
|
||||||
|
@ -919,13 +689,11 @@ class JobStates:
|
||||||
|
|
||||||
self.state = self.idle
|
self.state = self.idle
|
||||||
self.prev_state = None
|
self.prev_state = None
|
||||||
self.gather_wood_states = GatherWoodStates(self.g)
|
self.lumberjack_states = LumberjackStates(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.grab_sapling_states = GrabSaplingStates(self.g)
|
|
||||||
|
|
||||||
def tick(self):
|
def tick(self):
|
||||||
self.state()
|
self.state()
|
||||||
|
|
5
main.py
5
main.py
|
@ -7,19 +7,18 @@ import json
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
from munch import Munch
|
from bunch import Bunch
|
||||||
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 = Munch()
|
global_state = Bunch()
|
||||||
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
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ def get_packets(old_get_packets):
|
||||||
mc_packets.add(packets.AcknowledgePlayerDiggingPacket)
|
mc_packets.add(packets.AcknowledgePlayerDiggingPacket)
|
||||||
mc_packets.add(packets.BlockBreakAnimationPacket)
|
mc_packets.add(packets.BlockBreakAnimationPacket)
|
||||||
mc_packets.add(packets.SetSlotPacket)
|
mc_packets.add(packets.SetSlotPacket)
|
||||||
|
mc_packets.add(packets.TimeUpdatePacket)
|
||||||
mc_packets.add(packets.PlayerDiggingPacket)
|
mc_packets.add(packets.PlayerDiggingPacket)
|
||||||
mc_packets.add(packets.PickItemPacket)
|
mc_packets.add(packets.PickItemPacket)
|
||||||
mc_packets.add(packets.HeldItemChangePacket)
|
mc_packets.add(packets.HeldItemChangePacket)
|
||||||
|
@ -21,8 +22,8 @@ def get_packets(old_get_packets):
|
||||||
mc_packets.add(packets.ServerWindowConfirmationPacket)
|
mc_packets.add(packets.ServerWindowConfirmationPacket)
|
||||||
mc_packets.add(packets.EntityMetadataPacket)
|
mc_packets.add(packets.EntityMetadataPacket)
|
||||||
mc_packets.add(packets.SpawnLivingEntityPacket)
|
mc_packets.add(packets.SpawnLivingEntityPacket)
|
||||||
|
mc_packets.add(packets.EntityPositionPacket)
|
||||||
mc_packets.add(packets.EntityPositionRotationPacket)
|
mc_packets.add(packets.EntityPositionRotationPacket)
|
||||||
mc_packets.add(packets.DestroyEntitiesPacket)
|
|
||||||
|
|
||||||
return mc_packets
|
return mc_packets
|
||||||
return lambda x: wrapper(old_get_packets, x)
|
return lambda x: wrapper(old_get_packets, x)
|
||||||
|
|
|
@ -174,6 +174,15 @@ class SetSlotPacket(Packet):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class TimeUpdatePacket(Packet):
|
||||||
|
id = 0x4E
|
||||||
|
packet_name = 'time update'
|
||||||
|
definition = [
|
||||||
|
{'world_age': Long},
|
||||||
|
{'time_of_day': Long},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class PlayerDiggingPacket(Packet):
|
class PlayerDiggingPacket(Packet):
|
||||||
# used when player mines / breaks blocks
|
# used when player mines / breaks blocks
|
||||||
# https://wiki.vg/Protocol#Player_Digging
|
# https://wiki.vg/Protocol#Player_Digging
|
||||||
|
@ -325,9 +334,24 @@ class SpawnLivingEntityPacket(Packet):
|
||||||
{'yaw': Angle},
|
{'yaw': Angle},
|
||||||
{'pitch': Angle},
|
{'pitch': Angle},
|
||||||
{'head_pitch': Angle},
|
{'head_pitch': Angle},
|
||||||
{'velocity_x': Short},
|
{'x_velocity': Short},
|
||||||
{'velocity_y': Short},
|
{'y_velocity': Short},
|
||||||
{'velocity_z': Short},
|
{'z_velocity': Short},
|
||||||
|
]
|
||||||
|
|
||||||
|
class EntityPositionPacket(Packet):
|
||||||
|
# Sent by the server when an entity moves less then 8 blocks
|
||||||
|
# https://wiki.vg/Protocol#Spawn_Entity
|
||||||
|
|
||||||
|
id = 0x27
|
||||||
|
packet_name = 'entity position'
|
||||||
|
|
||||||
|
definition = [
|
||||||
|
{'entity_id': VarInt},
|
||||||
|
{'delta_x': Short},
|
||||||
|
{'delta_y': Short},
|
||||||
|
{'delta_z': Short},
|
||||||
|
{'on_ground': Boolean},
|
||||||
]
|
]
|
||||||
|
|
||||||
class EntityPositionRotationPacket(Packet):
|
class EntityPositionRotationPacket(Packet):
|
||||||
|
@ -346,18 +370,3 @@ 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)
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user