Uhh i forgot
This commit is contained in:
parent
7ac026dccc
commit
d6772f6db2
|
@ -6,3 +6,4 @@ packets.txt
|
||||||
packets.txt.gz
|
packets.txt.gz
|
||||||
packets*.txt
|
packets*.txt
|
||||||
packets*.txt.gz
|
packets*.txt.gz
|
||||||
|
/packets/
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
| ID | Packet name | Ready |
|
||||||
|
+=====+==================================+=======+
|
||||||
|
| 000 | Packet0KeepAlive | YES |
|
||||||
|
| 001 | Packet1Login | YES |
|
||||||
|
| 002 | Packet2Handshake | YES |
|
||||||
|
| 003 | Packet3Chat | YES |
|
||||||
|
| 004 | Packet4UpdateTime | YES |
|
||||||
|
| 005 | Packet5PlayerInventory | YES |
|
||||||
|
| 006 | Packet6SpawnPosition | YES |
|
||||||
|
| 007 | Packet7UseEntity | YES |
|
||||||
|
| 008 | Packet8UpdateHealth | YES |
|
||||||
|
| 009 | Packet9Respawn | YES |
|
||||||
|
| 010 | Packet10Flying | YES |
|
||||||
|
| 011 | Packet11PlayerPosition | YES |
|
||||||
|
| 012 | Packet12PlayerLook | YES |
|
||||||
|
| 013 | Packet13PlayerLookMove | YES |
|
||||||
|
| 014 | Packet14BlockDig | YES |
|
||||||
|
| 015 | Packet15Place | YES |
|
||||||
|
| 016 | Packet16BlockItemSwitch | YES |
|
||||||
|
| 017 | Packet17Sleep | YES |
|
||||||
|
| 018 | Packet18Animation | YES |
|
||||||
|
| 019 | Packet19EntityAction | YES |
|
||||||
|
| 020 | Packet20NamedEntitySpawn | YES |
|
||||||
|
| 021 | Packet21PickupSpawn | YES |
|
||||||
|
| 022 | Packet22Collect | YES |
|
||||||
|
| 023 | Packet23VehicleSpawn | YES |
|
||||||
|
| 024 | Packet24MobSpawn | YES |
|
||||||
|
| 025 | Packet25EntityPainting | YES |
|
||||||
|
| 027 | Packet27Position | No |
|
||||||
|
| 028 | Packet28EntityVelocity | YES |
|
||||||
|
| 029 | Packet29DestroyEntity | YES |
|
||||||
|
| 030 | Packet30Entity | YES |
|
||||||
|
| 031 | Packet31RelEntityMove | YES |
|
||||||
|
| 032 | Packet32EntityLook | YES |
|
||||||
|
| 033 | Packet33RelEntityMoveLook | YES |
|
||||||
|
| 034 | Packet34EntityTeleport | YES |
|
||||||
|
| 035 | Packet35EntityNickname | YES |
|
||||||
|
| 038 | Packet38EntityStatus | YES |
|
||||||
|
| 039 | Packet39AttachEntity | YES |
|
||||||
|
| 040 | Packet40EntityMetadata | YES |
|
||||||
|
| 041 | Packet41EntityPlayerGamemode | YES |
|
||||||
|
| 050 | Packet50PreChunk | YES |
|
||||||
|
| 051 | Packet51MapChunk | YES |
|
||||||
|
| 052 | Packet52MultiBlockChange | YES |
|
||||||
|
| 053 | Packet53BlockChange | YES |
|
||||||
|
| 054 | Packet54PlayNoteBlock | YES |
|
||||||
|
| 056 | Packet56RequestChunk | No |
|
||||||
|
| 060 | Packet60Explosion | YES |
|
||||||
|
| 061 | Packet61PlaySoundEffect | YES |
|
||||||
|
| 070 | Packet70Bed | No |
|
||||||
|
| 071 | Packet71Weather | No |
|
||||||
|
| 072 | Packet72UpdatePlayerProfile | YES |
|
||||||
|
| 073 | Packet73WeatherStatus | YES |
|
||||||
|
| 100 | Packet100OpenWindow | YES |
|
||||||
|
| 101 | Packet101CloseWindow | YES |
|
||||||
|
| 102 | Packet102WindowClick | YES |
|
||||||
|
| 103 | Packet103SetSlot | YES |
|
||||||
|
| 104 | Packet104WindowItems | YES |
|
||||||
|
| 105 | Packet105UpdateProgressbar | YES |
|
||||||
|
| 106 | Packet106Transaction | YES |
|
||||||
|
| 107 | Packet107UpdateCreativeInventory | YES |
|
||||||
|
| 108 | Packet108SetHotbarOffset | YES |
|
||||||
|
| 130 | Packet130UpdateSign | YES |
|
||||||
|
| 131 | Packet131MapData | YES |
|
||||||
|
| 132 | Packet132SetMobSpawner | YES |
|
||||||
|
| 133 | Packet133OpenGuidebook | YES |
|
||||||
|
| 134 | Packet134ItemData | YES |
|
||||||
|
| 135 | Packet135PlacementMode | YES |
|
||||||
|
| 136 | Packet136SendKey | YES |
|
||||||
|
| 137 | Packet137UpdateFlag | YES |
|
||||||
|
| 138 | Packet138PlayerList | YES |
|
||||||
|
| 139 | Packet139SetPaintingMotive | YES |
|
||||||
|
| 140 | Packet140TileEntityData | YES |
|
||||||
|
| 141 | Packet141UpdateFlag | YES |
|
||||||
|
| 142 | Packet142OpenFlagWindow | YES |
|
||||||
|
| 143 | Packet143PhotoMode | YES |
|
||||||
|
| 200 | Packet200Statistic | YES |
|
||||||
|
| 255 | Packet255KickDisconnect | YES |
|
|
@ -1,27 +1,27 @@
|
||||||
# x-run: cd .. && python -m bta_proxy '201:4f8c:4ea:0:71ec:6d7:6f1b:a4f9'
|
# x-run: cd .. && python -m bta_proxy '201:4f8c:4ea:0:71ec:6d7:6f1b:a4f9'
|
||||||
import asyncio
|
import asyncio
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser, Namespace
|
||||||
from sys import argv
|
|
||||||
|
|
||||||
from bta_proxy.proxy import BTAProxy
|
from bta_proxy.proxy import BTAProxy
|
||||||
|
|
||||||
MAX_SIZE = 0x400000
|
parser = ArgumentParser("bta_proxy", description="Better Than Adventure proxy with Deep Packet Inspection")
|
||||||
|
|
||||||
|
parser.add_argument("remote_host", type=str)
|
||||||
|
parser.add_argument("remote_port", type=int, default=25565)
|
||||||
|
parser.add_argument("--bind", type=str, default="127.0.0.1")
|
||||||
|
parser.add_argument("--bind-port", type=int, default=25565)
|
||||||
|
|
||||||
|
async def main(args: Namespace):
|
||||||
async def main(args: list[str]):
|
|
||||||
loop = asyncio.get_running_loop()
|
loop = asyncio.get_running_loop()
|
||||||
port: int = 25565
|
proxy = BTAProxy(args.remote_host, args.remote_port, loop)
|
||||||
if len(args) >= 2:
|
server = await asyncio.start_server(proxy.handle_client, args.bind, args.bind_port)
|
||||||
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("listening on", str.join(", ", [str(s.getsockname()) for s in server.sockets]))
|
||||||
print("forwarding to", args[0], port)
|
print("forwarding to", args.remote_host, args.remote_port)
|
||||||
|
|
||||||
async with server:
|
async with server:
|
||||||
await server.serve_forever()
|
await server.serve_forever()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
asyncio.run(main(argv[1:]))
|
asyncio.run(main(parser.parse_args()))
|
||||||
|
|
|
@ -25,7 +25,7 @@ async def inspect_client(queue: Queue, addr: tuple[str, int]):
|
||||||
|
|
||||||
last_time = time.time()
|
last_time = time.time()
|
||||||
|
|
||||||
f = open_gzip("packets-%s-%d-client.txt.gz" % addr, "wt")
|
f = open_gzip("packets-%d-%s-%d-client.txt.gz" % (int(time.time()), addr[0], addr[1]), "wt")
|
||||||
get_event_loop().create_task(queue_writer(queue, stream_queue, f))
|
get_event_loop().create_task(queue_writer(queue, stream_queue, f))
|
||||||
|
|
||||||
stats: dict[int, int] = {}
|
stats: dict[int, int] = {}
|
||||||
|
@ -43,14 +43,14 @@ async def inspect_client(queue: Queue, addr: tuple[str, int]):
|
||||||
stats[pkt.packet_id] = stats.get(pkt.packet_id, 0) + 1
|
stats[pkt.packet_id] = stats.get(pkt.packet_id, 0) + 1
|
||||||
|
|
||||||
match pkt.packet_id:
|
match pkt.packet_id:
|
||||||
# case Packet10Flying.packet_id:
|
case Packet10Flying.packet_id:
|
||||||
# continue
|
continue
|
||||||
# case Packet11PlayerPosition.packet_id:
|
case Packet11PlayerPosition.packet_id:
|
||||||
# continue
|
continue
|
||||||
# case Packet12PlayerLook.packet_id:
|
case Packet12PlayerLook.packet_id:
|
||||||
# continue
|
continue
|
||||||
# case Packet13LookMove.packet_id:
|
case Packet13LookMove.packet_id:
|
||||||
# continue
|
continue
|
||||||
case _:
|
case _:
|
||||||
print(f"C {delta*1000:+8.1f}ms {pkt}")
|
print(f"C {delta*1000:+8.1f}ms {pkt}")
|
||||||
if pkt.packet_id == Packet255KickDisconnect.packet_id:
|
if pkt.packet_id == Packet255KickDisconnect.packet_id:
|
||||||
|
@ -68,7 +68,7 @@ async def inspect_server(queue: Queue, addr: tuple[str, int]):
|
||||||
|
|
||||||
last_time = time.time()
|
last_time = time.time()
|
||||||
|
|
||||||
f = open_gzip("packets-%s-%d-server.txt.gz" % addr, "wt")
|
f = open_gzip("packets-%d-%s-%d-server.txt.gz" % (int(time.time()), addr[0], addr[1]), "wt")
|
||||||
get_event_loop().create_task(queue_writer(queue, stream_queue, f))
|
get_event_loop().create_task(queue_writer(queue, stream_queue, f))
|
||||||
|
|
||||||
stats: dict[int, int] = {}
|
stats: dict[int, int] = {}
|
||||||
|
@ -86,26 +86,26 @@ async def inspect_server(queue: Queue, addr: tuple[str, int]):
|
||||||
stats[pkt.packet_id] = stats.get(pkt.packet_id, 0) + 1
|
stats[pkt.packet_id] = stats.get(pkt.packet_id, 0) + 1
|
||||||
|
|
||||||
match pkt.packet_id:
|
match pkt.packet_id:
|
||||||
# case Packet53BlockChange.packet_id:
|
case Packet53BlockChange.packet_id:
|
||||||
# continue
|
continue
|
||||||
# case Packet50PreChunk.packet_id:
|
case Packet50PreChunk.packet_id:
|
||||||
# continue
|
continue
|
||||||
# case Packet51MapChunk.packet_id:
|
case Packet51MapChunk.packet_id:
|
||||||
# continue
|
continue
|
||||||
# case Packet34EntityTeleport.packet_id:
|
case Packet34EntityTeleport.packet_id:
|
||||||
# continue
|
continue
|
||||||
# case Packet28EntityVelocity.packet_id:
|
case Packet28EntityVelocity.packet_id:
|
||||||
# continue
|
continue
|
||||||
# case Packet31RelEntityMove.packet_id:
|
case Packet31RelEntityMove.packet_id:
|
||||||
# continue
|
continue
|
||||||
# case Packet32EntityLook.packet_id:
|
case Packet32EntityLook.packet_id:
|
||||||
# continue
|
continue
|
||||||
# case Packet33RelEntityMoveLook.packet_id:
|
case Packet33RelEntityMoveLook.packet_id:
|
||||||
# continue
|
continue
|
||||||
# case Packet73WeatherStatus.packet_id:
|
# case Packet73WeatherStatus.packet_id:
|
||||||
# continue
|
# continue
|
||||||
# case Packet52MultiBlockChange.packet_id:
|
case Packet52MultiBlockChange.packet_id:
|
||||||
# continue
|
continue
|
||||||
case _:
|
case _:
|
||||||
print(f"S {delta*1000:+8.1f}ms {pkt}")
|
print(f"S {delta*1000:+8.1f}ms {pkt}")
|
||||||
finally:
|
finally:
|
||||||
|
|
|
@ -6,6 +6,10 @@ from dataclasses import dataclass
|
||||||
|
|
||||||
from bta_proxy.itemstack import ItemStack
|
from bta_proxy.itemstack import ItemStack
|
||||||
|
|
||||||
|
from logging import getLogger
|
||||||
|
|
||||||
|
logger = getLogger(__name__)
|
||||||
|
|
||||||
class DataItemType(Enum):
|
class DataItemType(Enum):
|
||||||
BYTE = 0
|
BYTE = 0
|
||||||
SHORT = 1
|
SHORT = 1
|
||||||
|
@ -25,7 +29,8 @@ class EntityData:
|
||||||
@classmethod
|
@classmethod
|
||||||
async def read_from(cls, dis: AsyncDataInputStream) -> list[DataItem]:
|
async def read_from(cls, dis: AsyncDataInputStream) -> list[DataItem]:
|
||||||
items = []
|
items = []
|
||||||
while (data := await dis.read()) != 0x7F:
|
while (data := await dis.read()) not in (127, 255):
|
||||||
|
logger.debug(f"Read byte: {data} (type={(data & 0xE0) >> 5}, id={data & 0x1F})")
|
||||||
item_type = DataItemType((data & 0xE0) >> 5)
|
item_type = DataItemType((data & 0xE0) >> 5)
|
||||||
item_id: int = data & 0x1F
|
item_id: int = data & 0x1F
|
||||||
match item_type:
|
match item_type:
|
||||||
|
@ -49,7 +54,7 @@ class EntityData:
|
||||||
@classmethod
|
@classmethod
|
||||||
def read_from_sync(cls, dis: SyncDataInputStream) -> list[DataItem]:
|
def read_from_sync(cls, dis: SyncDataInputStream) -> list[DataItem]:
|
||||||
items = []
|
items = []
|
||||||
while (data := dis.read()) != 0x7F:
|
while (data := dis.read()) not in (127, 255):
|
||||||
item_type = DataItemType((data & 0xE0) >> 5)
|
item_type = DataItemType((data & 0xE0) >> 5)
|
||||||
item_id: int = data & 0x1F
|
item_id: int = data & 0x1F
|
||||||
match item_type:
|
match item_type:
|
||||||
|
|
|
@ -60,6 +60,11 @@ class Packet:
|
||||||
await Packet.read_field(stream, args, fields)
|
await Packet.read_field(stream, args, fields)
|
||||||
for _ in range(length)
|
for _ in range(length)
|
||||||
]
|
]
|
||||||
|
case "tuple", *tuples:
|
||||||
|
out = []
|
||||||
|
for tup in tuples:
|
||||||
|
out.append(await Packet.read_field(stream, tup, fields))
|
||||||
|
return tuple(out)
|
||||||
case "uint":
|
case "uint":
|
||||||
return await stream.read_uint()
|
return await stream.read_uint()
|
||||||
case "int":
|
case "int":
|
||||||
|
@ -190,7 +195,8 @@ class Packet:
|
||||||
for key, _ in self.FIELDS:
|
for key, _ in self.FIELDS:
|
||||||
if "?" in key:
|
if "?" in key:
|
||||||
key, cond = key.split("?", 1)
|
key, cond = key.split("?", 1)
|
||||||
fields.append(f"{key}={getattr(self, key, None)!r} if {cond}")
|
fields.append(f"{key}={getattr(self, key, None)!r} depending on {cond}")
|
||||||
else:
|
else:
|
||||||
fields.append(f"{key}={getattr(self, key)!r}")
|
fields.append(f"{key}={getattr(self, key)!r}")
|
||||||
return f'<{pkt_name} {str.join(", ", fields)}>'
|
return f'<{pkt_name} {str.join(", ", fields)}>'
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,5 @@ from .base import Packet
|
||||||
class Packet138PlayerList(Packet, packet_id=138):
|
class Packet138PlayerList(Packet, packet_id=138):
|
||||||
FIELDS = [
|
FIELDS = [
|
||||||
('n_players', 'int'),
|
('n_players', 'int'),
|
||||||
('players', ('list', 'n_players', 'str')),
|
('players', ('list', 'n_players', 'tuple', 'str', 'int')),
|
||||||
('scores', ('list', 'n_players', 'int')),
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -11,5 +11,5 @@ class Packet24MobSpawn(Packet, packet_id=24):
|
||||||
('pitch', 'byte'),
|
('pitch', 'byte'),
|
||||||
('metadata', 'entitydata'),
|
('metadata', 'entitydata'),
|
||||||
('nickname', 'string'),
|
('nickname', 'string'),
|
||||||
('chatcolor', 'byte'),
|
('chatcolor', 'ubyte'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -37,7 +37,7 @@ class CustomFormatter(logging.Formatter):
|
||||||
return formatter.format(record)
|
return formatter.format(record)
|
||||||
|
|
||||||
streamhandler = logging.StreamHandler()
|
streamhandler = logging.StreamHandler()
|
||||||
streamhandler.setLevel(logging.INFO)
|
streamhandler.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
streamhandler.setFormatter(CustomFormatter())
|
streamhandler.setFormatter(CustomFormatter())
|
||||||
|
|
||||||
|
@ -55,15 +55,13 @@ async def amain(stream: AsyncDataInputStream):
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
pkt = await Packet.read_packet(stream)
|
pkt = await Packet.read_packet(stream)
|
||||||
logger.info(f"we just got a package {pkt.__class__.__name__}")
|
logger.info(f"we just got a package {pkt!r}")
|
||||||
for key, _ in pkt.FIELDS:
|
|
||||||
logger.info(f"=== pkt.{key} = {getattr(pkt, key)!r}")
|
|
||||||
except EOFError:
|
except EOFError:
|
||||||
logger.warning("EOFError")
|
logger.warning("EOFError")
|
||||||
break
|
break
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(e)
|
logger.error(e)
|
||||||
logger.warning("ignoring it :)")
|
raise e
|
||||||
logger.info("exiting")
|
logger.info("exiting")
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue