Merge branch 'dev' into tweak/server-config-check

This commit is contained in:
Zedifus 2024-01-16 19:13:13 +00:00
commit a8fc90d0f9
6 changed files with 127 additions and 30 deletions

View File

@ -1,11 +1,12 @@
# Changelog
## --- [4.2.3] - 2023/TBD
### New features
TBD
- Use Papermc Group's API for `paper` & `folia` builds in server builder ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/688))
### Bug fixes
TBD
- Fix bukkit and downstream fork MOTD crash ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/686))
- Fix bug where invalid server Id leads to stack ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/690))
### Tweaks
TBD
- Refactor Forge server initialisation flow for newer versions ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/687))
### Lang
TBD
<br><br>

View File

@ -462,7 +462,10 @@ class ServersController(metaclass=Singleton):
@staticmethod
def server_id_exists(server_id):
try:
srv = ServersController().get_server_instance_by_id(server_id)
except ValueError:
return False
return srv.stats_helper.server_id_exists()
@staticmethod

View File

@ -12,6 +12,7 @@ from app.classes.minecraft.bedrock_ping import BedrockPing
from app.classes.shared.console import Console
logger = logging.getLogger(__name__)
MOTD_CODES = ["bold", "italic", "underlined", "strikethrough"]
class Server:
@ -34,18 +35,19 @@ class Server:
lines = []
description = self.description
if "text" in description.keys():
lines.append(description["text"])
if "extra" in description.keys():
if isinstance(description["extra"], list):
for e in description["extra"]:
if not isinstance(e, dict):
lines.append(e)
continue
# Conversion format code needed only for Java Version
lines.append(get_code_format("reset"))
if "bold" in e.keys():
lines.append(get_code_format("bold"))
if "italic" in e.keys():
lines.append(get_code_format("italic"))
if "underlined" in e.keys():
lines.append(get_code_format("underlined"))
if "strikethrough" in e.keys():
lines.append(get_code_format("strikethrough"))
for item in MOTD_CODES:
if e.get(item, False):
lines.append(get_code_format(item))
if "color" in e.keys():
lines.append(get_code_format(e["color"]))
# Then append the text

View File

@ -11,12 +11,18 @@ from app.classes.models.server_permissions import PermissionsServers
from app.classes.shared.websocket_manager import WebSocketManager
logger = logging.getLogger(__name__)
PAPERJARS = ["paper", "folia"]
class ServerJars:
def __init__(self, helper):
self.helper = helper
self.base_url = "https://serverjars.com"
self.paper_base = "https://api.papermc.io"
@staticmethod
def get_paper_jars():
return PAPERJARS
def _get_api_result(self, call_url: str):
full_url = f"{self.base_url}{call_url}"
@ -38,6 +44,40 @@ class ServerJars:
return api_response
def get_paper_versions(self, project):
try:
response = requests.get(
f"{self.paper_base}/v2/projects/{project}/", timeout=2
)
response.raise_for_status()
api_data = json.loads(response.content)
except Exception as e:
logger.error(
f"Unable to load https://api.papermc.io/v2/projects/{project}/"
f"api due to error: {e}"
)
return {}
versions = api_data.get("versions", [])
versions.reverse()
return versions
def get_paper_build(self, project, version):
try:
response = requests.get(
f"{self.paper_base}/v2/projects/{project}/versions/{version}/builds/",
timeout=2,
)
response.raise_for_status()
api_data = json.loads(response.content)
except Exception as e:
logger.error(
f"Unable to load https://api.papermc.io/v2/projects/{project}/"
f"api due to error: {e}"
)
return {}
build = api_data.get("builds", [])[-1]
return build
def _read_cache(self):
cache_file = self.helper.serverjar_cache
cache = {}
@ -95,6 +135,8 @@ class ServerJars:
for j in data["types"].get(s):
versions = self._get_jar_details(j, s)
data["types"][s].update({j: versions})
for item in PAPERJARS:
data["types"]["servers"][item] = self.get_paper_versions(item)
# save our cache
try:
with open(cache_file, "w", encoding="utf-8") as f:
@ -133,6 +175,8 @@ class ServerJars:
for j in data["types"].get(s):
versions = self._get_jar_details(j, s)
data["types"][s].update({j: versions})
for item in PAPERJARS:
data["types"]["servers"][item] = self.get_paper_versions(item)
# save our cache
try:
with open(cache_file, "w", encoding="utf-8") as f:
@ -171,7 +215,17 @@ class ServerJars:
def a_download_jar(self, jar, server, version, path, server_id):
# delaying download for server register to finish
time.sleep(3)
if server not in PAPERJARS:
fetch_url = f"{self.base_url}/api/fetchJar/{jar}/{server}/{version}"
else:
build = self.get_paper_build(server, version).get("build", None)
if not build:
return
fetch_url = (
f"{self.paper_base}/v2/projects"
f"/{server}/versions/{version}/builds/{build}/downloads/"
f"{server}-{version}-{build}.jar"
)
server_users = PermissionsServers.get_server_user_list(server_id)
# We need to make sure the server is registered before

