More packets
This commit is contained in:
parent
f2155a631d
commit
69a00c1a2b
|
@ -3,3 +3,4 @@ __pycache__/
|
||||||
venv/
|
venv/
|
||||||
state
|
state
|
||||||
packets.txt
|
packets.txt
|
||||||
|
packets*.txt
|
||||||
|
|
|
@ -9,9 +9,15 @@ MAX_SIZE = 0x400000
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def main(args):
|
async def main(args: list[str]):
|
||||||
loop = asyncio.get_running_loop()
|
loop = asyncio.get_running_loop()
|
||||||
server = await asyncio.start_server(BTAProxy(args[0], 25565, loop).handle_client, "localhost", 25565)
|
port: int = 25565
|
||||||
|
if len(args) >= 2:
|
||||||
|
port = int(args[1])
|
||||||
|
server = await asyncio.start_server(BTAProxy(args[0], port, loop).handle_client, "localhost", 25565)
|
||||||
|
|
||||||
|
print("listening on", str.join(", ", [str(s.getsockname()) for s in server.sockets]))
|
||||||
|
print("forwarding to", args[0], port)
|
||||||
|
|
||||||
async with server:
|
async with server:
|
||||||
await server.serve_forever()
|
await server.serve_forever()
|
||||||
|
|
|
@ -15,6 +15,8 @@ class AsyncDataInputStream:
|
||||||
async def read_bytes(self, n: int) -> bytes:
|
async def read_bytes(self, n: int) -> bytes:
|
||||||
if len(self._buffer) < n:
|
if len(self._buffer) < n:
|
||||||
self._last = (await self._queue.get())
|
self._last = (await self._queue.get())
|
||||||
|
if not self._last:
|
||||||
|
raise EOFError('empty packet was received')
|
||||||
self._buffer += self._last
|
self._buffer += self._last
|
||||||
out, self._buffer = self._buffer[:n], self._buffer[n:]
|
out, self._buffer = self._buffer[:n], self._buffer[n:]
|
||||||
return out
|
return out
|
||||||
|
@ -76,7 +78,7 @@ class AsyncDataInputStream:
|
||||||
try:
|
try:
|
||||||
return (await self.read_bytes(size)).decode('utf-8')
|
return (await self.read_bytes(size)).decode('utf-8')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise ValueError(f'failed reading string of size {size} in {last}') from e
|
raise ValueError(f'failed reading string of size {size} in {last!r}') from e
|
||||||
|
|
||||||
class SyncDataInputStream:
|
class SyncDataInputStream:
|
||||||
def __init__(self, buffer: bytes):
|
def __init__(self, buffer: bytes):
|
||||||
|
@ -98,7 +100,7 @@ class SyncDataInputStream:
|
||||||
|
|
||||||
def read(self) -> int:
|
def read(self) -> int:
|
||||||
if self._cursor >= len(self._buffer):
|
if self._cursor >= len(self._buffer):
|
||||||
raise EOFError(f'stream overread in {self._buffer} at {self._cursor}')
|
raise EOFError(f'stream overread in {self._buffer!r} at {self._cursor}')
|
||||||
self._cursor += 1
|
self._cursor += 1
|
||||||
return self._buffer[self._cursor - 1]
|
return self._buffer[self._cursor - 1]
|
||||||
|
|
||||||
|
|
|
@ -5,49 +5,62 @@ import time
|
||||||
from bta_proxy.datainputstream import AsyncDataInputStream
|
from bta_proxy.datainputstream import AsyncDataInputStream
|
||||||
from bta_proxy.packets import *
|
from bta_proxy.packets import *
|
||||||
|
|
||||||
|
|
||||||
async def inspect_client(queue: Queue, addr: tuple[str, int]):
|
async def inspect_client(queue: Queue, addr: tuple[str, int]):
|
||||||
dis = AsyncDataInputStream(queue)
|
dis = AsyncDataInputStream(queue)
|
||||||
last_time = time.time()
|
last_time = time.time()
|
||||||
while True:
|
|
||||||
pkt = await Packet.read_packet(dis)
|
|
||||||
now = time.time()
|
|
||||||
delta = now - last_time
|
|
||||||
last_time = now
|
|
||||||
|
|
||||||
match pkt.packet_id:
|
with open("packets-%s-%d-client.txt" % addr, "w") as f:
|
||||||
case Packet10Flying.packet_id:
|
while True:
|
||||||
continue
|
try:
|
||||||
case Packet11PlayerPosition.packet_id:
|
pkt = await Packet.read_packet(dis)
|
||||||
continue
|
except EOFError:
|
||||||
case Packet12PlayerLook.packet_id:
|
|
||||||
continue
|
|
||||||
case Packet13LookMove.packet_id:
|
|
||||||
continue
|
|
||||||
case Packet255KickDisconnect.packet_id:
|
|
||||||
break
|
break
|
||||||
case _:
|
now = time.time()
|
||||||
print(f"C {delta*1000:+8.1f}ms {pkt}")
|
delta = now - last_time
|
||||||
|
last_time = now
|
||||||
|
|
||||||
|
print(f"{delta*1000:+8.1f}ms {pkt}", file=f)
|
||||||
|
|
||||||
|
match pkt.packet_id:
|
||||||
|
case Packet10Flying.packet_id:
|
||||||
|
continue
|
||||||
|
case Packet11PlayerPosition.packet_id:
|
||||||
|
continue
|
||||||
|
case Packet12PlayerLook.packet_id:
|
||||||
|
continue
|
||||||
|
case Packet13LookMove.packet_id:
|
||||||
|
continue
|
||||||
|
case Packet255KickDisconnect.packet_id:
|
||||||
|
break
|
||||||
|
case _:
|
||||||
|
print(f"C {delta*1000:+8.1f}ms {pkt}")
|
||||||
|
|
||||||
async def inspect_server(queue: Queue, addr: tuple[str, int]):
|
async def inspect_server(queue: Queue, addr: tuple[str, int]):
|
||||||
dis = AsyncDataInputStream(queue)
|
dis = AsyncDataInputStream(queue)
|
||||||
last_time = time.time()
|
last_time = time.time()
|
||||||
while True:
|
|
||||||
pkt = await Packet.read_packet(dis)
|
|
||||||
now = time.time()
|
|
||||||
delta = now - last_time
|
|
||||||
last_time = now
|
|
||||||
|
|
||||||
match pkt.packet_id:
|
with open("packets-%s-%d-server.txt" % addr, "w") as f:
|
||||||
case Packet50PreChunk.packet_id:
|
while True:
|
||||||
continue
|
try:
|
||||||
case Packet51MapChunk.packet_id:
|
pkt = await Packet.read_packet(dis)
|
||||||
continue
|
except EOFError:
|
||||||
case Packet31RelEntityMove.packet_id:
|
break
|
||||||
continue
|
now = time.time()
|
||||||
case Packet32EntityLook.packet_id:
|
delta = now - last_time
|
||||||
continue
|
last_time = now
|
||||||
case Packet33RelEntityMoveLook.packet_id:
|
|
||||||
continue
|
print(f"{delta*1000:+8.1f}ms {pkt}", file=f)
|
||||||
case _:
|
|
||||||
print(f"S {delta*1000:+8.1f}ms {pkt}")
|
match pkt.packet_id:
|
||||||
|
case Packet50PreChunk.packet_id:
|
||||||
|
continue
|
||||||
|
case Packet51MapChunk.packet_id:
|
||||||
|
continue
|
||||||
|
case Packet31RelEntityMove.packet_id:
|
||||||
|
continue
|
||||||
|
case Packet32EntityLook.packet_id:
|
||||||
|
continue
|
||||||
|
case Packet33RelEntityMoveLook.packet_id:
|
||||||
|
continue
|
||||||
|
case _:
|
||||||
|
print(f"S {delta*1000:+8.1f}ms {pkt}")
|
||||||
|
|
|
@ -56,5 +56,12 @@ from .packet132setmobspawner import Packet132SetMobSpawner
|
||||||
from .packet39attachentity import Packet39AttachEntity
|
from .packet39attachentity import Packet39AttachEntity
|
||||||
from .packet35entitynickname import Packet35EntityNickname
|
from .packet35entitynickname import Packet35EntityNickname
|
||||||
from .packet52multiblockchange import Packet52MultiBlockChange
|
from .packet52multiblockchange import Packet52MultiBlockChange
|
||||||
from .packet20statistic import Packet20Statistic
|
from .packet200statistic import Packet200Statistic
|
||||||
from .packet0keepalive import Packet0KeepAlive
|
from .packet0keepalive import Packet0KeepAlive
|
||||||
|
from .packet106transaction import Packet106Transaction
|
||||||
|
from .packet20namedentityspawn import Packet20NamedEntitySpawn
|
||||||
|
from .packet107updatecreativeinventory import Packet107UpdateCreativeInventory
|
||||||
|
from .packet22collect import Packet22Collect
|
||||||
|
from .packet9respawn import Packet9Respawn
|
||||||
|
from .packet60explosion import Packet60Explosion
|
||||||
|
from .packet60explosion import Packet60Explosion
|
||||||
|
|
|
@ -47,9 +47,11 @@ class Packet:
|
||||||
):
|
):
|
||||||
match datatype:
|
match datatype:
|
||||||
case "list", sizekey, *args:
|
case "list", sizekey, *args:
|
||||||
|
args = args[0] if len(args) == 1 else tuple(args)
|
||||||
|
length = sizekey if isinstance(try_int(sizekey), int) else fields[sizekey]
|
||||||
return [
|
return [
|
||||||
await Packet.read_field(stream, args, fields)
|
await Packet.read_field(stream, args, fields)
|
||||||
for _ in range(fields[sizekey])
|
for _ in range(length)
|
||||||
]
|
]
|
||||||
case "uint":
|
case "uint":
|
||||||
return await stream.read_uint()
|
return await stream.read_uint()
|
||||||
|
@ -98,8 +100,8 @@ class Packet:
|
||||||
case "itemstack":
|
case "itemstack":
|
||||||
return await ItemStack.read_from(stream)
|
return await ItemStack.read_from(stream)
|
||||||
case "itemstack", length_or_key:
|
case "itemstack", length_or_key:
|
||||||
|
items: list[Optional[ItemStack]] = []
|
||||||
if isinstance(length_or_key, int):
|
if isinstance(length_or_key, int):
|
||||||
items: list[Optional[ItemStack]] = []
|
|
||||||
for _ in range(length_or_key):
|
for _ in range(length_or_key):
|
||||||
if (item_id := await stream.read_short()) >= 0:
|
if (item_id := await stream.read_short()) >= 0:
|
||||||
count = await stream.read()
|
count = await stream.read()
|
||||||
|
@ -115,7 +117,6 @@ class Packet:
|
||||||
raise KeyError(
|
raise KeyError(
|
||||||
f"failed to find {length_or_key} in {fields} to read number of itemstacks"
|
f"failed to find {length_or_key} in {fields} to read number of itemstacks"
|
||||||
)
|
)
|
||||||
items: list[Optional[ItemStack]] = []
|
|
||||||
for _ in range(fields[length_or_key]):
|
for _ in range(fields[length_or_key]):
|
||||||
if (item_id := await stream.read_short()) >= 0:
|
if (item_id := await stream.read_short()) >= 0:
|
||||||
count = await stream.read()
|
count = await stream.read()
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
from .base import Packet
|
||||||
|
|
||||||
|
class Packet106Transaction(Packet, packet_id=106):
|
||||||
|
__slots__ = ('window_id', 'action_id', 'flag')
|
||||||
|
FIELDS = [
|
||||||
|
('window_id', 'ubyte'),
|
||||||
|
('action_id', 'short'),
|
||||||
|
('flag', 'bool'),
|
||||||
|
]
|
|
@ -0,0 +1,9 @@
|
||||||
|
from .base import Packet
|
||||||
|
|
||||||
|
class Packet107UpdateCreativeInventory(Packet, packet_id=107):
|
||||||
|
__slots__ = ('window_id', 'page', 'text')
|
||||||
|
FIELDS = [
|
||||||
|
('window_id', 'ubyte'),
|
||||||
|
('page', 'int'),
|
||||||
|
('text', 'str'),
|
||||||
|
]
|
|
@ -1,6 +1,6 @@
|
||||||
from .base import Packet
|
from .base import Packet
|
||||||
|
|
||||||
class Packet20Statistic(Packet, packet_id=20):
|
class Packet200Statistic(Packet, packet_id=200):
|
||||||
__slots__ = ('field_27052_a', 'field_27051')
|
__slots__ = ('field_27052_a', 'field_27051')
|
||||||
FIELDS = [
|
FIELDS = [
|
||||||
('field_27052_a', 'int'),
|
('field_27052_a', 'int'),
|
|
@ -0,0 +1,16 @@
|
||||||
|
from .base import Packet
|
||||||
|
|
||||||
|
class Packet20NamedEntitySpawn(Packet, packet_id=20):
|
||||||
|
__slots__ = ('entity_id', 'name', 'x', 'y', 'z', 'yaw', 'pitch', 'item', 'name', 'color')
|
||||||
|
FIELDS = [
|
||||||
|
('entity_id', 'int'),
|
||||||
|
('name', 'str'),
|
||||||
|
('x', 'int'),
|
||||||
|
('y', 'int'),
|
||||||
|
('z', 'int'),
|
||||||
|
('yaw', 'byte'),
|
||||||
|
('pitch', 'byte'),
|
||||||
|
('item', 'short'),
|
||||||
|
('name', 'str'),
|
||||||
|
('color', 'ubyte'),
|
||||||
|
]
|
|
@ -0,0 +1,8 @@
|
||||||
|
from .base import Packet
|
||||||
|
|
||||||
|
class Packet22Collect(Packet, packet_id=22):
|
||||||
|
__slots__ = ('collected', 'collector')
|
||||||
|
FIELDS = [
|
||||||
|
('collected', 'int'),
|
||||||
|
('collector', 'int'),
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
from .base import Packet
|
||||||
|
|
||||||
|
class Packet60Explosion(Packet, packet_id=60):
|
||||||
|
__slots__ = ('x', 'y', 'z', 'size', 'destroyed_len', 'rel_destroyed', 'is_cannonball')
|
||||||
|
FIELDS = [
|
||||||
|
('x', 'double'),
|
||||||
|
('y', 'double'),
|
||||||
|
('z', 'double'),
|
||||||
|
('size', 'float'),
|
||||||
|
('destroyed_len', 'int'),
|
||||||
|
('rel_destroyed', ('list', 'destroyed_len', 'list', 3, 'byte')),
|
||||||
|
('is_cannonball', 'bool'),
|
||||||
|
]
|
|
@ -0,0 +1,8 @@
|
||||||
|
from .base import Packet
|
||||||
|
|
||||||
|
class Packet9Respawn(Packet, packet_id=9):
|
||||||
|
__slots__ = ('dimension', 'world_type')
|
||||||
|
FIELDS = [
|
||||||
|
('dimension', 'byte'),
|
||||||
|
('world_type', 'byte'),
|
||||||
|
]
|
Loading…
Reference in New Issue