Added back synchronous DataInputStream and related
This commit is contained in:
parent
358289cf42
commit
79d9da259e
|
@ -62,3 +62,74 @@ class AsyncDataInputStream:
|
||||||
size = await self.read_short()
|
size = await self.read_short()
|
||||||
return (await self.read_bytes(size)).decode('utf-8')
|
return (await self.read_bytes(size)).decode('utf-8')
|
||||||
|
|
||||||
|
class SyncDataInputStream:
|
||||||
|
def __init__(self, buffer: bytes):
|
||||||
|
self._buffer = buffer
|
||||||
|
self._cursor = 0
|
||||||
|
|
||||||
|
def read_bytes(self, n: int) -> bytes:
|
||||||
|
if self._cursor + n > len(self._buffer):
|
||||||
|
raise EOFError('stream overread')
|
||||||
|
blob = self._buffer[self._cursor : self._cursor + n]
|
||||||
|
self._cursor += n
|
||||||
|
return blob
|
||||||
|
|
||||||
|
def empty(self):
|
||||||
|
return self._cursor >= len(self._buffer) - 1
|
||||||
|
|
||||||
|
def end(self) -> bytes:
|
||||||
|
return self.read_bytes(len(self._buffer) - self._cursor)
|
||||||
|
|
||||||
|
def read(self) -> int:
|
||||||
|
if self._cursor >= len(self._buffer):
|
||||||
|
raise EOFError(f'stream overread in {self._buffer} at {self._cursor}')
|
||||||
|
self._cursor += 1
|
||||||
|
return self._buffer[self._cursor - 1]
|
||||||
|
|
||||||
|
def read_boolean(self) -> bool:
|
||||||
|
return self.read() != 0
|
||||||
|
|
||||||
|
def read_short(self) -> int:
|
||||||
|
return struct.unpack('>h', self.read_bytes(2))[0]
|
||||||
|
|
||||||
|
def read_ushort(self) -> int:
|
||||||
|
return struct.unpack('>H', self.read_bytes(2))[0]
|
||||||
|
|
||||||
|
def read_int(self) -> int:
|
||||||
|
return struct.unpack('>i', self.read_bytes(4))[0]
|
||||||
|
|
||||||
|
def read_uint(self) -> int:
|
||||||
|
return struct.unpack('>I', self.read_bytes(4))[0]
|
||||||
|
|
||||||
|
def read_long(self) -> int:
|
||||||
|
return struct.unpack('>q', self.read_bytes(8))[0]
|
||||||
|
|
||||||
|
def read_ulong(self) -> int:
|
||||||
|
return struct.unpack('>Q', self.read_bytes(8))[0]
|
||||||
|
|
||||||
|
def read_float(self) -> float:
|
||||||
|
return struct.unpack('>f', self.read_bytes(4))[0]
|
||||||
|
|
||||||
|
def read_double(self) -> float:
|
||||||
|
return struct.unpack('>d', self.read_bytes(8))[0]
|
||||||
|
|
||||||
|
def read_char(self) -> str:
|
||||||
|
return chr(self.read_ushort())
|
||||||
|
|
||||||
|
def read_varint(self, bits: int = 32) -> int:
|
||||||
|
value: int = 0
|
||||||
|
position: int = 0
|
||||||
|
while True:
|
||||||
|
byte = self.read()
|
||||||
|
value |= (byte & 0x7F) << position
|
||||||
|
if ((byte & 0x80) == 0):
|
||||||
|
break
|
||||||
|
position += 7
|
||||||
|
if position >= bits:
|
||||||
|
raise ValueError('varint too big')
|
||||||
|
return value
|
||||||
|
|
||||||
|
def read_string(self) -> str:
|
||||||
|
size = self.read_short()
|
||||||
|
return self.read_bytes(size).decode('utf-8')
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from bta_proxy.datainputstream import AsyncDataInputStream
|
from bta_proxy.datainputstream import AsyncDataInputStream, SyncDataInputStream
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
@ -46,3 +46,27 @@ class EntityData:
|
||||||
items.append(DataItem(item_type, item_id, (x, y, z)))
|
items.append(DataItem(item_type, item_id, (x, y, z)))
|
||||||
return items
|
return items
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def read_from_sync(cls, dis: SyncDataInputStream) -> list[DataItem]:
|
||||||
|
items = []
|
||||||
|
while (data := dis.read()) != 0x7F:
|
||||||
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
from bta_proxy.datainputstream import AsyncDataInputStream
|
from bta_proxy.datainputstream import AsyncDataInputStream, SyncDataInputStream
|
||||||
|
|
||||||
|
|
||||||
class ItemStack:
|
class ItemStack:
|
||||||
|
@ -15,3 +15,10 @@ class ItemStack:
|
||||||
count = await stream.read()
|
count = await stream.read()
|
||||||
data = await stream.read_ushort()
|
data = await stream.read_ushort()
|
||||||
return cls(item_id, count, data)
|
return cls(item_id, count, data)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def read_from_sync(cls, stream: SyncDataInputStream) -> 'ItemStack':
|
||||||
|
item_id = stream.read_short()
|
||||||
|
count = stream.read()
|
||||||
|
data = stream.read_ushort()
|
||||||
|
return cls(item_id, count, data)
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
from bta_proxy.datainputstream import AsyncDataInputStream
|
|
||||||
from bta_proxy.itemstack import ItemStack
|
|
||||||
from .base import Packet
|
from .base import Packet
|
||||||
|
|
||||||
class Packet102WindowClick(Packet, packet_id=102):
|
class Packet102WindowClick(Packet, packet_id=102):
|
||||||
|
|
Loading…
Reference in New Issue