mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
Merge branch 'refactor/big-bucket' into 'dev'
Refactor SBuilder to use Big Bucket. See merge request crafty-controller/crafty-4!755
This commit is contained in:
commit
64082092b4
@ -2,6 +2,7 @@
|
||||
## --- [4.3.3] - 2024/TBD
|
||||
### Refactor
|
||||
- Refactor API keys "super user" to "full access" ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/731))
|
||||
- Refactor SBuilder to use Big Bucket Svc ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/755))
|
||||
### New features
|
||||
TBD
|
||||
### Bug fixes
|
||||
|
236
app/classes/minecraft/bigbucket.py
Normal file
236
app/classes/minecraft/bigbucket.py
Normal file
@ -0,0 +1,236 @@
|
||||
import os
|
||||
import json
|
||||
import threading
|
||||
import time
|
||||
import logging
|
||||
from datetime import datetime
|
||||
import requests
|
||||
|
||||
from app.classes.controllers.servers_controller import ServersController
|
||||
from app.classes.models.server_permissions import PermissionsServers
|
||||
from app.classes.shared.file_helpers import FileHelpers
|
||||
from app.classes.shared.websocket_manager import WebSocketManager
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
# Temp type var until sjars restores generic fetchTypes0
|
||||
|
||||
|
||||
class BigBucket:
|
||||
def __init__(self, helper):
|
||||
self.helper = helper
|
||||
# remove any trailing slash from config.json
|
||||
# url since we add it on all the calls
|
||||
self.base_url = str(
|
||||
self.helper.get_setting("big_bucket_repo", "https://jars.arcadiatech.org")
|
||||
).rstrip("/")
|
||||
|
||||
def _read_cache(self) -> dict:
|
||||
cache_file = self.helper.big_bucket_cache
|
||||
cache = {}
|
||||
try:
|
||||
with open(cache_file, "r", encoding="utf-8") as f:
|
||||
cache = json.load(f)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Unable to read big_bucket cache file: {e}")
|
||||
|
||||
return cache
|
||||
|
||||
def get_bucket_data(self):
|
||||
data = self._read_cache()
|
||||
return data.get("categories")
|
||||
|
||||
def _check_bucket_alive(self) -> bool:
|
||||
logger.info("Checking Big Bucket status")
|
||||
|
||||
check_url = f"{self.base_url}/healthcheck"
|
||||
try:
|
||||
response = requests.get(check_url, timeout=2)
|
||||
response_json = response.json()
|
||||
if (
|
||||
response.status_code in [200, 201]
|
||||
and response_json.get("status") == "ok"
|
||||
):
|
||||
logger.info("Big bucket is alive and responding as expected")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Unable to connect to big bucket due to error: {e}")
|
||||
return False
|
||||
|
||||
logger.error(
|
||||
"Big bucket manifest is not available as expected or unable to contact"
|
||||
)
|
||||
return False
|
||||
|
||||
def _get_big_bucket(self) -> dict:
|
||||
logger.debug("Calling for big bucket manifest.")
|
||||
try:
|
||||
response = requests.get(f"{self.base_url}/manifest.json", timeout=5)
|
||||
if response.status_code in [200, 201]:
|
||||
data = response.json()
|
||||
del data["manifest_version"]
|
||||
return data
|
||||
return {}
|
||||
except TimeoutError as e:
|
||||
logger.error(f"Unable to get jars from remote with error {e}")
|
||||
return {}
|
||||
|
||||
def _refresh_cache(self):
|
||||
"""
|
||||
Contains the shared logic for refreshing the cache.
|
||||
This method is called by both manual_refresh_cache and refresh_cache methods.
|
||||
"""
|
||||
if not self._check_bucket_alive():
|
||||
logger.error("big bucket API is not available.")
|
||||
return False
|
||||
|
||||
cache_data = {
|
||||
"last_refreshed": datetime.now().strftime("%m/%d/%Y, %H:%M:%S"),
|
||||
"categories": self._get_big_bucket(),
|
||||
}
|
||||
try:
|
||||
with open(
|
||||
self.helper.big_bucket_cache, "w", encoding="utf-8"
|
||||
) as cache_file:
|
||||
json.dump(cache_data, cache_file, indent=4)
|
||||
logger.info("Cache file successfully refreshed manually.")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to update cache file manually: {e}")
|
||||
|
||||
def manual_refresh_cache(self):
|
||||
"""
|
||||
Manually triggers the cache refresh process.
|
||||
"""
|
||||
logger.info("Manual bucket cache refresh initiated.")
|
||||
self._refresh_cache()
|
||||
logger.info("Manual refresh completed.")
|
||||
|
||||
def refresh_cache(self):
|
||||
"""
|
||||
Automatically trigger cache refresh process based age.
|
||||
|
||||
This method checks if the cache file is older than a specified number of days
|
||||
before deciding to refresh.
|
||||
"""
|
||||
cache_file_path = self.helper.big_bucket_cache
|
||||
|
||||
# Determine if the cache is old and needs refreshing
|
||||
cache_old = self.helper.is_file_older_than_x_days(cache_file_path)
|
||||
|
||||
# debug override
|
||||
# cache_old = True
|
||||
|
||||
if not self._check_bucket_alive():
|
||||
logger.error("big bucket API is not available.")
|
||||
return False
|
||||
|
||||
if not cache_old:
|
||||
logger.info("Cache file is not old enough to require automatic refresh.")
|
||||
return False
|
||||
|
||||
logger.info("Automatic cache refresh initiated due to old cache.")
|
||||
self._refresh_cache()
|
||||
|
||||
def get_fetch_url(self, jar, server, version) -> str:
|
||||
"""
|
||||
Constructs the URL for downloading a server JAR file based on the server type.
|
||||
Parameters:
|
||||
jar (str): The category of the JAR file to download.
|
||||
server (str): Server software name (e.g., "paper").
|
||||
version (str): Server version.
|
||||
|
||||
Returns:
|
||||
str or None: URL for downloading the JAR file, or None if URL cannot be
|
||||
constructed or an error occurs.
|
||||
"""
|
||||
try:
|
||||
# Read cache file for URL that is in a list of one item
|
||||
return self.get_bucket_data()[jar]["types"][server]["versions"][version][
|
||||
"url"
|
||||
][0]
|
||||
except Exception as e:
|
||||
logger.error(f"An error occurred while constructing fetch URL: {e}")
|
||||
return None
|
||||
|
||||
def download_jar(self, jar, server, version, path, server_id):
|
||||
update_thread = threading.Thread(
|
||||
name=f"server_download-{server_id}-{server}-{version}",
|
||||
target=self.a_download_jar,
|
||||
daemon=True,
|
||||
args=(jar, server, version, path, server_id),
|
||||
)
|
||||
update_thread.start()
|
||||
|
||||
def a_download_jar(self, jar, server, version, path, server_id):
|
||||
"""
|
||||
Downloads a server JAR file and performs post-download actions including
|
||||
notifying users and setting import status.
|
||||
|
||||
This method waits for the server registration to complete, retrieves the
|
||||
download URL for the specified server JAR file.
|
||||
|
||||
Upon successful download, it either runs the installer for
|
||||
Forge servers or simply finishes the import process for other types. It
|
||||
notifies server users about the completion of the download.
|
||||
|
||||
Parameters:
|
||||
- jar (str): The category of the JAR file to download.
|
||||
- server (str): The type of server software (e.g., 'forge', 'paper').
|
||||
- version (str): The version of the server software.
|
||||
- path (str): The local filesystem path where the JAR file will be saved.
|
||||
- server_id (str): The unique identifier for the server being updated or
|
||||
imported, used for notifying users and setting the import status.
|
||||
|
||||
Returns:
|
||||
- bool: True if the JAR file was successfully downloaded and saved;
|
||||
False otherwise.
|
||||
|
||||
The method ensures that the server is properly registered before proceeding
|
||||
with the download and handles exceptions by logging errors and reverting
|
||||
the import status if necessary.
|
||||
"""
|
||||
# delaying download for server register to finish
|
||||
time.sleep(3)
|
||||
|
||||
fetch_url = self.get_fetch_url(jar, server, version)
|
||||
if not fetch_url:
|
||||
return False
|
||||
|
||||
server_users = PermissionsServers.get_server_user_list(server_id)
|
||||
|
||||
# Make sure the server is registered before updating its stats
|
||||
while True:
|
||||
try:
|
||||
ServersController.set_import(server_id)
|
||||
for user in server_users:
|
||||
WebSocketManager().broadcast_user(user, "send_start_reload", {})
|
||||
break
|
||||
except Exception as ex:
|
||||
logger.debug(f"Server not registered yet. Delaying download - {ex}")
|
||||
|
||||
# Initiate Download
|
||||
jar_dir = os.path.dirname(path)
|
||||
jar_name = os.path.basename(path)
|
||||
logger.info(fetch_url)
|
||||
success = FileHelpers.ssl_get_file(fetch_url, jar_dir, jar_name)
|
||||
|
||||
# Post-download actions
|
||||
if success:
|
||||
if server == "forge-installer":
|
||||
# If this is the newer Forge version, run the installer
|
||||
ServersController.finish_import(server_id, True)
|
||||
else:
|
||||
ServersController.finish_import(server_id)
|
||||
|
||||
# Notify users
|
||||
for user in server_users:
|
||||
WebSocketManager().broadcast_user(
|
||||
user, "notification", "Executable download finished"
|
||||
)
|
||||
time.sleep(3) # Delay for user notification
|
||||
WebSocketManager().broadcast_user(user, "send_start_reload", {})
|
||||
else:
|
||||
logger.error(f"Unable to save jar to {path} due to download failure.")
|
||||
ServersController.finish_import(server_id)
|
||||
|
||||
return success
|
@ -1,395 +0,0 @@
|
||||
import os
|
||||
import json
|
||||
import threading
|
||||
import time
|
||||
import logging
|
||||
from datetime import datetime
|
||||
import requests
|
||||
|
||||
from app.classes.controllers.servers_controller import ServersController
|
||||
from app.classes.models.server_permissions import PermissionsServers
|
||||
from app.classes.shared.file_helpers import FileHelpers
|
||||
from app.classes.shared.websocket_manager import WebSocketManager
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
# Temp type var until sjars restores generic fetchTypes0
|
||||
SERVERJARS_TYPES = ["modded", "proxies", "servers", "vanilla"]
|
||||
PAPERJARS = ["paper", "folia"]
|
||||
|
||||
|
||||
class ServerJars:
|
||||
def __init__(self, helper):
|
||||
self.helper = helper
|
||||
self.base_url = "https://api.serverjars.com"
|
||||
self.paper_base = "https://api.papermc.io"
|
||||
|
||||
@staticmethod
|
||||
def get_paper_jars():
|
||||
return PAPERJARS
|
||||
|
||||
def get_paper_versions(self, project):
|
||||
"""
|
||||
Retrieves a list of versions for a specified project from the PaperMC API.
|
||||
|
||||
Parameters:
|
||||
project (str): The project name to query for available versions.
|
||||
|
||||
Returns:
|
||||
list: A list of version strings available for the project. Returns an empty
|
||||
list if the API call fails or if no versions are found.
|
||||
|
||||
This function makes a GET request to the PaperMC API to fetch available project
|
||||
versions, The versions are returned in reverse order, with the most recent
|
||||
version first.
|
||||
"""
|
||||
try:
|
||||
response = requests.get(
|
||||
f"{self.paper_base}/v2/projects/{project}/", timeout=2
|
||||
)
|
||||
response.raise_for_status()
|
||||
api_data = response.json()
|
||||
except Exception as e:
|
||||
logger.error(f"Error loading project versions for {project}: {e}")
|
||||
return []
|
||||
|
||||
versions = api_data.get("versions", [])
|
||||
versions.reverse() # Ensure the most recent version comes first
|
||||
return versions
|
||||
|
||||
def get_paper_build(self, project, version):
|
||||
"""
|
||||
Fetches the latest build for a specified project and version from PaperMC API.
|
||||
|
||||
Parameters:
|
||||
project (str): Project name, typically a server software like 'paper'.
|
||||
version (str): Project version to fetch the build number for.
|
||||
|
||||
Returns:
|
||||
int or None: Latest build number if successful, None if not or on error.
|
||||
|
||||
This method attempts to query the PaperMC API for the latest build and
|
||||
handles exceptions by logging errors and returning None.
|
||||
"""
|
||||
try:
|
||||
response = requests.get(
|
||||
f"{self.paper_base}/v2/projects/{project}/versions/{version}/builds/",
|
||||
timeout=2,
|
||||
)
|
||||
response.raise_for_status()
|
||||
api_data = response.json()
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching build for {project} {version}: {e}")
|
||||
return None
|
||||
|
||||
builds = api_data.get("builds", [])
|
||||
return builds[-1] if builds else None
|
||||
|
||||
def _read_cache(self):
|
||||
cache_file = self.helper.serverjar_cache
|
||||
cache = {}
|
||||
try:
|
||||
with open(cache_file, "r", encoding="utf-8") as f:
|
||||
cache = json.load(f)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Unable to read serverjars.com cache file: {e}")
|
||||
|
||||
return cache
|
||||
|
||||
def get_serverjar_data(self):
|
||||
data = self._read_cache()
|
||||
return data.get("types")
|
||||
|
||||
def _check_sjars_api_alive(self):
|
||||
logger.info("Checking serverjars.com API status")
|
||||
|
||||
check_url = f"{self.base_url}"
|
||||
try:
|
||||
response = requests.get(check_url, timeout=2)
|
||||
response_json = response.json()
|
||||
|
||||
if (
|
||||
response.status_code in [200, 201]
|
||||
and response_json.get("status") == "success"
|
||||
and response_json.get("response", {}).get("status") == "ok"
|
||||
):
|
||||
logger.info("Serverjars.com API is alive and responding as expected")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Unable to connect to serverjar.com API due to error: {e}")
|
||||
return False
|
||||
|
||||
logger.error(
|
||||
"Serverjars.com API is not responding as expected or unable to contact"
|
||||
)
|
||||
return False
|
||||
|
||||
def _fetch_projects_for_type(self, server_type):
|
||||
"""
|
||||
Fetches projects for a given server type from the ServerJars API.
|
||||
"""
|
||||
try:
|
||||
response = requests.get(
|
||||
f"{self.base_url}/api/fetchTypes/{server_type}", timeout=5
|
||||
)
|
||||
response.raise_for_status() # Ensure HTTP errors are caught
|
||||
data = response.json()
|
||||
if data.get("status") == "success":
|
||||
return data["response"].get("servers", [])
|
||||
except requests.RequestException as e:
|
||||
print(f"Error fetching projects for type {server_type}: {e}")
|
||||
return []
|
||||
|
||||
def _get_server_type_list(self):
|
||||
"""
|
||||
Builds the type structure with projects fetched for each type.
|
||||
"""
|
||||
type_structure = {}
|
||||
for server_type in SERVERJARS_TYPES:
|
||||
projects = self._fetch_projects_for_type(server_type)
|
||||
type_structure[server_type] = {project: [] for project in projects}
|
||||
return type_structure
|
||||
|
||||
def _get_jar_versions(self, server_type, project_name, max_ver=50):
|
||||
"""
|
||||
Grabs available versions for specified project
|
||||
|
||||
Args:
|
||||
server_type (str): Server Type Category (modded, servers, etc)
|
||||
project_name (str): Target project (paper, forge, magma, etc)
|
||||
max (int, optional): Max versions returned. Defaults to 50.
|
||||
|
||||
Returns:
|
||||
list: An array of versions
|
||||
"""
|
||||
url = f"{self.base_url}/api/fetchAll/{server_type}/{project_name}?max={max_ver}"
|
||||
try:
|
||||
response = requests.get(url, timeout=5)
|
||||
response.raise_for_status() # Ensure HTTP errors are caught
|
||||
data = response.json()
|
||||
logger.debug(f"Received data for {server_type}/{project_name}: {data}")
|
||||
|
||||
if data.get("status") == "success":
|
||||
versions = [
|
||||
item.get("version")
|
||||
for item in data.get("response", [])
|
||||
if "version" in item
|
||||
]
|
||||
versions.reverse() # Reverse so versions are newest -> oldest
|
||||
logger.debug(f"Versions extracted: {versions}")
|
||||
return versions
|
||||
except requests.RequestException as e:
|
||||
logger.error(
|
||||
f"Error fetching jar versions for {server_type}/{project_name}: {e}"
|
||||
)
|
||||
|
||||
return []
|
||||
|
||||
def _refresh_cache(self):
|
||||
"""
|
||||
Contains the shared logic for refreshing the cache.
|
||||
This method is called by both manual_refresh_cache and refresh_cache methods.
|
||||
"""
|
||||
now = datetime.now()
|
||||
cache_data = {
|
||||
"last_refreshed": now.strftime("%m/%d/%Y, %H:%M:%S"),
|
||||
"types": self._get_server_type_list(),
|
||||
}
|
||||
|
||||
for server_type, projects in cache_data["types"].items():
|
||||
for project_name in projects:
|
||||
versions = self._get_jar_versions(server_type, project_name)
|
||||
cache_data["types"][server_type][project_name] = versions
|
||||
|
||||
for paper_project in PAPERJARS:
|
||||
cache_data["types"]["servers"][paper_project] = self.get_paper_versions(
|
||||
paper_project
|
||||
)
|
||||
|
||||
return cache_data
|
||||
|
||||
def manual_refresh_cache(self):
|
||||
"""
|
||||
Manually triggers the cache refresh process.
|
||||
"""
|
||||
if not self._check_sjars_api_alive():
|
||||
logger.error("ServerJars API is not available.")
|
||||
return False
|
||||
|
||||
logger.info("Manual cache refresh requested.")
|
||||
cache_data = self._refresh_cache()
|
||||
|
||||
# Save the updated cache data
|
||||
try:
|
||||
with open(self.helper.serverjar_cache, "w", encoding="utf-8") as cache_file:
|
||||
json.dump(cache_data, cache_file, indent=4)
|
||||
logger.info("Cache file successfully refreshed manually.")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to update cache file manually: {e}")
|
||||
|
||||
def refresh_cache(self):
|
||||
"""
|
||||
Automatically trigger cache refresh process based age.
|
||||
|
||||
This method checks if the cache file is older than a specified number of days
|
||||
before deciding to refresh.
|
||||
"""
|
||||
cache_file_path = self.helper.serverjar_cache
|
||||
|
||||
# Determine if the cache is old and needs refreshing
|
||||
cache_old = self.helper.is_file_older_than_x_days(cache_file_path)
|
||||
|
||||
# debug override
|
||||
# cache_old = True
|
||||
|
||||
if not self._check_sjars_api_alive():
|
||||
logger.error("ServerJars API is not available.")
|
||||
return False
|
||||
|
||||
if not cache_old:
|
||||
logger.info("Cache file is not old enough to require automatic refresh.")
|
||||
return False
|
||||
|
||||
logger.info("Automatic cache refresh initiated due to old cache.")
|
||||
cache_data = self._refresh_cache()
|
||||
|
||||
# Save the updated cache data
|
||||
try:
|
||||
with open(cache_file_path, "w", encoding="utf-8") as cache_file:
|
||||
json.dump(cache_data, cache_file, indent=4)
|
||||
logger.info("Cache file successfully refreshed automatically.")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to update cache file automatically: {e}")
|
||||
|
||||
def get_fetch_url(self, jar, server, version):
|
||||
"""
|
||||
Constructs the URL for downloading a server JAR file based on the server type.
|
||||
|
||||
Supports two main types of server JAR sources:
|
||||
- ServerJars API for servers not in PAPERJARS.
|
||||
- Paper API for servers available through the Paper project.
|
||||
|
||||
Parameters:
|
||||
jar (str): Name of the JAR file.
|
||||
server (str): Server software name (e.g., "paper").
|
||||
version (str): Server version.
|
||||
|
||||
Returns:
|
||||
str or None: URL for downloading the JAR file, or None if URL cannot be
|
||||
constructed or an error occurs.
|
||||
"""
|
||||
try:
|
||||
# Check if the server type is not specifically handled by Paper.
|
||||
if server not in PAPERJARS:
|
||||
return f"{self.base_url}/api/fetchJar/{jar}/{server}/{version}"
|
||||
|
||||
# For Paper servers, attempt to get the build for the specified version.
|
||||
paper_build_info = self.get_paper_build(server, version)
|
||||
if paper_build_info is None:
|
||||
# Log an error or handle the case where paper_build_info is None
|
||||
logger.error(
|
||||
"Error: Unable to get build information for server:"
|
||||
f" {server}, version: {version}"
|
||||
)
|
||||
return None
|
||||
|
||||
build = paper_build_info.get("build")
|
||||
if not build:
|
||||
# Log an error or handle the case where build is None or not found
|
||||
logger.error(
|
||||
f"Error: Build number not found for server:"
|
||||
f" {server}, version: {version}"
|
||||
)
|
||||
return None
|
||||
|
||||
# Construct and return the URL for downloading the Paper server JAR.
|
||||
return (
|
||||
f"{self.paper_base}/v2/projects/{server}/versions/{version}/"
|
||||
f"builds/{build}/downloads/{server}-{version}-{build}.jar"
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"An error occurred while constructing fetch URL: {e}")
|
||||
return None
|
||||
|
||||
def download_jar(self, jar, server, version, path, server_id):
|
||||
update_thread = threading.Thread(
|
||||
name=f"server_download-{server_id}-{server}-{version}",
|
||||
target=self.a_download_jar,
|
||||
daemon=True,
|
||||
args=(jar, server, version, path, server_id),
|
||||
)
|
||||
update_thread.start()
|
||||
|
||||
def a_download_jar(self, jar, server, version, path, server_id):
|
||||
"""
|
||||
Downloads a server JAR file and performs post-download actions including
|
||||
notifying users and setting import status.
|
||||
|
||||
This method waits for the server registration to complete, retrieves the
|
||||
download URL for the specified server JAR file.
|
||||
|
||||
Upon successful download, it either runs the installer for
|
||||
Forge servers or simply finishes the import process for other types. It
|
||||
notifies server users about the completion of the download.
|
||||
|
||||
Parameters:
|
||||
- jar (str): The name of the JAR file to download.
|
||||
- server (str): The type of server software (e.g., 'forge', 'paper').
|
||||
- version (str): The version of the server software.
|
||||
- path (str): The local filesystem path where the JAR file will be saved.
|
||||
- server_id (str): The unique identifier for the server being updated or
|
||||
imported, used for notifying users and setting the import status.
|
||||
|
||||
Returns:
|
||||
- bool: True if the JAR file was successfully downloaded and saved;
|
||||
False otherwise.
|
||||
|
||||
The method ensures that the server is properly registered before proceeding
|
||||
with the download and handles exceptions by logging errors and reverting
|
||||
the import status if necessary.
|
||||
"""
|
||||
# delaying download for server register to finish
|
||||
time.sleep(3)
|
||||
|
||||
fetch_url = self.get_fetch_url(jar, server, version)
|
||||
if not fetch_url:
|
||||
return False
|
||||
|
||||
server_users = PermissionsServers.get_server_user_list(server_id)
|
||||
|
||||
# Make sure the server is registered before updating its stats
|
||||
while True:
|
||||
try:
|
||||
ServersController.set_import(server_id)
|
||||
for user in server_users:
|
||||
WebSocketManager().broadcast_user(user, "send_start_reload", {})
|
||||
break
|
||||
except Exception as ex:
|
||||
logger.debug(f"Server not registered yet. Delaying download - {ex}")
|
||||
|
||||
# Initiate Download
|
||||
jar_dir = os.path.dirname(path)
|
||||
jar_name = os.path.basename(path)
|
||||
logger.info(fetch_url)
|
||||
success = FileHelpers.ssl_get_file(fetch_url, jar_dir, jar_name)
|
||||
|
||||
# Post-download actions
|
||||
if success:
|
||||
if server == "forge":
|
||||
# If this is the newer Forge version, run the installer
|
||||
ServersController.finish_import(server_id, True)
|
||||
else:
|
||||
ServersController.finish_import(server_id)
|
||||
|
||||
# Notify users
|
||||
for user in server_users:
|
||||
WebSocketManager().broadcast_user(
|
||||
user, "notification", "Executable download finished"
|
||||
)
|
||||
time.sleep(3) # Delay for user notification
|
||||
WebSocketManager().broadcast_user(user, "send_start_reload", {})
|
||||
else:
|
||||
logger.error(f"Unable to save jar to {path} due to download failure.")
|
||||
ServersController.finish_import(server_id)
|
||||
|
||||
return success
|
@ -72,7 +72,7 @@ class Helpers:
|
||||
self.db_path = os.path.join(
|
||||
self.root_dir, "app", "config", "db", "crafty.sqlite"
|
||||
)
|
||||
self.serverjar_cache = os.path.join(self.config_dir, "serverjars.json")
|
||||
self.big_bucket_cache = os.path.join(self.config_dir, "bigbucket.json")
|
||||
self.credits_cache = os.path.join(self.config_dir, "credits.json")
|
||||
self.passhasher = PasswordHasher()
|
||||
self.exiting = False
|
||||
@ -516,6 +516,7 @@ class Helpers:
|
||||
"monitored_mounts": mounts,
|
||||
"dir_size_poll_freq_minutes": 5,
|
||||
"crafty_logs_delete_after_days": 0,
|
||||
"big_bucket_repo": "https://jars.arcadiatech.org",
|
||||
}
|
||||
|
||||
def get_all_settings(self):
|
||||
|
@ -32,7 +32,7 @@ from app.classes.shared.console import Console
|
||||
from app.classes.shared.helpers import Helpers
|
||||
from app.classes.shared.file_helpers import FileHelpers
|
||||
from app.classes.shared.import_helper import ImportHelpers
|
||||
from app.classes.minecraft.serverjars import ServerJars
|
||||
from app.classes.minecraft.bigbucket import BigBucket
|
||||
from app.classes.shared.websocket_manager import WebSocketManager
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -43,7 +43,7 @@ class Controller:
|
||||
self.helper: Helpers = helper
|
||||
self.file_helper: FileHelpers = file_helper
|
||||
self.import_helper: ImportHelpers = import_helper
|
||||
self.server_jars: ServerJars = ServerJars(helper)
|
||||
self.big_bucket: BigBucket = BigBucket(helper)
|
||||
self.users_helper: HelperUsers = HelperUsers(database, self.helper)
|
||||
self.roles_helper: HelperRoles = HelperRoles(database)
|
||||
self.servers_helper: HelperServers = HelperServers(database)
|
||||
@ -436,7 +436,7 @@ class Controller:
|
||||
if root_create_data["create_type"] == "download_jar":
|
||||
if Helpers.is_os_windows():
|
||||
# Let's check for and setup for install server commands
|
||||
if create_data["type"] == "forge":
|
||||
if create_data["type"] == "forge-installer":
|
||||
server_command = (
|
||||
f"java -Xms{Helpers.float_to_string(min_mem)}M "
|
||||
f"-Xmx{Helpers.float_to_string(max_mem)}M "
|
||||
@ -449,7 +449,7 @@ class Controller:
|
||||
f'-jar "{server_file}" nogui'
|
||||
)
|
||||
else:
|
||||
if create_data["type"] == "forge":
|
||||
if create_data["type"] == "forge-installer":
|
||||
server_command = (
|
||||
f"java -Xms{Helpers.float_to_string(min_mem)}M "
|
||||
f"-Xmx{Helpers.float_to_string(max_mem)}M "
|
||||
@ -569,19 +569,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"
|
||||
and create_data["type"] not in ServerJars.get_paper_jars()
|
||||
):
|
||||
if create_data["type"] != "forge-installer":
|
||||
server_obj = self.servers.get_server_obj(new_server_id)
|
||||
url = (
|
||||
"https://api.serverjars.com/api/fetchJar/"
|
||||
f"{create_data['category']}"
|
||||
f"/{create_data['type']}/{create_data['version']}"
|
||||
url = self.big_bucket.get_fetch_url(
|
||||
create_data["category"],
|
||||
create_data["type"],
|
||||
create_data["version"],
|
||||
)
|
||||
server_obj.executable_update_url = url
|
||||
self.servers.update_server(server_obj)
|
||||
self.server_jars.download_jar(
|
||||
self.big_bucket.download_jar(
|
||||
create_data["category"],
|
||||
create_data["type"],
|
||||
create_data["version"],
|
||||
|
@ -690,7 +690,8 @@ class ServerInstance:
|
||||
try:
|
||||
# Getting the forge version from the executable command
|
||||
version = re.findall(
|
||||
r"forge-([0-9\.]+)((?:)|(?:-([0-9\.]+)-[a-zA-Z]+)).jar",
|
||||
r"forge-installer-([0-9\.]+)((?:)|"
|
||||
r"(?:-([0-9\.]+)-[a-zA-Z]+)).jar",
|
||||
server_obj.execution_command,
|
||||
)
|
||||
version_param = version[0][0].split(".")
|
||||
|
@ -685,16 +685,16 @@ class TasksManager:
|
||||
id="stats",
|
||||
)
|
||||
|
||||
def serverjar_cache_refresher(self):
|
||||
logger.info("Refreshing serverjars.com cache on start")
|
||||
self.controller.server_jars.refresh_cache()
|
||||
def big_bucket_cache_refresher(self):
|
||||
logger.info("Refreshing big bucket cache on start")
|
||||
self.controller.big_bucket.refresh_cache()
|
||||
|
||||
logger.info("Scheduling Serverjars.com cache refresh service every 12 hours")
|
||||
logger.info("Scheduling big bucket cache refresh service every 12 hours")
|
||||
self.scheduler.add_job(
|
||||
self.controller.server_jars.refresh_cache,
|
||||
self.controller.big_bucket.refresh_cache,
|
||||
"interval",
|
||||
hours=12,
|
||||
id="serverjars",
|
||||
id="big_bucket",
|
||||
)
|
||||
|
||||
def realtime(self):
|
||||
|
@ -31,6 +31,7 @@ config_json_schema = {
|
||||
"monitored_mounts": {"type": "array"},
|
||||
"dir_size_poll_freq_minutes": {"type": "integer"},
|
||||
"crafty_logs_delete_after_days": {"type": "integer"},
|
||||
"big_bucket_repo": {"type": "string"},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
|
@ -17,11 +17,11 @@ class ApiCraftyJarCacheIndexHandler(BaseApiHandler):
|
||||
if not auth_data[4]["superuser"]:
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
|
||||
self.controller.server_jars.manual_refresh_cache()
|
||||
self.controller.big_bucket.manual_refresh_cache()
|
||||
self.finish_json(
|
||||
200,
|
||||
{
|
||||
"status": "ok",
|
||||
"data": self.controller.server_jars.get_serverjar_data(),
|
||||
"data": self.controller.big_bucket.get_bucket_data(),
|
||||
},
|
||||
)
|
||||
|
@ -139,7 +139,7 @@ new_server_schema = {
|
||||
"category": {
|
||||
"title": "Jar Category",
|
||||
"type": "string",
|
||||
"examples": ["modded", "vanilla"],
|
||||
"examples": ["Mc_java_servers", "Mc_java_proxies"],
|
||||
},
|
||||
"properties": {
|
||||
"type": {
|
||||
|
@ -146,12 +146,12 @@ class ServerHandler(BaseHandler):
|
||||
return
|
||||
page_data["server_api"] = False
|
||||
if page_data["online"]:
|
||||
page_data["server_api"] = self.helper.check_address_status(
|
||||
"https://api.serverjars.com"
|
||||
page_data["server_api"] = (
|
||||
self.controller.big_bucket._check_bucket_alive()
|
||||
)
|
||||
page_data["server_types"] = self.controller.server_jars.get_serverjar_data()
|
||||
page_data["server_types"] = self.controller.big_bucket.get_bucket_data()
|
||||
page_data["js_server_types"] = json.dumps(
|
||||
self.controller.server_jars.get_serverjar_data()
|
||||
self.controller.big_bucket.get_bucket_data()
|
||||
)
|
||||
if page_data["server_types"] is None:
|
||||
page_data["server_types"] = []
|
||||
|
@ -1,120 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 683.6 143.8" style="enable-background:new 0 0 683.6 143.8;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{opacity:0.85;fill:#FFFFFF;enable-background:new ;}
|
||||
.st1{opacity:0.85;}
|
||||
.st2{fill:#FFFFFF;}
|
||||
.st3{fill:none;}
|
||||
.st4{fill:url(#SVGID_1_);}
|
||||
.st5{fill:url(#SVGID_00000137122815686618769650000009047437546445953421_);}
|
||||
.st6{fill:url(#SVGID_00000170963539203169094570000007184871682409824703_);}
|
||||
.st7{fill:url(#SVGID_00000169549353698428389090000007910489870824235905_);}
|
||||
.st8{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_00000029754379306852418700000008865188217784465572_);}
|
||||
</style>
|
||||
<path class="st0" d="M175.8,111.5h17.6v3.8h-13.2v8.9h12.1v3.7h-12.1v11.8h-4.4V111.5z"/>
|
||||
<path class="st0" d="M196.3,119.1h4.2v3.5h0.1c0.4-2.3,2.4-3.9,4.7-3.9c0.5,0,1,0.1,1.5,0.2v3.9c-0.6-0.2-1.3-0.3-1.9-0.2
|
||||
c-2.7,0-4.4,1.8-4.4,4.8v12.3h-4.2L196.3,119.1z"/>
|
||||
<path class="st0" d="M207.2,129.4L207.2,129.4c0-6.6,3.9-10.6,9.7-10.6s9.8,4,9.8,10.6l0,0c0,6.6-3.9,10.7-9.8,10.7
|
||||
S207.2,136,207.2,129.4z M222.4,129.4L222.4,129.4c0-4.5-2.2-7.1-5.5-7.1s-5.4,2.6-5.4,7.1l0,0c0,4.5,2.2,7.2,5.5,7.2
|
||||
S222.4,133.9,222.4,129.4L222.4,129.4z"/>
|
||||
<path class="st0" d="M229.6,119.1h4.2v3.2h0.1c1-2.3,3.2-3.7,5.7-3.6c2.6-0.2,5,1.5,5.7,4h0.1c1.1-2.5,3.6-4.1,6.4-4
|
||||
c4.1,0,6.7,2.7,6.7,6.8v14.1h-4.2v-13.1c0-2.7-1.4-4.2-3.9-4.2c-2.3,0-4.2,1.8-4.3,4.2c0,0.1,0,0.2,0,0.3v12.9H242v-13.4
|
||||
c0.2-2-1.3-3.8-3.3-3.9c-0.2,0-0.4,0-0.5,0c-2.4,0-4.3,2-4.3,4.3c0,0.1,0,0.2,0,0.3v12.7h-4.2L229.6,119.1z"/>
|
||||
<g id="Layer_2_00000138553854520646606810000012156271018779627156_" class="st1">
|
||||
<g id="Layer_1-2">
|
||||
<path class="st2" d="M343.7,139.9c-6.9,0-12.5-5.6-12.5-12.5s5.6-12.5,12.5-12.5c2.1,0,4.2,0.5,6,1.5c1.8,1,3.3,2.4,4.3,4.1
|
||||
l-4.1,2.4c-0.6-1.1-1.5-1.9-2.5-2.5c-3.1-1.6-6.8-1.1-9.4,1.3c-1.5,1.5-2.2,3.6-2.1,5.7c-0.1,2.1,0.7,4.1,2.1,5.7
|
||||
c1.5,1.5,3.5,2.3,5.7,2.2c1.3,0,2.6-0.3,3.7-0.9c1.1-0.6,2-1.4,2.5-2.5l4.1,2.4c-1,1.7-2.5,3.2-4.3,4.1
|
||||
C347.8,139.4,345.8,139.9,343.7,139.9z"/>
|
||||
<path class="st2" d="M361.4,122.3v3c0.3-1,1.1-1.9,2-2.5c1-0.6,2.1-0.9,3.2-0.8v4.9c-1.3-0.2-2.6,0.1-3.6,0.8
|
||||
c-1.1,0.8-1.7,2.2-1.6,3.5v8.2H357v-17.2H361.4z"/>
|
||||
<path class="st2" d="M381.6,124.3v-2h4.4v17.2h-4.4v-2c-1.4,1.7-3.4,2.6-5.6,2.5c-2.2,0-4.4-0.9-5.9-2.6c-1.6-1.8-2.5-4.1-2.4-6.5
|
||||
c-0.1-2.4,0.8-4.7,2.4-6.4c1.5-1.7,3.6-2.7,5.9-2.7C378.1,121.7,380.2,122.6,381.6,124.3z M373.4,134.3c1.9,1.8,4.9,1.8,6.8,0
|
||||
c0.9-0.9,1.4-2.2,1.4-3.5c0.1-1.3-0.4-2.6-1.4-3.5c-1.9-1.8-4.9-1.8-6.8,0c-0.9,0.9-1.4,2.2-1.3,3.5
|
||||
C372,132.1,372.5,133.4,373.4,134.3z"/>
|
||||
<path class="st2" d="M399.2,115v4.2c-2.4-0.2-3.6,0.8-3.7,2.9v0.2h3.6v4.3h-3.6v12.9h-4.4v-12.9h-2.5v-4.2h2.5v-0.2
|
||||
c-0.2-2,0.6-4.1,2-5.5C394.5,115.3,396.6,114.8,399.2,115z"/>
|
||||
<path class="st2" d="M411.6,122.3v4.2h-3.9v7.1c0,0.5,0.1,1,0.5,1.3c0.4,0.3,0.8,0.5,1.3,0.5c0.7,0,1.4,0,2.1,0v4
|
||||
c-3,0.3-5.1,0.1-6.4-0.8s-1.9-2.5-1.9-4.9v-7.1h-3v-4.2h3v-3.5l4.4-1.3v4.8L411.6,122.3z"/>
|
||||
<path class="st2" d="M427.2,124.3v-2h4.4v17.2h-4.4v-2c-1.4,1.7-3.4,2.6-5.6,2.5c-2.2,0-4.4-0.9-5.9-2.6c-1.6-1.8-2.5-4.1-2.4-6.5
|
||||
c-0.1-2.4,0.8-4.7,2.4-6.4c1.5-1.7,3.6-2.7,5.9-2.7C423.8,121.7,425.9,122.6,427.2,124.3z M419.1,134.3c1.9,1.8,4.9,1.8,6.8,0
|
||||
c0.9-0.9,1.4-2.2,1.4-3.5c0-1.3-0.4-2.5-1.4-3.5c-1.9-1.8-4.9-1.8-6.8,0c-0.9,0.9-1.4,2.2-1.3,3.5
|
||||
C417.7,132.1,418.2,133.4,419.1,134.3L419.1,134.3z"/>
|
||||
<path class="st2" d="M440.1,122.3v3c0.4-1,1.1-1.9,2-2.5c1-0.6,2.1-0.9,3.2-0.8v4.9c-1.3-0.2-2.6,0.1-3.6,0.8
|
||||
c-1.1,0.8-1.7,2.2-1.6,3.5v8.2h-4.4v-17.2H440.1z"/>
|
||||
<path class="st2" d="M461.9,137.3c-3.6,3.6-9.3,3.6-12.9,0s-3.6-9.3,0-12.9l0,0c3.6-3.5,9.3-3.5,12.9,0.1c1.7,1.7,2.6,4,2.6,6.4
|
||||
C464.5,133.3,463.6,135.6,461.9,137.3z M452.1,134.3c1.9,1.8,4.8,1.8,6.7,0c1.8-1.9,1.8-4.9,0-6.8c-1.9-1.8-4.8-1.8-6.7,0
|
||||
C450.3,129.4,450.3,132.3,452.1,134.3L452.1,134.3z"/>
|
||||
<path class="st2" d="M320,137.6l-2.9-20.3c-0.4-2.7-2.7-4.7-5.5-4.7h-9c-0.3,0-0.5,0.2-0.7,0.4l-0.9,2H292l-0.9-2
|
||||
c-0.1-0.3-0.4-0.4-0.7-0.4h-9c-2.7,0-5.1,2-5.5,4.7l-2.9,20.3c-0.4,3,1.7,5.8,4.7,6.2c0,0,0,0,0,0l0,0c0.3,0,0.5,0.1,0.8,0.1h36
|
||||
c3,0,5.5-2.5,5.5-5.5l0,0C320,138.1,320,137.8,320,137.6z M287.1,130c-2.7,0-4.9-2.2-4.9-4.9c0-2.7,2.2-4.9,4.9-4.9
|
||||
c2.7,0,4.9,2.2,4.9,4.9c0,0,0,0,0,0l0,0C292,127.8,289.8,130,287.1,130z M296.5,138c-2.7,0-4.9-2.2-4.9-4.9h9.8
|
||||
C301.4,135.8,299.3,138,296.5,138L296.5,138L296.5,138z M305.9,130c-2.7,0-4.9-2.2-4.9-4.9c0-2.7,2.2-4.9,4.9-4.9
|
||||
c2.7,0,4.9,2.2,4.9,4.9c0,0,0,0,0,0l0,0C310.8,127.8,308.6,130,305.9,130L305.9,130z"/>
|
||||
</g>
|
||||
</g>
|
||||
<path class="st2" d="M133.1,19.2H9.7c-1.8,0-3.2-1.4-3.2-3.2V3.2C6.5,1.5,7.9,0,9.7,0h123.4c1.8,0,3.2,1.4,3.2,3.2V16
|
||||
C136.3,17.8,134.9,19.2,133.1,19.2"/>
|
||||
<path class="st2" d="M23.6,36.7c-3.4,0-6.7,1.6-8.8,4.3c-2.9,3.6-4.1,8.3-3.2,12.8l9.2,51.9c1.2,6.6,6.2,11.4,12.1,11.4H110
|
||||
c5.8,0,10.9-4.8,12.1-11.4l9.2-51.9c0.8-4.5-0.4-9.2-3.3-12.8c-2.1-2.7-5.4-4.3-8.8-4.3H23.6z M110,128.3H32.8
|
||||
c-11.3,0-21-8.7-23.1-20.7L0.5,55.8c-1.5-7.8,0.6-15.9,5.7-22c4.3-5.2,10.7-8.3,17.4-8.3h95.6c6.8,0.1,13.1,3.1,17.4,8.3
|
||||
c5.1,6.1,7.2,14.2,5.7,22l-9.2,51.9C130.9,119.7,121.2,128.4,110,128.3"/>
|
||||
<path class="st2" d="M120.8,23.8v-2.2c2,0,3.5-1.6,3.5-3.6c0-1.8-1.5-3.4-3.3-3.5H21.6c-2,0.1-3.5,1.8-3.4,3.7
|
||||
c0.1,1.8,1.5,3.3,3.4,3.4v2.2c-3.2-0.1-5.7-2.8-5.6-6c0.1-3,2.5-5.4,5.6-5.6h99.2c3.2-0.1,5.9,2.4,6,5.6s-2.4,5.9-5.6,6
|
||||
C121.1,23.8,121,23.8,120.8,23.8"/>
|
||||
<path class="st2" d="M120.8,33.1H21.6c-3.2,0-5.8-2.6-5.8-5.8c0-3.2,2.6-5.8,5.8-5.8v2.2c-2,0.1-3.5,1.8-3.4,3.7
|
||||
c0.1,1.8,1.5,3.3,3.4,3.4h99.2c2,0.1,3.7-1.3,3.8-3.3c0.1-2-1.3-3.7-3.3-3.8c-0.1,0-0.2,0-0.3,0h-0.2v-2.2c3.2-0.1,5.9,2.4,6,5.6
|
||||
s-2.4,5.9-5.6,6C121.1,33.1,121,33.1,120.8,33.1"/>
|
||||
<path class="st2" d="M21.6,21.5l36.1,1.1l-36.1,1.1V21.5z"/>
|
||||
<path class="st2" d="M125.5,23.8l-45.1-1.1l45.1-1.1V23.8z"/>
|
||||
<rect x="-2.5" y="-1.1" class="st3" width="571.3" height="131.4"/>
|
||||
<path class="st2" d="M163.8,91.7l7.3-10.9c5.8,5.5,14.3,9.3,22.3,9.3c7.1,0,13.1-3.3,13.1-8.3c0-6-8.1-7.9-15.4-9.6
|
||||
c-13.7-3.2-24.8-9.8-24.8-22.3c0-12.7,11.1-21,27.1-21c10.7,0,19.4,3.7,24.7,8.9l-6.6,10.8c-4-3.9-11.2-6.9-18.3-6.9
|
||||
s-12.2,3.2-12.2,7.7c0,5.5,7.4,7.9,14.1,9.3s26.2,6.2,26.2,22.5c0,12.8-12.2,21.6-27.8,21.6C182.6,102.8,171.1,98.4,163.8,91.7z"/>
|
||||
<path class="st2" d="M281.7,80.1h-40.9c1.9,6.6,7.5,10.9,15.1,10.9c5.6,0.1,10.9-2.3,14.5-6.5l9,7.9c-5.5,6.5-14,10.5-23.9,10.5
|
||||
c-16.8,0-29.3-12-29.3-27.8c0-15.6,12.1-27.4,28-27.4S282,59.4,282,75.3C282,76.9,281.9,78.5,281.7,80.1z M240.8,70.3h26.9
|
||||
c-1.7-6.6-6.9-10.9-13.4-10.9C247.7,59.4,242.5,63.8,240.8,70.3L240.8,70.3z"/>
|
||||
<path class="st2" d="M321.3,48v13.9h-2.3c-9.6,0-15.2,5.7-15.2,14.7v25h-13.4V48.9h13.5v6.8c3.6-4.8,9.2-7.7,15.2-7.7L321.3,48z"/>
|
||||
<path class="st2" d="M381.9,48.9L360,101.6h-13.9l-21.9-52.8h15.3l13.8,35.9L367,48.9H381.9z"/>
|
||||
<path class="st2" d="M437.1,80.1h-40.9c1.9,6.6,7.5,10.9,15.1,10.9c5.6,0.1,10.9-2.3,14.5-6.5l9,7.9c-5.5,6.5-14,10.5-23.9,10.5
|
||||
c-16.8,0-29.3-12-29.3-27.8c0-15.6,12.1-27.4,28-27.4s27.7,11.8,27.7,27.7C437.4,76.9,437.3,78.5,437.1,80.1z M396.1,70.3H423
|
||||
c-1.7-6.6-6.9-10.9-13.4-10.9S397.7,63.8,396.1,70.3L396.1,70.3z"/>
|
||||
<path class="st2" d="M476.7,48v13.9h-2.2c-9.6,0-15.2,5.7-15.2,14.7v25h-13.5V48.9h13.5v6.8c3.6-4.8,9.2-7.7,15.2-7.7L476.7,48z"/>
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="870.0443" y1="434.2369" x2="907.1767" y2="465.2789" gradientTransform="matrix(1 0 0 1 -374.6 -381.3801)">
|
||||
<stop offset="0" style="stop-color:#FEAF6F"/>
|
||||
<stop offset="1" style="stop-color:#FD5E83"/>
|
||||
</linearGradient>
|
||||
<path class="st4" d="M492.5,100.6V87c3.2,1.4,6.6,2.1,10,2.2c7.3,0,11.8-3.9,11.8-10.9v-48h14.3V79c0,15-9.8,23.9-24.5,23.9
|
||||
C500,102.9,496.1,102.1,492.5,100.6z"/>
|
||||
<linearGradient id="SVGID_00000162328622213414588160000008200821717462734513_" gradientUnits="userSpaceOnUse" x1="920.7661" y1="434.5518" x2="972.3098" y2="477.6348" gradientTransform="matrix(1 0 0 1 -374.6 -381.3801)">
|
||||
<stop offset="0" style="stop-color:#FEAF6F"/>
|
||||
<stop offset="1" style="stop-color:#FD5E83"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000162328622213414588160000008200821717462734513_);" d="M593.2,48.9v52.8h-13.5v-6.3
|
||||
c-4.4,4.9-10.6,7.6-17.2,7.5c-14.7,0-25.8-11.9-25.8-27.6s11.1-27.6,25.8-27.6c6.5-0.1,12.8,2.7,17.2,7.5v-6.3L593.2,48.9z
|
||||
M579.8,75.2c0-8-6.6-14.5-14.6-14.5c-8,0-14.5,6.6-14.5,14.6c0,8,6.5,14.4,14.5,14.5c7.9,0.2,14.4-6,14.6-13.9
|
||||
C579.8,75.7,579.8,75.5,579.8,75.2z"/>
|
||||
<linearGradient id="SVGID_00000026849485640012965730000014957007722205225107_" gradientUnits="userSpaceOnUse" x1="973.2171" y1="437.9167" x2="1007.0711" y2="466.2133" gradientTransform="matrix(1 0 0 1 -374.6 -381.3801)">
|
||||
<stop offset="0" style="stop-color:#FEAF6F"/>
|
||||
<stop offset="1" style="stop-color:#FD5E83"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000026849485640012965730000014957007722205225107_);" d="M635.9,48v13.9h-2.3
|
||||
c-9.6,0-15.2,5.7-15.2,14.7v25H605V48.9h13.4v6.8c3.6-4.8,9.2-7.7,15.2-7.7L635.9,48z"/>
|
||||
<linearGradient id="SVGID_00000011000279650532451330000005619277557075874698_" gradientUnits="userSpaceOnUse" x1="1015.3561" y1="439.477" x2="1056.9301" y2="474.2302" gradientTransform="matrix(1 0 0 1 -374.6 -381.3801)">
|
||||
<stop offset="0" style="stop-color:#FEAF6F"/>
|
||||
<stop offset="1" style="stop-color:#FD5E83"/>
|
||||
</linearGradient>
|
||||
<path style="fill:url(#SVGID_00000011000279650532451330000005619277557075874698_);" d="M638.7,94.8l6.5-8.9
|
||||
c4.2,3.8,9.7,5.9,15.4,5.9c5.4,0,9.3-1.8,9.3-5c0-3.5-4.6-4.8-10.3-6.1c-8.4-1.9-19.2-4.5-19.2-16.5c0-11.2,9.8-16.7,21.5-16.7
|
||||
c7.4-0.1,14.6,2.3,20.5,6.9l-6.5,9c-3.9-3.1-8.7-4.8-13.7-4.9c-4.6,0-8.3,1.5-8.3,4.5c0,3.5,4.4,4.7,10.3,5.9
|
||||
c8.4,1.9,19.2,4.5,19.2,16.4c0,11.2-9.9,17.3-22.6,17.3C652.9,102.9,644.9,100.1,638.7,94.8z"/>
|
||||
<linearGradient id="SVGID_00000176732902084481618460000012775063734620060048_" gradientUnits="userSpaceOnUse" x1="408.7259" y1="431.5905" x2="485.4144" y2="495.6844" gradientTransform="matrix(1 0 0 1 -374.6 -381.3801)">
|
||||
<stop offset="0" style="stop-color:#FEAF6F"/>
|
||||
<stop offset="1" style="stop-color:#FD5E83"/>
|
||||
</linearGradient>
|
||||
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_00000176732902084481618460000012775063734620060048_);" d="
|
||||
M124.5,62c-12.7,0.9-27,5.5-35.7,12.3c-38.7,30.3-69.2-6.6-69.3-6.6l6.8,36.8c0.8,4.3,4.6,7.5,9,7.5l73,0.2c4.5,0,8.3-3.2,9.1-7.6
|
||||
L124.5,62z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 10 KiB |
@ -1 +0,0 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 142.71 128.36"><defs><style>.cls-1{fill:#fff;}.cls-2{fill-rule:evenodd;fill:url(#linear-gradient);}</style><linearGradient id="linear-gradient" x1="408.73" y1="431.59" x2="485.41" y2="495.68" gradientTransform="translate(-374.6 -381.38)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#feaf6f"/><stop offset="1" stop-color="#fd5e83"/></linearGradient></defs><path class="cls-1" d="M133.09,19.17H9.67A3.24,3.24,0,0,1,6.46,16V3.24A3.24,3.24,0,0,1,9.7,0H133.09a3.25,3.25,0,0,1,3.25,3.24V16a3.25,3.25,0,0,1-3.25,3.24"/><path class="cls-1" d="M23.61,36.67A11.41,11.41,0,0,0,14.8,41a15.79,15.79,0,0,0-3.25,12.8l9.18,51.92c1.17,6.62,6.25,11.42,12.06,11.42H110c5.82,0,10.89-4.8,12.06-11.42l9.18-51.91A15.86,15.86,0,0,0,128,41a11.5,11.5,0,0,0-8.82-4.33ZM110,128.35H32.8c-11.27,0-21-8.7-23.12-20.69L.46,55.75a26.72,26.72,0,0,1,5.71-22,22.77,22.77,0,0,1,17.41-8.34h95.56a22.8,22.8,0,0,1,17.41,8.34,26.79,26.79,0,0,1,5.71,22l-9.19,51.91c-2.12,12-11.84,20.7-23.12,20.7"/><path class="cls-1" d="M120.8,23.76V21.51A3.56,3.56,0,0,0,121,14.4H21.59a3.56,3.56,0,0,0,0,7.11v2.25a5.81,5.81,0,0,1,0-11.61H120.8a5.81,5.81,0,0,1,.48,11.61h-.48"/><path class="cls-1" d="M120.8,33.11H21.59a5.8,5.8,0,0,1,0-11.6v2.24a3.56,3.56,0,0,0,0,7.11H120.8a3.56,3.56,0,0,0,.52-7.1h-.52V21.51a5.81,5.81,0,0,1,.48,11.61,3.84,3.84,0,0,1-.48,0"/><path class="cls-1" d="M21.59,21.51l36.13,1.13L21.59,23.76Z"/><path class="cls-1" d="M125.46,23.76,80.35,22.64l45.11-1.13Z"/><path class="cls-2" d="M124.46,62c-12.72.93-27,5.55-35.7,12.34-38.69,30.34-69.25-6.6-69.28-6.58l6.75,36.83a9.16,9.16,0,0,0,9,7.52l73,.16a9.17,9.17,0,0,0,9.06-7.64Z"/></svg>
|
Before Width: | Height: | Size: 1.7 KiB |
@ -20,7 +20,8 @@
|
||||
data-internet="{{ translate('startup', 'internet', data['lang']) }}"
|
||||
data-tasks="{{ translate('startup', 'tasks', data['lang']) }}"
|
||||
data-internals="{{ translate('startup', 'internals', data['lang']) }}"
|
||||
data-almost="{{ translate('startup', 'almost', data['lang']) }}">
|
||||
data-almost="{{ translate('startup', 'almost', data['lang']) }}"
|
||||
data-cache="{{ translate('startup', 'cache', data['lang'])}}">
|
||||
{{ translate('startup', 'starting', data['lang']) }}</h2>
|
||||
</div>
|
||||
|
||||
|
@ -20,11 +20,6 @@
|
||||
<div class="col-sm-6 grid-margin stretch-card">
|
||||
<div class="card" id="creation_wizard">
|
||||
<div class="card-body">
|
||||
{% if data["server_api"] and data["online"] %}
|
||||
<a href="https://serverjars.com/" target="_blank" alt="serverjars icon"><img
|
||||
src="../../static/assets/images/serverjars/ICON.svg"
|
||||
style="float: right; width: 40px; position: relative;"></a>
|
||||
{% end %}
|
||||
|
||||
<h4>{{ translate('serverWizard', 'newServer', data['lang']) }}</h4>
|
||||
<br />
|
||||
@ -67,16 +62,19 @@
|
||||
{% end %}
|
||||
{% raw xsrf_form_html() %}
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="server_jar">{{ translate('serverWizard', 'serverType', data['lang'])
|
||||
}}</label>
|
||||
<label for="server_jar">{{ translate('serverWizard', 'serverType', data['lang']) }}</label>
|
||||
<div class="input-group">
|
||||
<select required class="form-control form-control-lg select-css" id="server_jar"
|
||||
name="server_jar" onchange="serverJarChange(this)">
|
||||
<option value="None">{{ translate('serverWizard', 'selectType', data['lang']) }}</option>
|
||||
<select required class="form-control form-control-lg select-css" id="server_jar" name="type"
|
||||
onchange="serverJarChange(this)">
|
||||
<option value="">{{ translate('serverWizard', 'selectServer', data['lang']) }}</option>
|
||||
{% for s in data['server_types'] %}
|
||||
<option value="{{ s }}">{{ s.capitalize() }}</option>
|
||||
{% if data['server_types'][s].get("enabled", False) %}
|
||||
<option value="{{ s }}">{{ data["server_types"][s].get("friendly_name", s).capitalize() }}
|
||||
{% end %}
|
||||
</option>
|
||||
{% end %}
|
||||
</select>
|
||||
{% if data['super_user'] %}
|
||||
@ -108,7 +106,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<span data-html="true" class="version-hint text-center"
|
||||
data-content="⚠️ {{ translate('serverWizard', 'unsupported', data['lang']) }} ⚠️" , data-placement="right"></span>
|
||||
data-content="⚠️ {{ translate('serverWizard', 'unsupported', data['lang']) }} ⚠️" ,
|
||||
data-placement="right"></span>
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="server_name">{{ translate('serverWizard', 'serverName', data['lang']) }}</label>
|
||||
@ -191,10 +190,12 @@
|
||||
{% if not data["server_api"] and data["online"] %}
|
||||
<div class="api-alert" style="position: absolute; top: -5px; z-index: 100; opacity: .99;">
|
||||
<p style="color: white !important;"><i class="fas fa-exclamation-triangle" style="color: red;"></i> {{
|
||||
translate('error', 'serverJars1', data['lang']) }}<a style="color: red;" ;
|
||||
href="https://status.craftycontrol.com/status/craftycontrol" target="_blank" rel="noopener"> {{ translate('error',
|
||||
translate('error', 'bigBucket1', data['lang']) }}<a style="color: red;" ;
|
||||
href="https://status.craftycontrol.com/status/craftycontrol" target="_blank" rel="noopener"> {{
|
||||
translate('error',
|
||||
'craftyStatus', data['lang']) }}</a>
|
||||
{{ translate('error', 'serverJars2', data['lang']) }}</p>
|
||||
{{ translate('error', 'bigBucket2', data['lang']) }}</br></br><small>{{ translate('error', 'selfHost',
|
||||
data['lang'])}}</small></p>
|
||||
</div>
|
||||
{% end %}
|
||||
{% if not data["online"] %}
|
||||
@ -827,7 +828,7 @@
|
||||
message: '<p class="text-center mb-0"><i class="fa fa-spin fa-cog"></i> Please wait while we gather your files...</p>',
|
||||
closeButton: false
|
||||
});
|
||||
setTimeout(function(){
|
||||
setTimeout(function () {
|
||||
getDirView();
|
||||
}, 2000);
|
||||
} else {
|
||||
@ -845,9 +846,9 @@
|
||||
message: '<p class="text-center mb-0"><i class="fa fa-spin fa-cog"></i> Please wait while we gather your files...</p>',
|
||||
closeButton: false
|
||||
});
|
||||
setTimeout(function(){
|
||||
getDirView();
|
||||
}, 2000);
|
||||
setTimeout(function () {
|
||||
getDirView();
|
||||
}, 2000);
|
||||
});
|
||||
var upload = false;
|
||||
var file;
|
||||
@ -1137,7 +1138,7 @@
|
||||
function wait_msg(importing) {
|
||||
bootbox.alert({
|
||||
title: importing ? '{% raw translate("serverWizard", "importing", data["lang"]) %}' : '{% raw translate("serverWizard", "downloading", data["lang"]) %}',
|
||||
message: importing ? '<i class="fas fa-cloud-download"></i> {% raw translate("serverWizard", "bePatient", data["lang"]) %}' : '<i class="fas fa-cloud-download"></i> {% raw translate("serverWizard", "bePatient", data["lang"]) %}<br><br><a href="https://serverjars.com" target="_blank" style="text-align: center;"><img src="../../static/assets/images/serverjars/FULL-WHITE.svg" alt="Powered by serverjars.com" width="40%"></a>',
|
||||
message: importing ? '<i class="fas fa-cloud-download"></i> {% raw translate("serverWizard", "bePatient", data["lang"]) %}' : '<i class="fas fa-cloud-download"></i> {% raw translate("serverWizard", "bePatient", data["lang"]) %}',
|
||||
});
|
||||
}
|
||||
|
||||
@ -1197,33 +1198,28 @@
|
||||
*/
|
||||
function serverTypeChange(selectObj) {
|
||||
// get the index of the selected option
|
||||
let idx = document.getElementById('server_type').selectedIndex;
|
||||
let idx = document.getElementById('server_type').value;
|
||||
let idx_list = idx.split("|");
|
||||
// get the value of the selected option
|
||||
let cSelect = document.getElementById("server");
|
||||
let which = {};
|
||||
try {
|
||||
which = document.getElementById('server_type').options[idx].value;
|
||||
versions = Object.keys(serverTypesLists[idx_list[0]]["types"][idx_list[1]]["versions"]);
|
||||
} catch {
|
||||
while (cSelect.options.length > 0) {
|
||||
cSelect.remove(0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
let server_type = which.split('|')[0];
|
||||
let server = which.split('|')[1];
|
||||
// use the selected option value to retrieve the list of items from the serverTypesLists array
|
||||
let cList = serverTypesLists[server_type];
|
||||
// get the country select element via its known id
|
||||
cSelect = document.getElementById("server");
|
||||
// remove the current options from the country select
|
||||
while (cSelect.options.length > 0) {
|
||||
cSelect.remove(0);
|
||||
}
|
||||
let newOption;
|
||||
|
||||
$("#server option").each(function () {
|
||||
$(this).remove()
|
||||
})
|
||||
|
||||
// create new options ordered by ascending
|
||||
cList[server].forEach(type => {
|
||||
versions.forEach(type => {
|
||||
newOption = document.createElement("option");
|
||||
newOption.value = which + "|" + type; // assumes option string and value are the same
|
||||
newOption.value = idx + "|" + type; // assumes option string and value are the same
|
||||
newOption.text = type;
|
||||
// add the new option
|
||||
try {
|
||||
@ -1234,17 +1230,18 @@
|
||||
}
|
||||
})
|
||||
}
|
||||
$("#server").change(function (){
|
||||
|
||||
$("#server").change(function () {
|
||||
let selected_version = $("#server :selected").text().split(".");
|
||||
if(parseInt(selected_version[0]) === 1 && parseInt(selected_version[1]) < 8 ){
|
||||
if (parseInt(selected_version[0]) === 1 && parseInt(selected_version[1]) < 8) {
|
||||
$('[data-toggle="popover"]').popover();
|
||||
if ($(window).width() < 1000) {
|
||||
$('.version-hint').attr("data-placement", "top")
|
||||
if ($(window).width() < 1000) {
|
||||
$('.version-hint').attr("data-placement", "top")
|
||||
} else {
|
||||
$('.version-hint').attr("data-placement", "right")
|
||||
}
|
||||
$('.version-hint').popover("show");
|
||||
} else {
|
||||
$('.version-hint').attr("data-placement", "right")
|
||||
}
|
||||
$('.version-hint').popover("show");
|
||||
}else{
|
||||
$('.version-hint').popover("hide");
|
||||
}
|
||||
});
|
||||
@ -1253,6 +1250,15 @@
|
||||
const type_select = document.getElementById('server_jar')
|
||||
const tidx = type_select.selectedIndex;
|
||||
const val = type_select.options[tidx].value;
|
||||
if (!val) {
|
||||
$("#server_type option").each(function () {
|
||||
$(this).remove()
|
||||
})
|
||||
$("#server option").each(function () {
|
||||
$(this).remove()
|
||||
})
|
||||
return;
|
||||
}
|
||||
let jcSelect = {};
|
||||
if (val == 'None') {
|
||||
jcSelect = document.getElementById("server_type");
|
||||
@ -1267,7 +1273,7 @@
|
||||
// get the value of the selected option
|
||||
let jwhich = selectObj.options[jidx].value;
|
||||
// use the selected option value to retrieve the list of items from the serverTypesLists array
|
||||
let jcList = Object.keys(serverTypesLists[jwhich]);
|
||||
let jcList = Object.keys(serverTypesLists[jwhich]["types"]);
|
||||
// get the country select element via its known id
|
||||
jcSelect = document.getElementById("server_type");
|
||||
// remove the current options from the country select
|
||||
|
@ -117,7 +117,6 @@
|
||||
"welcome": "Vítejte v Crafty Controlleru"
|
||||
},
|
||||
"datatables": {
|
||||
"loadingRecords": "Načítání...",
|
||||
"i18n": {
|
||||
"aria": {
|
||||
"sortAscending": ": aktivace řazení sloupce vzestupně",
|
||||
@ -194,11 +193,14 @@
|
||||
},
|
||||
"thousands": " ",
|
||||
"zeroRecords": "Nebyly nalezeny žádné odpovídající záznamy"
|
||||
}
|
||||
},
|
||||
"loadingRecords": "Načítání..."
|
||||
},
|
||||
"error": {
|
||||
"agree": "Souhlasím",
|
||||
"bedrockError": "Stažení Bedrocku není dostupné. Prosím zkontrolujte",
|
||||
"bigBucket1": "Big Bucket Kontrola stavu selhala. Prosím zkontrolujte jej",
|
||||
"bigBucket2": "pro nejnovější informace.",
|
||||
"cancel": "Zrušit",
|
||||
"contact": "Kontaktujte podporu Crafty přes Discord",
|
||||
"craftyStatus": "Crafty stav systémů",
|
||||
@ -221,6 +223,7 @@
|
||||
"portReminder": "Zjistili jsme, že server {} byl spuštěn poprvé. Ujistěte se, že jste přesměrovali port {} přes váš směrovač/firewall, aby byl tento port vzdáleně přístupný z internetu.",
|
||||
"privMsg": "a ",
|
||||
"return": "vrátit se na hlavní stránku",
|
||||
"selfHost": "Pokud Hostujete sami toto uložiště prosím zkontrolujte adresu nebo si přečtěte náš průvodce odstraňováním problémů.",
|
||||
"serverJars1": "Server JAR api je nepřístupná. Prosím zkontrolujte",
|
||||
"serverJars2": "pro aktualní informace.",
|
||||
"start-error": "Server {} se nepodařilo spustit s kódem chyby: {}",
|
||||
@ -622,6 +625,7 @@
|
||||
},
|
||||
"startup": {
|
||||
"almost": "Dokončuji. Držte se...",
|
||||
"cache": "Znovu načítam mezipaměť Big Bucket",
|
||||
"internals": "Nastavuji a startuji Crafty interní komponenty",
|
||||
"internet": "Kontroluju připojení k internetu",
|
||||
"server": "Konfigurace ",
|
||||
|
@ -117,7 +117,6 @@
|
||||
"welcome": "Willkommen bei Crafty Controller"
|
||||
},
|
||||
"datatables": {
|
||||
"loadingRecords": "Laden...",
|
||||
"i18n": {
|
||||
"aria": {
|
||||
"sortAscending": ": Aktivieren, um die Spalte aufsteigend zu sortieren",
|
||||
@ -179,11 +178,14 @@
|
||||
},
|
||||
"thousands": ".",
|
||||
"zeroRecords": "Keine passenden Einträge gefunden"
|
||||
}
|
||||
},
|
||||
"loadingRecords": "Laden..."
|
||||
},
|
||||
"error": {
|
||||
"agree": "Zustimmen",
|
||||
"bedrockError": "Bedrock-Downloads sind nicht verfügbar. Bitte überprüfen Sie",
|
||||
"bigBucket1": "Big Bucket Zustandsprüfung fehlgeschlagen. Bitte Überprüfen",
|
||||
"bigBucket2": "für die aktuellsten Informationen.",
|
||||
"cancel": "Abbrechen",
|
||||
"contact": "Kontaktieren Sie den Crafty Control Support über Discord",
|
||||
"craftyStatus": "Crafty-Statusseite",
|
||||
@ -206,6 +208,7 @@
|
||||
"portReminder": "Wir haben festgestellt, dass dies das erste Mal ist, dass {} ausgeführt wurde. Stellen Sie sicher, dass Sie Port {} durch Ihren Router/Firewall weiterleiten, um den Fernzugriff aus dem Internet zu ermöglichen.",
|
||||
"privMsg": "und der/die/das ",
|
||||
"return": "Zurück zum Dashboard",
|
||||
"selfHost": "Wenn Sie dieses Repo selbst hosten, überprüfen Sie bitte Ihre Adresse oder konsultieren Sie unsere Anleitung zur Fehlerbehebung.",
|
||||
"serverJars1": "Server-JAR-API nicht erreichbar. Bitte überprüfen Sie ",
|
||||
"serverJars2": "um die aktuellsten Informationen zu erhalten.",
|
||||
"start-error": "Der Server {} konnte wegen dem Fehlercode: {} nicht gestartet werden",
|
||||
@ -603,6 +606,7 @@
|
||||
},
|
||||
"startup": {
|
||||
"almost": "Nur noch einen Moment, fast geschafft",
|
||||
"cache": "Aktualisieren der Big Bucket-Cache-Datei",
|
||||
"internals": "Crafty's interne Komponneten initialisieren und starten",
|
||||
"internet": "Verbindung zum Internet überprüfen",
|
||||
"server": "initialisieren ",
|
||||
|
@ -116,7 +116,6 @@
|
||||
"welcome": "Welcome to Crafty Controller"
|
||||
},
|
||||
"datatables": {
|
||||
"loadingRecords": "Loading...",
|
||||
"i18n": {
|
||||
"aria": {
|
||||
"sortAscending": ": activate to sort column ascending",
|
||||
@ -178,11 +177,14 @@
|
||||
},
|
||||
"thousands": ",",
|
||||
"zeroRecords": "No matching records found"
|
||||
}
|
||||
},
|
||||
"loadingRecords": "Loading..."
|
||||
},
|
||||
"error": {
|
||||
"agree": "Agree",
|
||||
"bedrockError": "Bedrock downloads unavailable. Please check",
|
||||
"bigBucket1": "Big Bucket Health Check Failed. Please check",
|
||||
"bigBucket2": "for the most up to date information.",
|
||||
"cancel": "Cancel",
|
||||
"contact": "Contact Crafty Control Support via Discord",
|
||||
"craftyStatus": "Crafty's status page",
|
||||
@ -205,8 +207,7 @@
|
||||
"portReminder": "We have detected this is the first time {} has been run. Make sure to forward port {} through your router/firewall to make this remotely accessible from the internet.",
|
||||
"privMsg": "and the ",
|
||||
"return": "Return to Dashboard",
|
||||
"serverJars1": "Server JARs API unreachable. Please check",
|
||||
"serverJars2": "for the most up to date information.",
|
||||
"selfHost": "If you are self-hosting this repo please check your address or consult our troubleshooting guide.",
|
||||
"start-error": "Server {} failed to start with error code: {}",
|
||||
"superError": "You must be a super user to complete this action.",
|
||||
"terribleFailure": "What a Terrible Failure!"
|
||||
@ -601,6 +602,7 @@
|
||||
},
|
||||
"startup": {
|
||||
"almost": "Finishing up. Hang on tight...",
|
||||
"cache": "Refreshing Big Bucket cache file",
|
||||
"internals": "Configuring and starting Crafty's internal components",
|
||||
"internet": "Checking for internet connection",
|
||||
"server": "Initializing ",
|
||||
|
@ -117,7 +117,6 @@
|
||||
"welcome": "Bienvenido a Crafty Controller"
|
||||
},
|
||||
"datatables": {
|
||||
"loadingRecords": "Cargando...",
|
||||
"i18n": {
|
||||
"aria": {
|
||||
"sortAscending": ": activar para ordenar las columnas de manera ascendente",
|
||||
@ -179,7 +178,8 @@
|
||||
},
|
||||
"thousands": ",",
|
||||
"zeroRecords": "No se encontraron registros que coincidan"
|
||||
}
|
||||
},
|
||||
"loadingRecords": "Cargando..."
|
||||
},
|
||||
"error": {
|
||||
"agree": "Aceptar",
|
||||
|
@ -117,7 +117,6 @@
|
||||
"welcome": "Bienvenue sur Crafty Controller"
|
||||
},
|
||||
"datatables": {
|
||||
"loadingRecords": "Chargement ...",
|
||||
"i18n": {
|
||||
"aria": {
|
||||
"sortAscending": ": activer pour trier les colonnes dans l'ordre croissant",
|
||||
@ -179,11 +178,14 @@
|
||||
},
|
||||
"thousands": ",",
|
||||
"zeroRecords": "Aucun enregistrement correspondant trouvcé"
|
||||
}
|
||||
},
|
||||
"loadingRecords": "Chargement ..."
|
||||
},
|
||||
"error": {
|
||||
"agree": "Agree",
|
||||
"bedrockError": "Téléchargement Bedrock non disponible. Merci de vérifier",
|
||||
"bigBucket1": "Echec de vérification de l'état de Big Bucket. Veuillez vérifier",
|
||||
"bigBucket2": " pour l'information la plus à jour.",
|
||||
"cancel": "Annuler",
|
||||
"contact": "Contacter le Support de Crafty Control via Discord",
|
||||
"craftyStatus": "Page de statut de Crafty",
|
||||
@ -206,6 +208,7 @@
|
||||
"portReminder": "Nous avons détecté que c'est la première fois que {} est exécuté. Assurez-vous de transférer le port {} via votre routeur/pare-feu pour le rendre accessible à distance depuis Internet.",
|
||||
"privMsg": "et le ",
|
||||
"return": "Revenir au Tableau de Bord",
|
||||
"selfHost": "Si vous hébergez vous-même ce repo, veuillez vérifier votre adresse et votre guide de dépannage.",
|
||||
"serverJars1": "l'API Server JARs est inaccessible. Merci de vérifier",
|
||||
"serverJars2": "pour les informations les plus à jour.",
|
||||
"start-error": "Le serveur {} n'a pas pu démarrer avec le code d'erreur : {}",
|
||||
@ -603,6 +606,7 @@
|
||||
},
|
||||
"startup": {
|
||||
"almost": "Finalisation. Patienter ...",
|
||||
"cache": "Mise à jour du fichier cache de Big Bucket",
|
||||
"internals": "Configuration et Démarrage des composants internes de Crafty",
|
||||
"internet": "Vérification de la connexion à Internet",
|
||||
"server": "Initialisation ",
|
||||
|
@ -117,7 +117,6 @@
|
||||
"welcome": "ברוכים הבאים ל-פאנל קראפטי"
|
||||
},
|
||||
"datatables": {
|
||||
"loadingRecords": "...טוען",
|
||||
"i18n": {
|
||||
"aria": {
|
||||
"sortAscending": ": הפעילו כדי למיין עמודות בסדר עולה",
|
||||
@ -179,7 +178,8 @@
|
||||
},
|
||||
"thousands": ",",
|
||||
"zeroRecords": "לא נמצאו תוצאות תואמות"
|
||||
}
|
||||
},
|
||||
"loadingRecords": "...טוען"
|
||||
},
|
||||
"error": {
|
||||
"agree": "מסכים",
|
||||
|
@ -117,7 +117,6 @@
|
||||
"welcome": "Benvenuto su Crafty Controller"
|
||||
},
|
||||
"datatables": {
|
||||
"loadingRecords": "Carico...",
|
||||
"i18n": {
|
||||
"aria": {
|
||||
"sortAscending": ": attiva per ordinare le colonne in modo ascendente",
|
||||
@ -179,11 +178,14 @@
|
||||
},
|
||||
"thousands": ",",
|
||||
"zeroRecords": "Nessun record corrispondente trovato"
|
||||
}
|
||||
},
|
||||
"loadingRecords": "Carico..."
|
||||
},
|
||||
"error": {
|
||||
"agree": "Conferma",
|
||||
"bedrockError": "I download di Bedrock non sono disponibili. Si prega di controllare",
|
||||
"bigBucket1": "Controllo integrità di Big Bucket fallito. Controlla nuovamente",
|
||||
"bigBucket2": "per informazioni più aggiornate.",
|
||||
"cancel": "Annulla",
|
||||
"contact": "Contact Crafty Control Support via Discord",
|
||||
"craftyStatus": "Stato di Crafty",
|
||||
@ -206,6 +208,7 @@
|
||||
"portReminder": "We have detected this is the first time {} has been run. Make sure to forward port {} through your router/firewall to make this remotely accessible from the internet.",
|
||||
"privMsg": "e il ",
|
||||
"return": "Torna alla pagina iniziale",
|
||||
"selfHost": "se stai ospitando te questo repo, controlla il tuo indirizzo o consulta la nostra guida di risoluzione dei problemi.",
|
||||
"serverJars1": "API JAR del server non raggiungibile. Si prega di controllare",
|
||||
"serverJars2": "per informazioni più aggiornate.",
|
||||
"start-error": "Server {} failed to start with error code: {}",
|
||||
@ -603,6 +606,7 @@
|
||||
},
|
||||
"startup": {
|
||||
"almost": "Finalizzazione. Tieniti forte...",
|
||||
"cache": "Aggiornamento cache di Big Bucket",
|
||||
"internals": "Configurazione e avvio dei componenti interni di Crafty",
|
||||
"internet": "Controllo connessione a internet",
|
||||
"server": "Inizializzazione ",
|
||||
|
@ -117,7 +117,6 @@
|
||||
"welcome": "WELCOM 2 CWAFTY CONTROLLR"
|
||||
},
|
||||
"datatables": {
|
||||
"loadingRecords": "Loading...",
|
||||
"i18n": {
|
||||
"aria": {
|
||||
"sortAscending": ": activate to sort column ascending",
|
||||
@ -179,11 +178,14 @@
|
||||
},
|
||||
"thousands": ",",
|
||||
"zeroRecords": "No matching records found"
|
||||
}
|
||||
},
|
||||
"loadingRecords": "Loading..."
|
||||
},
|
||||
"error": {
|
||||
"agree": "YESH PLS",
|
||||
"bedrockError": "BEDROCKZ DOWNLOADZ NO WORKY. CHECK PLZ.",
|
||||
"bigBucket1": "Big Bucket No Worky. Plz check",
|
||||
"bigBucket2": "for da freshest nooz.",
|
||||
"cancel": "NOPEZ",
|
||||
"contact": "CONTACK CWAFTY CONTROLLR SUPORT ON DA DIZORD",
|
||||
"craftyStatus": "CWAFTY'S STATUSZ",
|
||||
@ -206,6 +208,7 @@
|
||||
"portReminder": "WE HAS DETECTD DIS AR TEH FURST TIEM {} IZ BEAN RUN. IF U WANTS IT ACESIBLE TO NEIGHBORHOOD CATS PLZ UNLOCK CAT_FLAP, {}, THRU UR ROUTR IF U HAS NOT DUN SO.",
|
||||
"privMsg": "AND THEEZ ",
|
||||
"return": "Go Bak to Dashbored",
|
||||
"selfHost": "If u iz self-hostin' dis repo, check ur addy or peep our fix-it guide.",
|
||||
"serverJars1": "CAN'T TALK TO SERVER JARS API. CHECKZ",
|
||||
"serverJars2": "TO SEE NEWZ STUFFZ.",
|
||||
"start-error": "CHAIR {} FAILD 2 START WIF OOF CODE: {}",
|
||||
@ -603,6 +606,7 @@
|
||||
},
|
||||
"startup": {
|
||||
"almost": "ALMOST DUN. HOLD ON TO YER WHISKERS...",
|
||||
"cache": "Fightin' for a Big Bucket o Fish",
|
||||
"internals": "SETTIN' UP AN' STARTIN' CWAFTY'S INSIDE BITZ",
|
||||
"internet": "LOOKIN' FOR OUTER SPACE TALKY",
|
||||
"server": "WAKIN' UPZ ",
|
||||
|
@ -118,7 +118,6 @@
|
||||
"welcome": "Esiet sveicināts Crafty Controller"
|
||||
},
|
||||
"datatables": {
|
||||
"loadingRecords": "Ielādē...",
|
||||
"i18n": {
|
||||
"aria": {
|
||||
"sortAscending": ": aktivizēt lai kārotu kolonnu augoši",
|
||||
@ -180,11 +179,14 @@
|
||||
},
|
||||
"thousands": ",",
|
||||
"zeroRecords": "Nav atrasti atbilstoši ieraksti"
|
||||
}
|
||||
},
|
||||
"loadingRecords": "Ielādē..."
|
||||
},
|
||||
"error": {
|
||||
"agree": "Piekrītu",
|
||||
"bedrockError": "Bedrock lejupielādes nav pieejamas. Lūdzu pārbaudi",
|
||||
"bigBucket1": "Big Bucket stāvokļa pārbaude neizdevās. Lūdzu izpētiet",
|
||||
"bigBucket2": "priekš jaunākās informācijas.",
|
||||
"cancel": "Atcelt",
|
||||
"contact": "Sazinies ar Crafty Control Atbalstu izmantojot Discord",
|
||||
"craftyStatus": "Crafty statusa lapa",
|
||||
@ -207,6 +209,7 @@
|
||||
"portReminder": "Mēs noteicām ka šī ir pirmā reize, kad {} ir ticis palaists. Pārliecinies izlaist portu {} cauri savam rūterim/ugunsmūrim lai padarītu šo attāli pieejamu no interneta.",
|
||||
"privMsg": "un ",
|
||||
"return": "Atgriezties uz pārskatu",
|
||||
"selfHost": "Ja jūs paši uzturat šo repozitoriju, pārbaudiet savu adresi vai apskatiet mūsu kļūdu novēršanas dokumentāciju.",
|
||||
"serverJars1": "Serveru JAR API nav sasniedzams. Lūdzu pārbaudiet",
|
||||
"serverJars2": "priekš jaunākās informācijas.",
|
||||
"start-error": "Serveris {} neveiskmīgi startējās ar kļūdas kodu: {}",
|
||||
@ -604,6 +607,7 @@
|
||||
},
|
||||
"startup": {
|
||||
"almost": "Pabeidz. Vēl tik nedaudz...",
|
||||
"cache": "Atjauno Big Bucket keša failu",
|
||||
"internals": "Konfigurē un Startē Crafty iekšējās komponenetes",
|
||||
"internet": "Pārbauda interneta savienojumu",
|
||||
"server": "Inicializē ",
|
||||
|
@ -117,7 +117,6 @@
|
||||
"welcome": "Welkom bij Crafty Controller "
|
||||
},
|
||||
"datatables": {
|
||||
"loadingRecords": "Bezig met laden...",
|
||||
"i18n": {
|
||||
"aria": {
|
||||
"sortAscending": ": activeren om kolom oplopend te sorteren",
|
||||
@ -179,11 +178,14 @@
|
||||
},
|
||||
"thousands": ",",
|
||||
"zeroRecords": "Geen overeenkomende records gevonden"
|
||||
}
|
||||
},
|
||||
"loadingRecords": "Bezig met laden..."
|
||||
},
|
||||
"error": {
|
||||
"agree": "Akkoord",
|
||||
"bedrockError": "Bedrock-downloads niet beschikbaar. Controleer alstublieft",
|
||||
"bigBucket1": "Big Bucket-gezondheidscontrole mislukt. Controleer alstublieft",
|
||||
"bigBucket2": "voor de meest recente informatie.",
|
||||
"cancel": "Annuleren",
|
||||
"contact": "Neem contact op met Crafty Control ondersteuning via Discord",
|
||||
"craftyStatus": "Crafty's statuspagina",
|
||||
@ -206,6 +208,7 @@
|
||||
"portReminder": "We hebben ontdekt dat dit de eerste keer is dat {} wordt uitgevoerd. Zorg ervoor dat u poort {} doorstuurt via uw router/firewall om deze op afstand toegankelijk te maken vanaf het internet.",
|
||||
"privMsg": "en de ",
|
||||
"return": "Terug naar Dashboard",
|
||||
"selfHost": "Als u deze repository zelf host, controleer dan uw adres of raadpleeg onze handleiding voor probleemoplossing.",
|
||||
"serverJars1": "Server JARs API niet bereikbaar. Controleer alstublieft",
|
||||
"serverJars2": "voor de meest recente informatie.",
|
||||
"start-error": "Server {} kan niet starten met foutcode: {}",
|
||||
@ -603,6 +606,7 @@
|
||||
},
|
||||
"startup": {
|
||||
"almost": "De laatste hand leggen. Houd je vast...",
|
||||
"cache": "Big Bucket-cachebestand vernieuwen",
|
||||
"internals": "Crafty's interne componenten configureren en starten",
|
||||
"internet": "Controleren op internetverbinding",
|
||||
"server": "Initialiseren ",
|
||||
|
@ -117,7 +117,6 @@
|
||||
"welcome": "Witamy w Crafty Controller"
|
||||
},
|
||||
"datatables": {
|
||||
"loadingRecords": "Wczytywanie...",
|
||||
"i18n": {
|
||||
"aria": {
|
||||
"sortAscending": ": aktywuj, aby sortować kolumny w góre",
|
||||
@ -179,11 +178,14 @@
|
||||
},
|
||||
"thousands": ",",
|
||||
"zeroRecords": "Nie znaleziono pasujacego wyniku"
|
||||
}
|
||||
},
|
||||
"loadingRecords": "Wczytywanie..."
|
||||
},
|
||||
"error": {
|
||||
"agree": "Zgadzam się",
|
||||
"bedrockError": "Pobieranie serwera bedrock jest teraz niedostępne. Proszę sprawdź",
|
||||
"bigBucket1": "Odświeżanie Big Bucket nie powiodło się. Sprawdź",
|
||||
"bigBucket2": "dla najnowszych informacji.",
|
||||
"cancel": "Anuluj",
|
||||
"contact": "Podrzebujesz pomocy? Zapraszamy na serwer discord Crafty Controler",
|
||||
"craftyStatus": "Status strony Craftyiego",
|
||||
@ -206,6 +208,7 @@
|
||||
"portReminder": "Zauważyliśmy że to jest pierwszy raz {} kiedy był włączony. Upewnij się że otworzyłeś port {} na swoim routerze/firewallu aby korzystać z tego poza domem.",
|
||||
"privMsg": "i także ",
|
||||
"return": "Powrót do panelu",
|
||||
"selfHost": "Jeśli zarządasz tą repozytorią upewnij się że adres hest poprawny, w innym przypadku odwiedź strone rozwiązywania problemów.",
|
||||
"serverJars1": "API Server Jars jest niedostępne. Proszę sprawdź",
|
||||
"serverJars2": "dla najnowzsych informacji.",
|
||||
"start-error": "Serwer {} nie mógł się odpalić z powodu: {}",
|
||||
@ -602,6 +605,7 @@
|
||||
},
|
||||
"startup": {
|
||||
"almost": "Prawie gotowe! Jeszcze tylko chwilka...",
|
||||
"cache": "Odświeżanie pamięci podręcznej Big Bucket",
|
||||
"internals": "Konfigurowanie i włączanie backendu...",
|
||||
"internet": "Sprawdzam połączenie z internetem",
|
||||
"server": "Włączanie ",
|
||||
|
@ -117,7 +117,6 @@
|
||||
"welcome": "ยินดีต้อนรับสู่ Crafty Controller"
|
||||
},
|
||||
"datatables": {
|
||||
"loadingRecords": "กำลังโหลด...",
|
||||
"i18n": {
|
||||
"aria": {
|
||||
"sortAscending": ": เปิดใช้งานเพื่อเรียงลำดับคอลัมน์จากน้อยไปมาก",
|
||||
@ -179,7 +178,8 @@
|
||||
},
|
||||
"thousands": ",",
|
||||
"zeroRecords": "ไม่พบรายการที่ตรงกัน"
|
||||
}
|
||||
},
|
||||
"loadingRecords": "กำลังโหลด..."
|
||||
},
|
||||
"error": {
|
||||
"agree": "ยอมรับ",
|
||||
|
@ -117,7 +117,6 @@
|
||||
"welcome": "Crafty Controller'a Hoşgeldiniz!"
|
||||
},
|
||||
"datatables": {
|
||||
"loadingRecords": "Yükleniyor...",
|
||||
"i18n": {
|
||||
"aria": {
|
||||
"sortAscending": ": artan sütun sıralamasını aktifleştir",
|
||||
@ -179,11 +178,14 @@
|
||||
},
|
||||
"thousands": ".",
|
||||
"zeroRecords": "Eşleşen kayıt bulunamadı"
|
||||
}
|
||||
},
|
||||
"loadingRecords": "Yükleniyor..."
|
||||
},
|
||||
"error": {
|
||||
"agree": "Kabul Et",
|
||||
"bedrockError": "Bedrock indirmeleri kullanılamıyor. Lütfen kontrol edin",
|
||||
"bigBucket1": "Big Bucket sağlık kontrolü yapılamadı. En güncel bilgileri burada bulabilirsiniz:",
|
||||
"bigBucket2": ".",
|
||||
"cancel": "İptal",
|
||||
"contact": "Crafty Control Destek Discord Sunucusu",
|
||||
"craftyStatus": "Crafty'nin durum sayfası",
|
||||
@ -206,6 +208,7 @@
|
||||
"portReminder": "{} ilk kez çalıştırılıyor olduğunu tespit ettik. Bunu internetten uzaktan erişilebilir kılmak için {} bağlantı noktasını yönlendiriciniz/güvenlik duvarınız üzerinden ilettiğinizden emin olun.",
|
||||
"privMsg": "ve ",
|
||||
"return": "Arayüze Geri Dön",
|
||||
"selfHost": "Bu depoyu kendiniz barındırıyorsanız lütfen adresinizi kontrol ediniz veya sorun giderme kılavuzumuza bakınız.",
|
||||
"serverJars1": "Sunucu JARs API'ına erişilemiyor.",
|
||||
"serverJars2": "en güncel bilgilere sahiptir",
|
||||
"start-error": "{} sunucusu başlamatılamadı. Hata kodu: {}",
|
||||
@ -602,6 +605,7 @@
|
||||
},
|
||||
"startup": {
|
||||
"almost": "Bitiriliyor. Sıkı tutun...",
|
||||
"cache": "Big Bucket önbellek dosyası yenileniyor",
|
||||
"internals": "Crafty'nin dahili bileşenlerini konfigüre etme ve başlatma",
|
||||
"internet": "İnternet bağlantısı kontrol ediliyor",
|
||||
"server": "Başlatılıyor ",
|
||||
|
@ -117,7 +117,6 @@
|
||||
"welcome": "Ласкаво просимо у Crafty Controller"
|
||||
},
|
||||
"datatables": {
|
||||
"loadingRecords": "Завантаження...",
|
||||
"i18n": {
|
||||
"aria": {
|
||||
"sortAscending": ": активуйте, щоб сортувати стовпці за зростанням",
|
||||
@ -179,11 +178,14 @@
|
||||
},
|
||||
"thousands": ",",
|
||||
"zeroRecords": "Не знайдено збігів в базі"
|
||||
}
|
||||
},
|
||||
"loadingRecords": "Завантаження..."
|
||||
},
|
||||
"error": {
|
||||
"agree": "Згодний",
|
||||
"bedrockError": "Bedrock недоступний для скачування. Перевірте будь ласка",
|
||||
"bigBucket1": "Перевірка Big Bucket не пройдено. Будь ласка, перевірте",
|
||||
"bigBucket2": "для найактуальнішої інформації.",
|
||||
"cancel": "Відміна",
|
||||
"contact": "Зв'язатись з Crafty Control підтримкою через Discord",
|
||||
"craftyStatus": "Crafty's статус",
|
||||
@ -206,6 +208,7 @@
|
||||
"portReminder": "Ми виявили це вперше {} був запущений. Обов’язково перенаправте порт {} через ваш маршрутизатор/брандмауер, щоб зробити це доступним з Інтернету.",
|
||||
"privMsg": "і ",
|
||||
"return": "Повернутись до панелі",
|
||||
"selfHost": "Якщо ви самостійно розміщуєте цей репозеторій, перевірте свою адресу або зверніться до нашого посібника з усунення несправностей.",
|
||||
"serverJars1": "API сервера JAR недоступний. Будь ласка, перевірте",
|
||||
"serverJars2": "для найактуальнішої інформації.",
|
||||
"start-error": "Сервер {} не запустився через помилку: {}",
|
||||
@ -602,6 +605,7 @@
|
||||
},
|
||||
"startup": {
|
||||
"almost": "Закінчуємо. Тримайся міцніше...",
|
||||
"cache": "Оновлення файлу кешу Big Bucket",
|
||||
"internals": "Налаштування та запуск внутрішніх компонентів Crafty ",
|
||||
"internet": "Перевірка доступу до інтернету",
|
||||
"server": "Ініціалізація ",
|
||||
|
@ -117,7 +117,6 @@
|
||||
"welcome": "欢迎来到 Crafty Controller"
|
||||
},
|
||||
"datatables": {
|
||||
"loadingRecords": "正在加载……",
|
||||
"i18n": {
|
||||
"aria": {
|
||||
"sortAscending": ":激活对队列的升序排列",
|
||||
@ -179,11 +178,14 @@
|
||||
},
|
||||
"thousands": ",",
|
||||
"zeroRecords": "没有找到匹配的记录"
|
||||
}
|
||||
},
|
||||
"loadingRecords": "正在加载……"
|
||||
},
|
||||
"error": {
|
||||
"agree": "同意",
|
||||
"bedrockError": "基岩版下载不可用。请检查",
|
||||
"bigBucket1": "Big Bucket 查活失败。请检查",
|
||||
"bigBucket2": "以获取最新信息。",
|
||||
"cancel": "取消",
|
||||
"contact": "通过 Discord 联系 Crafty Control 支持",
|
||||
"craftyStatus": "Crafty 的状态页面",
|
||||
@ -206,6 +208,7 @@
|
||||
"portReminder": "我们检测到这是你首次运行 {}。请确保从您的路由器/防火墙转发 {} 端口,以使程序可以从公网远程访问。",
|
||||
"privMsg": "以及",
|
||||
"return": "返回仪表板",
|
||||
"selfHost": "如果您自托管此仓库,请检查您的地址或参考我们的故障排除指南。",
|
||||
"serverJars1": "无法访问服务器 JAR API。请检查",
|
||||
"serverJars2": "以获取最新信息。",
|
||||
"start-error": "服务器 {} 启动失败,错误代码为:{}",
|
||||
@ -603,6 +606,7 @@
|
||||
},
|
||||
"startup": {
|
||||
"almost": "即将完成。请稍候……",
|
||||
"cache": "正在刷新 Big Bucket 缓存文件",
|
||||
"internals": "正在配置并启动 Crafty 的内部组件",
|
||||
"internet": "正在检查网络连接",
|
||||
"server": "正在初始化 ",
|
||||
|
8
main.py
8
main.py
@ -118,7 +118,7 @@ def controller_setup():
|
||||
def tasks_starter():
|
||||
"""
|
||||
Method starts stats recording, app scheduler, and
|
||||
serverjars/steamCMD cache refreshers
|
||||
big bucket/steamCMD cache refreshers
|
||||
"""
|
||||
# start stats logging
|
||||
tasks_manager.start_stats_recording()
|
||||
@ -128,8 +128,8 @@ def tasks_starter():
|
||||
tasks_manager.start_scheduler()
|
||||
|
||||
# refresh our cache and schedule for every 12 hoursour cache refresh
|
||||
# for serverjars.com
|
||||
tasks_manager.serverjar_cache_refresher()
|
||||
# for big bucket.com
|
||||
tasks_manager.big_bucket_cache_refresher()
|
||||
|
||||
|
||||
def signal_handler(signum, _frame):
|
||||
@ -213,6 +213,8 @@ def setup_starter():
|
||||
time.sleep(2)
|
||||
controller_setup_thread.start()
|
||||
|
||||
web_sock.broadcast("update", {"section": "cache"})
|
||||
controller.big_bucket.manual_refresh_cache()
|
||||
# Wait for the setup threads to finish
|
||||
web_sock.broadcast(
|
||||
"update",
|
||||
|
Loading…
Reference in New Issue
Block a user