Compare commits

..

2 Commits

Author SHA1 Message Date
320f925fa1 Fix sand gather state machine 2020-09-21 13:40:33 -06:00
6489984640 Fix item caching bugs 2020-09-20 23:41:55 -06:00
5 changed files with 97 additions and 28 deletions

View File

@ -22,8 +22,7 @@ SINGLE_SNOW = 3921
#SOUL_TORCH = 4008 #SOUL_TORCH = 4008
SOUL_TORCH = 1435 SOUL_TORCH = 1435
#TEST_BLOCK = (616, 78, 496) TEST_BLOCK = (616, 78, 496)
TEST_BLOCK = (-100, 64, -167)
AVOID = [ AVOID = [

40
game.py
View File

@ -10,7 +10,8 @@ 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, OpenWindowPacket, ClickWindowPacket, CloseWindowPacket from protocol.packets import TimeUpdatePacket, SetSlotPacket, PlayerDiggingPacket, BlockBreakAnimationPacket, AcknowledgePlayerDiggingPacket, HeldItemChangePacket, PickItemPacket, OpenWindowPacket, ClickWindowPacket, CloseWindowPacket, ServerWindowConfirmationPacket, ClientWindowConfirmationPacket
from protocol.types import Slot
import utils import utils
importlib.reload(utils) importlib.reload(utils)
@ -186,6 +187,7 @@ class Game:
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) register(self.handle_window, OpenWindowPacket)
register(self.handle_window_confirmation, ClientWindowConfirmationPacket)
self.g.chat.set_handler(self.handle_chat) self.g.chat.set_handler(self.handle_chat)
@ -296,12 +298,16 @@ class Game:
reply = 'ok' reply = 'ok'
if command == 'inv': if command == 'inv':
print(self.g.inv)
inv_list = [] inv_list = []
for i in self.g.inv.values(): for i in self.g.inv.values():
if i.present: if i.present:
inv_list.append('{}:{} x {}'.format(items.ITEM_NAMES[i.item_id], str(i.item_id), i.item_count)) inv_list.append('{}:{} x {}'.format(items.ITEM_NAMES[i.item_id], str(i.item_id), i.item_count))
reply = ', '.join(inv_list) reply = ', '.join(inv_list)
if not reply:
reply = 'empty'
if command == 'drop': if command == 'drop':
self.drop_stack() self.drop_stack()
@ -334,10 +340,13 @@ class Game:
if command == 'click' and data: if command == 'click' and data:
if self.g.window: if self.g.window:
window_id, slot, button, mode = [int(x) for x in data.split(' ')] slot, button, mode = [int(x) for x in data.split(' ')]
item = self.g.window.contents[slot] try:
item = self.g.window.contents[slot]
except KeyError:
item = Slot(present=False, item_id=None, item_count=None, nbt=None)
print(item) print(item)
self.click_window(window_id, slot, button, mode, item) self.click_window(slot, button, mode, item)
else: else:
reply = 'nothing open' reply = 'nothing open'
@ -356,7 +365,8 @@ class Game:
elif g.window: elif g.window:
g.window.contents[packet.slot] = packet.slot_data g.window.contents[packet.slot] = packet.slot_data
if not packet.slot_data.present: if packet.window_id >= 0 and not packet.slot_data.present:
print('unlocking item lock')
g.item_lock = False g.item_lock = False
def break_block(self, location): def break_block(self, location):
@ -451,17 +461,22 @@ class Game:
def handle_window(self, packet): def handle_window(self, packet):
print(packet) print(packet)
self.g.window = Bunch(data=packet, contents=dict()) self.g.window = Bunch(data=packet, contents=dict(), count=0)
def click_window(self, slot, button, mode, item):
w = self.g.window
def click_window(self, window_id, slot, button, mode, item):
packet = ClickWindowPacket() packet = ClickWindowPacket()
packet.window_id = window_id packet.window_id = w.data.window_id
packet.slot = slot packet.slot = slot
packet.button = button packet.button = button
packet.action_number = 1 packet.action_number = w.count
packet.mode = mode packet.mode = mode
packet.clicked_item = item packet.clicked_item = item
self.g.connection.write_packet(packet) self.g.connection.write_packet(packet)
print('<--', packet)
w.count += 1
def close_window(self): def close_window(self):
packet = CloseWindowPacket() packet = CloseWindowPacket()
@ -469,6 +484,13 @@ class Game:
self.g.connection.write_packet(packet) self.g.connection.write_packet(packet)
self.g.window = None self.g.window = None
def handle_window_confirmation(self, packet):
print(packet)
packet2 = ServerWindowConfirmationPacket()
packet2.window_id = packet.window_id
packet2.action_number = packet.action_number
packet2.accepted = packet.accepted
self.g.connection.write_packet(packet2)
def tick(self): def tick(self):
if self.g.breaking: if self.g.breaking:

53
jobs.py
View File

@ -15,6 +15,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 LumberjackStates: class LumberjackStates:
@ -377,9 +379,10 @@ class CacheItemsStates:
return None return None
def init(self): def init(self):
#if len(self.g.inv) >= 27: num_stacks = len([x for x in self.g.inv.values() if x.present])
if len(self.g.inv) >= 2: print('inventory amount:', num_stacks)
self.state = self.find_chest_spot if num_stacks >= 27:
self.state = self.find_cache_spot
else: else:
print('Aborting caching, not full') print('Aborting caching, not full')
self.state = self.cleanup self.state = self.cleanup
@ -453,8 +456,8 @@ class CacheItemsStates:
if self.g.item_lock: return if self.g.item_lock: return
w = self.g.window w = self.g.window
w_data = data.WINDOWS[w.window_type] w_info = data.WINDOWS[w.data.window_type]
w_inventory_slots = w_data.inventory w_inventory_slots = w_info.inventory
for slot_num in w_inventory_slots: for slot_num in w_inventory_slots:
if slot_num not in w.contents: if slot_num not in w.contents:
@ -462,24 +465,28 @@ class CacheItemsStates:
slot = w.contents[slot_num] slot = w.contents[slot_num]
if not slot.present:
continue
if slot.item_id in items.USEFUL_ITEMS: if slot.item_id in items.USEFUL_ITEMS:
continue continue
print('moving', slot) print('moving', slot)
inv_slot_num = slot_num - w_data.slot_diff #inv_slot_num = slot_num - w_info.slot_diff
self.g.inv.pop(inv_slot_num, None) #self.g.inv.pop(inv_slot_num, None)
self.g.item_lock = True self.g.item_lock = True
self.g.game.click_window(w.window_id, slot_num, 0, 1, slot) self.g.game.click_window(slot_num, 0, 1, slot)
return return
print('nothing left to move') print('nothing left to move')
self.state = close_chest self.state = self.close_chest
def close_chest(self): def close_chest(self):
print('closing chest') print('closing chest')
self.g.game.close_window() self.g.game.close_window()
self.g.chat.send('cache at ' + str(self.area)[1:-1])
self.state = self.cleanup self.state = self.cleanup
def cleanup(self): def cleanup(self):
@ -509,17 +516,29 @@ class JobStates:
return None return None
def gather_sand(self): def gather_sand(self):
s = self.gather_sand_states s1 = self.gather_sand_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
self.prev_state = self.gather_sand 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 lumberjack(self): def lumberjack(self):
s1 = self.lumberjack_states s1 = self.lumberjack_states

View File

@ -18,6 +18,8 @@ def get_packets(old_get_packets):
mc_packets.add(packets.OpenWindowPacket) mc_packets.add(packets.OpenWindowPacket)
mc_packets.add(packets.CloseWindowPacket) mc_packets.add(packets.CloseWindowPacket)
mc_packets.add(packets.ClickWindowPacket) mc_packets.add(packets.ClickWindowPacket)
mc_packets.add(packets.ClientWindowConfirmationPacket)
mc_packets.add(packets.ServerWindowConfirmationPacket)
return mc_packets return mc_packets
return lambda x: wrapper(old_get_packets, x) return lambda x: wrapper(old_get_packets, x)

View File

@ -259,3 +259,30 @@ class ClickWindowPacket(Packet):
{'mode': VarInt}, {'mode': VarInt},
{'clicked_item': Slot}, {'clicked_item': Slot},
] ]
class ClientWindowConfirmationPacket(Packet):
# Sent by the server indicating whether a request from the client was accepted
# https://wiki.vg/Protocol#Window_Confirmation_.28clientbound.29
id = 0x11
packet_name = 'client window confirmation'
definition = [
{'window_id': Byte},
{'action_number': Short},
{'accepted': Boolean},
]
class ServerWindowConfirmationPacket(Packet):
# Sent by the client to confirm an unaccepted click
# https://wiki.vg/Protocol#Window_Confirmation_.28serverbound.29
id = 0x07
packet_name = 'client window confirmation'
definition = [
{'window_id': Byte},
{'action_number': Short},
{'accepted': Boolean},
]