Compare commits

..

No commits in common. "b8952db7420f84ed167788916a6fe2a672770907" and "6ba9288fd71b512d95b498de1167447a90e7a9eb" have entirely different histories.

8 changed files with 317 additions and 550 deletions

View File

@ -16,13 +16,10 @@ for name, data in JSON_BLOCKS.items():
for state in data['states']: for state in data['states']:
BLOCKS[state['id']] = name.replace('minecraft:', '') BLOCKS[state['id']] = name.replace('minecraft:', '')
BREAK_DISTANCE = 6
AIR = 0 AIR = 0
SAND = 66 SAND = 66
SINGLE_SNOW = 3921 SINGLE_SNOW = 3921
SOUL_TORCH = 4008 SOUL_TORCH = 4008
EMERALD_BLOCK = 5407
TEST_BLOCK = (616, 78, 496) TEST_BLOCK = (616, 78, 496)
@ -247,7 +244,6 @@ TRAPPED_CHESTS = [
INDEXED = [ INDEXED = [
'chest', 'chest',
'trapped_chest', 'trapped_chest',
'emerald_block',
] ]

2
bot.py
View File

@ -203,8 +203,6 @@ def init(global_state):
g.job = jobs.JobStates(g) g.job = jobs.JobStates(g)
g.chopped_tree = False g.chopped_tree = False
g.queue_afk = False
def bot(global_state): def bot(global_state):
g = global_state g = global_state

438
game.py
View File

@ -2,7 +2,6 @@ import re
import time import time
import importlib import importlib
import random import random
import functools
from math import hypot from math import hypot
from itertools import count from itertools import count
from munch import Munch from munch import Munch
@ -20,7 +19,6 @@ from protocol.packets import (
ClickWindowPacket, CloseWindowPacket, ServerWindowConfirmationPacket, ClickWindowPacket, CloseWindowPacket, ServerWindowConfirmationPacket,
ClientWindowConfirmationPacket, EntityMetadataPacket, ClientWindowConfirmationPacket, EntityMetadataPacket,
SpawnLivingEntityPacket, EntityPositionRotationPacket, DestroyEntitiesPacket, SpawnLivingEntityPacket, EntityPositionRotationPacket, DestroyEntitiesPacket,
EntityActionPacket,
) )
from protocol.types import Slot from protocol.types import Slot
@ -35,8 +33,6 @@ import items
importlib.reload(items) importlib.reload(items)
import data import data
importlib.reload(data) importlib.reload(data)
import mobs
importlib.reload(mobs)
class MCWorld: class MCWorld:
def __init__(self, global_state): def __init__(self, global_state):
@ -45,13 +41,6 @@ class MCWorld:
def block_at(self, x, y, z): def block_at(self, x, y, z):
return self.g.chunks.get_block_at(x, y, z) return self.g.chunks.get_block_at(x, y, z)
def check_air_column(self, pos, distance):
for i in range(distance):
check = utils.padd(pos, (0, i, 0))
if self.block_at(*check) not in blocks.NON_SOLID_IDS:
return False
return True
def find_blocks_3d(self, center, block_ids, distance=0, y_limit=0): def find_blocks_3d(self, center, block_ids, distance=0, y_limit=0):
for offset in utils.search_3d(distance, y_limit): for offset in utils.search_3d(distance, y_limit):
check = utils.padd(center, offset) check = utils.padd(center, offset)
@ -200,9 +189,10 @@ class MCWorld:
return safe_sand return safe_sand
def check_sand_slice(self, center): def check_sand_slice(self, center):
# checks if a 5x5x1 slice has sand in it # checks if a 5x5x1 slice has diggable sand in it
for i in range(9): for i in range(9):
s = utils.padd(center, utils.spiral(i)) s = utils.padd(center, utils.spiral(i))
if self.block_at(*s) != blocks.SAND: if self.block_at(*s) != blocks.SAND:
continue continue
# make sure it has solid below # make sure it has solid below
@ -216,17 +206,18 @@ class MCWorld:
continue continue
if not self.sand_adjacent_safe(s): if not self.sand_adjacent_safe(s):
continue continue
return True return True
return False return False
def find_sand_slice(self, center, distance, y_limit=0, bad_slices=[], prev_layer=0): def find_sand_slice(self, center, distance, bad_slices=[]):
# returns the centre coord of the next 5x5x1 slice that still has # returns the centre coord of the next 5x5x1 slice that still has
# diggable sand in it. lower slices are only valid if there's an # diggable sand in it. lower slices are only valid if there's an
# adjacent slice farther at the same level. this should ensure an # adjacent slice farther at the same level. this should ensure an
# upside down pyramid gets excavated so the edges are still climbable # upside down pyramid gets excavated so the edges are still climbable
for v in count(prev_layer): for v in count():
peak = utils.padd(center, (0, 10-v, 0)) peak = utils.padd(center, (0, 20-v, 0))
slices = [] slices = []
layer = 0 layer = 0
@ -237,16 +228,14 @@ class MCWorld:
check = utils.padd(peak, offset) check = utils.padd(peak, offset)
check = utils.padd(check, (0, layer, 0)) check = utils.padd(check, (0, layer, 0))
if y_limit and check[1] - center[1] > y_limit: if utils.phyp(center, check) >= distance:
break
if utils.phyp_king(center, check) > distance:
break break
if self.check_sand_slice(check) and check not in bad_slices: if self.check_sand_slice(check) and check not in bad_slices:
slices.append(check) slices.append(check)
if len(slices): if len(slices):
return v, slices[-1] return slices[-1]
elif v > 40: elif v > 40:
return None, None return None, None
@ -273,31 +262,6 @@ class MCWorld:
for a in self.find_blocks_3d(center, blocks.LEAF_IDS, distance, 10): for a in self.find_blocks_3d(center, blocks.LEAF_IDS, distance, 10):
yield a yield a
def find_monsters(self, center, distance):
# finds monsters within distance
result = []
for eid, mob in self.g.mobs.items():
if mob.type not in mobs.EVIL_IDS:
continue
pos = utils.pint((mob.x, mob.y, mob.z))
if utils.phyp(center, pos) > distance:
continue
result.append(mob)
return result
def find_threats(self, center, distance):
# finds monsters on the surface within distance
monsters = self.find_monsters(center, distance)
result = []
for mob in monsters:
pos = utils.pint((mob.x, mob.y, mob.z))
# check distance number of blocks above, close enough?
if not self.check_air_column(pos, distance):
continue
result.append(mob)
return result
class Game: class Game:
def __init__(self, global_state): def __init__(self, global_state):
@ -342,7 +306,7 @@ class Game:
if solution: if solution:
solution = list(solution) solution = list(solution)
self.g.path = solution self.g.path = solution
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')
@ -386,11 +350,6 @@ class Game:
self.g.command_lock = False self.g.command_lock = False
return return
if text == 'You are now AFK.':
self.g.afk = True
elif text == 'You are no longer AFK.':
self.g.afk = False
match1 = re.match(r'<(\w+)> (.*)', text) match1 = re.match(r'<(\w+)> (.*)', text)
match2 = re.match(r'\[(\w+) -> me] (.*)', text) match2 = re.match(r'\[(\w+) -> me] (.*)', text)
if match1: if match1:
@ -401,9 +360,6 @@ class Game:
else: else:
return return
if text.startswith('zzz'):
text = '!zzz'
if text.startswith('! '): if text.startswith('! '):
text = text[2:] text = text[2:]
elif text.startswith('!'): elif text.startswith('!'):
@ -418,205 +374,153 @@ class Game:
command = text command = text
data = None data = None
try: if command == 'ping':
if command == 'ping': reply = 'pong'
reply = 'pong'
if command == 'echo' and data: if command == 'echo' and data:
reply = data reply = data
if command == 'respawn': if command == 'respawn':
packet = serverbound.play.ClientStatusPacket() packet = serverbound.play.ClientStatusPacket()
packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN
self.g.connection.write_packet(packet) self.g.connection.write_packet(packet)
reply = 'ok'
if command == 'pos':
reply = str(utils.pint(self.g.pos))[1:-1]
if command == 'afk':
reply = '/afk'
if command == 'error':
reply = 'ok'
raise
if command == 'break':
self.break_block(blocks.TEST_BLOCK)
reply = 'ok'
if command == 'gather' and data:
if data == 'wood':
self.g.job.state = self.g.job.gather_wood
reply = 'ok'
elif data == 'sand':
self.g.job.state = self.g.job.gather_sand
reply = 'ok' reply = 'ok'
if command == 'pos': if reply:
reply = str(utils.pint(self.g.pos))[1:-1]
if command == 'afk':
reply = '/afk'
if command == 'error':
reply = 'ok'
raise
if command == 'break':
self.break_block(blocks.TEST_BLOCK)
reply = 'ok'
if command == 'gather' and data:
if data == 'wood':
self.g.job.state = self.g.job.gather_wood
reply = 'ok'
elif data == 'sand':
self.g.job.state = self.g.job.gather_sand
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 == 'farm' and data:
if data == 'wood':
self.g.job.state = self.g.job.farm_wood
reply = 'ok'
elif data == 'sand':
self.g.job.state = self.g.job.farm_sand
reply = 'ok'
if reply:
for i in self.g.inv.values():
if i.item_id in items.BED_IDS:
break
else:
reply += ', I need a bed'
if command == 'stop':
self.g.job.stop()
self.g.path = []
self.g.look_at = None
reply = 'ok'
if command == 'inv':
inv_list = []
for i in self.g.inv.values(): for i in self.g.inv.values():
if i.present: print(i.item_id)
inv_list.append('{}:{} x {}'.format(items.ITEM_NAMES[i.item_id], str(i.item_id), i.item_count)) if i.item_id in items.BED_IDS:
inv_list.sort() break
result = '\n'.join(inv_list)
print(result or 'Empty')
if command == 'drop':
self.drop_stack()
if command == 'time':
reply = str(self.g.time)
if command == 'select' and data:
item = int(data)
if self.select_item([item]):
reply = 'ok'
else: else:
reply = 'not found' reply += ', I need a bed'
if command == 'dump' and data: if command == 'farm' and data:
item = int(data) if data == 'wood':
if self.count_items([item]): self.g.job.state = self.g.job.farm_wood
self.g.dumping = item
reply = 'ok'
else:
reply = 'not found'
if command == 'count' and data:
item = int(data)
reply = str(self.count_items([item]))
if command == 'open':
self.open_container(blocks.TEST_BLOCK)
if command == 'close':
if self.g.window:
self.close_window()
else:
reply = 'nothing open'
if command == 'click' and data:
if self.g.window:
slot, button, mode = [int(x) for x in data.split(' ')]
try:
item = self.g.window.contents[slot]
except KeyError:
item = Slot(present=False, item_id=None, item_count=None, nbt=None)
print(item)
self.click_window(slot, button, mode, item)
else:
reply = 'nothing open'
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' reply = 'ok'
if command == 'objects': if reply:
if data == 'clear': for i in self.g.inv.values():
self.g.objects = {} print(i.item_id)
reply = 'ok' if i.item_id in items.BED_IDS:
break
else: else:
for k, v in self.g.objects.items(): reply += ', I need a bed'
if data and v.item_id != int(data): continue
print(str(k) + ':', v, items.ITEM_NAMES[v.item_id])
if command == 'mobs': if command == 'stop':
if data == 'clear': self.g.job.state = self.g.job.stop
self.g.mobs = {} self.g.path = []
reply = 'ok' reply = 'ok'
else:
all_mobs = sorted(list(self.g.mobs.items()), key=lambda x: x[1].type)
for k, v in all_mobs:
if data and v.type != int(data): continue
print(str(k) + ':', v, mobs.MOB_NAMES[v.type])
reply = str(len(all_mobs)) + ' mobs'
if command == 'monsters': if command == 'inv':
monsters = sorted(list(self.g.mobs.items()), key=lambda x: x[1].type) inv_list = []
count = 0 for i in self.g.inv.values():
for k, v in monsters: if i.present:
if v.type not in mobs.EVIL_IDS: continue inv_list.append('{}:{} x {}'.format(items.ITEM_NAMES[i.item_id], str(i.item_id), i.item_count))
if data and v.type != int(data): continue inv_list.sort()
count += 1 result = '\n'.join(inv_list)
print(str(k) + ':', v, mobs.MOB_NAMES[v.type]) print(result or 'Empty')
reply = str(count) + ' monsters'
if command == 'threats': if command == 'drop':
distance = int(data) if data else 20 self.drop_stack()
p = utils.pint(self.g.pos)
threats = self.g.world.find_threats(p, distance)
for t in threats: if command == 'time':
print(str(t.entity_id) + ':', t, mobs.MOB_NAMES[t.type]) reply = str(self.g.time)
reply = str(len(threats)) + ' threats'
if command == 'cache': if command == 'select' and data:
self.g.job.state = self.g.job.cache_items item = int(data)
self.g.job.cache_items_states.minimum = 0 if self.select_item([item]):
self.g.job.cache_items_states.silent = True
reply = 'ok' reply = 'ok'
else:
reply = 'not found'
if command == 'spiral' and data: if command == 'dump' and data:
for i in range(int(data)): item = int(data)
print(utils.spiral(i)) if self.count_items([item]):
self.g.dumping = item
reply = 'ok'
else:
reply = 'not found'
if command == 'sand_slice': if command == 'count' and data:
item = int(data)
reply = str(self.count_items([item]))
if command == 'open':
self.open_container(blocks.TEST_BLOCK)
if command == 'close':
if self.g.window:
self.close_window()
else:
reply = 'nothing open'
if command == 'click' and data:
if self.g.window:
slot, button, mode = [int(x) for x in data.split(' ')]
try:
item = self.g.window.contents[slot]
except KeyError:
item = Slot(present=False, item_id=None, item_count=None, nbt=None)
print(item)
self.click_window(slot, button, mode, item)
else:
reply = 'nothing open'
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 command == 'objects':
for k, v in self.g.objects.items():
if data and v.item_id != int(data): continue
print(str(k) + ':', v)
if command == 'cache':
self.g.job.state = self.g.job.cache_items
self.g.job.cache_items_states.minimum = 0
self.g.job.cache_items_states.silent = True
reply = 'ok'
if command == 'spiral' and data:
for i in range(int(data)):
print(utils.spiral(i))
if command == 'sand_slice':
try:
result = self.g.world.find_sand_slice(utils.pint(self.g.pos), 50) result = self.g.world.find_sand_slice(utils.pint(self.g.pos), 50)
reply = str(result) reply = str(result)
except:
if command == 'zzz': import traceback
if not self.g.afk: print(traceback.format_exc())
if self.g.path: reply = 'error'
travel_time = int(len(self.g.path) * 0.4) + 2
reply = 'give me ' + str(travel_time) + ' secs, moving'
self.g.queue_afk = True
else:
reply = '/afk'
if command == 'print' and sender == 'tanner6':
data = data.replace('^', '.')
reply = str(eval(data))
except BaseException as e:
import traceback
print(traceback.format_exc())
reply = 'Error: {} - {}\n'.format(e.__class__.__name__, e)
pass
if reply: if reply:
print(reply) print(reply)
@ -641,23 +545,16 @@ class Game:
g.item_lock = False g.item_lock = False
def break_block(self, location): def break_block(self, location):
p = utils.pint(self.g.pos)
#if utils.phyp(p, location) > blocks.BREAK_DISTANCE + 1:
# return False
bid = self.g.chunks.get_block_at(*location) bid = self.g.chunks.get_block_at(*location)
if bid == 0: if bid != 0:
return False packet = PlayerDiggingPacket()
packet.status = 0
packet.location = location
packet.face = 1
self.g.connection.write_packet(packet)
packet = PlayerDiggingPacket() self.g.breaking = location
packet.status = 0 self.g.break_time = time.time() + utils.break_time(bid, self.g.holding)
packet.location = location
packet.face = 1
self.g.connection.write_packet(packet)
self.g.breaking = location
self.g.break_time = time.time() + utils.break_time(bid, self.g.holding)
return True
def break_finish(self): def break_finish(self):
packet = PlayerDiggingPacket() packet = PlayerDiggingPacket()
@ -671,7 +568,6 @@ class Game:
self.g.breaking = None self.g.breaking = None
def handle_break_animation(self, packet): def handle_break_animation(self, packet):
return
print(packet) print(packet)
def handle_break_ack(self, packet): def handle_break_ack(self, packet):
@ -837,28 +733,22 @@ class Game:
obj.item_count = entry.value.item_count obj.item_count = entry.value.item_count
def handle_spawn_living(self, packet): def handle_spawn_living(self, packet):
self.g.mobs[packet.entity_id] = Munch( return
entity_id=packet.entity_id, print(packet)
entity_uuid=packet.entity_uuid,
type=packet.type,
x=packet.x,
y=packet.y,
z=packet.z,
)
def handle_entity_position(self, packet): def handle_entity_position(self, packet):
mob = self.g.mobs.get(packet.entity_id, None) obj = self.g.objects.get(packet.entity_id, None)
if mob: if obj:
mob.x += packet.delta_x / 4096.0 pass
mob.y += packet.delta_y / 4096.0 #obj.x += packet.delta_x
mob.z += packet.delta_z / 4096.0 #obj.y += packet.delta_y
#obj.z += packet.delta_z
def handle_entity_position_rotation(self, packet): def handle_entity_position_rotation(self, packet):
mob = self.g.mobs.get(packet.entity_id, None) obj = self.g.objects.get(packet.entity_id, None)
if mob: if obj:
mob.x += packet.delta_x / 4096.0 print('object rotation found:', packet)
mob.y += packet.delta_y / 4096.0 raise
mob.z += packet.delta_z / 4096.0
def handle_entity_velocity(self, packet): def handle_entity_velocity(self, packet):
obj = self.g.objects.get(packet.entity_id, None) obj = self.g.objects.get(packet.entity_id, None)
@ -872,16 +762,6 @@ class Game:
for eid in packet.entity_ids: for eid in packet.entity_ids:
if eid in self.g.objects: if eid in self.g.objects:
del self.g.objects[eid] del self.g.objects[eid]
if eid in self.g.mobs:
del self.g.mobs[eid]
def leave_bed(self):
packet = EntityActionPacket()
packet.entity_id = self.g.eid
packet.action_id = 2
packet.jump_boost = 0
self.g.connection.write_packet(packet)
def tick(self): def tick(self):
if self.g.breaking: if self.g.breaking:
@ -897,10 +777,6 @@ class Game:
else: else:
self.g.dumping = None self.g.dumping = None
if not self.g.path: if not len(self.g.path):
self.g.correction_count = 0 self.g.correction_count = 0
if self.g.queue_afk:
self.g.chat.send('/afk')
self.g.queue_afk = False

