From e274b0c67767bb4ec65a10e4cb17ae7fc7586f41 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Thu, 11 Jan 2024 19:20:50 -0500 Subject: [PATCH 1/7] Implement paper builds using mineacademy API Big shoutout to zed for fnding this --- app/classes/minecraft/serverjars.py | 30 ++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/app/classes/minecraft/serverjars.py b/app/classes/minecraft/serverjars.py index 447cf80b..55e98a80 100644 --- a/app/classes/minecraft/serverjars.py +++ b/app/classes/minecraft/serverjars.py @@ -11,12 +11,14 @@ from app.classes.models.server_permissions import PermissionsServers from app.classes.shared.websocket_manager import WebSocketManager logger = logging.getLogger(__name__) +MINEACADEMYJARS = ["paper", "folia"] class ServerJars: def __init__(self, helper): self.helper = helper self.base_url = "https://serverjars.com" + self.academy = "https://mineacademy.org" def _get_api_result(self, call_url: str): full_url = f"{self.base_url}{call_url}" @@ -38,6 +40,23 @@ class ServerJars: return api_response + def get_paper_versions(self, project): + try: + response = requests.get( + f"https://api.papermc.io/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 _read_cache(self): cache_file = self.helper.serverjar_cache cache = {} @@ -95,6 +114,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 MINEACADEMYJARS: + 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 +154,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 MINEACADEMYJARS: + data["types"]["servers"][item] = self.get_paper_versions() # save our cache try: with open(cache_file, "w", encoding="utf-8") as f: @@ -171,7 +194,12 @@ class ServerJars: def a_download_jar(self, jar, server, version, path, server_id): # delaying download for server register to finish time.sleep(3) - fetch_url = f"{self.base_url}/api/fetchJar/{jar}/{server}/{version}" + if server not in MINEACADEMYJARS: + fetch_url = f"{self.base_url}/api/fetchJar/{jar}/{server}/{version}" + else: + fetch_url = ( + f"https://mineacademy.org/api/{server}/{str(version).replace('.', '_')}" + ) server_users = PermissionsServers.get_server_user_list(server_id) # We need to make sure the server is registered before From cd3b8d4d9cdc8ad11173f7b163ddd9e4ee86c350 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Thu, 11 Jan 2024 19:35:08 -0500 Subject: [PATCH 2/7] Fix update urls --- app/classes/minecraft/serverjars.py | 4 ++++ app/classes/shared/main_controller.py | 15 +++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/app/classes/minecraft/serverjars.py b/app/classes/minecraft/serverjars.py index 55e98a80..5c6d6d91 100644 --- a/app/classes/minecraft/serverjars.py +++ b/app/classes/minecraft/serverjars.py @@ -20,6 +20,10 @@ class ServerJars: self.base_url = "https://serverjars.com" self.academy = "https://mineacademy.org" + @staticmethod + def get_mineacademy_jars(): + return MINEACADEMYJARS + def _get_api_result(self, call_url: str): full_url = f"{self.base_url}{call_url}" diff --git a/app/classes/shared/main_controller.py b/app/classes/shared/main_controller.py index ae58d988..60f3c5df 100644 --- a/app/classes/shared/main_controller.py +++ b/app/classes/shared/main_controller.py @@ -538,10 +538,17 @@ class Controller: # modded update urls from server jars will only update the installer if create_data["category"] != "modded": server_obj = self.servers.get_server_obj(new_server_id) - url = ( - f"https://serverjars.com/api/fetchJar/{create_data['category']}" - f"/{create_data['type']}/{create_data['version']}" - ) + if create_data["type"] not in ServerJars.get_mineacademy_jars(): + url = ( + "https://serverjars.com/api/fetchJar/" + f"{create_data['category']}" + f"/{create_data['type']}/{create_data['version']}" + ) + else: + url = ( + "https://mineacademy.org/api/" + f"{create_data['type']}/{create_data['version']}" + ) server_obj.executable_update_url = url self.servers.update_server(server_obj) self.server_jars.download_jar( From 96d5ce58d2e2d675a237c9adfc0dd0620c2c13f9 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Fri, 12 Jan 2024 11:23:35 -0500 Subject: [PATCH 3/7] Get jars direct frrom paper --- app/classes/minecraft/serverjars.py | 40 +++++++++++++++++++++------ app/classes/shared/main_controller.py | 2 +- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/app/classes/minecraft/serverjars.py b/app/classes/minecraft/serverjars.py index 5c6d6d91..cadcb376 100644 --- a/app/classes/minecraft/serverjars.py +++ b/app/classes/minecraft/serverjars.py @@ -11,18 +11,18 @@ from app.classes.models.server_permissions import PermissionsServers from app.classes.shared.websocket_manager import WebSocketManager logger = logging.getLogger(__name__) -MINEACADEMYJARS = ["paper", "folia"] +PAPERJARS = ["paper", "folia"] class ServerJars: def __init__(self, helper): self.helper = helper self.base_url = "https://serverjars.com" - self.academy = "https://mineacademy.org" + self.paper_base = "https://api.papermc.io" @staticmethod - def get_mineacademy_jars(): - return MINEACADEMYJARS + def get_paper_jars(): + return PAPERJARS def _get_api_result(self, call_url: str): full_url = f"{self.base_url}{call_url}" @@ -47,7 +47,7 @@ class ServerJars: def get_paper_versions(self, project): try: response = requests.get( - f"https://api.papermc.io/v2/projects/{project}/", timeout=2 + f"{self.paper_base}/v2/projects/{project}/", timeout=2 ) response.raise_for_status() api_data = json.loads(response.content) @@ -61,6 +61,23 @@ class ServerJars: 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 = {} @@ -118,7 +135,7 @@ 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 MINEACADEMYJARS: + for item in PAPERJARS: data["types"]["servers"][item] = self.get_paper_versions(item) # save our cache try: @@ -158,7 +175,7 @@ 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 MINEACADEMYJARS: + for item in PAPERJARS: data["types"]["servers"][item] = self.get_paper_versions() # save our cache try: @@ -198,11 +215,16 @@ 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 MINEACADEMYJARS: + 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"https://mineacademy.org/api/{server}/{str(version).replace('.', '_')}" + 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) diff --git a/app/classes/shared/main_controller.py b/app/classes/shared/main_controller.py index 60f3c5df..ffc355ea 100644 --- a/app/classes/shared/main_controller.py +++ b/app/classes/shared/main_controller.py @@ -538,7 +538,7 @@ class Controller: # modded update urls from server jars will only update the installer if create_data["category"] != "modded": server_obj = self.servers.get_server_obj(new_server_id) - if create_data["type"] not in ServerJars.get_mineacademy_jars(): + if create_data["type"] not in ServerJars.get_paper_jars(): url = ( "https://serverjars.com/api/fetchJar/" f"{create_data['category']}" From 78b2feab01c8dd997e9c6bd9558a55964b9740f7 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Fri, 12 Jan 2024 14:46:25 -0500 Subject: [PATCH 4/7] Remove update url for paper builds --- app/classes/shared/main_controller.py | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/app/classes/shared/main_controller.py b/app/classes/shared/main_controller.py index ffc355ea..216c13e9 100644 --- a/app/classes/shared/main_controller.py +++ b/app/classes/shared/main_controller.py @@ -536,19 +536,16 @@ 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) - if create_data["type"] not in ServerJars.get_paper_jars(): - url = ( - "https://serverjars.com/api/fetchJar/" - f"{create_data['category']}" - f"/{create_data['type']}/{create_data['version']}" - ) - else: - url = ( - "https://mineacademy.org/api/" - f"{create_data['type']}/{create_data['version']}" - ) + url = ( + "https://serverjars.com/api/fetchJar/" + f"{create_data['category']}" + f"/{create_data['type']}/{create_data['version']}" + ) server_obj.executable_update_url = url self.servers.update_server(server_obj) self.server_jars.download_jar( From 09c2917e27a644e07c01add8d527df81c365596e Mon Sep 17 00:00:00 2001 From: Zedifus Date: Tue, 16 Jan 2024 18:26:17 +0000 Subject: [PATCH 5/7] Update changelog !688 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e94d0db..c2432de2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # 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 - Fix bukkit and downstream fork MOTD crash ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/686)) ### Tweaks From 7d7ae02bebd5ea5de76e2aac8a7b05b503537c7e Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Tue, 16 Jan 2024 13:50:05 -0500 Subject: [PATCH 6/7] Add parameter to version call --- app/classes/minecraft/serverjars.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/classes/minecraft/serverjars.py b/app/classes/minecraft/serverjars.py index cadcb376..29675e8d 100644 --- a/app/classes/minecraft/serverjars.py +++ b/app/classes/minecraft/serverjars.py @@ -176,7 +176,7 @@ class ServerJars: 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() + data["types"]["servers"][item] = self.get_paper_versions(item) # save our cache try: with open(cache_file, "w", encoding="utf-8") as f: From 0b520aae80c5d059044379853154388a9376709d Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Tue, 16 Jan 2024 13:53:50 -0500 Subject: [PATCH 7/7] Fix misc sonarcube finding --- app/classes/shared/server.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/classes/shared/server.py b/app/classes/shared/server.py index 035824c5..f413b0f2 100644 --- a/app/classes/shared/server.py +++ b/app/classes/shared/server.py @@ -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,7 +724,7 @@ class ServerInstance: f' -jar "{file_name}" nogui' ) server_obj.execution_command = execution_command - Console.debug("SUCCESS! Forge install completed") + Console.debug(SUCCESSMSG) elif version_major <= 1 and version_minor < 20: # NEW VERSION >= 1.17 and <= 1.20 @@ -771,7 +772,7 @@ 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) @@ -802,7 +803,7 @@ class ServerInstance: f' -jar "{file_name}" nogui' ) server_obj.execution_command = execution_command - Console.debug("SUCCESS! Forge install completed") + Console.debug(SUCCESSMSG) except: logger.debug("Could not find run file.") # TODO Use regex to get version and rebuild simple execution