2022-07-01 14:28:39 +04:00
|
|
|
"""Modifying server and world options"""
|
|
|
|
|
2023-05-24 17:41:33 +04:00
|
|
|
# TODO: Still needs refactoring
|
|
|
|
|
2022-01-11 18:08:59 +04:00
|
|
|
import enum
|
2021-10-15 15:12:45 +04:00
|
|
|
import re
|
2022-08-22 09:55:08 +04:00
|
|
|
|
2022-06-17 12:30:58 +04:00
|
|
|
from typing import Any, Dict, List, Union, Optional
|
2021-10-15 19:31:47 +04:00
|
|
|
from typing import TYPE_CHECKING
|
2021-10-15 15:12:45 +04:00
|
|
|
|
2022-08-22 09:55:08 +04:00
|
|
|
import lxml.html
|
|
|
|
|
2023-05-24 17:41:33 +04:00
|
|
|
from .atconnect import BASE_URL, AJAX_URL
|
2021-10-15 19:31:47 +04:00
|
|
|
if TYPE_CHECKING:
|
2022-06-23 15:13:56 +04:00
|
|
|
from .atserver import AternosServer
|
|
|
|
|
2023-05-24 17:41:33 +04:00
|
|
|
|
2022-06-23 15:13:56 +04:00
|
|
|
DAT_PREFIX = 'Data:'
|
|
|
|
DAT_GR_PREFIX = 'Data:GameRules:'
|
|
|
|
|
2021-10-15 19:31:47 +04:00
|
|
|
|
2022-01-11 18:08:59 +04:00
|
|
|
class ServerOpts(enum.Enum):
|
2022-06-17 12:30:58 +04:00
|
|
|
|
2022-06-23 15:13:56 +04:00
|
|
|
"""server.options file"""
|
|
|
|
|
|
|
|
players = 'max-players'
|
|
|
|
gm = 'gamemode'
|
|
|
|
difficulty = 'difficulty'
|
|
|
|
whl = 'white-list'
|
|
|
|
online = 'online-mode'
|
|
|
|
pvp = 'pvp'
|
|
|
|
cmdblock = 'enable-command-block'
|
|
|
|
flight = 'allow-flight'
|
|
|
|
animals = 'spawn-animals'
|
|
|
|
monsters = 'spawn-monsters'
|
|
|
|
villagers = 'spawn-npcs'
|
|
|
|
nether = 'allow-nether'
|
|
|
|
forcegm = 'force-gamemode'
|
|
|
|
spawnlock = 'spawn-protection'
|
|
|
|
cmds = 'allow-cheats'
|
|
|
|
packreq = 'require-resource-pack'
|
|
|
|
pack = 'resource-pack'
|
2021-10-15 15:12:45 +04:00
|
|
|
|
2022-01-11 18:08:59 +04:00
|
|
|
|
|
|
|
class WorldOpts(enum.Enum):
|
2022-06-17 12:30:58 +04:00
|
|
|
|
2022-06-23 15:13:56 +04:00
|
|
|
"""level.dat file"""
|
|
|
|
|
|
|
|
seed12 = 'randomseed'
|
|
|
|
seed = 'seed'
|
|
|
|
hardcore = 'hardcore'
|
|
|
|
difficulty = 'Difficulty'
|
2022-06-17 12:30:58 +04:00
|
|
|
|
2021-10-15 15:12:45 +04:00
|
|
|
|
2022-01-11 18:08:59 +04:00
|
|
|
class WorldRules(enum.Enum):
|
2022-06-17 12:30:58 +04:00
|
|
|
|
2022-06-23 15:13:56 +04:00
|
|
|
"""/gamerule list"""
|
|
|
|
|
|
|
|
advs = 'announceAdvancements'
|
|
|
|
univanger = 'universalAnger'
|
|
|
|
cmdout = 'commandBlockOutput'
|
|
|
|
elytra = 'disableElytraMovementCheck'
|
|
|
|
raids = 'disableRaids'
|
|
|
|
daynight = 'doDaylightCycle'
|
|
|
|
entdrop = 'doEntityDrops'
|
|
|
|
fire = 'doFireTick'
|
|
|
|
phantoms = 'doInsomnia'
|
|
|
|
immrespawn = 'doImmediateRespawn'
|
|
|
|
limitcraft = 'doLimitedCrafting'
|
|
|
|
mobloot = 'doMobLoot'
|
|
|
|
mobs = 'doMobSpawning'
|
|
|
|
patrols = 'doPatrolSpawning'
|
|
|
|
blockdrop = 'doTileDrops'
|
|
|
|
traders = 'doTraderSpawning'
|
|
|
|
weather = 'doWeatherCycle'
|
|
|
|
drowndmg = 'drowningDamage'
|
|
|
|
falldmg = 'fallDamage'
|
|
|
|
firedmg = 'fireDamage'
|
|
|
|
snowdmg = 'freezeDamage'
|
|
|
|
forgive = 'forgiveDeadPlayers'
|
|
|
|
keepinv = 'keepInventory'
|
|
|
|
deathmsg = 'showDeathMessages'
|
|
|
|
admincmdlog = 'logAdminCommands'
|
|
|
|
cmdlen = 'maxCommandChainLength'
|
|
|
|
entcram = 'maxEntityCramming'
|
|
|
|
mobgrief = 'mobGriefing'
|
|
|
|
regen = 'naturalRegeneration'
|
|
|
|
sleeppct = 'playersSleepingPercentage'
|
|
|
|
rndtick = 'randomTickSpeed'
|
|
|
|
spawnradius = 'spawnRadius'
|
|
|
|
reducedf3 = 'reducedDebugInfo'
|
|
|
|
spectchunkgen = 'spectatorsGenerateChunks'
|
|
|
|
cmdfb = 'sendCommandFeedback'
|
|
|
|
|
2021-10-15 15:12:45 +04:00
|
|
|
|
2022-01-11 18:08:59 +04:00
|
|
|
class Gamemode(enum.IntEnum):
|
2022-06-17 12:30:58 +04:00
|
|
|
|
2022-06-23 15:13:56 +04:00
|
|
|
"""/gamemode numeric list"""
|
|
|
|
|
|
|
|
survival = 0
|
|
|
|
creative = 1
|
|
|
|
adventure = 2
|
|
|
|
spectator = 3
|
2022-06-17 12:30:58 +04:00
|
|
|
|
2021-10-15 15:12:45 +04:00
|
|
|
|
2022-01-11 18:08:59 +04:00
|
|
|
class Difficulty(enum.IntEnum):
|
2022-06-17 12:30:58 +04:00
|
|
|
|
2022-06-23 15:13:56 +04:00
|
|
|
"""/difficulty numeric list"""
|
|
|
|
|
|
|
|
peaceful = 0
|
|
|
|
easy = 1
|
|
|
|
normal = 2
|
|
|
|
hard = 3
|
2022-06-17 12:30:58 +04:00
|
|
|
|
2021-10-15 15:12:45 +04:00
|
|
|
|
2022-03-25 16:45:38 +04:00
|
|
|
# checking timezone format
|
|
|
|
tzcheck = re.compile(r'(^[A-Z]\w+\/[A-Z]\w+$)|^UTC$')
|
2023-05-24 17:41:33 +04:00
|
|
|
|
2022-03-25 16:45:38 +04:00
|
|
|
# options types converting
|
2022-03-18 18:38:36 +04:00
|
|
|
convert = {
|
2022-06-23 15:13:56 +04:00
|
|
|
'config-option-number': int,
|
|
|
|
'config-option-select': int,
|
2023-05-24 17:41:33 +04:00
|
|
|
'config-option-toggle': bool,
|
2022-03-18 18:38:36 +04:00
|
|
|
}
|
2021-10-15 15:12:45 +04:00
|
|
|
|
2022-06-23 15:13:56 +04:00
|
|
|
|
2021-10-15 15:12:45 +04:00
|
|
|
class AternosConfig:
|
|
|
|
|
MkDocs, Readme, Files API, Automated session saving, v2.0.1
MkDocs: sphinx docstrings rewritten to google, improved config, written the major part of how-to.
Readme: centered title + logo, added badges, features list, updated changelog.
Improved Files API, added automatical session saving and restoring to Client.
Some changes in makefile and gitignore.
License Notice now refers to all contributors.
2022-08-26 16:14:07 +04:00
|
|
|
"""Class for editing server settings"""
|
2022-06-23 15:13:56 +04:00
|
|
|
|
|
|
|
def __init__(self, atserv: 'AternosServer') -> None:
|
MkDocs, Readme, Files API, Automated session saving, v2.0.1
MkDocs: sphinx docstrings rewritten to google, improved config, written the major part of how-to.
Readme: centered title + logo, added badges, features list, updated changelog.
Improved Files API, added automatical session saving and restoring to Client.
Some changes in makefile and gitignore.
License Notice now refers to all contributors.
2022-08-26 16:14:07 +04:00
|
|
|
"""Class for editing server settings
|
|
|
|
|
|
|
|
Args:
|
|
|
|
atserv (python_aternos.atserver.AternosServer):
|
|
|
|
atserver.AternosServer object
|
|
|
|
"""
|
|
|
|
|
2022-06-23 15:13:56 +04:00
|
|
|
self.atserv = atserv
|
2021-10-15 15:12:45 +04:00
|
|
|
|
2022-06-23 15:13:56 +04:00
|
|
|
def get_timezone(self) -> str:
|
|
|
|
"""Parses timezone from options page
|
2022-01-11 18:08:59 +04:00
|
|
|
|
MkDocs, Readme, Files API, Automated session saving, v2.0.1
MkDocs: sphinx docstrings rewritten to google, improved config, written the major part of how-to.
Readme: centered title + logo, added badges, features list, updated changelog.
Improved Files API, added automatical session saving and restoring to Client.
Some changes in makefile and gitignore.
License Notice now refers to all contributors.
2022-08-26 16:14:07 +04:00
|
|
|
Returns:
|
|
|
|
Area/Location
|
2022-06-23 15:13:56 +04:00
|
|
|
"""
|
2022-06-17 12:30:58 +04:00
|
|
|
|
2022-06-23 15:13:56 +04:00
|
|
|
optreq = self.atserv.atserver_request(
|
2023-05-24 17:41:33 +04:00
|
|
|
f'{BASE_URL}/options', 'GET'
|
2022-06-23 15:13:56 +04:00
|
|
|
)
|
|
|
|
opttree = lxml.html.fromstring(optreq)
|
2022-06-17 12:30:58 +04:00
|
|
|
|
2022-06-23 15:13:56 +04:00
|
|
|
tzopt = opttree.xpath(
|
|
|
|
'//div[@class="options-other-input timezone-switch"]'
|
|
|
|
)[0]
|
|
|
|
tztext = tzopt.xpath('.//div[@class="option current"]')[0].text
|
|
|
|
return tztext.strip()
|
2021-10-15 15:12:45 +04:00
|
|
|
|
2022-06-23 15:13:56 +04:00
|
|
|
def set_timezone(self, value: str) -> None:
|
|
|
|
"""Sets new timezone
|
2022-01-11 18:08:59 +04:00
|
|
|
|
MkDocs, Readme, Files API, Automated session saving, v2.0.1
MkDocs: sphinx docstrings rewritten to google, improved config, written the major part of how-to.
Readme: centered title + logo, added badges, features list, updated changelog.
Improved Files API, added automatical session saving and restoring to Client.
Some changes in makefile and gitignore.
License Notice now refers to all contributors.
2022-08-26 16:14:07 +04:00
|
|
|
Args:
|
|
|
|
value (str): New timezone
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
ValueError: If given string doesn't
|
|
|
|
match `Area/Location` format
|
2022-06-23 15:13:56 +04:00
|
|
|
"""
|
2022-06-17 12:30:58 +04:00
|
|
|
|
2022-06-23 15:13:56 +04:00
|
|
|
matches_tz = tzcheck.search(value)
|
|
|
|
if not matches_tz:
|
|
|
|
raise ValueError(
|
|
|
|
'Timezone must match zoneinfo format: Area/Location'
|
|
|
|
)
|
2022-06-17 12:30:58 +04:00
|
|
|
|
2022-06-23 15:13:56 +04:00
|
|
|
self.atserv.atserver_request(
|
2023-05-24 17:41:33 +04:00
|
|
|
f'{AJAX_URL}/timezone.php',
|
2022-06-23 15:13:56 +04:00
|
|
|
'POST', data={'timezone': value},
|
|
|
|
sendtoken=True
|
|
|
|
)
|
2021-10-15 15:12:45 +04:00
|
|
|
|
2022-06-23 15:13:56 +04:00
|
|
|
def get_java(self) -> int:
|
|
|
|
"""Parses Java version from options page
|
2022-06-17 12:30:58 +04:00
|
|
|
|
MkDocs, Readme, Files API, Automated session saving, v2.0.1
MkDocs: sphinx docstrings rewritten to google, improved config, written the major part of how-to.
Readme: centered title + logo, added badges, features list, updated changelog.
Improved Files API, added automatical session saving and restoring to Client.
Some changes in makefile and gitignore.
License Notice now refers to all contributors.
2022-08-26 16:14:07 +04:00
|
|
|
Returns:
|
|
|
|
Java image version
|
2022-06-23 15:13:56 +04:00
|
|
|
"""
|
2022-06-17 12:30:58 +04:00
|
|
|
|
2022-06-23 15:13:56 +04:00
|
|
|
optreq = self.atserv.atserver_request(
|
2023-05-24 17:41:33 +04:00
|
|
|
f'{BASE_URL}/options', 'GET'
|
2022-06-23 15:13:56 +04:00
|
|
|
)
|
|
|
|
opttree = lxml.html.fromstring(optreq)
|
|
|
|
imgopt = opttree.xpath(
|
|
|
|
'//div[@class="options-other-input image-switch"]'
|
|
|
|
)[0]
|
|
|
|
imgver = imgopt.xpath(
|
|
|
|
'.//div[@class="option current"]/@data-value'
|
|
|
|
)[0]
|
2022-01-11 18:08:59 +04:00
|
|
|
|
2022-06-23 15:13:56 +04:00
|
|
|
jdkver = str(imgver or '').removeprefix('openjdk:')
|
|
|
|
return int(jdkver)
|
2021-10-15 15:12:45 +04:00
|
|
|
|
2022-06-23 15:13:56 +04:00
|
|
|
def set_java(self, value: int) -> None:
|
|
|
|
"""Sets new Java version
|
|
|
|
|
MkDocs, Readme, Files API, Automated session saving, v2.0.1
MkDocs: sphinx docstrings rewritten to google, improved config, written the major part of how-to.
Readme: centered title + logo, added badges, features list, updated changelog.
Improved Files API, added automatical session saving and restoring to Client.
Some changes in makefile and gitignore.
License Notice now refers to all contributors.
2022-08-26 16:14:07 +04:00
|
|
|
Args:
|
|
|
|
value (int): New Java image version
|
2022-06-23 15:13:56 +04:00
|
|
|
"""
|
|
|
|
|
|
|
|
self.atserv.atserver_request(
|
2023-05-24 17:41:33 +04:00
|
|
|
f'{AJAX_URL}/image.php',
|
2022-06-23 15:13:56 +04:00
|
|
|
'POST', data={'image': f'openjdk:{value}'},
|
|
|
|
sendtoken=True
|
|
|
|
)
|
|
|
|
|
|
|
|
#
|
|
|
|
# server.properties
|
|
|
|
#
|
|
|
|
def set_server_prop(self, option: str, value: Any) -> None:
|
|
|
|
"""Sets server.properties option
|
|
|
|
|
MkDocs, Readme, Files API, Automated session saving, v2.0.1
MkDocs: sphinx docstrings rewritten to google, improved config, written the major part of how-to.
Readme: centered title + logo, added badges, features list, updated changelog.
Improved Files API, added automatical session saving and restoring to Client.
Some changes in makefile and gitignore.
License Notice now refers to all contributors.
2022-08-26 16:14:07 +04:00
|
|
|
Args:
|
|
|
|
option (str): Option name
|
|
|
|
value (Any): New value
|
2022-06-23 15:13:56 +04:00
|
|
|
"""
|
|
|
|
|
|
|
|
self.__set_prop(
|
|
|
|
'/server.properties',
|
|
|
|
option, value
|
|
|
|
)
|
|
|
|
|
|
|
|
def get_server_props(self, proptyping: bool = True) -> Dict[str, Any]:
|
|
|
|
"""Parses all server.properties from options page
|
|
|
|
|
MkDocs, Readme, Files API, Automated session saving, v2.0.1
MkDocs: sphinx docstrings rewritten to google, improved config, written the major part of how-to.
Readme: centered title + logo, added badges, features list, updated changelog.
Improved Files API, added automatical session saving and restoring to Client.
Some changes in makefile and gitignore.
License Notice now refers to all contributors.
2022-08-26 16:14:07 +04:00
|
|
|
Args:
|
|
|
|
proptyping (bool, optional):
|
|
|
|
If the returned dict should
|
|
|
|
contain value that matches
|
|
|
|
property type (e.g. max-players will be int)
|
|
|
|
instead of string
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
`server.properties` dictionary
|
2022-06-23 15:13:56 +04:00
|
|
|
"""
|
|
|
|
|
2023-05-24 17:41:33 +04:00
|
|
|
return self.__get_all_props(f'{BASE_URL}/options', proptyping)
|
2022-06-23 15:13:56 +04:00
|
|
|
|
|
|
|
def set_server_props(self, props: Dict[str, Any]) -> None:
|
|
|
|
"""Updates server.properties options with the given dict
|
|
|
|
|
MkDocs, Readme, Files API, Automated session saving, v2.0.1
MkDocs: sphinx docstrings rewritten to google, improved config, written the major part of how-to.
Readme: centered title + logo, added badges, features list, updated changelog.
Improved Files API, added automatical session saving and restoring to Client.
Some changes in makefile and gitignore.
License Notice now refers to all contributors.
2022-08-26 16:14:07 +04:00
|
|
|
Args:
|
|
|
|
props (Dict[str,Any]):
|
|
|
|
Dictionary with `{key:value}` properties
|
2022-06-23 15:13:56 +04:00
|
|
|
"""
|
|
|
|
|
|
|
|
for key in props:
|
|
|
|
self.set_server_prop(key, props[key])
|
|
|
|
|
|
|
|
#
|
|
|
|
# level.dat
|
|
|
|
#
|
|
|
|
def set_world_prop(
|
|
|
|
self, option: Union[WorldOpts, WorldRules],
|
|
|
|
value: Any, gamerule: bool = False,
|
|
|
|
world: str = 'world') -> None:
|
|
|
|
"""Sets level.dat option for specified world
|
|
|
|
|
MkDocs, Readme, Files API, Automated session saving, v2.0.1
MkDocs: sphinx docstrings rewritten to google, improved config, written the major part of how-to.
Readme: centered title + logo, added badges, features list, updated changelog.
Improved Files API, added automatical session saving and restoring to Client.
Some changes in makefile and gitignore.
License Notice now refers to all contributors.
2022-08-26 16:14:07 +04:00
|
|
|
Args:
|
|
|
|
option (Union[WorldOpts, WorldRules]): Option name
|
|
|
|
value (Any): New value
|
|
|
|
gamerule (bool, optional): If the option is a gamerule
|
|
|
|
world (str, optional): Name of the world which
|
|
|
|
`level.dat` must be edited
|
2022-06-23 15:13:56 +04:00
|
|
|
"""
|
|
|
|
|
|
|
|
prefix = DAT_PREFIX
|
|
|
|
if gamerule:
|
|
|
|
prefix = DAT_GR_PREFIX
|
|
|
|
|
|
|
|
self.__set_prop(
|
|
|
|
f'/{world}/level.dat',
|
|
|
|
f'{prefix}{option}',
|
|
|
|
value
|
|
|
|
)
|
|
|
|
|
|
|
|
def get_world_props(
|
|
|
|
self, world: str = 'world',
|
|
|
|
proptyping: bool = True) -> Dict[str, Any]:
|
|
|
|
"""Parses level.dat from specified world's options page
|
|
|
|
|
MkDocs, Readme, Files API, Automated session saving, v2.0.1
MkDocs: sphinx docstrings rewritten to google, improved config, written the major part of how-to.
Readme: centered title + logo, added badges, features list, updated changelog.
Improved Files API, added automatical session saving and restoring to Client.
Some changes in makefile and gitignore.
License Notice now refers to all contributors.
2022-08-26 16:14:07 +04:00
|
|
|
Args:
|
|
|
|
world (str, optional): Name of the worl
|
|
|
|
proptyping (bool, optional):
|
|
|
|
If the returned dict should
|
|
|
|
contain the value that matches
|
|
|
|
property type (e.g. randomTickSpeed will be bool)
|
|
|
|
instead of string
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
`level.dat` options dictionary
|
2022-06-23 15:13:56 +04:00
|
|
|
"""
|
|
|
|
|
2022-07-01 09:36:52 +04:00
|
|
|
return self.__get_all_props(
|
2023-05-24 17:41:33 +04:00
|
|
|
f'{BASE_URL}/files/{world}/level.dat',
|
2022-06-23 15:13:56 +04:00
|
|
|
proptyping, [DAT_PREFIX, DAT_GR_PREFIX]
|
|
|
|
)
|
|
|
|
|
2022-07-01 09:36:52 +04:00
|
|
|
def set_world_props(
|
|
|
|
self,
|
2022-07-01 14:28:39 +04:00
|
|
|
props: Dict[Union[WorldOpts, WorldRules], Any],
|
|
|
|
world: str = 'world') -> None:
|
|
|
|
"""Sets level.dat options from
|
|
|
|
the dictionary for the specified world
|
|
|
|
|
MkDocs, Readme, Files API, Automated session saving, v2.0.1
MkDocs: sphinx docstrings rewritten to google, improved config, written the major part of how-to.
Readme: centered title + logo, added badges, features list, updated changelog.
Improved Files API, added automatical session saving and restoring to Client.
Some changes in makefile and gitignore.
License Notice now refers to all contributors.
2022-08-26 16:14:07 +04:00
|
|
|
Args:
|
|
|
|
props (Dict[Union[WorldOpts, WorldRules], Any]):
|
|
|
|
`level.dat` options
|
|
|
|
world (str): name of the world which
|
|
|
|
`level.dat` must be edited
|
2022-07-01 14:28:39 +04:00
|
|
|
"""
|
2022-07-01 09:36:52 +04:00
|
|
|
|
2022-06-23 15:13:56 +04:00
|
|
|
for key in props:
|
2022-07-01 14:28:39 +04:00
|
|
|
self.set_world_prop(
|
|
|
|
option=key,
|
|
|
|
value=props[key],
|
|
|
|
world=world
|
|
|
|
)
|
2022-06-23 15:13:56 +04:00
|
|
|
|
|
|
|
#
|
|
|
|
# helpers
|
|
|
|
#
|
|
|
|
def __set_prop(self, file: str, option: str, value: Any) -> None:
|
|
|
|
|
|
|
|
self.atserv.atserver_request(
|
2023-05-24 17:41:33 +04:00
|
|
|
f'{AJAX_URL}/config.php',
|
2022-06-23 15:13:56 +04:00
|
|
|
'POST', data={
|
|
|
|
'file': file,
|
|
|
|
'option': option,
|
|
|
|
'value': value
|
|
|
|
}, sendtoken=True
|
|
|
|
)
|
|
|
|
|
|
|
|
def __get_all_props(
|
|
|
|
self, url: str, proptyping: bool = True,
|
|
|
|
prefixes: Optional[List[str]] = None) -> Dict[str, Any]:
|
|
|
|
|
|
|
|
optreq = self.atserv.atserver_request(url, 'GET')
|
|
|
|
opttree = lxml.html.fromstring(optreq.content)
|
|
|
|
configs = opttree.xpath('//div[@class="config-options"]')
|
|
|
|
|
|
|
|
for i, conf in enumerate(configs):
|
|
|
|
opts = conf.xpath('/div[contains(@class,"config-option ")]')
|
|
|
|
result = {}
|
|
|
|
|
|
|
|
for opt in opts:
|
|
|
|
key = opt.xpath(
|
|
|
|
'.//span[@class="config-option-output-key"]'
|
|
|
|
)[0].text
|
|
|
|
value = opt.xpath(
|
|
|
|
'.//span[@class="config-option-output-value"]'
|
|
|
|
)[0].text
|
|
|
|
|
|
|
|
if prefixes is not None:
|
|
|
|
key = f'{prefixes[i]}{key}'
|
|
|
|
|
|
|
|
opttype = opt.xpath('/@class').split(' ')[1]
|
|
|
|
if proptyping and opttype in convert:
|
|
|
|
value = convert[opttype](value)
|
|
|
|
|
|
|
|
result[key] = value
|
|
|
|
|
|
|
|
return result
|