WebSocket API, token parser updates
This commit is contained in:
parent
6993aadf03
commit
c0f60cfe5c
8 changed files with 216 additions and 70 deletions
|
@ -4,8 +4,16 @@ import base64
|
|||
|
||||
brkregex = re.compile(r'\((?!\)|[\'\"])(.+?)(?<!\(|[\'\"])\)')
|
||||
|
||||
def parse_brackets(f):
|
||||
return brkregex.search(f)[1]
|
||||
def parse_brackets(f, arrow):
|
||||
|
||||
match = brkregex.finditer(f)
|
||||
if not arrow:
|
||||
return match[0].group(1)
|
||||
|
||||
for r in match:
|
||||
func = r.group(1)
|
||||
if '=>' in func:
|
||||
return func
|
||||
|
||||
def to_ecma5_function(f):
|
||||
fnstart = f.find('{')+1
|
||||
|
|
|
@ -11,6 +11,7 @@ from . import aterrors
|
|||
from . import atfm
|
||||
from . import atconf
|
||||
from . import atplayers
|
||||
from .atwss import AternosWss
|
||||
|
||||
JAVA = 0
|
||||
BEDROCK = 1
|
||||
|
@ -26,7 +27,9 @@ class Status(enum.IntEnum):
|
|||
on = 1
|
||||
loading = 2
|
||||
shutdown = 3
|
||||
unknown = 6
|
||||
error = 7
|
||||
confirm = 10
|
||||
|
||||
class AternosServer:
|
||||
|
||||
|
@ -58,38 +61,12 @@ class AternosServer:
|
|||
self.atconn.parse_token(servreq.content)
|
||||
self.atconn.generate_sec()
|
||||
|
||||
async def wss(self):
|
||||
async def wss(self) -> AternosWss:
|
||||
|
||||
session = self.atconn.session.cookies['ATERNOS_SESSION']
|
||||
headers = [
|
||||
('User-Agent', atconnect.REQUA),
|
||||
('Cookie',
|
||||
f'ATERNOS_SESSION={session}; ' + \
|
||||
f'ATERNOS_SERVER={self.servid}')
|
||||
]
|
||||
|
||||
async with websockets.connect(
|
||||
'wss://aternos.org/hermes',
|
||||
extra_headers=headers
|
||||
) as websocket:
|
||||
while True:
|
||||
msg = await websocket.recv()
|
||||
r = json.loads(msg)
|
||||
|
||||
if r['type'] == 'line' \
|
||||
and r['stream'] == 'console'\
|
||||
and self.savelog:
|
||||
self.log.append(r['data'])
|
||||
|
||||
if r['type'] == 'heap':
|
||||
self._ram = r['data']['usage']
|
||||
|
||||
if r['type'] == 'tick':
|
||||
aver = 1000 / r['data']['averageTickTime']
|
||||
self._tps = 20 if aver > 20 else aver
|
||||
|
||||
if r['type'] == 'status':
|
||||
self._info = json.loads(r['message'])
|
||||
return AternosWss(
|
||||
self.atconn.session.cookies,
|
||||
self.servid
|
||||
)
|
||||
|
||||
def start(self, headstart:bool=False, accepteula:bool=True) -> None:
|
||||
|
||||
|
|
97
python_aternos/atwss.py
Normal file
97
python_aternos/atwss.py
Normal file
|
@ -0,0 +1,97 @@
|
|||
import enum
|
||||
import json
|
||||
import asyncio
|
||||
import websockets
|
||||
from typing import Union, Any, Dict, Callable, Coroutine
|
||||
|
||||
from .atconnect import REQUA
|
||||
|
||||
class Streams(enum.IntEnum):
|
||||
status = 0
|
||||
queue = 1
|
||||
console = 2
|
||||
ram = 3
|
||||
tps = 4
|
||||
|
||||
class AternosWss:
|
||||
|
||||
def __init__(self, session:str, servid:str) -> None:
|
||||
|
||||
self.session = session
|
||||
self.servid = servid
|
||||
self.recv = {}
|
||||
|
||||
def wssreceiver(self, stream:int) -> Callable[[Callable[[Any],Coroutine[Any,Any,None]]],Any]:
|
||||
def decorator(func:Callable[[Any],Coroutine[Any,Any,None]]) -> None:
|
||||
self.recv[stream] = func
|
||||
return decorator
|
||||
|
||||
async def connect(self) -> None:
|
||||
|
||||
headers = [
|
||||
('User-Agent', REQUA),
|
||||
(
|
||||
'Cookie',
|
||||
f'ATERNOS_SESSION={self.session}; ' +\
|
||||
f'ATERNOS_SERVER={self.servid}'
|
||||
)
|
||||
]
|
||||
self.socket = await websockets.connect(
|
||||
'wss://aternos.org/hermes',
|
||||
extra_headers=headers
|
||||
)
|
||||
asyncio.run(wssworker())
|
||||
|
||||
async def close(self) -> None:
|
||||
|
||||
await self.socket.close()
|
||||
del self.socket
|
||||
|
||||
async def send(self, obj:Union[Dict[str, Any],str]) -> None:
|
||||
|
||||
if isinstance(obj, dict):
|
||||
obj = json.dumps(obj)
|
||||
|
||||
self.socket.send(obj)
|
||||
|
||||
async def wssworker(self) -> None:
|
||||
|
||||
keep = asyncio.create_task(keepalive())
|
||||
msgs = asyncio.create_task(receiver())
|
||||
await keep
|
||||
await msgs
|
||||
|
||||
async def keepalive(self) -> None:
|
||||
|
||||
while True:
|
||||
await asyncio.sleep(49)
|
||||
await self.socket.send('{"type":"\u2764"}')
|
||||
|
||||
async def receiver(self) -> None:
|
||||
|
||||
while True:
|
||||
data = await self.socket.recv()
|
||||
obj = json.loads(data)
|
||||
|
||||
if obj['type'] == 'line':
|
||||
msgtype = Streams.console
|
||||
msg = obj['data'].strip('\r\n ')
|
||||
|
||||
elif obj['type'] == 'heap':
|
||||
msgtype = Streams.ram
|
||||
msg = int(obj['data']['usage'])
|
||||
|
||||
elif obj['type'] == 'tick':
|
||||
msgtype = Streams.tps
|
||||
ticks = 1000 / obj['data']['averageTickTime']
|
||||
msg = 20 if ticks > 20 else ticks
|
||||
|
||||
elif obj['type'] == 'status':
|
||||
msgtype = Streams.status
|
||||
msg = json.loads(obj['message'])
|
||||
|
||||
if msgtype in self.recv:
|
||||
t = asyncio.create_task(
|
||||
self.recv[msgtype](msg)
|
||||
)
|
||||
await t
|
Reference in a new issue