Add state machine for caching items into chests
This commit is contained in:
parent
b8cbd9a5f0
commit
f8d44e7e38
15
blocks.py
15
blocks.py
|
@ -1,11 +1,12 @@
|
||||||
import minecraft_data
|
|
||||||
import json
|
import json
|
||||||
|
import importlib
|
||||||
|
|
||||||
mcd = minecraft_data('1.16.2')
|
import data
|
||||||
|
importlib.reload(data)
|
||||||
|
|
||||||
MCD_BLOCKS = {}
|
MCD_BLOCKS = {}
|
||||||
for data in mcd.blocks.values():
|
for d in data.mcd.blocks.values():
|
||||||
MCD_BLOCKS[data['name']] = data
|
MCD_BLOCKS[d['name']] = d
|
||||||
|
|
||||||
with open('mcdata/blocks.json') as f:
|
with open('mcdata/blocks.json') as f:
|
||||||
JSON_BLOCKS = json.load(f)
|
JSON_BLOCKS = json.load(f)
|
||||||
|
@ -18,9 +19,11 @@ for name, data in JSON_BLOCKS.items():
|
||||||
AIR = 0
|
AIR = 0
|
||||||
SAND = 66
|
SAND = 66
|
||||||
SINGLE_SNOW = 3921
|
SINGLE_SNOW = 3921
|
||||||
SOUL_TORCH = 4008
|
#SOUL_TORCH = 4008
|
||||||
|
SOUL_TORCH = 1435
|
||||||
|
|
||||||
TEST_BLOCK = (616, 78, 496)
|
#TEST_BLOCK = (616, 78, 496)
|
||||||
|
TEST_BLOCK = (-100, 64, -167)
|
||||||
|
|
||||||
|
|
||||||
AVOID = [
|
AVOID = [
|
||||||
|
|
9
bot.py
9
bot.py
|
@ -10,6 +10,7 @@ from math import floor, ceil
|
||||||
USERNAME = os.environ['USERNAME']
|
USERNAME = os.environ['USERNAME']
|
||||||
PASSWORD = os.environ['PASSWORD']
|
PASSWORD = os.environ['PASSWORD']
|
||||||
SERVER = os.environ['SERVER']
|
SERVER = os.environ['SERVER']
|
||||||
|
PORT = int(os.environ.get('PORT', 25565))
|
||||||
|
|
||||||
import monkey_patch # must be before any possible pyCraft imports
|
import monkey_patch # must be before any possible pyCraft imports
|
||||||
|
|
||||||
|
@ -154,7 +155,9 @@ def init(global_state):
|
||||||
g.break_time = 0
|
g.break_time = 0
|
||||||
|
|
||||||
g.dumping = None
|
g.dumping = None
|
||||||
g.dump_lock = False
|
g.item_lock = False
|
||||||
|
|
||||||
|
g.window = None
|
||||||
|
|
||||||
g.job = jobs.JobStates(g)
|
g.job = jobs.JobStates(g)
|
||||||
|
|
||||||
|
@ -172,7 +175,7 @@ def bot(global_state):
|
||||||
print(e)
|
print(e)
|
||||||
sys.exit()
|
sys.exit()
|
||||||
print("Logged in as %s..." % auth_token.username)
|
print("Logged in as %s..." % auth_token.username)
|
||||||
g.connection = Connection(SERVER, 25565, auth_token=auth_token)
|
g.connection = Connection(SERVER, PORT, auth_token=auth_token)
|
||||||
|
|
||||||
g.chunks = ChunksManager(g.mcdata)
|
g.chunks = ChunksManager(g.mcdata)
|
||||||
|
|
||||||
|
@ -198,8 +201,6 @@ def bot(global_state):
|
||||||
init(g)
|
init(g)
|
||||||
print('Initialized.')
|
print('Initialized.')
|
||||||
|
|
||||||
print(blocks.mcd.windows)
|
|
||||||
|
|
||||||
while g.running:
|
while g.running:
|
||||||
tick(g)
|
tick(g)
|
||||||
|
|
||||||
|
|
26
data.py
Normal file
26
data.py
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import json
|
||||||
|
from bunch import Bunch
|
||||||
|
|
||||||
|
import minecraft_data
|
||||||
|
|
||||||
|
mcd = minecraft_data('1.16.2')
|
||||||
|
|
||||||
|
with open('mcdata/registries.json') as f:
|
||||||
|
DATA = json.load(f)
|
||||||
|
|
||||||
|
SINGLE_CHEST = 2
|
||||||
|
DOUBLE_CHEST = 5
|
||||||
|
|
||||||
|
WINDOWS = {
|
||||||
|
SINGLE_CHEST: Bunch(
|
||||||
|
container=list(range(0, 27)),
|
||||||
|
inventory=list(range(27, 63)),
|
||||||
|
slot_diff=18,
|
||||||
|
),
|
||||||
|
DOUBLE_CHEST: Bunch(
|
||||||
|
container=list(range(0, 54)),
|
||||||
|
inventory=list(range(54, 90)),
|
||||||
|
slot_diff=45,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
68
game.py
68
game.py
|
@ -3,13 +3,14 @@ import time
|
||||||
import importlib
|
import importlib
|
||||||
from math import hypot
|
from math import hypot
|
||||||
from itertools import count
|
from itertools import count
|
||||||
|
from bunch import Bunch
|
||||||
|
|
||||||
from panda3d.core import LPoint3f
|
from panda3d.core import LPoint3f
|
||||||
|
|
||||||
from minecraft.networking.packets import Packet, clientbound, serverbound
|
from minecraft.networking.packets import Packet, clientbound, serverbound
|
||||||
from minecraft.networking.types import BlockFace
|
from minecraft.networking.types import BlockFace
|
||||||
|
|
||||||
from protocol.packets import TimeUpdatePacket, SetSlotPacket, PlayerDiggingPacket, BlockBreakAnimationPacket, AcknowledgePlayerDiggingPacket, HeldItemChangePacket, PickItemPacket
|
from protocol.packets import TimeUpdatePacket, SetSlotPacket, PlayerDiggingPacket, BlockBreakAnimationPacket, AcknowledgePlayerDiggingPacket, HeldItemChangePacket, PickItemPacket, OpenWindowPacket, ClickWindowPacket, CloseWindowPacket
|
||||||
|
|
||||||
import utils
|
import utils
|
||||||
importlib.reload(utils)
|
importlib.reload(utils)
|
||||||
|
@ -19,6 +20,8 @@ import blocks
|
||||||
importlib.reload(blocks)
|
importlib.reload(blocks)
|
||||||
import items
|
import items
|
||||||
importlib.reload(items)
|
importlib.reload(items)
|
||||||
|
import data
|
||||||
|
importlib.reload(data)
|
||||||
|
|
||||||
class MCWorld:
|
class MCWorld:
|
||||||
def __init__(self, global_state):
|
def __init__(self, global_state):
|
||||||
|
@ -122,6 +125,9 @@ class MCWorld:
|
||||||
areas.sort(key=lambda x: utils.phyp(center, x))
|
areas.sort(key=lambda x: utils.phyp(center, x))
|
||||||
return areas
|
return areas
|
||||||
|
|
||||||
|
def find_cache_areas(self, center, distance):
|
||||||
|
return self.find_bed_areas(center, distance)
|
||||||
|
|
||||||
def sand_adjacent_safe(self, sand):
|
def sand_adjacent_safe(self, sand):
|
||||||
for direction in path.CHECK_DIRECTIONS:
|
for direction in path.CHECK_DIRECTIONS:
|
||||||
if self.block_at(*utils.padd(sand, direction)) in blocks.AVOID_IDS:
|
if self.block_at(*utils.padd(sand, direction)) in blocks.AVOID_IDS:
|
||||||
|
@ -163,6 +169,9 @@ class MCWorld:
|
||||||
result.append(utils.padd(area, direction))
|
result.append(utils.padd(area, direction))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def find_cache_openings(self, area):
|
||||||
|
return self.find_bed_openings(area)
|
||||||
|
|
||||||
|
|
||||||
class Game:
|
class Game:
|
||||||
def __init__(self, global_state):
|
def __init__(self, global_state):
|
||||||
|
@ -176,6 +185,7 @@ class Game:
|
||||||
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)
|
||||||
|
register(self.handle_window, OpenWindowPacket)
|
||||||
|
|
||||||
self.g.chat.set_handler(self.handle_chat)
|
self.g.chat.set_handler(self.handle_chat)
|
||||||
|
|
||||||
|
@ -314,7 +324,22 @@ class Game:
|
||||||
reply = 'not found'
|
reply = 'not found'
|
||||||
|
|
||||||
if command == 'open':
|
if command == 'open':
|
||||||
self.place_block(blocks.TEST_BLOCK, BlockFace.TOP)
|
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:
|
||||||
|
window_id, slot, button, mode = [int(x) for x in data.split(' ')]
|
||||||
|
item = self.g.window.contents[slot]
|
||||||
|
print(item)
|
||||||
|
self.click_window(window_id, slot, button, mode, item)
|
||||||
|
else:
|
||||||
|
reply = 'nothing open'
|
||||||
|
|
||||||
if reply:
|
if reply:
|
||||||
print(reply)
|
print(reply)
|
||||||
|
@ -324,12 +349,15 @@ class Game:
|
||||||
self.g.time = packet.time_of_day % 24000
|
self.g.time = packet.time_of_day % 24000
|
||||||
|
|
||||||
def handle_set_slot(self, packet):
|
def handle_set_slot(self, packet):
|
||||||
|
g = self.g
|
||||||
print(packet)
|
print(packet)
|
||||||
if packet.window_id == 0:
|
if packet.window_id == 0:
|
||||||
self.g.inv[packet.slot] = packet.slot_data
|
g.inv[packet.slot] = packet.slot_data
|
||||||
|
elif g.window:
|
||||||
|
g.window.contents[packet.slot] = packet.slot_data
|
||||||
|
|
||||||
if not packet.slot_data.present:
|
if not packet.slot_data.present:
|
||||||
self.g.dump_lock = False
|
g.item_lock = False
|
||||||
|
|
||||||
def break_block(self, location):
|
def break_block(self, location):
|
||||||
bid = self.g.chunks.get_block_at(*location)
|
bid = self.g.chunks.get_block_at(*location)
|
||||||
|
@ -416,6 +444,32 @@ class Game:
|
||||||
packet.face = 1
|
packet.face = 1
|
||||||
self.g.connection.write_packet(packet)
|
self.g.connection.write_packet(packet)
|
||||||
|
|
||||||
|
def open_container(self, location):
|
||||||
|
bid = self.g.chunks.get_block_at(*location)
|
||||||
|
# TODO: check if block is a chest??
|
||||||
|
self.place_block(location, BlockFace.TOP)
|
||||||
|
|
||||||
|
def handle_window(self, packet):
|
||||||
|
print(packet)
|
||||||
|
self.g.window = Bunch(data=packet, contents=dict())
|
||||||
|
|
||||||
|
def click_window(self, window_id, slot, button, mode, item):
|
||||||
|
packet = ClickWindowPacket()
|
||||||
|
packet.window_id = window_id
|
||||||
|
packet.slot = slot
|
||||||
|
packet.button = button
|
||||||
|
packet.action_number = 1
|
||||||
|
packet.mode = mode
|
||||||
|
packet.clicked_item = item
|
||||||
|
self.g.connection.write_packet(packet)
|
||||||
|
|
||||||
|
def close_window(self):
|
||||||
|
packet = CloseWindowPacket()
|
||||||
|
packet.window_id = self.g.window.data.window_id
|
||||||
|
self.g.connection.write_packet(packet)
|
||||||
|
self.g.window = None
|
||||||
|
|
||||||
|
|
||||||
def tick(self):
|
def tick(self):
|
||||||
if self.g.breaking:
|
if self.g.breaking:
|
||||||
self.animate()
|
self.animate()
|
||||||
|
@ -423,10 +477,10 @@ class Game:
|
||||||
if time.time() >= self.g.break_time - 2*utils.TICK:
|
if time.time() >= self.g.break_time - 2*utils.TICK:
|
||||||
self.break_finish()
|
self.break_finish()
|
||||||
|
|
||||||
if self.g.dumping and not self.g.dump_lock:
|
if self.g.dumping and not self.g.item_lock:
|
||||||
if self.select_item([self.g.dumping]):
|
if self.select_item([self.g.dumping]):
|
||||||
self.drop_stack()
|
self.drop_stack()
|
||||||
self.g.dump_lock = True
|
self.g.item_lock = True
|
||||||
else:
|
else:
|
||||||
self.g.dumping = None
|
self.g.dumping = None
|
||||||
|
|
||||||
|
|
4
items.py
4
items.py
|
@ -29,3 +29,7 @@ for item_name in BEDS:
|
||||||
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:', '')
|
||||||
|
|
||||||
|
CHEST_ID = set([ITEMS['minecraft:chest']['protocol_id']])
|
||||||
|
|
||||||
|
USEFUL_ITEMS = BED_IDS | CHEST_ID
|
||||||
|
|
179
jobs.py
179
jobs.py
|
@ -310,7 +310,7 @@ class SleepWithBedStates:
|
||||||
self.state = self.select_bed
|
self.state = self.select_bed
|
||||||
|
|
||||||
def select_bed(self):
|
def select_bed(self):
|
||||||
if self.game.select_item(items.BED_IDS):
|
if self.g.game.select_item(items.BED_IDS):
|
||||||
self.g.look_at = utils.padd(self.area, path.BLOCK_BELOW)
|
self.g.look_at = utils.padd(self.area, path.BLOCK_BELOW)
|
||||||
self.state = self.place_bed
|
self.state = self.place_bed
|
||||||
else:
|
else:
|
||||||
|
@ -372,32 +372,148 @@ class SleepWithBedStates:
|
||||||
self.state()
|
self.state()
|
||||||
|
|
||||||
|
|
||||||
class JobStates:
|
class CacheItemsStates:
|
||||||
def idle(self):
|
def idle(self):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def sleep_with_bed(self):
|
def init(self):
|
||||||
s = self.sleep_with_bed_states
|
#if len(self.g.inv) >= 27:
|
||||||
if s.state == s.idle:
|
if len(self.g.inv) >= 2:
|
||||||
s.state = s.init
|
self.state = self.find_chest_spot
|
||||||
elif s.state == s.done:
|
else:
|
||||||
s.state = s.init
|
print('Aborting caching, not full')
|
||||||
# check time, etc
|
self.state = self.cleanup
|
||||||
|
|
||||||
if self.prev_state:
|
def find_cache_spot(self):
|
||||||
print('Reverting to prev state')
|
print('Finding a chest spot...')
|
||||||
self.state = self.prev_state
|
w = self.g.world
|
||||||
return
|
p = utils.pint(self.g.pos)
|
||||||
|
|
||||||
s.run()
|
areas = w.find_cache_areas(p, 100)
|
||||||
|
print('Found areas:', areas)
|
||||||
|
|
||||||
|
if len(areas):
|
||||||
|
while areas[0] in self.bad_areas:
|
||||||
|
areas.pop(0)
|
||||||
|
self.area = areas[0]
|
||||||
|
elif self.last_area:
|
||||||
|
self.area = self.last_area
|
||||||
|
else:
|
||||||
|
print('Unable to find area, and no last area')
|
||||||
|
self.state = self.cleanup
|
||||||
|
return
|
||||||
|
|
||||||
|
openings = w.find_bed_openings(self.area)
|
||||||
|
|
||||||
|
for o in openings:
|
||||||
|
navpath = w.path_to_place(p, o)
|
||||||
|
self.opening = o
|
||||||
|
if navpath: break
|
||||||
|
else: # for
|
||||||
|
print('Unable to get to cache area', self.area)
|
||||||
|
self.bad_areas.append(self.area)
|
||||||
|
self.state = self.cleanup
|
||||||
|
return
|
||||||
|
|
||||||
|
self.g.path = navpath
|
||||||
|
self.state = self.going_to_area
|
||||||
|
self.last_area = self.area
|
||||||
|
|
||||||
|
def going_to_area(self):
|
||||||
|
if utils.pint(self.g.pos) == self.opening:
|
||||||
|
self.g.look_at = self.area
|
||||||
|
self.state = self.select_chest
|
||||||
|
|
||||||
|
def select_chest(self):
|
||||||
|
if self.g.game.select_item(items.CHEST_ID):
|
||||||
|
self.g.look_at = utils.padd(self.area, path.BLOCK_BELOW)
|
||||||
|
self.state = self.place_chest
|
||||||
|
else:
|
||||||
|
self.g.chat.send('I need a chest')
|
||||||
|
self.state = self.cleanup
|
||||||
|
|
||||||
|
def place_chest(self):
|
||||||
|
self.g.game.place_block(self.area, BlockFace.TOP)
|
||||||
|
self.state = self.open_chest
|
||||||
|
|
||||||
|
def open_chest(self):
|
||||||
|
print('Opening chest')
|
||||||
|
self.g.game.open_container(self.area)
|
||||||
|
self.wait_time = 1
|
||||||
|
self.state = self.wait
|
||||||
|
|
||||||
|
def wait(self):
|
||||||
|
# wait for server to send us chest contents
|
||||||
|
if self.wait_time > 0:
|
||||||
|
self.wait_time -= utils.TICK
|
||||||
|
else:
|
||||||
|
self.state = self.move_items
|
||||||
|
|
||||||
|
def move_items(self):
|
||||||
|
if self.g.item_lock: return
|
||||||
|
|
||||||
|
w = self.g.window
|
||||||
|
w_data = data.WINDOWS[w.window_type]
|
||||||
|
w_inventory_slots = w_data.inventory
|
||||||
|
|
||||||
|
for slot_num in w_inventory_slots:
|
||||||
|
if slot_num not in w.contents:
|
||||||
|
continue
|
||||||
|
|
||||||
|
slot = w.contents[slot_num]
|
||||||
|
|
||||||
|
if slot.item_id in items.USEFUL_ITEMS:
|
||||||
|
continue
|
||||||
|
|
||||||
|
print('moving', slot)
|
||||||
|
|
||||||
|
inv_slot_num = slot_num - w_data.slot_diff
|
||||||
|
self.g.inv.pop(inv_slot_num, None)
|
||||||
|
|
||||||
|
self.g.item_lock = True
|
||||||
|
self.g.game.click_window(w.window_id, slot_num, 0, 1, slot)
|
||||||
|
return
|
||||||
|
|
||||||
|
print('nothing left to move')
|
||||||
|
self.state = close_chest
|
||||||
|
|
||||||
|
def close_chest(self):
|
||||||
|
print('closing chest')
|
||||||
|
self.g.game.close_window()
|
||||||
|
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.area = None
|
||||||
|
self.opening = None
|
||||||
|
self.bad_areas = []
|
||||||
|
self.last_area = None
|
||||||
|
self.wait_time = 0
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.state()
|
||||||
|
|
||||||
|
|
||||||
|
class JobStates:
|
||||||
|
def idle(self):
|
||||||
|
return None
|
||||||
|
|
||||||
def gather_sand(self):
|
def gather_sand(self):
|
||||||
s = self.gather_sand_states
|
s = self.gather_sand_states
|
||||||
if s.state == s.idle:
|
if s.state == s.idle:
|
||||||
s.state = s.init
|
s.state = s.init
|
||||||
elif s.state == s.done:
|
elif s.state == s.done:
|
||||||
s.state = s.init
|
#s.state = s.init
|
||||||
# check time, etc
|
|
||||||
|
|
||||||
self.prev_state = self.gather_sand
|
self.prev_state = self.gather_sand
|
||||||
self.state = self.sleep_with_bed
|
self.state = self.sleep_with_bed
|
||||||
|
@ -406,23 +522,35 @@ class JobStates:
|
||||||
s.run()
|
s.run()
|
||||||
|
|
||||||
def lumberjack(self):
|
def lumberjack(self):
|
||||||
s = self.lumberjack_states
|
s1 = self.lumberjack_states
|
||||||
if s.state == s.idle:
|
s2 = self.sleep_with_bed_states
|
||||||
s.state = s.init
|
s3 = self.cache_items_states
|
||||||
elif s.state == s.done:
|
|
||||||
s.state = s.init
|
|
||||||
# check time, etc
|
|
||||||
|
|
||||||
self.prev_state = self.lumberjack
|
if s1.state == s1.idle:
|
||||||
self.state = self.sleep_with_bed
|
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
|
return
|
||||||
|
|
||||||
s.run()
|
s1.run()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.lumberjack_states = LumberjackStates(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.state = self.idle
|
self.state = self.idle
|
||||||
|
|
||||||
def __init__(self, global_state):
|
def __init__(self, global_state):
|
||||||
|
@ -433,6 +561,7 @@ class JobStates:
|
||||||
self.lumberjack_states = LumberjackStates(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)
|
||||||
|
|
||||||
def tick(self):
|
def tick(self):
|
||||||
self.state()
|
self.state()
|
||||||
|
|
12
main.py
12
main.py
|
@ -2,6 +2,7 @@ import importlib
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
|
import json
|
||||||
|
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
@ -21,9 +22,14 @@ g.inv = {}
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def hello_world():
|
def hello_world():
|
||||||
#print(chunks.chunks)
|
data = json.dumps(g, default=lambda o: str(o), indent=4)
|
||||||
return str(g.chunks.get_block_at(84,62,54))
|
|
||||||
#return 'ok'
|
response = app.response_class(
|
||||||
|
response=data,
|
||||||
|
status=200,
|
||||||
|
mimetype='application/json'
|
||||||
|
)
|
||||||
|
return response
|
||||||
|
|
||||||
reload_timeout = time.time()
|
reload_timeout = time.time()
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,9 @@ def get_packets(old_get_packets):
|
||||||
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)
|
||||||
|
mc_packets.add(packets.OpenWindowPacket)
|
||||||
|
mc_packets.add(packets.CloseWindowPacket)
|
||||||
|
mc_packets.add(packets.ClickWindowPacket)
|
||||||
|
|
||||||
return mc_packets
|
return mc_packets
|
||||||
return lambda x: wrapper(old_get_packets, x)
|
return lambda x: wrapper(old_get_packets, x)
|
||||||
|
|
|
@ -112,6 +112,8 @@ class ChatManager:
|
||||||
return ''.join([self.translate_chat(x) for x in data['extra']])
|
return ''.join([self.translate_chat(x) for x in data['extra']])
|
||||||
elif 'text' in data:
|
elif 'text' in data:
|
||||||
return data['text']
|
return data['text']
|
||||||
|
elif 'with' in data:
|
||||||
|
return '<{}> {}'.format(*[self.translate_chat(x) for x in data['with']])
|
||||||
elif 'translate' in data:
|
elif 'translate' in data:
|
||||||
return data['translate']
|
return data['translate']
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -4,7 +4,7 @@ from minecraft.networking.packets import Packet, PacketBuffer
|
||||||
from minecraft.networking.types import (
|
from minecraft.networking.types import (
|
||||||
VarInt, Integer, UnsignedByte, Position, Vector, MutableRecord,
|
VarInt, Integer, UnsignedByte, Position, Vector, MutableRecord,
|
||||||
attribute_alias, multi_attribute_alias, Long, Boolean, VarLong,
|
attribute_alias, multi_attribute_alias, Long, Boolean, VarLong,
|
||||||
Short, UnsignedLong, Byte, BlockFace,
|
Short, UnsignedLong, Byte, BlockFace, String
|
||||||
)
|
)
|
||||||
|
|
||||||
from protocol.types import Nbt, Slot
|
from protocol.types import Nbt, Slot
|
||||||
|
@ -217,3 +217,45 @@ class HeldItemChangePacket(Packet):
|
||||||
definition = [
|
definition = [
|
||||||
{'slot': Short},
|
{'slot': Short},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class OpenWindowPacket(Packet):
|
||||||
|
# Sent to the client when it should open an inventory, such as a chest, workbench, or furnace
|
||||||
|
# https://wiki.vg/Protocol#Open_Window
|
||||||
|
|
||||||
|
id = 0x2D
|
||||||
|
packet_name = 'open window'
|
||||||
|
|
||||||
|
definition = [
|
||||||
|
{'window_id': VarInt},
|
||||||
|
{'window_type': VarInt},
|
||||||
|
{'window_title': String},
|
||||||
|
]
|
||||||
|
|
||||||
|
class CloseWindowPacket(Packet):
|
||||||
|
# Sent by the client when closing a window
|
||||||
|
# https://wiki.vg/Protocol#Close_Window_.28serverbound.29
|
||||||
|
|
||||||
|
id = 0x0A
|
||||||
|
packet_name = 'close window'
|
||||||
|
|
||||||
|
definition = [
|
||||||
|
{'window_id': UnsignedByte},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ClickWindowPacket(Packet):
|
||||||
|
# Sent by the player when it clicks on a slot in a window
|
||||||
|
# https://wiki.vg/Protocol#Click_Window
|
||||||
|
|
||||||
|
id = 0x09
|
||||||
|
packet_name = 'click window'
|
||||||
|
|
||||||
|
definition = [
|
||||||
|
{'window_id': UnsignedByte},
|
||||||
|
{'slot': Short},
|
||||||
|
{'button': Byte},
|
||||||
|
{'action_number': Short},
|
||||||
|
{'mode': VarInt},
|
||||||
|
{'clicked_item': Slot},
|
||||||
|
]
|
||||||
|
|
|
@ -120,14 +120,10 @@ class Slot(Type):
|
||||||
item_count = Byte.read(file_object) if present else None
|
item_count = Byte.read(file_object) if present else None
|
||||||
nbt = TrailingByteArray.read(file_object) if present else None
|
nbt = TrailingByteArray.read(file_object) if present else None
|
||||||
return Slot(present, item_id, item_count, nbt)
|
return Slot(present, item_id, item_count, nbt)
|
||||||
#a = {}
|
|
||||||
#a['present'] = Boolean.read(file_object)
|
|
||||||
#a['item_id'] = VarInt.read(file_object) if a['present'] else None
|
|
||||||
#a['item_count'] = Byte.read(file_object) if a['present'] else None
|
|
||||||
#a['nbt'] = TrailingByteArray.read(file_object) if a['present'] else None
|
|
||||||
#return a
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def send(value, socket):
|
def send(value, socket):
|
||||||
# TODO
|
Boolean.send(value.present, socket)
|
||||||
pass
|
VarInt.send(value.item_id, socket)
|
||||||
|
Byte.send(value.item_count, socket)
|
||||||
|
TrailingByteArray.send(value.nbt, socket)
|
||||||
|
|
11
utils.py
11
utils.py
|
@ -3,6 +3,7 @@ from math import floor, ceil, sqrt, hypot
|
||||||
|
|
||||||
import blocks
|
import blocks
|
||||||
importlib.reload(blocks)
|
importlib.reload(blocks)
|
||||||
|
import data
|
||||||
|
|
||||||
TICK = 0.05
|
TICK = 0.05
|
||||||
|
|
||||||
|
@ -65,13 +66,13 @@ def diffrange(n):
|
||||||
|
|
||||||
def break_time(block_id, held_item=0, in_water=False, on_ground=True, enchantments=[], effects={}):
|
def break_time(block_id, held_item=0, in_water=False, on_ground=True, enchantments=[], effects={}):
|
||||||
# from PrismarineJS/prismarine-block
|
# from PrismarineJS/prismarine-block
|
||||||
data = blocks.get(block_id)
|
block_data = blocks.get(block_id)
|
||||||
|
|
||||||
can_harvest = 'harvestTools' not in data or str(held_item) in data['harvestTools']
|
can_harvest = 'harvestTools' not in block_data or str(held_item) in block_data['harvestTools']
|
||||||
material = data.get('material', 'n/a')
|
material = block_data.get('material', 'n/a')
|
||||||
tool_multipliers = blocks.mcd.materials.get(material, [])
|
tool_multipliers = data.mcd.materials.get(material, [])
|
||||||
is_best_tool = held_item in tool_multipliers
|
is_best_tool = held_item in tool_multipliers
|
||||||
time = data['hardness']
|
time = block_data['hardness']
|
||||||
|
|
||||||
if can_harvest:
|
if can_harvest:
|
||||||
time *= 1.5
|
time *= 1.5
|
||||||
|
|
Loading…
Reference in New Issue
Block a user