357
jobs.py
View File

@ -20,8 +20,8 @@ import items
importlib.reload(items) importlib.reload(items)
import data import data
importlib.reload(data) importlib.reload(data)
import mobs
importlib.reload(mobs) BREAK_DISTANCE = 5
class FindGappleStates: class FindGappleStates:
@ -310,13 +310,12 @@ class GatherSandStates:
w = self.g.world w = self.g.world
print('using origin', self.origin) print('using origin', self.origin)
start = time.time() s = w.find_sand_slice(self.origin, 50, self.bad_slices)
self.prev_layer, s = w.find_sand_slice(self.origin, 200, 10, self.bad_slices, self.prev_layer) print('Found slice:', s)
print('Found slice:', s, 'in', time.time() - start, 'seconds')
if s: if s:
self.slice = s self.slice = s
self.bad_slices.append(s) #self.bad_slices.append(s)
self.state = self.find_new_sand self.state = self.find_new_sand
else: else:
print('No slices remaining.') print('No slices remaining.')
@ -326,23 +325,24 @@ class GatherSandStates:
print('Finding new sand...') print('Finding new sand...')
w = self.g.world w = self.g.world
p = utils.pint(self.g.pos) p = utils.pint(self.g.pos)
head = utils.padd(p, path.BLOCK_ABOVE)
for sand in w.find_sand(self.slice, 2, p): sand = w.find_sand(self.slice, 2, p)
if sand not in self.bad_sand: print('Found sand:', sand)
print('Found sand:', sand)
break if not len(sand):
else: # for
print('No good sands left, aborting.')
self.state = self.cleanup self.state = self.cleanup
return return
self.sand = sand for check in sand:
if check in self.bad_sand:
continue
self.sand = check
break
if utils.phyp(head, self.sand) < blocks.BREAK_DISTANCE: if utils.phyp(p, self.sand) > BREAK_DISTANCE:
self.state = self.dig_sand
else:
self.state = self.nav_to_sand self.state = self.nav_to_sand
else:
self.state = self.dig_sand
def nav_to_sand(self): def nav_to_sand(self):
w = self.g.world w = self.g.world
@ -358,7 +358,6 @@ class GatherSandStates:
self.g.path = navpath[:-1] self.g.path = navpath[:-1]
self.state = self.going_to_sand self.state = self.going_to_sand
else: else:
print('Cant get to that sand')
self.bad_sand.append(self.sand) self.bad_sand.append(self.sand)
self.state = self.find_new_sand self.state = self.find_new_sand
@ -390,10 +389,8 @@ class GatherSandStates:
self.state = self.idle self.state = self.idle
self.origin = utils.pint(self.g.pos) self.origin = utils.pint(self.g.pos)
self.origin = (2019, 64, 238)
self.slice = None self.slice = None
self.bad_slices = [] self.bad_slices = []
self.prev_layer = 0
self.sand = None self.sand = None
self.bad_sand = [] self.bad_sand = []
self.wait_time = 0 self.wait_time = 0
@ -524,7 +521,7 @@ class SleepWithBedStates:
def going_to_area(self): def going_to_area(self):
if utils.pint(self.g.pos) == self.opening: if utils.pint(self.g.pos) == self.opening:
self.g.look_at = utils.padd(self.area, path.BLOCK_BELOW) self.g.look_at = self.area
self.state = self.place_bed self.state = self.place_bed
def place_bed(self): def place_bed(self):
@ -540,16 +537,8 @@ class SleepWithBedStates:
self.state = self.sleep_bed self.state = self.sleep_bed
def sleep_bed(self): def sleep_bed(self):
w = self.g.world if self.g.time < 100:
p = utils.pint(self.g.pos) print('Woke up')
threats = w.find_threats(p, 30)
if threats:
print('Waking up due to threats')
self.g.game.leave_bed()
self.state = self.break_bed
elif self.g.time < 100:
print('Woke up time')
self.state = self.break_bed self.state = self.break_bed
def break_bed(self): def break_bed(self):
@ -906,7 +895,7 @@ class ClearLeavesStates:
w = self.g.world w = self.g.world
p = utils.pint(self.g.pos) p = utils.pint(self.g.pos)
for l in w.find_leaves(p, blocks.BREAK_DISTANCE): for l in w.find_leaves(p, BREAK_DISTANCE):
self.leaves.append(l) self.leaves.append(l)
self.state = self.break_leaves self.state = self.break_leaves
@ -1017,101 +1006,137 @@ class GrabSaplingStates:
self.state() self.state()
class CheckThreatsStates:
def idle(self):
return None
def init(self):
self.state = self.find_threats
print('Checking for threats')
def find_threats(self):
w = self.g.world
p = utils.pint(self.g.pos)
threats = w.find_threats(p, 40)
if threats:
print('Found', len(threats), 'threats, fleeing')
self.state = self.find_safety
else:
print('Aborting, no threats')
self.state = self.cleanup
def find_safety(self):
w = self.g.world
p = utils.pint(self.g.pos)
safety = w.find_blocks_indexed(p, [blocks.EMERALD_BLOCK])
if not safety:
print('No emerald blocks found, aborting')
self.state = self.cleanup
return
safety.sort(key=lambda s: utils.phyp(p, s))
print('Found emerald blocks:', safety)
for s in safety:
s = utils.padd(s, path.BLOCK_ABOVE)
navpath = w.path_to_place(p, s)
if navpath:
self.g.path = navpath
self.state = self.going_to_safety
self.safety = s
print('Going to safety', self.safety)
return
else:
print('Cant get to safety', self.safety)
print('Cant get to safety, aborting')
self.state = self.cleanup
def going_to_safety(self):
if utils.pint(self.g.pos) == self.safety:
print('At safety spot, waiting to be moved')
self.state = self.wait_for_move
def wait_for_move(self):
# wait for the server to move the bot when it's safe
# ie. a piston + daylight sensor
if utils.pint(self.g.pos) != self.safety:
print('Moved, resuming job')
self.state = self.wait
self.wait_time = 3
def wait(self):
# wait to land, etc
if self.wait_time > 0:
self.wait_time -= utils.TICK
else:
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.safety = None
self.wait_time = 0
def run(self):
self.state()
class JobStates: class JobStates:
def idle(self): def idle(self):
return [] return None
def init_machines(self): def cache_items(self):
s1 = self.cache_items_states
if s1.state == s1.idle:
s1.state = s1.init
elif s1.state == s1.done:
self.state = self.idle
s1.run()
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.tp_to_coord
s1.run()
def gather_sand(self):
s1 = self.gather_sand_states
s2 = self.grab_sand_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 gather_wood(self):
s1 = self.gather_wood_states
s2 = self.sleep_with_bed_states
s3 = self.cache_items_states
if s1.state == s1.idle:
s1.state = s1.init
s2.state = s2.init
s3.state = s3.init
elif s1.state == s1.done:
if s2.state != s2.done:
s2.run()
return
if s3.state != s3.done:
s3.run()
return
s1.state = s1.init
s2.state = s2.init
s3.state = s3.init
return
s1.run()
def farm_wood(self):
self.sleep_with_bed_states.silent = True
self.cache_items_states.silent = True
s1 = self.gather_wood_states
s2 = self.plant_tree_states
s3 = self.clear_leaves_states
s4 = self.grab_sapling_states
s5 = self.sleep_with_bed_states
s6 = 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
s5.state = s5.init
s6.state = s6.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
if s6.state != s6.done:
s6.run()
return
s1.state = s1.init
s2.state = s2.init
s3.state = s3.init
s4.state = s4.init
s5.state = s5.init
s6.state = s6.init
return
s1.run()
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)
@ -1121,84 +1146,22 @@ class JobStates:
self.clear_leaves_states = ClearLeavesStates(self.g) self.clear_leaves_states = ClearLeavesStates(self.g)
self.grab_sapling_states = GrabSaplingStates(self.g) self.grab_sapling_states = GrabSaplingStates(self.g)
self.grab_sand_states = GrabSandStates(self.g) self.grab_sand_states = GrabSandStates(self.g)
self.check_threats_states = CheckThreatsStates(self.g)
def run_machines(self, machines):
for m in machines:
if m.state == m.idle:
continue
if m.state != m.done:
m.run()
return
# if we went through them all
for m in machines:
m.state = m.init
def gather_sand(self):
machines = [
self.gather_sand_states,
self.grab_sand_states,
self.cache_items_states,
self.sleep_with_bed_states,
]
return machines
def farm_sand(self):
machines = [
self.check_threats_states,
self.gather_sand_states,
self.grab_sand_states,
self.cache_items_states,
self.sleep_with_bed_states,
]
self.sleep_with_bed_states.silent = True
self.cache_items_states.silent = True
return machines
def cache_items(self):
machines = [
self.cache_items_states,
]
return machines
def find_gapple(self):
machines = [
self.find_gapple_states,
]
return machines
def gather_wood(self):
machines = [
self.gather_wood_states,
self.sleep_with_bed_states,
self.cache_items_states,
]
return machines
def farm_wood(self):
machines = [
self.gather_wood_states,
self.plant_tree_states,
self.clear_leaves_states,
self.grab_sapling_states,
self.sleep_with_bed_states,
self.cache_items_states,
]
self.sleep_with_bed_states.silent = True
self.cache_items_states.silent = True
return machines
def stop(self):
self.init_machines()
self.state = self.idle self.state = self.idle
def __init__(self, global_state): def __init__(self, global_state):
self.g = global_state self.g = global_state
self.init_machines()
self.state = self.idle self.state = self.idle
self.prev_state = None
self.gather_wood_states = GatherWoodStates(self.g)
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.plant_tree_states = PlantTreeStates(self.g)
self.clear_leaves_states = ClearLeavesStates(self.g)
self.grab_sapling_states = GrabSaplingStates(self.g)
self.grab_sand_states = GrabSandStates(self.g)
def tick(self): def tick(self):
self.run_machines(self.state()) self.state()