View File

@ -536,10 +536,14 @@ class Controller:
if data["create_type"] == "minecraft_java":
if root_create_data["create_type"] == "download_jar":
# modded update urls from server jars will only update the installer
if create_data["category"] != "modded":
if (
create_data["category"] != "modded"
and create_data["type"] not in ServerJars.get_paper_jars()
):
server_obj = self.servers.get_server_obj(new_server_id)
url = (
f"https://serverjars.com/api/fetchJar/{create_data['category']}"
"https://serverjars.com/api/fetchJar/"
f"{create_data['category']}"
f"/{create_data['type']}/{create_data['version']}"
)
server_obj.executable_update_url = url

View File

@ -43,6 +43,7 @@ with redirect_stderr(NullWriter()):
from psutil import NoSuchProcess
logger = logging.getLogger(__name__)
SUCCESSMSG = "SUCCESS! Forge install completed"
def callback(called_func):
@ -723,10 +724,11 @@ class ServerInstance:
f' -jar "{file_name}" nogui'
)
server_obj.execution_command = execution_command
Console.debug("SUCCESS! Forge install completed")
Console.debug(SUCCESSMSG)
else:
# NEW VERSION >= 1.17
elif version_major <= 1 and version_minor < 20:
# NEW VERSION >= 1.17 and <= 1.20
# (no jar file in server dir, only run.bat and run.sh)
run_file_path = ""
if self.helper.is_os_windows():
@ -770,7 +772,38 @@ class ServerInstance:
f" {server_command[4]}"
)
server_obj.execution_command = execution_command
Console.debug("SUCCESS! Forge install completed")
Console.debug(SUCCESSMSG)
else:
# NEW VERSION >= 1.20
# (executable jar is back in server dir)
# Retrieving the executable jar filename
file_path = glob.glob(
f"{server_obj.path}/forge-{version[0][0]}*.jar"
)[0]
file_name = re.findall(
r"(forge-[\-0-9.]+-shim.jar)",
file_path,
)[0]
# Let's set the proper server executable
server_obj.executable = os.path.join(file_name)
# Get memory values
memory_values = re.findall(
r"-Xms([A-Z0-9\.]+) -Xmx([A-Z0-9\.]+)",
server_obj.execution_command,
)
# Now lets set up the new run command.
# This is based off the run.sh/bat that
# Forge uses in 1.17 and <
execution_command = (
f"java -Xms{memory_values[0][0]} -Xmx{memory_values[0][1]}"
f' -jar "{file_name}" nogui'
)
server_obj.execution_command = execution_command
Console.debug(SUCCESSMSG)
except:
logger.debug("Could not find run file.")
# TODO Use regex to get version and rebuild simple execution