bta-proxy/bta_proxy/entitydata.py

78 lines
2.9 KiB
Python
Raw Normal View History

2023-08-24 17:40:23 +03:00
from typing import Any
from bta_proxy.datainputstream import AsyncDataInputStream, SyncDataInputStream
2023-08-24 17:40:23 +03:00
from enum import Enum
from dataclasses import dataclass
from bta_proxy.itemstack import ItemStack
2023-09-04 22:03:31 +03:00
from logging import getLogger
logger = getLogger(__name__)
2023-08-24 17:40:23 +03:00
class DataItemType(Enum):
BYTE = 0
SHORT = 1
INTEGER = 2
FLOAT = 3
STRING = 4
ITEMSTACK = 5
CHUNK_COORDINATES = 6
@dataclass
class DataItem:
type: DataItemType
id: int
value: Any
class EntityData:
@classmethod
2023-08-25 21:49:10 +03:00
async def read_from(cls, dis: AsyncDataInputStream) -> list[DataItem]:
2023-08-24 17:40:23 +03:00
items = []
2023-09-04 22:03:31 +03:00
while (data := await dis.read()) not in (127, 255):
logger.debug(f"Read byte: {data} (type={(data & 0xE0) >> 5}, id={data & 0x1F})")
2023-08-24 17:40:23 +03:00
item_type = DataItemType((data & 0xE0) >> 5)
item_id: int = data & 0x1F
match item_type:
case DataItemType.BYTE:
2023-08-25 21:49:10 +03:00
items.append(DataItem(item_type, item_id, await dis.read()))
2023-08-24 17:40:23 +03:00
case DataItemType.SHORT:
2023-08-25 21:49:10 +03:00
items.append(DataItem(item_type, item_id, await dis.read_short()))
2023-08-24 17:40:23 +03:00
case DataItemType.FLOAT:
2023-08-25 21:49:10 +03:00
items.append(DataItem(item_type, item_id, await dis.read_float()))
2023-08-24 17:40:23 +03:00
case DataItemType.STRING:
2023-08-25 21:49:10 +03:00
items.append(DataItem(item_type, item_id, await dis.read_string()))
2023-08-24 17:40:23 +03:00
case DataItemType.ITEMSTACK:
2023-08-25 21:49:10 +03:00
items.append(DataItem(item_type, item_id, await ItemStack.read_from(dis)))
2023-08-24 17:40:23 +03:00
case DataItemType.CHUNK_COORDINATES:
2023-08-25 21:49:10 +03:00
x = await dis.read_float()
y = await dis.read_float()
z = await dis.read_float()
2023-08-24 17:40:23 +03:00
items.append(DataItem(item_type, item_id, (x, y, z)))
return items
@classmethod
def read_from_sync(cls, dis: SyncDataInputStream) -> list[DataItem]:
items = []
2023-09-04 22:03:31 +03:00
while (data := dis.read()) not in (127, 255):
item_type = DataItemType((data & 0xE0) >> 5)
item_id: int = data & 0x1F
match item_type:
case DataItemType.BYTE:
items.append(DataItem(item_type, item_id, dis.read()))
case DataItemType.SHORT:
items.append(DataItem(item_type, item_id, dis.read_short()))
case DataItemType.FLOAT:
items.append(DataItem(item_type, item_id, dis.read_float()))
case DataItemType.STRING:
items.append(DataItem(item_type, item_id, dis.read_string()))
case DataItemType.ITEMSTACK:
items.append(DataItem(item_type, item_id, ItemStack.read_from_sync(dis)))
case DataItemType.CHUNK_COORDINATES:
x = dis.read_float()
y = dis.read_float()
z = dis.read_float()
items.append(DataItem(item_type, item_id, (x, y, z)))
return items