This repository has been archived on 2024-07-30. You can view files and clone it, but cannot push or open issues or pull requests.
python-aternos/python_aternos/atserver.py

465 lines
11 KiB
Python
Raw Normal View History

2022-07-01 13:28:39 +03:00
"""Aternos Minecraft server"""
import enum
import json
from typing import Optional
from typing import List, Dict, Any
import requests
2021-10-08 18:35:20 +03:00
2022-03-18 17:38:36 +03:00
from .atconnect import AternosConnect
2022-07-01 09:31:23 +03:00
from .aterrors import ServerStartError
2022-03-18 17:38:36 +03:00
from .atfm import FileManager
from .atconf import AternosConfig
from .atplayers import PlayersList
2022-06-16 14:40:10 +03:00
from .atplayers import Lists
2022-01-22 14:10:30 +03:00
from .atwss import AternosWss
2022-06-23 14:13:56 +03:00
2022-03-18 17:38:36 +03:00
class Edition(enum.IntEnum):
2022-06-16 14:40:10 +03:00
"""Server edition type enum (java, bedrock)"""
2022-06-23 14:13:56 +03:00
java = 0
bedrock = 1
2022-06-16 14:40:10 +03:00
class Status(enum.IntEnum):
2022-06-16 14:40:10 +03:00
2022-06-23 14:13:56 +03:00
"""Server numeric status enum.
It is highly recommended to use
`AternosServer.status` instead of
`AternosServer.status_num`"""
off = 0
on = 1
2022-06-23 14:13:56 +03:00
starting = 2
shutdown = 3
loading = 6
2022-06-23 14:13:56 +03:00
error = 7
preparing = 10
2022-06-23 14:13:56 +03:00
confirm = 10
2022-06-16 14:40:10 +03:00
2021-10-08 18:35:20 +03:00
class AternosServer:
"""Class for controlling your Aternos Minecraft server"""
2022-06-23 14:13:56 +03:00
def __init__(
self, servid: str,
atconn: AternosConnect,
reqinfo: bool = True) -> None:
"""Class for controlling your Aternos Minecraft server
Args:
servid (str): Unique server IDentifier
atconn (AternosConnect):
AternosConnect instance with initialized Aternos session
reqinfo (bool, optional): Automatically call
`fetch()` to get all info
"""
2022-06-23 14:13:56 +03:00
self.servid = servid
self.atconn = atconn
if reqinfo:
self.fetch()
def fetch(self) -> None:
"""Send a request to Aternos API to get all server info"""
servreq = self.atserver_request(
'https://aternos.org/panel/ajax/status.php',
'GET', sendtoken=True
)
self._info = json.loads(servreq.content)
def wss(self, autoconfirm: bool = False) -> AternosWss:
"""Returns AternosWss instance for
listening server streams in real-time
2022-06-23 14:13:56 +03:00
Args:
autoconfirm (bool, optional):
Automatically start server status listener
when AternosWss connects to API to confirm
server launching
Returns:
AternosWss object
2022-06-23 14:13:56 +03:00
"""
return AternosWss(self, autoconfirm)
2022-07-01 13:28:39 +03:00
def start(
self,
headstart: bool = False,
accepteula: bool = True) -> None:
2022-06-23 14:13:56 +03:00
"""Starts a server
Args:
headstart (bool, optional): Start a server in
the headstart mode which allows
you to skip all queue
accepteula (bool, optional):
Automatically accept the Mojang EULA
Raises:
ServerStartError: When Aternos
is unable to start the server
2022-06-23 14:13:56 +03:00
"""
startreq = self.atserver_request(
'https://aternos.org/panel/ajax/start.php',
'GET', params={'headstart': int(headstart)},
sendtoken=True
)
startresult = startreq.json()
2022-06-16 14:40:10 +03:00
2022-06-23 14:13:56 +03:00
if startresult['success']:
return
2022-07-01 09:31:23 +03:00
2022-06-23 14:13:56 +03:00
error = startresult['error']
2021-10-08 18:35:20 +03:00
2022-06-23 14:13:56 +03:00
if error == 'eula' and accepteula:
self.eula()
2022-07-01 13:28:39 +03:00
self.start(accepteula=False)
return
2022-07-01 09:31:23 +03:00
raise ServerStartError(error)
2022-06-23 14:13:56 +03:00
def confirm(self) -> None:
"""Confirms server launching"""
self.atserver_request(
'https://aternos.org/panel/ajax/confirm.php',
'GET', sendtoken=True
)
def stop(self) -> None:
"""Stops the server"""
self.atserver_request(
'https://aternos.org/panel/ajax/stop.php',
'GET', sendtoken=True
)
def cancel(self) -> None:
"""Cancels server launching"""
self.atserver_request(
'https://aternos.org/panel/ajax/cancel.php',
'GET', sendtoken=True
)
def restart(self) -> None:
"""Restarts the server"""
self.atserver_request(
'https://aternos.org/panel/ajax/restart.php',
'GET', sendtoken=True
)
def eula(self) -> None:
"""Accepts the Mojang EULA"""
self.atserver_request(
'https://aternos.org/panel/ajax/eula.php',
'GET', sendtoken=True
)
def files(self) -> FileManager:
"""Returns FileManager instance
for file operations
2022-06-23 14:13:56 +03:00
Returns:
FileManager object
2022-06-23 14:13:56 +03:00
"""
return FileManager(self)
def config(self) -> AternosConfig:
"""Returns AternosConfig instance
for editing server settings
2022-06-23 14:13:56 +03:00
Returns:
AternosConfig object
2022-06-23 14:13:56 +03:00
"""
return AternosConfig(self)
def players(self, lst: Lists) -> PlayersList:
"""Returns PlayersList instance
for managing operators, whitelist
and banned players lists
2022-06-23 14:13:56 +03:00
Args:
lst (Lists): Players list type,
must be the atplayers.Lists enum value
Returns:
PlayersList object
2022-06-23 14:13:56 +03:00
"""
return PlayersList(lst, self)
def atserver_request(
self, url: str, method: str,
params: Optional[Dict[Any, Any]] = None,
data: Optional[Dict[Any, Any]] = None,
headers: Optional[Dict[Any, Any]] = None,
sendtoken: bool = False) -> requests.Response:
2022-06-23 14:13:56 +03:00
"""Sends a request to Aternos API
with server IDenitfier parameter
Args:
url (str): Request URL
method (str): Request method, must be GET or POST
params (Optional[Dict[Any, Any]], optional): URL parameters
data (Optional[Dict[Any, Any]], optional): POST request data,
if the method is GET, this dict
will be combined with params
headers (Optional[Dict[Any, Any]], optional): Custom headers
sendtoken (bool, optional): If the ajax and SEC token should be sent
Returns:
API response
2022-06-23 14:13:56 +03:00
"""
return self.atconn.request_cloudflare(
url=url, method=method,
params=params, data=data,
headers=headers,
reqcookies={
'ATERNOS_SERVER': self.servid
},
sendtoken=sendtoken
)
@property
def subdomain(self) -> str:
"""Server subdomain
(the part of domain before `.aternos.me`)
2022-07-01 13:28:39 +03:00
Returns:
Subdomain
2022-07-01 13:28:39 +03:00
"""
2022-06-23 14:13:56 +03:00
atdomain = self.domain
return atdomain[:atdomain.find('.')]
@subdomain.setter
def subdomain(self, value: str) -> None:
"""Set a new subdomain for your server
2022-07-01 13:28:39 +03:00
Args:
value (str): Subdomain
2022-07-01 13:28:39 +03:00
"""
2022-06-23 14:13:56 +03:00
self.atserver_request(
'https://aternos.org/panel/ajax/options/subdomain.php',
'GET', params={'subdomain': value},
sendtoken=True
)
@property
def motd(self) -> str:
"""Server message of the day
which is shown below its name
in the Minecraft servers list
2022-07-01 13:28:39 +03:00
Returns:
MOTD
2022-07-01 13:28:39 +03:00
"""
2022-06-23 14:13:56 +03:00
return self._info['motd']
@motd.setter
def motd(self, value: str) -> None:
"""Set a new message of the day
2022-07-01 13:28:39 +03:00
Args:
value (str): New MOTD
2022-07-01 13:28:39 +03:00
"""
2022-06-23 14:13:56 +03:00
self.atserver_request(
'https://aternos.org/panel/ajax/options/motd.php',
'POST', data={'motd': value},
sendtoken=True
)
@property
def address(self) -> str:
"""Full server address
including domain and port
2022-07-01 13:28:39 +03:00
Returns:
Server address
2022-07-01 13:28:39 +03:00
"""
return f'{self.domain}:{self.port}'
2022-06-23 14:13:56 +03:00
@property
def domain(self) -> str:
"""Server domain (e.g. `test.aternos.me`).
In other words, address without port number
2022-07-01 13:28:39 +03:00
Returns:
Domain
2022-07-01 13:28:39 +03:00
"""
2022-06-23 14:13:56 +03:00
return self._info['ip']
@property
def port(self) -> int:
2022-07-01 13:28:39 +03:00
"""Server port number
Returns:
Port
2022-07-01 13:28:39 +03:00
"""
2022-06-23 14:13:56 +03:00
return self._info['port']
@property
2022-07-01 13:28:39 +03:00
def edition(self) -> Edition:
"""Server software edition: Java or Bedrock
Returns:
Software edition
2022-07-01 13:28:39 +03:00
"""
2022-06-23 14:13:56 +03:00
soft_type = self._info['bedrock']
2022-07-01 13:28:39 +03:00
return Edition(soft_type)
2022-06-23 14:13:56 +03:00
@property
def is_java(self) -> bool:
"""Check if server software is Java Edition
Returns:
Is it Minecraft JE
"""
return not self._info['bedrock']
@property
def is_bedrock(self) -> bool:
"""Check if server software is Bedrock Edition
Returns:
Is it Minecraft BE
"""
return bool(self._info['bedrock'])
2022-06-23 14:13:56 +03:00
@property
def software(self) -> str:
2022-07-01 13:28:39 +03:00
"""Server software name (e.g. `Vanilla`)
Returns:
Software name
2022-07-01 13:28:39 +03:00
"""
2022-06-23 14:13:56 +03:00
return self._info['software']
@property
def version(self) -> str:
"""Server software version (1.16.5)
2022-07-01 13:28:39 +03:00
Returns:
Software version
2022-07-01 13:28:39 +03:00
"""
2022-06-23 14:13:56 +03:00
return self._info['version']
@property
def css_class(self) -> str:
"""CSS class for
server status block
on official web site
(offline, loading,
loading starting, queueing)
2022-07-01 13:28:39 +03:00
Returns:
CSS class
2022-07-01 13:28:39 +03:00
"""
2022-06-23 14:13:56 +03:00
return self._info['class']
@property
def status(self) -> str:
"""Server status string
(offline, loading, preparing)
Returns:
Status string
"""
return self._info['lang']
@property
def status_num(self) -> Status:
"""Server numeric status.
It is highly recommended to use
status string instead of a number
2022-07-01 13:28:39 +03:00
Returns:
Status code
2022-07-01 13:28:39 +03:00
"""
return Status(self._info['status'])
2022-06-23 14:13:56 +03:00
@property
def players_list(self) -> List[str]:
"""List of connected players' nicknames
2022-07-01 13:28:39 +03:00
Returns:
Connected players
2022-07-01 13:28:39 +03:00
"""
2022-06-23 14:13:56 +03:00
return self._info['playerlist']
@property
def players_count(self) -> int:
"""How many players are connected
2022-07-01 13:28:39 +03:00
Returns:
Connected players count
2022-07-01 13:28:39 +03:00
"""
2022-06-23 14:13:56 +03:00
return int(self._info['players'])
@property
def slots(self) -> int:
"""Server slots, how many
players **can** connect
2022-07-01 13:28:39 +03:00
Returns:
Slots count
2022-07-01 13:28:39 +03:00
"""
2022-06-23 14:13:56 +03:00
return int(self._info['slots'])
@property
def ram(self) -> int:
2022-07-01 13:28:39 +03:00
"""Server used RAM in MB
Returns:
Used RAM
2022-07-01 13:28:39 +03:00
"""
2022-06-23 14:13:56 +03:00
return int(self._info['ram'])
2022-12-23 16:38:51 +03:00
@property
def countdown(self) -> int:
"""Server stop countdown
in seconds
Returns:
Stop countdown
"""
value = self._info['countdown']
return int(value or -1)