Code improvements
This commit is contained in:
parent
bb5978f8f5
commit
48f8090d2a
12 changed files with 207 additions and 187 deletions
12
examples/start_example.py
Normal file
12
examples/start_example.py
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
from getpass import getpass
|
||||||
|
from python_aternos import Client
|
||||||
|
|
||||||
|
user = input('Username: ')
|
||||||
|
pswd = getpass('Password: ')
|
||||||
|
aternos = Client.from_credentials(user, pswd)
|
||||||
|
|
||||||
|
srvs = aternos.servers
|
||||||
|
print(srvs)
|
||||||
|
|
||||||
|
s = srvs[0]
|
||||||
|
s.start()
|
|
@ -4,7 +4,9 @@ from typing import List
|
||||||
|
|
||||||
from .atserver import AternosServer
|
from .atserver import AternosServer
|
||||||
from .atconnect import AternosConnect
|
from .atconnect import AternosConnect
|
||||||
from .aterrors import AternosCredentialsError
|
from .aterrors import CredentialsError
|
||||||
|
|
||||||
|
__all__ = ['Client', 'atconf', 'atconnect', 'aterrors', 'atfile', 'atfm', 'atjsparse', 'atplayers', 'atserver', 'atwss']
|
||||||
|
|
||||||
class Client:
|
class Client:
|
||||||
|
|
||||||
|
@ -31,7 +33,7 @@ class Client:
|
||||||
)
|
)
|
||||||
|
|
||||||
if loginreq.cookies.get('ATERNOS_SESSION', None) == None:
|
if loginreq.cookies.get('ATERNOS_SESSION', None) == None:
|
||||||
raise AternosCredentialsError(
|
raise CredentialsError(
|
||||||
'Check your username and password'
|
'Check your username and password'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -65,8 +67,7 @@ class Client:
|
||||||
)
|
)
|
||||||
return auth.headers['Location']
|
return auth.headers['Location']
|
||||||
|
|
||||||
@property
|
def list_servers(self) -> List[atserver.AternosServer]:
|
||||||
def servers(self) -> List[atserver.AternosServer]:
|
|
||||||
serverspage = self.atconn.request_cloudflare(
|
serverspage = self.atconn.request_cloudflare(
|
||||||
'https://aternos.org/servers/',
|
'https://aternos.org/servers/',
|
||||||
atconnect.REQGET
|
atconnect.REQGET
|
||||||
|
|
|
@ -7,7 +7,7 @@ from typing import TYPE_CHECKING
|
||||||
from . import atconnect
|
from . import atconnect
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from atserver import AternosServer
|
from .atserver import AternosServer
|
||||||
|
|
||||||
class ServerOpts(enum.Enum):
|
class ServerOpts(enum.Enum):
|
||||||
players = 'max-players'
|
players = 'max-players'
|
||||||
|
@ -28,38 +28,47 @@ class ServerOpts(enum.Enum):
|
||||||
pack = 'resource-pack'
|
pack = 'resource-pack'
|
||||||
|
|
||||||
DAT_PREFIX = 'Data:'
|
DAT_PREFIX = 'Data:'
|
||||||
|
DAT_GR_PREFIX = 'Data:GameRules:'
|
||||||
|
|
||||||
class WorldOpts(enum.Enum):
|
class WorldOpts(enum.Enum):
|
||||||
seed = 'randomseed'
|
seed = 'randomseed'
|
||||||
hardcore = 'hardcore'
|
hardcore = 'hardcore'
|
||||||
difficulty = 'difficulty'
|
difficulty = 'difficulty'
|
||||||
|
|
||||||
DAT_GR_PREFIX = 'Data:GameRules:'
|
|
||||||
|
|
||||||
class WorldRules(enum.Enum):
|
class WorldRules(enum.Enum):
|
||||||
advs = 'announceadvancements'
|
advs = 'announceAdvancements'
|
||||||
cmdout = 'commandblockoutput'
|
univanger = 'universalAnger'
|
||||||
elytra = 'disableelytramovementcheck'
|
cmdout = 'commandBlockOutput'
|
||||||
daynight = 'dodaylightcycle'
|
elytra = 'disableElytraMovementCheck'
|
||||||
entdrop = 'doentitydrops'
|
raids = 'disableRaids'
|
||||||
fire = 'dofiretick'
|
daynight = 'doDaylightCycle'
|
||||||
limitcraft = 'dolimitedcrafting'
|
entdrop = 'doEntityDrops'
|
||||||
mobloot = 'domobloot'
|
fire = 'doFireTick'
|
||||||
mobs = 'domobspawning'
|
phantoms = 'doInsomnia'
|
||||||
blockdrop = 'dotiledrops'
|
immrespawn = 'doImmediateRespawn'
|
||||||
weather = 'doweathercycle'
|
limitcraft = 'doLimitedCrafting'
|
||||||
keepinv = 'keepinventory'
|
mobloot = 'doMobLoot'
|
||||||
deathmsg = 'showdeathmessages'
|
mobs = 'doMobSpawning'
|
||||||
admincmdlog = 'logadmincommands'
|
patrols = 'doPatrolSpawning'
|
||||||
cmdlen = 'maxcommandchainlength'
|
blockdrop = 'doTileDrops'
|
||||||
entcram = 'maxentitycramming'
|
traders = 'doTraderSpawning'
|
||||||
mobgrief = 'mobgriefing'
|
weather = 'doWeatherCycle'
|
||||||
regen = 'naturalregeneration'
|
drowndmg = 'drowningDamage'
|
||||||
rndtick = 'randomtickspeed'
|
falldmg = 'fallDamage'
|
||||||
spawnradius = 'spawnradius'
|
firedmg = 'fireDamage'
|
||||||
reducedf3 = 'reduceddebuginfo'
|
forgive = 'forgiveDeadPlayers'
|
||||||
spectchunkgen = 'spectatorsgeneratechunks'
|
keepinv = 'keepInventory'
|
||||||
cmdfb = 'sendcommandfeedback'
|
deathmsg = 'showDeathMessages'
|
||||||
|
admincmdlog = 'logAdminCommands'
|
||||||
|
cmdlen = 'maxCommandChainLength'
|
||||||
|
entcram = 'maxEntityCramming'
|
||||||
|
mobgrief = 'mobGriefing'
|
||||||
|
regen = 'naturalRegeneration'
|
||||||
|
rndtick = 'randomTickspeed'
|
||||||
|
spawnradius = 'spawnRadius'
|
||||||
|
reducedf3 = 'reducedDebugInfo'
|
||||||
|
spectchunkgen = 'spectatorsGenerateChunks'
|
||||||
|
cmdfb = 'sendCommandFeedback'
|
||||||
|
|
||||||
DAT_TYPE_WORLD = 0
|
DAT_TYPE_WORLD = 0
|
||||||
DAT_TYPE_GR = 1
|
DAT_TYPE_GR = 1
|
||||||
|
@ -78,6 +87,11 @@ class Difficulty(enum.IntEnum):
|
||||||
|
|
||||||
JDK = 'openjdk:{}'
|
JDK = 'openjdk:{}'
|
||||||
OJ9 = 'adoptopenjdk:{}-jre-openj9-bionic'
|
OJ9 = 'adoptopenjdk:{}-jre-openj9-bionic'
|
||||||
|
convert = {
|
||||||
|
'config-option-number': int,
|
||||||
|
'config-option-select': int,
|
||||||
|
'config-option-toggle': bool
|
||||||
|
}
|
||||||
|
|
||||||
FLAG_PROP_TYPE = 1
|
FLAG_PROP_TYPE = 1
|
||||||
|
|
||||||
|
@ -91,8 +105,7 @@ class AternosConfig:
|
||||||
def timezone(self) -> str:
|
def timezone(self) -> str:
|
||||||
|
|
||||||
optreq = self.atserv.atserver_request(
|
optreq = self.atserv.atserver_request(
|
||||||
'https://aternos.org/options',
|
'https://aternos.org/options', 'GET'
|
||||||
atconnect.REQGET
|
|
||||||
)
|
)
|
||||||
opttree = lxml.html.fromstring(optreq)
|
opttree = lxml.html.fromstring(optreq)
|
||||||
|
|
||||||
|
@ -109,7 +122,7 @@ class AternosConfig:
|
||||||
|
|
||||||
self.atserv.atserver_request(
|
self.atserv.atserver_request(
|
||||||
'https://aternos.org/panel/ajax/timezone.php',
|
'https://aternos.org/panel/ajax/timezone.php',
|
||||||
atconnect.REQPOST, data={'timezone': value},
|
'POST', data={'timezone': value},
|
||||||
sendtoken=True
|
sendtoken=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -118,7 +131,7 @@ class AternosConfig:
|
||||||
|
|
||||||
optreq = self.atserv.atserver_request(
|
optreq = self.atserv.atserver_request(
|
||||||
'https://aternos.org/options',
|
'https://aternos.org/options',
|
||||||
atconnect.REQGET
|
'GET'
|
||||||
)
|
)
|
||||||
opttree = lxml.html.fromstring(optreq)
|
opttree = lxml.html.fromstring(optreq)
|
||||||
|
|
||||||
|
@ -134,7 +147,7 @@ class AternosConfig:
|
||||||
|
|
||||||
self.atserv.atserver_request(
|
self.atserv.atserver_request(
|
||||||
'https://aternos.org/panel/ajax/image.php',
|
'https://aternos.org/panel/ajax/image.php',
|
||||||
atconnect.REQPOST, data={'image': value},
|
'POST', data={'image': value},
|
||||||
sendtoken=True
|
sendtoken=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -152,7 +165,7 @@ class AternosConfig:
|
||||||
|
|
||||||
def set_server_props(self, props:Dict[str,Any]) -> None:
|
def set_server_props(self, props:Dict[str,Any]) -> None:
|
||||||
for key in props:
|
for key in props:
|
||||||
set_server_prop(key, props[key])
|
self.set_server_prop(key, props[key])
|
||||||
|
|
||||||
#
|
#
|
||||||
# level.dat
|
# level.dat
|
||||||
|
@ -182,7 +195,7 @@ class AternosConfig:
|
||||||
|
|
||||||
def set_world_props(self, props:Dict[str,Any]) -> None:
|
def set_world_props(self, props:Dict[str,Any]) -> None:
|
||||||
for key in props:
|
for key in props:
|
||||||
set_world_prop(key, prop[key])
|
self.set_world_prop(key, props[key])
|
||||||
|
|
||||||
#
|
#
|
||||||
# helpers
|
# helpers
|
||||||
|
@ -191,7 +204,7 @@ class AternosConfig:
|
||||||
|
|
||||||
self.atserv.atserver_request(
|
self.atserv.atserver_request(
|
||||||
'https://aternos.org/panel/ajax/config.php',
|
'https://aternos.org/panel/ajax/config.php',
|
||||||
atconnect.REQPOST, data={
|
'POST', data={
|
||||||
'file': file,
|
'file': file,
|
||||||
'option': option,
|
'option': option,
|
||||||
'value': value
|
'value': value
|
||||||
|
@ -203,8 +216,8 @@ class AternosConfig:
|
||||||
prefixes:Optional[List[str]]=None) -> Dict[str,Any]:
|
prefixes:Optional[List[str]]=None) -> Dict[str,Any]:
|
||||||
|
|
||||||
optreq = self.atserv.atserver_request(
|
optreq = self.atserv.atserver_request(
|
||||||
'https://aternos.org/options',
|
url,
|
||||||
atconnect.REQGET
|
'GET'
|
||||||
)
|
)
|
||||||
opttree = lxml.html.fromstring(optreq.content)
|
opttree = lxml.html.fromstring(optreq.content)
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,9 @@ from requests import Response
|
||||||
from cloudscraper import CloudScraper
|
from cloudscraper import CloudScraper
|
||||||
from typing import Optional, Union
|
from typing import Optional, Union
|
||||||
|
|
||||||
from . import aterrors
|
|
||||||
from . import atjsparse
|
from . import atjsparse
|
||||||
|
from .aterrors import CredentialsError, CloudflareError
|
||||||
|
|
||||||
REQGET = 0
|
|
||||||
REQPOST = 1
|
|
||||||
REQUA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Goanna/4.8 Firefox/68.0 PaleMoon/29.4.0.2'
|
REQUA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Goanna/4.8 Firefox/68.0 PaleMoon/29.4.0.2'
|
||||||
|
|
||||||
class AternosConnect:
|
class AternosConnect:
|
||||||
|
@ -23,7 +21,7 @@ class AternosConnect:
|
||||||
|
|
||||||
if response == None:
|
if response == None:
|
||||||
loginpage = self.request_cloudflare(
|
loginpage = self.request_cloudflare(
|
||||||
f'https://aternos.org/go/', REQGET
|
f'https://aternos.org/go/', 'GET'
|
||||||
).content
|
).content
|
||||||
pagetree = lxml.html.fromstring(loginpage)
|
pagetree = lxml.html.fromstring(loginpage)
|
||||||
else:
|
else:
|
||||||
|
@ -36,13 +34,11 @@ class AternosConnect:
|
||||||
js_code = re.findall(r'\(\(\)(.*?)\)\(\);', text)
|
js_code = re.findall(r'\(\(\)(.*?)\)\(\);', text)
|
||||||
token_func = js_code[1] if len(js_code) > 1 else js_code[0]
|
token_func = js_code[1] if len(js_code) > 1 else js_code[0]
|
||||||
|
|
||||||
print('*** Function:', token_func)
|
|
||||||
|
|
||||||
ctx = atjsparse.exec(token_func)
|
ctx = atjsparse.exec(token_func)
|
||||||
self.token = ctx.window['AJAX_TOKEN']
|
self.token = ctx.window['AJAX_TOKEN']
|
||||||
|
|
||||||
except (IndexError, TypeError):
|
except (IndexError, TypeError):
|
||||||
raise aterrors.AternosCredentialsError(
|
raise CredentialsError(
|
||||||
'Unable to parse TOKEN from the page'
|
'Unable to parse TOKEN from the page'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -92,7 +88,7 @@ class AternosConnect:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def request_cloudflare(
|
def request_cloudflare(
|
||||||
self, url:str, method:int, retries:int=10,
|
self, url:str, method:str, retries:int=10,
|
||||||
params:Optional[dict]=None, data:Optional[dict]=None,
|
params:Optional[dict]=None, data:Optional[dict]=None,
|
||||||
headers:Optional[dict]=None, reqcookies:Optional[dict]=None,
|
headers:Optional[dict]=None, reqcookies:Optional[dict]=None,
|
||||||
sendtoken:bool=False, redirect:bool=True) -> Response:
|
sendtoken:bool=False, redirect:bool=True) -> Response:
|
||||||
|
@ -127,7 +123,7 @@ class AternosConnect:
|
||||||
|
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
if method == REQPOST:
|
if method == 'POST':
|
||||||
req = self.session.post(
|
req = self.session.post(
|
||||||
url, data=data, params=params,
|
url, data=data, params=params,
|
||||||
headers=headers, cookies=reqcookies,
|
headers=headers, cookies=reqcookies,
|
||||||
|
@ -143,7 +139,7 @@ class AternosConnect:
|
||||||
if not cftitle in req.text:
|
if not cftitle in req.text:
|
||||||
break
|
break
|
||||||
if not countdown > 0:
|
if not countdown > 0:
|
||||||
raise aterrors.CloudflareError(
|
raise CloudflareError(
|
||||||
'The retries limit has been reached'
|
'The retries limit has been reached'
|
||||||
)
|
)
|
||||||
countdown -= 1
|
countdown -= 1
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
class AternosError(Exception):
|
class AternosError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class AternosCredentialsError(AternosError):
|
class CredentialsError(AternosError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class AternosServerStartError(AternosError):
|
class ServerError(AternosError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class AternosIOError(AternosError):
|
class FileError(AternosError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class CloudflareError(AternosError):
|
class CloudflareError(AternosError):
|
||||||
|
|
|
@ -1,20 +1,22 @@
|
||||||
|
import enum
|
||||||
import lxml.html
|
import lxml.html
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from . import atconnect
|
from .aterrors import FileError
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from atserver import AternosServer
|
from .atserver import AternosServer
|
||||||
|
|
||||||
FTYPE_FILE = 0
|
class FileType(enum.IntEnum):
|
||||||
FTYPE_DIR = 1
|
file = 0
|
||||||
|
directory = 1
|
||||||
|
|
||||||
class AternosFile:
|
class AternosFile:
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, atserv:'AternosServer',
|
self, atserv:'AternosServer',
|
||||||
path:str, name:str, ftype:int=FTYPE_FILE,
|
path:str, name:str, ftype:int=FileType.file,
|
||||||
size:Union[int,float]=0, dlallowed:bool=False) -> None:
|
size:Union[int,float]=0, dlallowed:bool=False) -> None:
|
||||||
|
|
||||||
self.atserv = atserv
|
self.atserv = atserv
|
||||||
|
@ -28,33 +30,33 @@ class AternosFile:
|
||||||
|
|
||||||
self.atserv.atserver_request(
|
self.atserv.atserver_request(
|
||||||
'https://aternos.org/panel/ajax/delete.php',
|
'https://aternos.org/panel/ajax/delete.php',
|
||||||
atconnect.REQPOST, data={'file': self._name},
|
'POST', data={'file': self._name},
|
||||||
sendtoken=True
|
sendtoken=True
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
def get_content(self) -> bytes:
|
||||||
def content(self) -> bytes:
|
|
||||||
file = self.atserv.atserver_request(
|
file = self.atserv.atserver_request(
|
||||||
f'https://aternos.org/panel/ajax/files/download.php',
|
f'https://aternos.org/panel/ajax/files/download.php',
|
||||||
atconnect.REQGET, params={'file': self.path.replace('/','%2F')}
|
'GET', params={
|
||||||
|
'file': self._path
|
||||||
|
}
|
||||||
)
|
)
|
||||||
if not self._dlallowed:
|
if not self._dlallowed:
|
||||||
raise AternosIOError('Downloading this file is not allowed. Try to get text')
|
raise FileError('Downloading this file is not allowed. Try to get text')
|
||||||
return file.content
|
return file.content
|
||||||
|
|
||||||
@content.setter
|
def set_content(self, value:bytes) -> None:
|
||||||
def content(self, value:bytes) -> None:
|
|
||||||
self.atserv.atserver_request(
|
self.atserv.atserver_request(
|
||||||
f'https://aternos.org/panel/ajax/save.php',
|
f'https://aternos.org/panel/ajax/save.php',
|
||||||
atconnect.REQPOST, data={'content': value},
|
'POST', data={
|
||||||
sendtoken=True
|
'file': self._path,
|
||||||
|
'content': value
|
||||||
|
}, sendtoken=True
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
def get_text(self) -> str:
|
||||||
def text(self) -> str:
|
|
||||||
editor = self.atserv.atserver_request(
|
editor = self.atserv.atserver_request(
|
||||||
f'https://aternos.org/files/{self._name}',
|
f'https://aternos.org/files/{self._name}', 'GET'
|
||||||
atconnect.REQGET
|
|
||||||
)
|
)
|
||||||
edittree = lxml.html.fromstring(editor.content)
|
edittree = lxml.html.fromstring(editor.content)
|
||||||
|
|
||||||
|
@ -66,13 +68,8 @@ class AternosFile:
|
||||||
rawlines.append(line.text)
|
rawlines.append(line.text)
|
||||||
return rawlines
|
return rawlines
|
||||||
|
|
||||||
@text.setter
|
def set_text(self, value:str) -> None:
|
||||||
def text(self, value:str) -> None:
|
self.set_content(value.encode('utf-8'))
|
||||||
self.atserv.atserver_request(
|
|
||||||
f'https://aternos.org/panel/ajax/save.php',
|
|
||||||
atconnect.REQPOST, data={'content': value},
|
|
||||||
sendtoken=True
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def path(self):
|
def path(self):
|
||||||
|
@ -84,13 +81,13 @@ class AternosFile:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_dir(self) -> bool:
|
def is_dir(self) -> bool:
|
||||||
if self._ftype == FTYPE_DIR:
|
if self._ftype == FileType.directory:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_file(self) -> bool:
|
def is_file(self) -> bool:
|
||||||
if self._ftype == FTYPE_FILE:
|
if self._ftype == FileType.file:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
|
@ -1,28 +1,26 @@
|
||||||
import lxml.html
|
import lxml.html
|
||||||
from typing import Optional, Union, List
|
from typing import Union, List
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from . import atconnect
|
from .atfile import AternosFile, FileType
|
||||||
from . import atfile
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from atserver import AternosServer
|
from .atserver import AternosServer
|
||||||
|
|
||||||
class AternosFileManager:
|
class FileManager:
|
||||||
|
|
||||||
def __init__(self, atserv:'AternosServer') -> None:
|
def __init__(self, atserv:'AternosServer') -> None:
|
||||||
|
|
||||||
self.atserv = atserv
|
self.atserv = atserv
|
||||||
|
|
||||||
def listdir(self, path:str='') -> List[atfile.AternosFile]:
|
def listdir(self, path:str='') -> List[AternosFile]:
|
||||||
|
|
||||||
filesreq = self.atserv.atserver_request(
|
filesreq = self.atserv.atserver_request(
|
||||||
f'https://aternos.org/files/{path}',
|
f'https://aternos.org/files/{path}', 'GET'
|
||||||
atconnect.REQGET
|
|
||||||
)
|
)
|
||||||
filestree = lxml.html.fromstring(filesreq.content)
|
filestree = lxml.html.fromstring(filesreq.content)
|
||||||
fileslist = filestree.xpath(
|
fileslist = filestree.xpath(
|
||||||
'//div[@class="files"]/div[@class="directory dropzone"]' + \
|
'//div[@class="files"]' + \
|
||||||
|
'/div[@class="directory dropzone"]' + \
|
||||||
'/div[@class="file clickable"]'
|
'/div[@class="file clickable"]'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -30,9 +28,9 @@ class AternosFileManager:
|
||||||
for f in fileslist:
|
for f in fileslist:
|
||||||
|
|
||||||
ftype_raw = f.xpath('/@data-type')
|
ftype_raw = f.xpath('/@data-type')
|
||||||
ftype = atfile.FTYPE_FILE \
|
ftype = FileType.file \
|
||||||
if ftype_raw == 'file' \
|
if ftype_raw == 'file' \
|
||||||
else atfile.FTYPE_DIR
|
else FileType.directory
|
||||||
|
|
||||||
fsize_raw = f.xpath('/div[@class="filesize"]')
|
fsize_raw = f.xpath('/div[@class="filesize"]')
|
||||||
fsize = 0
|
fsize = 0
|
||||||
|
@ -43,11 +41,11 @@ class AternosFileManager:
|
||||||
fsize_msr = fsize_text[fsize_text.rfind(' ')+1:]
|
fsize_msr = fsize_text[fsize_text.rfind(' ')+1:]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
fsize = convert_size(float(fsize_num), fsize_msr)
|
fsize = self.convert_size(float(fsize_num), fsize_msr)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
fsize = -1
|
fsize = -1
|
||||||
|
|
||||||
dlbutton = f.xpath('/div[@class="js-download-file btn btn-main btn-small btn-notext btn-no-margin"]')
|
dlbutton = f.xpath('/div[contains(@class,"js-download-file ")]')
|
||||||
dlallowed = False
|
dlallowed = False
|
||||||
if len(dlbutton) > 0:
|
if len(dlbutton) > 0:
|
||||||
dlallowed = True
|
dlallowed = True
|
||||||
|
@ -56,7 +54,7 @@ class AternosFileManager:
|
||||||
filepath = fullpath[:fullpath.rfind('/')]
|
filepath = fullpath[:fullpath.rfind('/')]
|
||||||
filename = fullpath[fullpath.rfind('/'):]
|
filename = fullpath[fullpath.rfind('/'):]
|
||||||
files.append(
|
files.append(
|
||||||
atfile.AternosFile(
|
AternosFile(
|
||||||
self.atserv,
|
self.atserv,
|
||||||
filepath, filename,
|
filepath, filename,
|
||||||
ftype, fsize, dlallowed
|
ftype, fsize, dlallowed
|
||||||
|
@ -79,12 +77,12 @@ class AternosFileManager:
|
||||||
result = -1
|
result = -1
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def get_file(self, path:str) -> Union[atfile.AternosFile,None]:
|
def get_file(self, path:str) -> Union[AternosFile,None]:
|
||||||
|
|
||||||
filepath = path[:path.rfind('/')]
|
filepath = path[:path.rfind('/')]
|
||||||
filename = path[path.rfind('/'):]
|
filename = path[path.rfind('/'):]
|
||||||
|
|
||||||
filedir = listdir(filepath)
|
filedir = self.listdir(filepath)
|
||||||
for file in filedir:
|
for file in filedir:
|
||||||
if file.name == filename:
|
if file.name == filename:
|
||||||
return file
|
return file
|
||||||
|
@ -96,7 +94,7 @@ class AternosFileManager:
|
||||||
file = self.atserv.atserver_request(
|
file = self.atserv.atserver_request(
|
||||||
f'https://aternos.org/panel/ajax/files/download.php?' + \
|
f'https://aternos.org/panel/ajax/files/download.php?' + \
|
||||||
f'file={path.replace("/","%2F")}',
|
f'file={path.replace("/","%2F")}',
|
||||||
atconnect.REQGET
|
'GET'
|
||||||
)
|
)
|
||||||
|
|
||||||
return file.content
|
return file.content
|
||||||
|
@ -106,7 +104,7 @@ class AternosFileManager:
|
||||||
world = self.atserv.atserver_request(
|
world = self.atserv.atserver_request(
|
||||||
f'https://aternos.org/panel/ajax/worlds/download.php?' + \
|
f'https://aternos.org/panel/ajax/worlds/download.php?' + \
|
||||||
f'world={world.replace("/","%2F")}',
|
f'world={world.replace("/","%2F")}',
|
||||||
atconnect.REQGET
|
'GET'
|
||||||
)
|
)
|
||||||
|
|
||||||
return world.content
|
return world.content
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import regex
|
import regex
|
||||||
import base64
|
import base64
|
||||||
import js2py
|
import js2py
|
||||||
from typing import Optional, Union, List, Any
|
from typing import Any
|
||||||
|
|
||||||
# Thanks to http://regex.inginf.units.it/
|
# Thanks to http://regex.inginf.units.it/
|
||||||
arrowexp = regex.compile(r'\w[^\}]*+')
|
arrowexp = regex.compile(r'\w[^\}]*+')
|
||||||
|
|
|
@ -1,53 +1,78 @@
|
||||||
|
import enum
|
||||||
import lxml.html
|
import lxml.html
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from . import atconnect
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from atserver import AternosServer
|
from .atserver import AternosServer
|
||||||
|
|
||||||
class AternosPlayersList:
|
class Lists(enum.Enum):
|
||||||
|
|
||||||
|
whl = 'whitelist'
|
||||||
|
ops = 'ops'
|
||||||
|
ban = 'banned-players'
|
||||||
|
ips = 'banned-ips'
|
||||||
|
|
||||||
|
class PlayersList:
|
||||||
|
|
||||||
def __init__(self, lst:str, atserv:'AternosServer') -> None:
|
def __init__(self, lst:str, atserv:'AternosServer') -> None:
|
||||||
|
|
||||||
|
for ltype in Lists:
|
||||||
|
if ltype.value == lst:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise ValueError(
|
||||||
|
'Incorrect players list type! ' + \
|
||||||
|
'Use atplayers.Lists enum'
|
||||||
|
)
|
||||||
|
|
||||||
self.atserv = atserv
|
self.atserv = atserv
|
||||||
self.lst = lst
|
self.lst = lst
|
||||||
|
self.players = []
|
||||||
|
|
||||||
def add(self, name:str) -> None:
|
def list_players(self, cache:bool=True) -> List[str]:
|
||||||
|
|
||||||
self.atserv.atserver_request(
|
if cache:
|
||||||
'https://aternos.org/panel/ajax/players/add.php',
|
return self.players
|
||||||
atconnect.REQPOST, data={
|
|
||||||
'list': self.lst,
|
|
||||||
'name': name
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
def remove(self, name:str) -> None:
|
listreq = self.atserv.atserver_request(
|
||||||
|
f'https://aternos.org/players/{self.lst}', 'GET'
|
||||||
self.atserv.atserver_request(
|
|
||||||
'https://aternos.org/panel/ajax/players/remove.php',
|
|
||||||
atconnect.REQPOST, data={
|
|
||||||
'list': self.lst,
|
|
||||||
'name': name
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def players(self) -> List[str]:
|
|
||||||
listreq = atserv.atserver_request(
|
|
||||||
f'https://aternos.org/players/{lst}',
|
|
||||||
atconnect.REQGET
|
|
||||||
)
|
)
|
||||||
listtree = lxml.html.fromstring(listreq.content)
|
listtree = lxml.html.fromstring(listreq.content)
|
||||||
|
|
||||||
items = listtree.xpath(
|
items = listtree.xpath(
|
||||||
'//div[@class="player-list"]' + \
|
'//div[@class="player-list"]' + \
|
||||||
'/div[@class="list-item-container"]' + \
|
'/div[@class="list-item-container"]' + \
|
||||||
'/div[@class="list-item"]'
|
'/div[@class="list-item"]'
|
||||||
)
|
)
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
for i in items:
|
for i in items:
|
||||||
name = i.xpath('./div[@class="list-name"]')
|
name = i.xpath('./div[@class="list-name"]')
|
||||||
result.append(name)
|
result.append(name)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def add(self, name:str) -> None:
|
||||||
|
|
||||||
|
self.atserv.atserver_request(
|
||||||
|
'https://aternos.org/panel/ajax/players/add.php',
|
||||||
|
'POST', data={
|
||||||
|
'list': self.lst,
|
||||||
|
'name': name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.players.append(name)
|
||||||
|
|
||||||
|
def remove(self, name:str) -> None:
|
||||||
|
|
||||||
|
self.atserv.atserver_request(
|
||||||
|
'https://aternos.org/panel/ajax/players/remove.php',
|
||||||
|
'POST', data={
|
||||||
|
'list': self.lst,
|
||||||
|
'name': name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
for i, j in enumerate(self.players):
|
||||||
|
if j == name:
|
||||||
|
del self.players[i]
|
||||||
|
|
|
@ -2,25 +2,22 @@ import enum
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
import lxml.html
|
import lxml.html
|
||||||
import websockets
|
|
||||||
from requests import Response
|
from requests import Response
|
||||||
from typing import Optional, Dict
|
from typing import Optional
|
||||||
|
|
||||||
from . import atconnect
|
from .atconnect import AternosConnect
|
||||||
from . import aterrors
|
from .aterrors import ServerError
|
||||||
from . import atfm
|
from .atfm import FileManager
|
||||||
from . import atconf
|
from .atconf import AternosConfig
|
||||||
from . import atplayers
|
from .atplayers import PlayersList
|
||||||
from .atwss import AternosWss
|
from .atwss import AternosWss
|
||||||
|
|
||||||
JAVA = 0
|
JAVA = 0
|
||||||
BEDROCK = 1
|
BEDROCK = 1
|
||||||
|
|
||||||
class Lists(enum.Enum):
|
class Edition(enum.IntEnum):
|
||||||
whl = 'whitelist'
|
java = 0
|
||||||
ops = 'ops'
|
bedrock = 1
|
||||||
ban = 'banned-players'
|
|
||||||
ips = 'banned-ips'
|
|
||||||
|
|
||||||
class Status(enum.IntEnum):
|
class Status(enum.IntEnum):
|
||||||
off = 0
|
off = 0
|
||||||
|
@ -35,7 +32,7 @@ class AternosServer:
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, servid:str,
|
self, servid:str,
|
||||||
atconn:atconnect.AternosConnect,
|
atconn:AternosConnect,
|
||||||
savelog:bool=True) -> None:
|
savelog:bool=True) -> None:
|
||||||
|
|
||||||
self.servid = servid
|
self.servid = servid
|
||||||
|
@ -44,8 +41,7 @@ class AternosServer:
|
||||||
self.log = []
|
self.log = []
|
||||||
|
|
||||||
servreq = self.atserver_request(
|
servreq = self.atserver_request(
|
||||||
'https://aternos.org/server',
|
'https://aternos.org/server', 'GET'
|
||||||
atconnect.REQGET
|
|
||||||
)
|
)
|
||||||
servtree = lxml.html.fromstring(servreq.content)
|
servtree = lxml.html.fromstring(servreq.content)
|
||||||
|
|
||||||
|
@ -72,7 +68,7 @@ class AternosServer:
|
||||||
|
|
||||||
startreq = self.atserver_request(
|
startreq = self.atserver_request(
|
||||||
'https://aternos.org/panel/ajax/start.php',
|
'https://aternos.org/panel/ajax/start.php',
|
||||||
atconnect.REQGET, params={'headstart': int(headstart)},
|
'GET', params={'headstart': int(headstart)},
|
||||||
sendtoken=True
|
sendtoken=True
|
||||||
)
|
)
|
||||||
startresult = startreq.json()
|
startresult = startreq.json()
|
||||||
|
@ -86,33 +82,33 @@ class AternosServer:
|
||||||
self.start(accepteula=False)
|
self.start(accepteula=False)
|
||||||
|
|
||||||
elif error == 'eula':
|
elif error == 'eula':
|
||||||
raise aterrors.AternosServerStartError(
|
raise ServerError(
|
||||||
'EULA was not accepted. Use start(accepteula=True)'
|
'EULA was not accepted. Use start(accepteula=True)'
|
||||||
)
|
)
|
||||||
|
|
||||||
elif error == 'already':
|
elif error == 'already':
|
||||||
raise aterrors.AternosServerStartError(
|
raise ServerError(
|
||||||
'Server is already running'
|
'Server is already running'
|
||||||
)
|
)
|
||||||
|
|
||||||
elif error == 'wrongversion':
|
elif error == 'wrongversion':
|
||||||
raise aterrors.AternosServerStartError(
|
raise ServerError(
|
||||||
'Incorrect software version installed'
|
'Incorrect software version installed'
|
||||||
)
|
)
|
||||||
|
|
||||||
elif error == 'file':
|
elif error == 'file':
|
||||||
raise aterrors.AternosServerStartError(
|
raise ServerError(
|
||||||
'File server is unavailbale, view status.aternos.gmbh'
|
'File server is unavailbale, view status.aternos.gmbh'
|
||||||
)
|
)
|
||||||
|
|
||||||
elif error == 'size':
|
elif error == 'size':
|
||||||
raise aterrors.AternosServerStartError(
|
raise ServerError(
|
||||||
f'Available storage size is 4GB, ' + \
|
f'Available storage size is 4GB, ' + \
|
||||||
f'your server used: {startresult["size"]}'
|
f'your server used: {startresult["size"]}'
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise aterrors.AternosServerStartError(
|
raise ServerError(
|
||||||
f'Unable to start server, code: {error}'
|
f'Unable to start server, code: {error}'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -120,56 +116,48 @@ class AternosServer:
|
||||||
|
|
||||||
self.atserver_request(
|
self.atserver_request(
|
||||||
'https://aternos.org/panel/ajax/confirm.php',
|
'https://aternos.org/panel/ajax/confirm.php',
|
||||||
atconnect.REQGET, sendtoken=True
|
'GET', sendtoken=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def stop(self) -> None:
|
def stop(self) -> None:
|
||||||
|
|
||||||
self.atserver_request(
|
self.atserver_request(
|
||||||
'https://aternos.org/panel/ajax/stop.php',
|
'https://aternos.org/panel/ajax/stop.php',
|
||||||
atconnect.REQGET, sendtoken=True
|
'GET', sendtoken=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def cancel(self) -> None:
|
def cancel(self) -> None:
|
||||||
|
|
||||||
self.atserver_request(
|
self.atserver_request(
|
||||||
'https://aternos.org/panel/ajax/cancel.php',
|
'https://aternos.org/panel/ajax/cancel.php',
|
||||||
atconnect.REQGET, sendtoken=True
|
'GET', sendtoken=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def restart(self) -> None:
|
def restart(self) -> None:
|
||||||
|
|
||||||
self.atserver_request(
|
self.atserver_request(
|
||||||
'https://aternos.org/panel/ajax/restart.php',
|
'https://aternos.org/panel/ajax/restart.php',
|
||||||
atconnect.REQGET, sendtoken=True
|
'GET', sendtoken=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def eula(self) -> None:
|
def eula(self) -> None:
|
||||||
|
|
||||||
self.atserver_request(
|
self.atserver_request(
|
||||||
'https://aternos.org/panel/ajax/eula.php',
|
'https://aternos.org/panel/ajax/eula.php',
|
||||||
atconnect.REQGET, sendtoken=True
|
'GET', sendtoken=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def files(self) -> atfm.AternosFileManager:
|
def files(self) -> FileManager:
|
||||||
|
|
||||||
return atfm.AternosFileManager(self)
|
return FileManager(self)
|
||||||
|
|
||||||
def config(self) -> atconf.AternosConfig:
|
def config(self) -> AternosConfig:
|
||||||
|
|
||||||
return atconf.AternosConfig(self)
|
return AternosConfig(self)
|
||||||
|
|
||||||
def players(self, lst:str) -> atplayers.AternosPlayersList:
|
def get_players(self, lst:str) -> PlayersList:
|
||||||
|
|
||||||
correct = False
|
return PlayersList(lst, self)
|
||||||
for lsttype in Lists:
|
|
||||||
if lsttype.value == lst:
|
|
||||||
correct = True
|
|
||||||
|
|
||||||
if not correct:
|
|
||||||
raise AttributeError('Incorrect players list type! Use Lists enum')
|
|
||||||
|
|
||||||
return atplayers.AternosPlayersList(lst, self)
|
|
||||||
|
|
||||||
def atserver_request(
|
def atserver_request(
|
||||||
self, url:str, method:int,
|
self, url:str, method:int,
|
||||||
|
@ -197,7 +185,7 @@ class AternosServer:
|
||||||
def subdomain(self, value:str) -> None:
|
def subdomain(self, value:str) -> None:
|
||||||
self.atserver_request(
|
self.atserver_request(
|
||||||
'https://aternos.org/panel/ajax/options/subdomain.php',
|
'https://aternos.org/panel/ajax/options/subdomain.php',
|
||||||
atconnect.REQGET, params={'subdomain': value},
|
'GET', params={'subdomain': value},
|
||||||
sendtoken=True
|
sendtoken=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -209,7 +197,7 @@ class AternosServer:
|
||||||
def motd(self, value:str) -> None:
|
def motd(self, value:str) -> None:
|
||||||
self.atserver_request(
|
self.atserver_request(
|
||||||
'https://aternos.org/panel/ajax/options/motd.php',
|
'https://aternos.org/panel/ajax/options/motd.php',
|
||||||
atconnect.REQPOST, data={'motd': value},
|
'POST', data={'motd': value},
|
||||||
sendtoken=True
|
sendtoken=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
lxml==4.8.0
|
lxml>=4.8.0
|
||||||
requests==2.25.1
|
requests>=2.25.1
|
||||||
cloudscraper==1.2.58
|
cloudscraper>=1.2.58
|
||||||
js2py==0.71
|
js2py>=0.71
|
||||||
websockets==10.1
|
websockets>=10.1
|
||||||
|
regex>=2022.3.15
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
from python_aternos import Client as AternosClient
|
|
||||||
|
|
||||||
aternos = AternosClient('', password='')
|
|
||||||
|
|
||||||
srvs = aternos.servers
|
|
||||||
|
|
||||||
print(srvs)
|
|
||||||
|
|
||||||
s = srvs[0]
|
|
||||||
|
|
||||||
s.start()
|
|
Reference in a new issue