View File

@ -20,12 +20,10 @@ g.mcdata = False
g.pos = False g.pos = False
g.inv = {} g.inv = {}
g.objects = {} g.objects = {}
g.mobs = {}
g.window = None g.window = None
g.job = None g.job = None
g.correction_count = 0 g.correction_count = 0
g.holding = 0 g.holding = 0
g.afk = False
@app.route('/') @app.route('/')
def hello_world(): def hello_world():

50
mobs.py
View File

@ -1,50 +0,0 @@
import json
with open('mcdata/registries.json') as f:
MOBS = json.load(f)['minecraft:entity_type']['entries']
EVIL = [
'blaze',
'cave_spider',
'creeper',
'drowned',
'elder_guardian',
'ender_dragon',
'enderman',
'endermite',
'evoker',
'ghast',
'giant',
'guardian',
'hoglin',
'husk',
'illusioner',
'magma_cube',
'phantom',
'piglin',
'piglin_brute',
'pillager',
'ravager',
'shulker',
'silverfish',
'skeleton',
'skeleton_horse',
'slime',
'spider',
'stray',
'vex',
'vindicator',
'witch',
'wither',
'zoglin',
'zombie',
'zombie_villager',
]
EVIL_IDS = set()
for mob_name in EVIL:
EVIL_IDS.add(MOBS['minecraft:'+mob_name]['protocol_id'])
MOB_NAMES = {}
for mob_name, mob in MOBS.items():
MOB_NAMES[MOBS[mob_name]['protocol_id']] = mob_name.replace('minecraft:', '')

View File

@ -23,7 +23,6 @@ def get_packets(old_get_packets):
mc_packets.add(packets.SpawnLivingEntityPacket) mc_packets.add(packets.SpawnLivingEntityPacket)
mc_packets.add(packets.EntityPositionRotationPacket) mc_packets.add(packets.EntityPositionRotationPacket)
mc_packets.add(packets.DestroyEntitiesPacket) mc_packets.add(packets.DestroyEntitiesPacket)
mc_packets.add(packets.EntityActionPacket)
return mc_packets return mc_packets
return lambda x: wrapper(old_get_packets, x) return lambda x: wrapper(old_get_packets, x)

View File

@ -361,16 +361,3 @@ class DestroyEntitiesPacket(Packet):
for _ in range(self.count): for _ in range(self.count):
eid = VarInt.read(file_object) eid = VarInt.read(file_object)
self.entity_ids.append(eid) self.entity_ids.append(eid)
class EntityActionPacket(Packet):
# Sent by the client when it performs an action
# https://wiki.vg/Protocol#Entity_Action
id = 0x1C
packet_name = 'entity action'
definition = [
{'entity_id': VarInt},
{'action_id': VarInt},
{'jump_boost': VarInt},
]