This commit is contained in:
rooba 2022-03-17 14:52:04 +00:00
parent 5c818cac5a
commit 1779b47daf
14 changed files with 355 additions and 309 deletions

3
.gitignore vendored
View File

@ -17,3 +17,6 @@ test*.*
.accounts_2
.names
.words
.zprofile
.junk

View File

@ -1,3 +1,10 @@
from .character import Character, Traits
from .client import Client
from .client_base import ClientBase, JUNK
from .packet import Packet, iPacket, oPacket
from .packet_helper import Helpers
from .client import NAMES
__all__ = (
"Character",
"ClientBase",
@ -8,18 +15,5 @@ __all__ = (
"oPacket",
"NAMES",
"Traits",
"JUNK"
)
from .character import Character, Traits
from .client_base import ClientBase
from .client import Client
from .packet import Packet, iPacket, oPacket
from .packet_helper import Helpers
NAMES = []
with open("maple_clb/.names", "r") as f:
NAMES.extend([l.rstrip("\n") for l in f.readlines()])
with open("maple_clb/.words", "r") as f:
NAMES.extend([l.rstrip("\n") for l in f.readlines()])

View File

@ -1,6 +1,6 @@
from random import choice, randint
from asyncio import sleep, Event
from asyncio import Event, sleep
from ipaddress import IPv4Address
from random import choice, randint
from rich import print
@ -11,11 +11,14 @@ from .packet_helper import Helpers
from .tools import big_fuckin_mac
NAMES = []
class Client(ClientBase):
def __init__(
self,
loop=None,
names=None,
# names=None,
username=None,
password=None,
proxy=None,
@ -33,7 +36,7 @@ class Client(ClientBase):
self._characters = []
self._character_id = 0
self._char_selected = None
self._NAMES = names
self._NAMES = NAMES
self._char_name = ""

270
clb/client_base.py Normal file
View File

@ -0,0 +1,270 @@
from asyncio import (Event, Lock, Queue, Task, TimeoutError, create_task,
get_event_loop, sleep)
from datetime import datetime
from socket import AF_INET, IPPROTO_TCP, SOCK_STREAM, TCP_NODELAY, socket
# from socks import socksocket, SOCKS5, create_connection
try:
from python_socks import ProxyConnectionError
from python_socks.async_.asyncio._connect import connect_tcp
from python_socks.async_.asyncio._proxy import Socks5Proxy
except ImportError:
print("python_socks is required to enable proxied connections, all connections made will be unproxied.") # type: ignore
try:
from rich import print
except ImportError:
...
from re import compile
from .crypto import MapleAes, MapleIV, decrypt_transform, encrypt_transform
from .opcodes import RecvOps, SendOps
from .packet import PacketHandler, iPacket
PROXY_RE = compile(r"(?=^(?:([^:]+):([^@]+)@)?([^:]+):([^$]+)$)")
JUNK = set()
LOGIN_PORT = 8485
class ClientBase:
def __init__(self, _loop=None, proxy=None, pproxy=None):
self._loop = _loop or get_event_loop()
self._proxy_url = proxy or ""
match = PROXY_RE.match(self._proxy_url)
if match:
if len(match.groups()) > 2:
self._prox_user, self._prox_pass, self._prox_ip, self._prox_port = match.groups()
self._prox_port = int(self._prox_port)
else:
self._proxy_ip, self._proxy_port = match.groups()
self._proxy_port = int(self._proxy_port)
self._proxy_user = None
self._proxy_pass = None
else:
...
self._tasks = []
self._packet_handlers = []
self._can_login: Event = Event()
self._migrating: Event = Event()
self._migrated: Event = Event()
self._wait_sock_connect = Event()
self._lock: Lock = Lock()
self._action_queue: Queue = Queue()
self._events_task: Task
self._conn_port = 0
self._sock: socket
self._version = None
self._sub_version = None
self._locale = None
self._recv_iv: MapleIV = MapleIV()
self._send_iv: MapleIV = MapleIV()
self._buff = bytearray()
self._prev_buff = bytearray()
self.add_packet_handlers()
async def _connect_sock(self):
# self._sock = socket(family=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP)
# self._sock.setblocking(False)
# self._sock.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)
# self._sock.setproxy(proxy_type=SOCKS5, addr=self._prox_ip, port=self._prox_port, username=self._prox_user, password=self._prox_pass)
# await self._loop.sock_connect(self._sock, (self._host, self._conn_port))
self._conn = Socks5Proxy(proxy_host=self._prox_ip, proxy_port=self._prox_port, username=self._prox_user, password=self._prox_pass)
try:
self._sock = await self._conn.connect(self._host, self._conn_port)
except ProxyConnectionError:
print(f"{ProxyConnectionError.__name__} | Unable connect to proxy socket")
JUNK.add(self._proxy_url)
del self._events_task
return
except TimeoutError:
print(f"{TimeoutError.__name__} | Unable to connect to proxy")
JUNK.add(self._proxy_url)
del self._events_task
return
except Exception as e:
print(f"Unhandled Exception | {e.__class__.__name__}")
del self._events_task
self._wait_sock_connect.set()
async def start(self):
self._events_task = create_task(self.process_events())
self._host = "51.222.56.169"
self._conn_port = LOGIN_PORT
await self._sock_recv()
async def send_packet(self, opacket, raw=False):
async with self._lock:
opkt = bytearray(opacket.getvalue())
length = len(opkt)
buf = bytearray(length + 4)
buf[0:4] = self._send_iv.get_header(self._version, length)
opkt = bytearray(encrypt_transform(opkt))
MapleAes.transform(opkt, self._send_iv)
buf[4 : length + 4] = opkt
print(f"[{datetime.now().strftime('%d %H:%M:%S.%f')}] [SEND] : {SendOps(opacket.op_code).name} | {opacket.to_string()}")
if not self._sock:
return
await self._loop.sock_sendall(self._sock, buf)
def schedule_action(self, op_code, delay: None | float = 1.0):
async def schd():
if delay:
await sleep(delay)
await self._action_queue.put(op_code)
self._tasks.append(create_task(schd()))
async def _sock_recv(self):
await self._connect_sock()
while self._loop.is_running():
try:
await self._wait_sock_connect.wait()
while self._sock:
await sleep(1)
try:
self._buff.extend(bytearray((await self._loop.sock_recv(self._sock, 8192))))
if self._buff == bytearray(b"\x00\x00\x00\x00\x00\x00"):
self._wait_sock_connect.clear()
self._recv_iv.reset()
self._send_iv.reset()
self._buff = bytearray()
self._prev_buff = bytearray()
break
if not self._send_iv and self._buff:
begin_packet = iPacket(self._buff)
op_code = 0x0E
print(f"[{datetime.now().strftime('%d %H:%M:%S.%f')}] [Client Hello]")
self._version = begin_packet.decode_short()
self._sub_version = int(begin_packet.decode_string())
self._send_iv(begin_packet.decode_int())
self._recv_iv(begin_packet.decode_int())
self._locale = begin_packet.decode_byte()
self._buff = bytearray()
if self._conn_port != LOGIN_PORT and self._migrating.is_set():
self.schedule_action(SendOps.PLAYER_LOGGEDIN, 2.0)
self._migrated.set()
self._migrating.clear()
else:
self.schedule_action(SendOps.LOGIN_PASSWORD, 2.0)
else:
while len(self._buff) > 0:
try:
length = MapleAes.get_length(self._buff[0:4])
buf = bytearray(bytearray(self._buff)[4 : length + 4])
buf = bytearray(MapleAes.transform(buf, self._recv_iv))
buf = decrypt_transform(buf)
packet = iPacket(buf)
await self.handle_packet(packet)
if len(self._buff) - (length + 4) > 0:
self._buff = self._buff[length + 4 :]
else:
self._buff = bytearray()
self._prev_buff = self._buff
except:
...
except ConnectionResetError as e:
self._recv_iv.reset()
self._send_iv.reset()
self._buff = bytearray()
self._prev_buff = bytearray()
self._wait_sock_connect.clear()
await self._connect_sock()
except Exception as e:
print(f"[{datetime.now().strftime('%d %H:%M:%S.%f')}] error in sock_recv: {e}")
else:
print(f"Sock got terminated")
break
except Exception as e:
print(f"Unhandled Exception line 215: {e}")
async def handle_packet(self, packet):
coro = None
for pkt_hndl in self._packet_handlers:
if pkt_hndl.op_code == packet.op_code:
coro = pkt_hndl.callback
break
else:
print(
f"[{datetime.now().strftime('%d %H:%M:%S.%f')}] [RECV] [UNHANDLED] : {RecvOps(packet.op_code).name} | {packet.to_string()}"
)
return
if not coro:
return
# raise AttributeError
print(f"[{datetime.now().strftime('%d %H:%M:%S.%f')}] [RECV] : {RecvOps(packet.op_code).name} | {packet.to_string()}")
if packet.op_code == RecvOps.SERVER_IP:
self._migrating.set()
packet.decode_short()
packet.decode_int()
self._conn_port = packet.decode_short()
self._client_id = packet.decode_int()
self._sock.close()
del self._sock
self._send_iv.reset()
self._recv_iv.reset()
self._buff = bytearray()
self._prev_buff = bytearray()
self._wait_sock_connect.clear()
await self._connect_sock()
return False
# await self._connect_sock()
else:
create_task(coro(self, packet))
def add_packet_handlers(self):
import inspect
members = inspect.getmembers(self)
for _, member in members:
if (
isinstance(member, PacketHandler)
and member not in self._packet_handlers
):
self._packet_handlers.append(member)
async def process_events(self):
raise NotImplementedError

View File

@ -1,7 +1,5 @@
from Crypto.Cipher import AES
# from struct import unpack, pack
class MapleAes:
_user_key = bytearray([

View File

@ -4,7 +4,7 @@ from random import randint, choice
def big_fuckin_mac() -> str:
hexchars = "ABCDEF0123456789"
return f'''{', '.join([
choice(["FF-AA-66-66-00-77", "NN-II-GG-GG-EE-RR"]) for _ in range(4)
choice(["FF-AA-66-66-00-77", "NN-II-GG-GG-EE-RR"]) for _ in range(40)
])}, {'-'.join([f"{choice(hexchars)}{choice(hexchars)}" for _ in range(6)])}'''

View File

@ -1,243 +0,0 @@
from asyncio import (
BaseTransport,
Event,
Future,
Lock,
Queue,
Task,
get_event_loop,
sleep,
get_running_loop,
new_event_loop,
create_task
)
from asyncio.trsock import TransportSocket
from socket import AF_INET, IPPROTO_TCP, SOCK_STREAM, TCP_NODELAY, socket
from socks import socksocket, SOCKS5, create_connection
from rich import print
from .crypto import MapleAes, MapleIV, decrypt_transform, encrypt_transform
from .opcodes import RecvOps, SendOps
from .packet import PacketHandler, iPacket
from random import randint
from re import compile
PROXY_RE = compile(r'(?=^([^:]+):([^@]+)@([^:]+):([^$]+)$)')
LOGIN_PORT = 8485
class ClientBase:
def __init__(self, _loop=None, proxy=None, pproxy=None):
self._loop = _loop or get_event_loop()
self._proxy_url = proxy
match = PROXY_RE.match(self._proxy_url)
if match:
self._prox_user, self._prox_pass, self._prox_ip, self._prox_port = match.groups()
self._prox_port = int(self._prox_port)
else:
...
self._tasks = []
self._packet_handlers = []
self._can_login: Event = Event()
self._migrating: Event = Event()
self._migrated: Event = Event()
self._ready: Event = Event()
self._lock: Lock = Lock()
self._action_queue: Queue = Queue()
self._sock: socket | socksocket
self._sock_file_desc: int
self._version = None
self._sub_version = None
self._locale = None
self._recv_iv: MapleIV = MapleIV()
self._send_iv: MapleIV = MapleIV()
self._wait_sock_connect = Event()
self._buff = bytearray()
self._prev_buff = bytearray()
self._conn_port = 0
self.add_packet_handlers()
# def create(
# cls,
# proxy_type: ProxyType,
# host: str,
# port: int,
# username: str = None,
# password: str = None,
# rdns: bool = None,
# **kwargs,
async def _connect_sock(self):
# if hasattr(self, "_proxy_url"):
self._sock = socksocket(family=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP)
self._sock.setproxy(proxy_type=SOCKS5, addr=self._prox_ip, port=self._prox_port, username=self._prox_user, password=self._prox_pass)
# else:
# self._sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
self._sock.setblocking(False)
self._sock.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)
# self._sock = TransportSocket(self._sock)
await self._loop.sock_connect(self._sock, (self._host, self._conn_port))
self._wait_sock_connect.set()
async def start(self):
self._tasks.append(create_task(self.process_events()))
self._host = "51.222.56.169"
self._conn_port = LOGIN_PORT
self._ready.set()
self._tasks.append(await self._sock_recv())
async def send_packet(self, opacket, raw=False):
async with self._lock:
opkt = bytearray(opacket.getvalue())
length = len(opkt)
buf = bytearray(length + 4)
buf[0:4] = self._send_iv.get_header(self._version, length)
opkt = bytearray(encrypt_transform(opkt))
MapleAes.transform(opkt, self._send_iv)
buf[4 : length + 4] = opkt
print(f"[SEND] : {SendOps(opacket.op_code).name} | {opacket.to_string()}")
if not self._sock:
return
await self._loop.sock_sendall(self._sock, buf)
def schedule_action(self, op_code, delay: None | float = 1.0):
async def schd():
if delay:
await sleep(delay)
await self._action_queue.put(op_code)
self._tasks.append(create_task(schd()))
async def _sock_recv(self):
await self._connect_sock()
data = bytearray()
while self._loop.is_running():
await self._wait_sock_connect.wait()
print(self._sock)
while self._sock:
await sleep(0.1)
try:
self._buff.extend(bytearray((await self._loop.sock_recv(self._sock, 8192))))
if self._buff == bytearray(b"\x00\x00\x00\x00\x00\x00"):
self._wait_sock_connect.clear()
self._recv_iv.reset()
self._send_iv.reset()
self._buff = bytearray()
self._prev_buff = bytearray()
break
if not self._send_iv and self._buff:
begin_packet = iPacket(self._buff)
op_code = 0x0E
print("[Client Hello]")
self._version = begin_packet.decode_short()
self._sub_version = int(begin_packet.decode_string())
self._send_iv(begin_packet.decode_int())
self._recv_iv(begin_packet.decode_int())
self._locale = begin_packet.decode_byte()
self._buff = bytearray()
if self._conn_port != LOGIN_PORT or self._migrating.is_set():
self.schedule_action(SendOps.PLAYER_LOGGEDIN, 2.0)
self._migrated.set()
self._migrating.clear()
else:
self.schedule_action(SendOps.LOGIN_PASSWORD, 2.0)
else:
while len(self._buff) > 0:
try:
length = MapleAes.get_length(self._buff[0:4])
buf = bytearray(bytearray(self._buff)[4 : length + 4])
buf = bytearray(MapleAes.transform(buf, self._recv_iv))
buf = decrypt_transform(buf)
packet = iPacket(buf)
await self.handle_packet(packet)
if len(self._buff) - (length + 4) > 0:
self._buff = self._buff[length + 4 :]
else:
self._buff = bytearray()
self._prev_buff = self._buff
except:
...
except Exception as e:
print(f"error in sock_recv: {e}")
async def handle_packet(self, packet):
coro = None
for pkt_hndl in self._packet_handlers:
if pkt_hndl.op_code == packet.op_code:
coro = pkt_hndl.callback
break
else:
print(
f"[RECV] [UNHANDLED] : {RecvOps(packet.op_code).name} | {packet.to_string()}"
)
return
if not coro:
raise AttributeError
print(f"[RECV] : {RecvOps(packet.op_code).name} | {packet.to_string()}")
if packet.op_code == RecvOps.SERVER_IP:
self._migrating.set()
packet.decode_short()
packet.decode_int()
self._conn_port = packet.decode_short()
self._client_id = packet.decode_int()
self._sock.close()
del self._sock
self._send_iv.reset()
self._recv_iv.reset()
self._buff = bytearray()
self._prev_buff = bytearray()
self._wait_sock_connect.clear()
await self._connect_sock()
return False
# await self._connect_sock()
else:
create_task(coro(self, packet))
def add_packet_handlers(self):
import inspect
members = inspect.getmembers(self)
for _, member in members:
if (
isinstance(member, PacketHandler)
and member not in self._packet_handlers
):
self._packet_handlers.append(member)
async def process_events(self):
raise NotImplementedError

View File

@ -1,4 +1,5 @@
pycryptodome==3.14.1
Pygments==2.11.2
rich==12.0.0
attrs==21.4.0
attrs==21.4.0
uvloop>=0.16.0
async_timeout>=4.0.2
python_socks>=2.0.3

62
run.py Normal file
View File

@ -0,0 +1,62 @@
from asyncio import create_task, get_event_loop, new_event_loop, run, sleep
from json import loads
from random import choice
import clb
try:
import uvloop
uvloop.install()
except ImportError:
...
from os.path import dirname
dir_path = dirname(__file__)
ACCOUNTS = []
TASKS = []
PROXIES = []
with open(f"{dir_path}/.names", "r") as f:
clb.NAMES.extend([l.rstrip("\n") for l in f.readlines()])
with open(f"{dir_path}/.words", "r") as f:
clb.NAMES.extend([l.rstrip("\n") for l in f.readlines()])
with open(f"{dir_path}/.proxies", "r") as f:
for line in f.readlines():
PROXIES.append(line.rstrip("\n"))
with open(f"{dir_path}/.accounts_2", "r") as f:
ACCOUNTS = loads(f.read())
print(len(clb.NAMES), len(PROXIES), len(ACCOUNTS))
loop = new_event_loop()
async def create_clients():
loop.set_debug(True)
for account in ACCOUNTS[65:67]:
client = clb.Client(
loop=loop,
# names=NAMES,
username=account["username"],
password=account["password"],
proxy=choice(PROXIES)
)
create_task(client.start())
while loop.is_running():
await sleep(60.0)
loop.run_until_complete(create_clients())
# loop.run_forever()
with open("{dir_path}/.junk", "w+") as f:
for l in clb.JUNK:
f.write(f"{l}""\n")

42
run_.py
View File

@ -1,42 +0,0 @@
from maple_clb import Client, NAMES
from asyncio import run, create_task, new_event_loop, sleep, get_event_loop
from json import loads
try:
import uvloop
uvloop.install()
except:
print("wot")
tasks = []
ACCOUNTS = []
clients = []
with open("maple_clb/.accounts2", "r") as f:
ACCOUNTS = loads(f.read())
loop=new_event_loop()
async def create_clients(accounts):
loop.set_debug(True)
for account in accounts[1700:1730]:
client = Client(
loop=loop,
names=NAMES,
username=account["username"],
password=account["password"],
proxy=account["proxy"]
)
clients.append(create_task(client.start()))
# for client in clients:
# create_task(client.start())
while loop.is_running():
await sleep(5.0)
loop.run_until_complete(create_clients(ACCOUNTS))
loop.run_forever()