proper packet header
This commit is contained in:
parent
d7dfd654ef
commit
0a6097e7be
@ -17,6 +17,10 @@ class Client(ClientBase):
|
|||||||
match action:
|
match action:
|
||||||
case SendOps.LOGIN_PASSWORD:
|
case SendOps.LOGIN_PASSWORD:
|
||||||
self._loop.create_task(self.do_login())
|
self._loop.create_task(self.do_login())
|
||||||
|
case _:
|
||||||
|
...
|
||||||
|
|
||||||
|
await sleep(0.5)
|
||||||
|
|
||||||
@packet_handler(RecvOps.PING)
|
@packet_handler(RecvOps.PING)
|
||||||
async def pong(self, ipkt):
|
async def pong(self, ipkt):
|
||||||
@ -29,4 +33,5 @@ class Client(ClientBase):
|
|||||||
opkt = oPacket(SendOps.LOGIN_PASSWORD)
|
opkt = oPacket(SendOps.LOGIN_PASSWORD)
|
||||||
opkt.encode_string(self._username)
|
opkt.encode_string(self._username)
|
||||||
opkt.encode_string(self._password)
|
opkt.encode_string(self._password)
|
||||||
|
print(f"Sending login request")
|
||||||
await self.send_packet(opkt)
|
await self.send_packet(opkt)
|
@ -1,9 +1,15 @@
|
|||||||
from asyncio import Event, get_event_loop, get_running_loop, run_coroutine_threadsafe, sleep, Lock, Queue, Task
|
from asyncio import (
|
||||||
|
Event, Lock, Queue, Task, get_event_loop, get_running_loop,
|
||||||
|
run_coroutine_threadsafe, sleep
|
||||||
|
)
|
||||||
from socket import AF_INET, IPPROTO_TCP, SOCK_STREAM, TCP_NODELAY, socket
|
from socket import AF_INET, IPPROTO_TCP, SOCK_STREAM, TCP_NODELAY, socket
|
||||||
from .packet import PacketHandler, Packet, iPacket, oPacket
|
|
||||||
from .crypto import MapleAes, decrypt_transform, encrypt_transform, MapleIV
|
|
||||||
from rich import print
|
from rich import print
|
||||||
|
|
||||||
|
from .crypto import MapleAes, MapleIV, decrypt_transform, encrypt_transform
|
||||||
|
from .opcodes import SendOps
|
||||||
|
from .packet import PacketHandler, iPacket, oPacket
|
||||||
|
|
||||||
|
|
||||||
class ClientBase:
|
class ClientBase:
|
||||||
|
|
||||||
@ -19,8 +25,8 @@ class ClientBase:
|
|||||||
self._version = None
|
self._version = None
|
||||||
self._sub_version = None
|
self._sub_version = None
|
||||||
self._locale = None
|
self._locale = None
|
||||||
self._recv_iv: MapleIV | None = None
|
self._recv_iv: MapleIV = None # type: ignore
|
||||||
self._send_iv: MapleIV | None = None
|
self._send_iv: MapleIV = None # type: ignore
|
||||||
self._buff = bytearray()
|
self._buff = bytearray()
|
||||||
self._recv_task = None
|
self._recv_task = None
|
||||||
self.add_packet_handlers()
|
self.add_packet_handlers()
|
||||||
@ -39,12 +45,24 @@ class ClientBase:
|
|||||||
opkt = bytearray(opacket.getvalue())
|
opkt = bytearray(opacket.getvalue())
|
||||||
length = len(opkt)
|
length = len(opkt)
|
||||||
|
|
||||||
# buf = memoryview(opkt)
|
buf = bytearray(length + 4)
|
||||||
header = MapleAes.get_header(self._send_iv, length, self._version)
|
buf[0:4] = self._send_iv.get_header(self._version, length)
|
||||||
encrypt_transform(opkt)
|
opkt = encrypt_transform(opkt)
|
||||||
opkt = MapleAes.transform(opkt, self._send_iv)
|
MapleAes.transform(opkt, self._send_iv)
|
||||||
|
buf[4:length + 4] = opkt
|
||||||
|
await self._loop.sock_sendall(self._sock, buf)
|
||||||
|
|
||||||
await self._loop.sock_sendall(self._sock, header + opkt)
|
def schedule_action(self, op_code, delay: None | float = 1.0):
|
||||||
|
|
||||||
|
async def schd():
|
||||||
|
if delay:
|
||||||
|
await sleep(delay)
|
||||||
|
if self._sock.fileno():
|
||||||
|
await self._action_queue.put(op_code)
|
||||||
|
else:
|
||||||
|
raise ConnectionResetError
|
||||||
|
|
||||||
|
return self._loop.create_task(schd())
|
||||||
|
|
||||||
async def _sock_recv(self):
|
async def _sock_recv(self):
|
||||||
# 51.222.56.169
|
# 51.222.56.169
|
||||||
@ -58,12 +76,13 @@ class ClientBase:
|
|||||||
while self._sock.fileno():
|
while self._sock.fileno():
|
||||||
try:
|
try:
|
||||||
self._buff.extend(
|
self._buff.extend(
|
||||||
(await self._loop.sock_recv(self._sock, nbytes)))
|
(await self._loop.sock_recv(self._sock, nbytes))
|
||||||
|
)
|
||||||
except ConnectionResetError:
|
except ConnectionResetError:
|
||||||
print("Connection reset, attempting to reconnect..")
|
print("Connection reset, attempting to reconnect..")
|
||||||
self._create_sock()
|
self._create_sock()
|
||||||
self._send_iv = None
|
del self._send_iv
|
||||||
self._recv_iv = None
|
del self._recv_iv
|
||||||
if self._action_task:
|
if self._action_task:
|
||||||
self._action_task.cancel()
|
self._action_task.cancel()
|
||||||
self._action_queue = Queue()
|
self._action_queue = Queue()
|
||||||
@ -73,20 +92,27 @@ class ClientBase:
|
|||||||
begin_packet = iPacket(self._buff)
|
begin_packet = iPacket(self._buff)
|
||||||
op_code = 0x0E
|
op_code = 0x0E
|
||||||
self._version = begin_packet.decode_short()
|
self._version = begin_packet.decode_short()
|
||||||
self._sub_version = begin_packet.decode_string()
|
self._sub_version = int(begin_packet.decode_string())
|
||||||
self._send_iv = MapleIV(begin_packet.decode_int())
|
self._send_iv = MapleIV(begin_packet.decode_int())
|
||||||
self._recv_iv = MapleIV(begin_packet.decode_int())
|
self._recv_iv = MapleIV(begin_packet.decode_int())
|
||||||
self._locale = begin_packet.decode_byte()
|
self._locale = begin_packet.decode_byte()
|
||||||
# print(begin_packet)
|
# print(begin_packet)
|
||||||
self._action_task = self._loop.create_task(
|
self._action_task = self._loop.create_task(
|
||||||
getattr(self, "begin")())
|
getattr(self, "begin")()
|
||||||
|
)
|
||||||
print(
|
print(
|
||||||
f"Op Code: {op_code} [Client Hello] | Version: {self._version} | Sub Version: {self._sub_version} | Locale: {self._locale} | Send IV: {self._send_iv} | Recv IV: {self._recv_iv}"
|
f"Op Code: {op_code} [Client Hello] "
|
||||||
|
f"| Version: {self._version} "
|
||||||
|
f"| Sub Version: {self._sub_version} "
|
||||||
|
f"| Locale: {self._locale} "
|
||||||
|
f"| Send IV: {self._send_iv} "
|
||||||
|
f"| Recv IV: {self._recv_iv}"
|
||||||
)
|
)
|
||||||
self._buff = bytearray()
|
self._buff = bytearray()
|
||||||
|
self.schedule_action(SendOps.LOGIN_PASSWORD, 5.0)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if self._buff and len(self._buff) > 4:
|
if self._buff:
|
||||||
length = MapleAes.get_length(self._buff[0:4])
|
length = MapleAes.get_length(self._buff[0:4])
|
||||||
|
|
||||||
if length != len(self._buff[4:length + 4]):
|
if length != len(self._buff[4:length + 4]):
|
||||||
@ -140,4 +166,4 @@ class ClientBase:
|
|||||||
self._packet_handlers.append(member)
|
self._packet_handlers.append(member)
|
||||||
|
|
||||||
async def begin(self):
|
async def begin(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
17
crypto.py
17
crypto.py
@ -54,8 +54,8 @@ class MapleAes:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_header(iv, length, major_ver):
|
def get_header(iv, length, major_ver):
|
||||||
first = -(major_ver + 1) ^ iv.hiword
|
first = iv.hiword ^ major_ver
|
||||||
second = (first + 2**16) ^ length
|
second = first ^ length
|
||||||
return bytearray([
|
return bytearray([
|
||||||
first & 0xFF, first >> 8 & 0xFF, second & 0xFF, second >> 8 & 0xFF
|
first & 0xFF, first >> 8 & 0xFF, second & 0xFF, second >> 8 & 0xFF
|
||||||
])
|
])
|
||||||
@ -64,6 +64,10 @@ class MapleAes:
|
|||||||
def get_length(data):
|
def get_length(data):
|
||||||
return ((data[1] << 8) + data[0]) ^ ((data[3] << 8) + data[2])
|
return ((data[1] << 8) + data[0]) ^ ((data[3] << 8) + data[2])
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def encode_length(data):
|
||||||
|
return ((data[1] << 8) + data[0]) | ((data[3] << 8) + data[2])
|
||||||
|
|
||||||
|
|
||||||
class MapleIV:
|
class MapleIV:
|
||||||
_shuffle = bytearray([
|
_shuffle = bytearray([
|
||||||
@ -108,6 +112,13 @@ class MapleIV:
|
|||||||
def loword(self):
|
def loword(self):
|
||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
|
def get_header(self, version, length):
|
||||||
|
first = self.hiword ^ version
|
||||||
|
second = first ^ length
|
||||||
|
return bytearray([
|
||||||
|
first & 0xFF, first >> 8 & 0xFF, second & 0xFF, second >> 8 & 0xFF
|
||||||
|
])
|
||||||
|
|
||||||
def shuffle(self):
|
def shuffle(self):
|
||||||
seed = [0xF2, 0x53, 0x50, 0xC6]
|
seed = [0xF2, 0x53, 0x50, 0xC6]
|
||||||
p_iv = self.value
|
p_iv = self.value
|
||||||
@ -225,7 +236,7 @@ def encrypt_transform(data):
|
|||||||
length -= 1
|
length -= 1
|
||||||
i -= 1
|
i -= 1
|
||||||
|
|
||||||
return bytearray([b[b_] for b_ in b])
|
return bytearray([byte for byte in b.values()])
|
||||||
|
|
||||||
|
|
||||||
def roll_left(value, shift):
|
def roll_left(value, shift):
|
||||||
|
Loading…
Reference in New Issue
Block a user