From bb5978f8f5aaf1ea4af2df5fe23e4281096fb327 Mon Sep 17 00:00:00 2001 From: DarkCat09 Date: Thu, 17 Mar 2022 10:24:58 +0400 Subject: [PATCH] Arrow exprs parser! --- python_aternos/__init__.py | 16 ++++---- python_aternos/atjsparse.py | 58 ++++++---------------------- requirements.txt | 2 +- setup.py | 1 + tests/js2py_test.py | 46 +++-------------------- tests/js2py_test.py.old | 75 ------------------------------------- token.txt | 3 ++ 7 files changed, 29 insertions(+), 172 deletions(-) delete mode 100644 tests/js2py_test.py.old diff --git a/python_aternos/__init__.py b/python_aternos/__init__.py index a3ddfa1..ac41858 100644 --- a/python_aternos/__init__.py +++ b/python_aternos/__init__.py @@ -1,11 +1,9 @@ import hashlib import lxml.html -from typing import Optional, Union, List - -from . import atserver -from . import atconnect -from . import aterrors +from typing import List +from .atserver import AternosServer +from .atconnect import AternosConnect from .aterrors import AternosCredentialsError class Client: @@ -17,7 +15,7 @@ class Client: @classmethod def from_hashed(cls, username:str, md5:str): - atconn = atconnect.AternosConnect() + atconn = AternosConnect() atconn.parse_token() atconn.generate_sec() @@ -50,7 +48,7 @@ class Client: @classmethod def from_session(cls, session:str): - atconn = atconnect.AternosConnect() + atconn = AternosConnect() atconn.session.cookies.set('ATERNOS_SESSION', session) atconn.parse_token() atconn.generate_sec() @@ -60,7 +58,7 @@ class Client: @staticmethod def google() -> str: - atconn = atconnect.AternosConnect() + atconn = AternosConnect() auth = atconn.request_cloudflare( 'https://aternos.org/auth/google-login', atconnect.REQGET, redirect=False @@ -79,6 +77,6 @@ class Client: servers = [] for server in serverslist: servid = server.xpath('./div[@class="server-body"]/@data-id')[0] - servers.append(atserver.AternosServer(servid, self.atconn)) + servers.append(AternosServer(servid, self.atconn)) return servers diff --git a/python_aternos/atjsparse.py b/python_aternos/atjsparse.py index 0d0eaeb..5da1223 100644 --- a/python_aternos/atjsparse.py +++ b/python_aternos/atjsparse.py @@ -1,57 +1,21 @@ -import re +import regex import base64 import js2py from typing import Optional, Union, List, Any -# regexr.com/6el10 -arrowexp = re.compile(r'(\(?(\w+(?:,\s*\w+)*)\)?|\(\))\s*=>\s*(({\s*.+\s*})|(.+;|.+$))') - -# Thanks to https://stackoverflow.com/a/1651562/17901968 -def brackets(s:str, search:Optional[str]=None) -> List[Union[int]]: - result = [] - content = [s] - repeated = False - for expr in content: - if expr.find('(') == -1: continue - count = -1 - indexes = [] - cont = False - for i, ch in enumerate(expr): - if ch == '(': - indexes.append(i) - if count == -1: - count = 1 - else: - count += 1 - if ch == ')': - if len(indexes) > 1: - indexes.pop() - else: - indexes.append(i) - if expr.find('(', i) != -1: - cont = True - count -= 1 - if count == 0: break - if count != 0: - raise ValueError('Unmatched parenthesis') - else: - inner = expr[indexes[0]+1:indexes[1]] - if repeated: - content.pop() - repeated = False - content.append(inner) - if search == None \ - or search in inner: - result.append(indexes) - if cont: - content.append(content[len(content)-2]) - repeated = True - return result +# Thanks to http://regex.inginf.units.it/ +arrowexp = regex.compile(r'\w[^\}]*+') def to_ecma5_function(f:str) -> str: - pass + match = arrowexp.search(f) + conv = '(function(){' + match.group(0) + '})()' + return regex.sub( + r'(?:s|\(s\)) => s.split\([\'"]{2}\).reverse\(\).join\([\'"]{2}\)', + 'function(s){return s.split(\'\').reverse().join(\'\')}', + conv + ) -def atob(s): +def atob(s:str) -> str: return base64.standard_b64decode(str(s)).decode('utf-8') def exec(f:str) -> Any: diff --git a/requirements.txt b/requirements.txt index 4142fad..a3ad386 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -lxml==4.6.2 +lxml==4.8.0 requests==2.25.1 cloudscraper==1.2.58 js2py==0.71 diff --git a/setup.py b/setup.py index 6174251..17e5e94 100644 --- a/setup.py +++ b/setup.py @@ -22,6 +22,7 @@ setuptools.setup( 'Documentation': 'https://github.com/DarkCat09/python-aternos/wiki/Client-(entry-point)', }, classifiers=[ + 'Development Status :: 4 - Beta', 'Programming Language :: Python :: 3', 'License :: OSI Approved :: Apache Software License', 'Operating System :: OS Independent' diff --git a/tests/js2py_test.py b/tests/js2py_test.py index a25b4ae..e07b61a 100644 --- a/tests/js2py_test.py +++ b/tests/js2py_test.py @@ -1,7 +1,5 @@ -#!/usr/bin/env python3 import re -import base64 -import js2py +from python_aternos import atjsparse # Use tests from a file tests = [] @@ -10,43 +8,10 @@ with open('../token.txt', 'rt') as f: del lines[len(lines)-1] # Remove empty string tests = lines -arrowre = re.compile(r'(\w+?|\(\w+?(?:,\s*\w+?)*\)|\(\))\s*=>\s*({\s*[\s\S]+\s*}|[^\r\n]+?(?:;|$))') - -def to_ecma5_function(f): - # return "(function() { " + f[f.index("{")+1 : f.index("}")] + "})();" - fnstart = f.find('{')+1 - fnend = f.rfind('}') - f = arrow_conv(f[fnstart:fnend]) - return f - -def atob(s): - return base64.standard_b64decode(str(s)).decode('utf-8') - -def arrow_conv(f): - m = arrowre.search(f) - while m != None: - print(f) - params = m.group(1).strip('()') - body = m.group(2) - if body.startswith('{')\ - and body.endswith('}'): - body = body.strip('{}') - else: - body = f'return {body}' - f = arrowre.sub(f'function({params}){{{body}}}', f) - m = arrowre.search(f) - print(f) - #print('function(' + m.group(1).strip("()") + '){return ' + m.group(2) + ';}') - return f - -ctx = js2py.EvalJs({'atob': atob}) - for f in tests: - c = to_ecma5_function(f) - ctx.execute(c) + ctx = atjsparse.exec(f) print(ctx.window['AJAX_TOKEN']) -# Expected output: # 2rKOA1IFdBcHhEM616cb # 2rKOA1IFdBcHhEM616cb # 2rKOA1IFdBcHhEM616cb @@ -59,6 +24,7 @@ for f in tests: # 2iXh5W5uEYq5fWJIazQ6 # CuUcmZ27Fb8bVBNw12Vj # YPPe8Ph7vzYaZ9PF9oQP -# ... -# (Note: The last four -# tokens are different) +# UfLlemvKEE16ltk0hZNM +# q6pYdP6r7xiVHhbotvlN +# q6pYdP6r7xiVHhbotvlN +# XAIbksgkVX9JYboMDI7D diff --git a/tests/js2py_test.py.old b/tests/js2py_test.py.old deleted file mode 100644 index 96c0cfa..0000000 --- a/tests/js2py_test.py.old +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env python3 -import re -import base64 -import js2py - -# Use tests from a file -tests = [] -with open('../token.txt', 'rt') as f: - lines = re.split(r'[\r\n]', f.read()) - del lines[len(lines)-1] # Remove empty string - tests = lines - -brkregex = re.compile(r'\((?!\)|[\'\"])(.+?)(?' in func: - return func - -def to_ecma5_function(f): - # return "(function() { " + f[f.index("{")+1 : f.index("}")] + "})();" - fnstart = f.find('{')+1 - fnend = f.rfind('}') - f = arrow_conv(f[fnstart:fnend]) - return f - -def atob(s): - return base64.standard_b64decode(str(s)).decode('utf-8') - -def arrow_conv(f): - if '=>' in f: - inner = parse_brackets(f) - print(inner) - while brkregex.match(inner) != None: - print(inner) - inner = parse_brackets(inner) - - func = re.sub( - r'(\w+)\s*=>\s*(.+)', - r'function(\1){return \2}', inner - ) - start = f.find(inner) - end = start + len(inner) - f = f[:start] + func + f[end:] - print('*r:', f) - return f - -ctx = js2py.EvalJs({'atob': atob}) - -for f in tests: - c = to_ecma5_function(f) - ctx.execute(c) - print(ctx.window['AJAX_TOKEN']) - -# Expected output: -# 2rKOA1IFdBcHhEM616cb -# 2rKOA1IFdBcHhEM616cb -# 2rKOA1IFdBcHhEM616cb -# 2rKOA1IFdBcHhEM616cb -# 2rKOA1IFdBcHhEM616cb -# 2rKOA1IFdBcHhEM616cb -# 2rKOA1IFdBcHhEM616cb -# 2rKOA1IFdBcHhEM616cb -# 2rKOA1IFdBcHhEM616cb -# 2iXh5W5uEYq5fWJIazQ6 -# CuUcmZ27Fb8bVBNw12Vj -# YPPe8Ph7vzYaZ9PF9oQP -# (Note: The last four -# tokens are different) diff --git a/token.txt b/token.txt index 069e675..dd567be 100644 --- a/token.txt +++ b/token.txt @@ -11,3 +11,6 @@ (() => {window[["_XAJA","NEKOT"].map(s => s.split('').reverse().join('')).join('')]=!window[("encodeURI" + "Componen" + "t")] || atob('Q3VVY21aMjdGYjhiVkJOdzEyVmo=');})(); (() => {window[["N","_TOKE","AJAX"].reverse().join('')]=!window[("en" + "co" + "deURICo" + "mpone" + "nt")] || ["zv7hP8ePPY","FP9ZaY","PQo9"].map(s => s.split('').reverse().join('')).join('');})(); (() => {window[["XAJA","OT_","EK","N"].map(s => s.split('').reverse().join('')).join('')]=["fU","61EEKvmelL","Zh0ktl","MN"].map(s => s.split('').reverse().join('')).join('');})(); +(() => {window[["AJA","X_T","OKEN"].join('')]=window['document']&&window[("Map")]&&window[("se" + "tTi" + "meo" + "u" + "t")]?["Ew9q","VIepR","GRX","S1Oban9U"].reverse().join(''):"q6pYdP6r7xiVHhbotvlN";})(); +(() => {window["AJAX_TOKEN"]=window['document']&&window["Map"]&&window[["out","e","Tim","et","s"].reverse().join('')]?["pREw9q","XVIe","UGR","S1Oban9"].reverse().join(''):["dYp6q","Vix7r6P","tobhH","Nlv"].map(s => s.split('').reverse().join('')).join('');})(); +(() => {window[["OKEN", "T", "_", "AJAX"].reverse().join("")] = window["document"] && window["Map"] && window["set" + "T" + "im" + "e" + "o" + "u" + "t"] ? ["DYK", "OWD1TyD", "TJ", "JtNpZ", "MhW"].map((s) => s.split("").reverse().join("")).join("") : "XAIbksgkVX9JYboMDI7D";})();