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:
Iain Powrie 2024-05-10 20:46:05 +00:00
commit 64082092b4
31 changed files with 416 additions and 640 deletions

View File

@ -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

View 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

View File

@ -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

View File

@ -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):

View File

@ -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"],

View File

@ -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(".")

View File

@ -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):

View File

@ -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,

View File

@ -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(),
},
)

View File

@ -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": {

View File

@ -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"] = []

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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>&nbsp;{{
translate('error', 'serverJars1', data['lang']) }}<a style="color: red;" ;
href="https://status.craftycontrol.com/status/craftycontrol" target="_blank" rel="noopener">&nbsp;{{ translate('error',
translate('error', 'bigBucket1', data['lang']) }}<a style="color: red;" ;
href="https://status.craftycontrol.com/status/craftycontrol" target="_blank" rel="noopener">&nbsp;{{
translate('error',
'craftyStatus', data['lang']) }}</a>
&nbsp;{{ translate('error', 'serverJars2', data['lang']) }}</p>
&nbsp;{{ 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

View File

@ -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 ",

View File

@ -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 ",

View File

@ -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 ",

View File

@ -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",

View File

@ -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 ",

View File

@ -117,7 +117,6 @@
"welcome": "ברוכים הבאים ל-פאנל קראפטי"
},
"datatables": {
"loadingRecords": "...טוען",
"i18n": {
"aria": {
"sortAscending": ": הפעילו כדי למיין עמודות בסדר עולה",
@ -179,7 +178,8 @@
},
"thousands": ",",
"zeroRecords": "לא נמצאו תוצאות תואמות"
}
},
"loadingRecords": "...טוען"
},
"error": {
"agree": "מסכים",

View File

@ -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 ",

View File

@ -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 ",

View File

@ -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ē ",

View File

@ -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 ",

View File

@ -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 ",

View File

@ -117,7 +117,6 @@
"welcome": "ยินดีต้อนรับสู่ Crafty Controller"
},
"datatables": {
"loadingRecords": "กำลังโหลด...",
"i18n": {
"aria": {
"sortAscending": ": เปิดใช้งานเพื่อเรียงลำดับคอลัมน์จากน้อยไปมาก",
@ -179,7 +178,8 @@
},
"thousands": ",",
"zeroRecords": "ไม่พบรายการที่ตรงกัน"
}
},
"loadingRecords": "กำลังโหลด..."
},
"error": {
"agree": "ยอมรับ",

View File

@ -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 ",

View File

@ -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": "Ініціалізація ",

View File

@ -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": "正在初始化 ",

View File

@ -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",