fix: correctly reset window state
This commit is contained in:
parent
bcf293a8ad
commit
5465837478
1 changed files with 55 additions and 37 deletions
|
@ -4,6 +4,8 @@ from typing import List, Optional
|
||||||
|
|
||||||
#from aiocraft.client import MinecraftClient
|
#from aiocraft.client import MinecraftClient
|
||||||
from aiocraft.mc.definitions import Item
|
from aiocraft.mc.definitions import Item
|
||||||
|
from aiocraft.mc.proto.play.clientbound import PacketTransaction
|
||||||
|
from aiocraft.mc.proto.play.serverbound import PacketTransaction as PacketTransactionServerbound
|
||||||
from aiocraft.mc.proto import (
|
from aiocraft.mc.proto import (
|
||||||
PacketOpenWindow, PacketCloseWindow, PacketSetSlot
|
PacketOpenWindow, PacketCloseWindow, PacketSetSlot
|
||||||
)
|
)
|
||||||
|
@ -11,65 +13,81 @@ from aiocraft.mc.proto import (
|
||||||
from ..events import JoinGameEvent, DeathEvent, ConnectedEvent, DisconnectedEvent
|
from ..events import JoinGameEvent, DeathEvent, ConnectedEvent, DisconnectedEvent
|
||||||
from ..scaffold import Scaffold
|
from ..scaffold import Scaffold
|
||||||
|
|
||||||
|
class WindowContainer:
|
||||||
|
id: int
|
||||||
|
title: str
|
||||||
|
type: str
|
||||||
|
entity_id: Optional[int]
|
||||||
|
transaction_id: int
|
||||||
|
inventory: List[Optional[Item]]
|
||||||
|
|
||||||
|
def __init__(self, id:int, title: str, type: str, entity_id:int = None, slot_count:int = 27):
|
||||||
|
self.id = id
|
||||||
|
self.title = title
|
||||||
|
self.type = type
|
||||||
|
self.entity_id = entity_id
|
||||||
|
self.transaction_id = 0
|
||||||
|
self.inventory = [ None ] * (slot_count + 36)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def next_tid(self) -> int:
|
||||||
|
self.transaction_id += 1
|
||||||
|
if self.transaction_id > 32767:
|
||||||
|
self.transaction_id = -32768 # force short overflow since this is sent over the socket as a short
|
||||||
|
return self.transaction_id
|
||||||
|
|
||||||
class GameContainer(Scaffold):
|
class GameContainer(Scaffold):
|
||||||
window_id : int
|
window: Optional[WindowContainer]
|
||||||
window_title : str
|
|
||||||
window_inventory_type : str
|
|
||||||
window_entity_id : Optional[int]
|
|
||||||
window_transaction_id : int
|
|
||||||
window_inventory : List[Optional[Item]]
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_container_open(self) -> bool:
|
def is_container_open(self) -> bool:
|
||||||
return self.window_id > 0
|
return self.window is not None
|
||||||
|
|
||||||
@property
|
|
||||||
def next_window_tid(self) -> int:
|
|
||||||
self.window_transaction_id += 1
|
|
||||||
return self.window_transaction_id
|
|
||||||
|
|
||||||
async def close_container(self):
|
async def close_container(self):
|
||||||
await self.dispatcher.write(
|
await self.dispatcher.write(
|
||||||
PacketCloseWindow(
|
PacketCloseWindow(
|
||||||
self.dispatcher.proto,
|
self.dispatcher.proto,
|
||||||
windowId=self.window_id
|
windowId=self.window.id
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
# TODO move slots 0-36 to inventory?
|
self.window = None
|
||||||
self.window_transaction_id = 0
|
|
||||||
self.window_id = 0
|
|
||||||
self.window_title = ""
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
self.window = None
|
||||||
self.window_transaction_id = 0
|
|
||||||
self.window_id = 0
|
|
||||||
self.window_title = ""
|
|
||||||
self.window_inventory_type = ""
|
|
||||||
self.window_entity_id = None
|
|
||||||
self.window_inventory = []
|
|
||||||
|
|
||||||
@self.on(DisconnectedEvent)
|
@self.on(DisconnectedEvent)
|
||||||
async def disconnected_cb(_):
|
async def disconnected_cb(_):
|
||||||
self.window_transaction_id = 0
|
self.window = None
|
||||||
self.window_id = 0
|
|
||||||
self.window_title = ""
|
|
||||||
|
|
||||||
@self.on_packet(PacketOpenWindow)
|
@self.on_packet(PacketOpenWindow)
|
||||||
async def on_player_open_window(packet:PacketOpenWindow):
|
async def on_player_open_window(packet:PacketOpenWindow):
|
||||||
assert isinstance(packet.inventoryType, str)
|
assert isinstance(packet.inventoryType, str)
|
||||||
self.window_id = packet.windowId
|
window_entity_id = packet.entityId if packet.inventoryType == "EntityHorse" and hasattr(packet, "entityId") else None
|
||||||
self.window_title = packet.windowTitle
|
self.window = WindowContainer(
|
||||||
self.window_inventory_type = packet.inventoryType
|
packet.windowId,
|
||||||
self.window_entity_id = packet.entityId if packet.inventoryType == "EntityHorse" and hasattr(packet, "entityId") else None
|
packet.windowTitle,
|
||||||
self.window_inventory = [None] * ((packet.slotCount or 36) + 36) # add slots for player inventory
|
packet.inventoryType,
|
||||||
|
entity_id=window_entity_id,
|
||||||
|
slot_count=packet.slotCount or 27
|
||||||
|
)
|
||||||
|
|
||||||
@self.on_packet(PacketSetSlot)
|
@self.on_packet(PacketSetSlot)
|
||||||
async def on_set_slot(packet:PacketSetSlot):
|
async def on_set_slot(packet:PacketSetSlot):
|
||||||
if packet.windowId == 0:
|
if packet.windowId == 0:
|
||||||
self.window_entity_id = 0
|
self.window = None
|
||||||
self.window_id = 0
|
elif self.window and packet.windowId == self.window.id:
|
||||||
self.window_title = ""
|
self.window.inventory[packet.slot] = packet.item
|
||||||
elif packet.windowId == self.window_id:
|
|
||||||
self.window_inventory[packet.slot] = packet.item
|
@self.on_packet(PacketTransaction)
|
||||||
|
async def on_transaction_denied(packet:PacketTransaction):
|
||||||
|
if self.window and packet.windowId == self.window.id:
|
||||||
|
if not packet.accepted: # apologize to server automatically
|
||||||
|
await self.dispatcher.write(
|
||||||
|
PacketTransactionServerbound(
|
||||||
|
self.dispatcher.proto,
|
||||||
|
windowId=packet.windowId,
|
||||||
|
action=packet.action,
|
||||||
|
accepted=packet.accepted,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in a new issue