mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
Merge branch 'dev' into tweak/password-reset
This commit is contained in:
commit
385ceb9655
@ -2,9 +2,11 @@
|
|||||||
## --- [4.0.12] - 2022/09/04
|
## --- [4.0.12] - 2022/09/04
|
||||||
### New features
|
### New features
|
||||||
- Win Portable Updater will now be included in Windows Package ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/446))
|
- Win Portable Updater will now be included in Windows Package ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/446))
|
||||||
|
- Bedrock Server Creator ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/443))
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
- Fix performance issues on server metrics panels (Temporarily setting to 24hr query) ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/440))
|
- Fix performance issues on server metrics panels 'with metrics range' ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/440)) ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/448))
|
||||||
- Fix no id on import3 servers ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/442))
|
- Fix no id on import3 servers ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/442))
|
||||||
|
- Fix functionality of bedrock update ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/441))
|
||||||
### Tweaks
|
### Tweaks
|
||||||
TBD
|
TBD
|
||||||
### Lang
|
### Lang
|
||||||
|
@ -105,10 +105,9 @@ class ServersController(metaclass=Singleton):
|
|||||||
server_instance.update_server_instance()
|
server_instance.update_server_instance()
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def get_history_stats(self, server_id):
|
def get_history_stats(self, server_id, days):
|
||||||
now = datetime.datetime.now()
|
|
||||||
srv = ServersController().get_server_instance_by_id(server_id)
|
srv = ServersController().get_server_instance_by_id(server_id)
|
||||||
return srv.stats_helper.get_history_stats(server_id)
|
return srv.stats_helper.get_history_stats(server_id, days)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def update_unloaded_server(server_obj):
|
def update_unloaded_server(server_obj):
|
||||||
|
@ -138,8 +138,8 @@ class HelperServerStats:
|
|||||||
)
|
)
|
||||||
return server_data
|
return server_data
|
||||||
|
|
||||||
def get_history_stats(self, server_id):
|
def get_history_stats(self, server_id, num_days):
|
||||||
max_age = datetime.datetime.now() - timedelta(days=1)
|
max_age = datetime.datetime.now() - timedelta(days=num_days)
|
||||||
return (
|
return (
|
||||||
ServerStats.select()
|
ServerStats.select()
|
||||||
.where(ServerStats.created > max_age)
|
.where(ServerStats.created > max_age)
|
||||||
|
@ -64,6 +64,11 @@ class FileHelpers:
|
|||||||
FileHelpers.copy_dir(src_path, dest_path)
|
FileHelpers.copy_dir(src_path, dest_path)
|
||||||
FileHelpers.del_dirs(src_path)
|
FileHelpers.del_dirs(src_path)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def move_dir_exist(src_path, dest_path):
|
||||||
|
FileHelpers.copy_dir(src_path, dest_path, True)
|
||||||
|
FileHelpers.del_dirs(src_path)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def move_file(src_path, dest_path):
|
def move_file(src_path, dest_path):
|
||||||
FileHelpers.copy_file(src_path, dest_path)
|
FileHelpers.copy_file(src_path, dest_path)
|
||||||
@ -290,7 +295,7 @@ class FileHelpers:
|
|||||||
for item in os.listdir(full_root_path):
|
for item in os.listdir(full_root_path):
|
||||||
if os.path.isdir(os.path.join(full_root_path, item)):
|
if os.path.isdir(os.path.join(full_root_path, item)):
|
||||||
try:
|
try:
|
||||||
FileHelpers.move_dir(
|
FileHelpers.move_dir_exist(
|
||||||
os.path.join(full_root_path, item),
|
os.path.join(full_root_path, item),
|
||||||
os.path.join(new_dir, item),
|
os.path.join(new_dir, item),
|
||||||
)
|
)
|
||||||
|
@ -107,6 +107,42 @@ class Helpers:
|
|||||||
logger.error(f"Unable to check for new crafty version! \n{e}")
|
logger.error(f"Unable to check for new crafty version! \n{e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_latest_bedrock_url():
|
||||||
|
"""
|
||||||
|
Get latest bedrock executable url \n\n
|
||||||
|
returns url if successful, False if not
|
||||||
|
"""
|
||||||
|
url = "https://minecraft.net/en-us/download/server/bedrock/"
|
||||||
|
headers = {
|
||||||
|
"Accept-Encoding": "identity",
|
||||||
|
"Accept-Language": "en",
|
||||||
|
"User-Agent": (
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
|
||||||
|
"AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||||
|
"Chrome/104.0.0.0 Safari/537.36"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
target_win = 'https://minecraft.azureedge.net/bin-win/[^"]*'
|
||||||
|
target_linux = 'https://minecraft.azureedge.net/bin-linux/[^"]*'
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Get minecraft server download page
|
||||||
|
# (hopefully the don't change the structure)
|
||||||
|
download_page = get(url, headers=headers)
|
||||||
|
|
||||||
|
# Search for our string targets
|
||||||
|
win_download_url = re.search(target_win, download_page.text).group(0)
|
||||||
|
linux_download_url = re.search(target_linux, download_page.text).group(0)
|
||||||
|
|
||||||
|
if os.name == "nt":
|
||||||
|
return win_download_url
|
||||||
|
|
||||||
|
return linux_download_url
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Unable to resolve remote bedrock download url! \n{e}")
|
||||||
|
return False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def find_java_installs():
|
def find_java_installs():
|
||||||
# If we're windows return oracle java versions,
|
# If we're windows return oracle java versions,
|
||||||
|
@ -3,6 +3,7 @@ import time
|
|||||||
import shutil
|
import shutil
|
||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
|
import urllib
|
||||||
|
|
||||||
from app.classes.controllers.server_perms_controller import PermissionsServers
|
from app.classes.controllers.server_perms_controller import PermissionsServers
|
||||||
from app.classes.controllers.servers_controller import ServersController
|
from app.classes.controllers.servers_controller import ServersController
|
||||||
@ -214,3 +215,43 @@ class ImportHelpers:
|
|||||||
os.chmod(full_jar_path, 0o2760)
|
os.chmod(full_jar_path, 0o2760)
|
||||||
# deletes temp dir
|
# deletes temp dir
|
||||||
FileHelpers.del_dirs(temp_dir)
|
FileHelpers.del_dirs(temp_dir)
|
||||||
|
|
||||||
|
def download_bedrock_server(self, path, new_id):
|
||||||
|
download_thread = threading.Thread(
|
||||||
|
target=self.download_threaded_bedrock_server,
|
||||||
|
daemon=True,
|
||||||
|
args=(path, new_id),
|
||||||
|
name=f"{new_id}_download",
|
||||||
|
)
|
||||||
|
download_thread.start()
|
||||||
|
|
||||||
|
def download_threaded_bedrock_server(self, path, new_id):
|
||||||
|
|
||||||
|
# downloads zip from remote url
|
||||||
|
try:
|
||||||
|
bedrock_url = Helpers.get_latest_bedrock_url()
|
||||||
|
if bedrock_url.lower().startswith("https"):
|
||||||
|
urllib.request.urlretrieve(
|
||||||
|
bedrock_url,
|
||||||
|
os.path.join(path, "bedrock_server.zip"),
|
||||||
|
)
|
||||||
|
|
||||||
|
unzip_path = os.path.join(path, "bedrock_server.zip")
|
||||||
|
unzip_path = self.helper.wtol_path(unzip_path)
|
||||||
|
# unzips archive that was downloaded.
|
||||||
|
FileHelpers.unzip_file(unzip_path)
|
||||||
|
# adjusts permissions for execution if os is not windows
|
||||||
|
if not self.helper.is_os_windows():
|
||||||
|
os.chmod(os.path.join(path, "bedrock_server"), 0o0744)
|
||||||
|
|
||||||
|
# we'll delete the zip we downloaded now
|
||||||
|
os.remove(os.path.join(path, "bedrock_server.zip"))
|
||||||
|
except Exception as e:
|
||||||
|
logger.critical(
|
||||||
|
f"Failed to download bedrock executable during server creation! \n{e}"
|
||||||
|
)
|
||||||
|
|
||||||
|
ServersController.finish_import(new_id)
|
||||||
|
server_users = PermissionsServers.get_server_user_list(new_id)
|
||||||
|
for user in server_users:
|
||||||
|
self.helper.websocket_helper.broadcast_user(user, "send_start_reload", {})
|
||||||
|
@ -697,6 +697,49 @@ class Controller:
|
|||||||
)
|
)
|
||||||
return new_id
|
return new_id
|
||||||
|
|
||||||
|
def create_bedrock_server(self, server_name, user_id):
|
||||||
|
server_id = Helpers.create_uuid()
|
||||||
|
new_server_dir = os.path.join(self.helper.servers_dir, server_id)
|
||||||
|
backup_path = os.path.join(self.helper.backup_path, server_id)
|
||||||
|
server_exe = "bedrock_server"
|
||||||
|
if Helpers.is_os_windows():
|
||||||
|
# if this is windows we will override the linux bedrock server name.
|
||||||
|
server_exe = "bedrock_server.exe"
|
||||||
|
new_server_dir = Helpers.wtol_path(new_server_dir)
|
||||||
|
backup_path = Helpers.wtol_path(backup_path)
|
||||||
|
new_server_dir.replace(" ", "^ ")
|
||||||
|
backup_path.replace(" ", "^ ")
|
||||||
|
|
||||||
|
Helpers.ensure_dir_exists(new_server_dir)
|
||||||
|
Helpers.ensure_dir_exists(backup_path)
|
||||||
|
|
||||||
|
full_jar_path = os.path.join(new_server_dir, server_exe)
|
||||||
|
|
||||||
|
if Helpers.is_os_windows():
|
||||||
|
server_command = f'"{full_jar_path}"'
|
||||||
|
else:
|
||||||
|
server_command = f"./{server_exe}"
|
||||||
|
logger.debug("command: " + server_command)
|
||||||
|
server_log_file = ""
|
||||||
|
server_stop = "stop"
|
||||||
|
|
||||||
|
new_id = self.register_server(
|
||||||
|
server_name,
|
||||||
|
server_id,
|
||||||
|
new_server_dir,
|
||||||
|
backup_path,
|
||||||
|
server_command,
|
||||||
|
server_exe,
|
||||||
|
server_log_file,
|
||||||
|
server_stop,
|
||||||
|
"19132",
|
||||||
|
user_id,
|
||||||
|
server_type="minecraft-bedrock",
|
||||||
|
)
|
||||||
|
ServersController.set_import(new_id)
|
||||||
|
self.import_helper.download_bedrock_server(new_server_dir, new_id)
|
||||||
|
return new_id
|
||||||
|
|
||||||
def import_bedrock_zip_server(
|
def import_bedrock_zip_server(
|
||||||
self,
|
self,
|
||||||
server_name: str,
|
server_name: str,
|
||||||
|
@ -9,6 +9,7 @@ import threading
|
|||||||
import logging.config
|
import logging.config
|
||||||
import subprocess
|
import subprocess
|
||||||
import html
|
import html
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
# TZLocal is set as a hidden import on win pipeline
|
# TZLocal is set as a hidden import on win pipeline
|
||||||
from tzlocal import get_localzone
|
from tzlocal import get_localzone
|
||||||
@ -337,7 +338,7 @@ class ServerInstance:
|
|||||||
"eula =true",
|
"eula =true",
|
||||||
]
|
]
|
||||||
|
|
||||||
if not e_flag:
|
if not e_flag and self.settings["type"] == "minecraft-java":
|
||||||
if user_id:
|
if user_id:
|
||||||
self.helper.websocket_helper.broadcast_user(
|
self.helper.websocket_helper.broadcast_user(
|
||||||
user_id, "send_eula_bootbox", {"id": self.server_id}
|
user_id, "send_eula_bootbox", {"id": self.server_id}
|
||||||
@ -1078,66 +1079,91 @@ class ServerInstance:
|
|||||||
)
|
)
|
||||||
# checks if backup directory already exists
|
# checks if backup directory already exists
|
||||||
if os.path.isdir(backup_dir):
|
if os.path.isdir(backup_dir):
|
||||||
backup_executable = os.path.join(backup_dir, "old_server.jar")
|
backup_executable = os.path.join(backup_dir, self.settings["executable"])
|
||||||
else:
|
else:
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Executable backup directory not found for Server: {self.name}."
|
f"Executable backup directory not found for Server: {self.name}."
|
||||||
f" Creating one."
|
f" Creating one."
|
||||||
)
|
)
|
||||||
os.mkdir(backup_dir)
|
os.mkdir(backup_dir)
|
||||||
backup_executable = os.path.join(backup_dir, "old_server.jar")
|
backup_executable = os.path.join(backup_dir, self.settings["executable"])
|
||||||
|
|
||||||
if os.path.isfile(backup_executable):
|
if len(os.listdir(backup_dir)) > 0:
|
||||||
# removes old backup
|
# removes old backup
|
||||||
logger.info(f"Old backup found for server: {self.name}. Removing...")
|
logger.info(f"Old backups found for server: {self.name}. Removing...")
|
||||||
os.remove(backup_executable)
|
for item in os.listdir(backup_dir):
|
||||||
logger.info(f"Old backup removed for server: {self.name}.")
|
os.remove(os.path.join(backup_dir, item))
|
||||||
else:
|
logger.info(f"Old backups removed for server: {self.name}.")
|
||||||
logger.info(f"No old backups found for server: {self.name}")
|
else:
|
||||||
|
logger.info(f"No old backups found for server: {self.name}")
|
||||||
|
|
||||||
current_executable = os.path.join(
|
current_executable = os.path.join(
|
||||||
Helpers.get_os_understandable_path(self.settings["path"]),
|
Helpers.get_os_understandable_path(self.settings["path"]),
|
||||||
self.settings["executable"],
|
self.settings["executable"],
|
||||||
)
|
)
|
||||||
|
|
||||||
# copies to backup dir
|
try:
|
||||||
FileHelpers.copy_file(current_executable, backup_executable)
|
# copies to backup dir
|
||||||
|
FileHelpers.copy_file(current_executable, backup_executable)
|
||||||
|
except FileNotFoundError:
|
||||||
|
logger.error("Could not create backup of jarfile. File not found.")
|
||||||
|
|
||||||
# boolean returns true for false for success
|
# wait for backup
|
||||||
downloaded = Helpers.download_file(
|
while self.is_backingup:
|
||||||
self.settings["executable_update_url"], current_executable
|
time.sleep(10)
|
||||||
)
|
|
||||||
|
|
||||||
while self.stats_helper.get_server_stats()["updating"]:
|
# check if backup was successful
|
||||||
if downloaded and not self.is_backingup:
|
if self.last_backup_failed:
|
||||||
logger.info("Executable updated successfully. Starting Server")
|
server_users = PermissionsServers.get_server_user_list(self.server_id)
|
||||||
|
for user in server_users:
|
||||||
|
self.helper.websocket_helper.broadcast_user(
|
||||||
|
user,
|
||||||
|
"notification",
|
||||||
|
"Backup failed for " + self.name + ". canceling update.",
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
self.stats_helper.set_update(False)
|
# lets download the files
|
||||||
if len(self.helper.websocket_helper.clients) > 0:
|
if HelperServers.get_server_type_by_id(self.server_id) != "minecraft-bedrock":
|
||||||
# There are clients
|
# boolean returns true for false for success
|
||||||
self.check_update()
|
downloaded = Helpers.download_file(
|
||||||
server_users = PermissionsServers.get_server_user_list(
|
self.settings["executable_update_url"], current_executable
|
||||||
self.server_id
|
)
|
||||||
|
else:
|
||||||
|
# downloads zip from remote url
|
||||||
|
try:
|
||||||
|
bedrock_url = Helpers.get_latest_bedrock_url()
|
||||||
|
if bedrock_url.lower().startswith("https"):
|
||||||
|
urllib.request.urlretrieve(
|
||||||
|
bedrock_url,
|
||||||
|
os.path.join(self.settings["path"], "bedrock_server.zip"),
|
||||||
)
|
)
|
||||||
for user in server_users:
|
|
||||||
self.helper.websocket_helper.broadcast_user(
|
unzip_path = os.path.join(self.settings["path"], "bedrock_server.zip")
|
||||||
user,
|
unzip_path = self.helper.wtol_path(unzip_path)
|
||||||
"notification",
|
# unzips archive that was downloaded.
|
||||||
"Executable update finished for " + self.name,
|
FileHelpers.unzip_file(unzip_path)
|
||||||
)
|
# adjusts permissions for execution if os is not windows
|
||||||
time.sleep(3)
|
if not self.helper.is_os_windows():
|
||||||
self.helper.websocket_helper.broadcast_page(
|
os.chmod(
|
||||||
"/panel/server_detail",
|
os.path.join(self.settings["path"], "bedrock_server"), 0o0744
|
||||||
"update_button_status",
|
|
||||||
{
|
|
||||||
"isUpdating": self.check_update(),
|
|
||||||
"server_id": self.server_id,
|
|
||||||
"wasRunning": was_started,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
self.helper.websocket_helper.broadcast_page(
|
|
||||||
"/panel/dashboard", "send_start_reload", {}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# we'll delete the zip we downloaded now
|
||||||
|
os.remove(os.path.join(self.settings["path"], "bedrock_server.zip"))
|
||||||
|
downloaded = True
|
||||||
|
except Exception as e:
|
||||||
|
logger.critical(
|
||||||
|
f"Failed to download bedrock executable for update \n{e}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if downloaded:
|
||||||
|
logger.info("Executable updated successfully. Starting Server")
|
||||||
|
|
||||||
|
self.stats_helper.set_update(False)
|
||||||
|
if len(self.helper.websocket_helper.clients) > 0:
|
||||||
|
# There are clients
|
||||||
|
self.check_update()
|
||||||
server_users = PermissionsServers.get_server_user_list(self.server_id)
|
server_users = PermissionsServers.get_server_user_list(self.server_id)
|
||||||
for user in server_users:
|
for user in server_users:
|
||||||
self.helper.websocket_helper.broadcast_user(
|
self.helper.websocket_helper.broadcast_user(
|
||||||
@ -1145,29 +1171,52 @@ class ServerInstance:
|
|||||||
"notification",
|
"notification",
|
||||||
"Executable update finished for " + self.name,
|
"Executable update finished for " + self.name,
|
||||||
)
|
)
|
||||||
|
# sleep so first notif can completely run
|
||||||
self.management_helper.add_to_audit_log_raw(
|
time.sleep(3)
|
||||||
"Alert",
|
self.helper.websocket_helper.broadcast_page(
|
||||||
"-1",
|
"/panel/server_detail",
|
||||||
self.server_id,
|
"update_button_status",
|
||||||
"Executable update finished for " + self.name,
|
{
|
||||||
self.settings["server_ip"],
|
"isUpdating": self.check_update(),
|
||||||
|
"server_id": self.server_id,
|
||||||
|
"wasRunning": was_started,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
if was_started:
|
self.helper.websocket_helper.broadcast_page(
|
||||||
self.start_server()
|
"/panel/dashboard", "send_start_reload", {}
|
||||||
elif not downloaded and not self.is_backingup:
|
)
|
||||||
time.sleep(5)
|
self.helper.websocket_helper.broadcast_page(
|
||||||
server_users = PermissionsServers.get_server_user_list(self.server_id)
|
"/panel/server_detail", "remove_spinner", {}
|
||||||
for user in server_users:
|
)
|
||||||
self.helper.websocket_helper.broadcast_user(
|
server_users = PermissionsServers.get_server_user_list(self.server_id)
|
||||||
user,
|
for user in server_users:
|
||||||
"notification",
|
self.helper.websocket_helper.broadcast_user(
|
||||||
"Executable update failed for "
|
user,
|
||||||
+ self.name
|
"notification",
|
||||||
+ ". Check log file for details.",
|
"Executable update finished for " + self.name,
|
||||||
)
|
)
|
||||||
logger.error("Executable download failed.")
|
|
||||||
self.stats_helper.set_update(False)
|
self.management_helper.add_to_audit_log_raw(
|
||||||
|
"Alert",
|
||||||
|
"-1",
|
||||||
|
self.server_id,
|
||||||
|
"Executable update finished for " + self.name,
|
||||||
|
self.settings["server_ip"],
|
||||||
|
)
|
||||||
|
if was_started:
|
||||||
|
self.start_server()
|
||||||
|
else:
|
||||||
|
server_users = PermissionsServers.get_server_user_list(self.server_id)
|
||||||
|
for user in server_users:
|
||||||
|
self.helper.websocket_helper.broadcast_user(
|
||||||
|
user,
|
||||||
|
"notification",
|
||||||
|
"Executable update failed for "
|
||||||
|
+ self.name
|
||||||
|
+ ". Check log file for details.",
|
||||||
|
)
|
||||||
|
logger.error("Executable download failed.")
|
||||||
|
self.stats_helper.set_update(False)
|
||||||
|
|
||||||
# **********************************************************************************
|
# **********************************************************************************
|
||||||
# Minecraft Servers Statistics
|
# Minecraft Servers Statistics
|
||||||
|
@ -756,8 +756,21 @@ class PanelHandler(BaseHandler):
|
|||||||
page_data["backup_path"] = Helpers.wtol_path(server_info["backup_path"])
|
page_data["backup_path"] = Helpers.wtol_path(server_info["backup_path"])
|
||||||
|
|
||||||
if subpage == "metrics":
|
if subpage == "metrics":
|
||||||
|
try:
|
||||||
|
days = int(self.get_argument("days", "1"))
|
||||||
|
except ValueError as e:
|
||||||
|
self.redirect(
|
||||||
|
f"/panel/error?error=Type error: Argument must be an int {e}"
|
||||||
|
)
|
||||||
|
page_data["options"] = [1, 2, 3]
|
||||||
|
if not days in page_data["options"]:
|
||||||
|
page_data["options"].insert(0, days)
|
||||||
|
else:
|
||||||
|
page_data["options"].insert(
|
||||||
|
0, page_data["options"].pop(page_data["options"].index(days))
|
||||||
|
)
|
||||||
page_data["history_stats"] = self.controller.servers.get_history_stats(
|
page_data["history_stats"] = self.controller.servers.get_history_stats(
|
||||||
server_id
|
server_id, days
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_banned_players_html():
|
def get_banned_players_html():
|
||||||
@ -1500,17 +1513,18 @@ class PanelHandler(BaseHandler):
|
|||||||
if Helpers.is_os_windows():
|
if Helpers.is_os_windows():
|
||||||
server_path.replace(" ", "^ ")
|
server_path.replace(" ", "^ ")
|
||||||
server_path = Helpers.wtol_path(server_path)
|
server_path = Helpers.wtol_path(server_path)
|
||||||
log_path = self.get_argument("log_path", None)
|
log_path = self.get_argument("log_path", "")
|
||||||
if Helpers.is_os_windows():
|
if log_path:
|
||||||
log_path.replace(" ", "^ ")
|
if Helpers.is_os_windows():
|
||||||
log_path = Helpers.wtol_path(log_path)
|
log_path.replace(" ", "^ ")
|
||||||
if not self.helper.validate_traversal(server_obj.path, log_path):
|
log_path = Helpers.wtol_path(log_path)
|
||||||
log_path = ""
|
if not self.helper.validate_traversal(server_obj.path, log_path):
|
||||||
|
log_path = ""
|
||||||
executable = self.get_argument("executable", None)
|
executable = self.get_argument("executable", None)
|
||||||
execution_command = self.get_argument("execution_command", None)
|
execution_command = self.get_argument("execution_command", None)
|
||||||
server_ip = self.get_argument("server_ip", None)
|
server_ip = self.get_argument("server_ip", None)
|
||||||
server_port = self.get_argument("server_port", None)
|
server_port = self.get_argument("server_port", None)
|
||||||
executable_update_url = self.get_argument("executable_update_url", None)
|
executable_update_url = self.get_argument("executable_update_url", "")
|
||||||
show_status = int(float(self.get_argument("show_status", "0")))
|
show_status = int(float(self.get_argument("show_status", "0")))
|
||||||
else:
|
else:
|
||||||
execution_command = server_obj.execution_command
|
execution_command = server_obj.execution_command
|
||||||
|
@ -97,6 +97,7 @@ class ServerHandler(BaseHandler):
|
|||||||
"version_data": self.helper.get_version_string(),
|
"version_data": self.helper.get_version_string(),
|
||||||
"user_data": exec_user,
|
"user_data": exec_user,
|
||||||
"user_role": exec_user_role,
|
"user_role": exec_user_role,
|
||||||
|
"online": Helpers.check_internet(),
|
||||||
"roles": list_roles,
|
"roles": list_roles,
|
||||||
"super_user": exec_user["superuser"],
|
"super_user": exec_user["superuser"],
|
||||||
"user_crafty_permissions": exec_user_crafty_permissions,
|
"user_crafty_permissions": exec_user_crafty_permissions,
|
||||||
@ -173,7 +174,6 @@ class ServerHandler(BaseHandler):
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
page_data["online"] = Helpers.check_internet()
|
|
||||||
page_data["server_types"] = self.controller.server_jars.get_serverjar_data()
|
page_data["server_types"] = self.controller.server_jars.get_serverjar_data()
|
||||||
page_data["js_server_types"] = json.dumps(
|
page_data["js_server_types"] = json.dumps(
|
||||||
self.controller.server_jars.get_serverjar_data()
|
self.controller.server_jars.get_serverjar_data()
|
||||||
@ -548,25 +548,14 @@ class ServerHandler(BaseHandler):
|
|||||||
self.get_remote_ip(),
|
self.get_remote_ip(),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
if len(server_parts) != 2:
|
|
||||||
self.redirect("/panel/error?error=Invalid server data")
|
new_server_id = self.controller.create_bedrock_server(
|
||||||
return
|
|
||||||
server_type, server_version = server_parts
|
|
||||||
# TODO: add server type check here and call the correct server
|
|
||||||
# add functions if not a jar
|
|
||||||
new_server_id = self.controller.create_jar_server(
|
|
||||||
server_type,
|
|
||||||
server_version,
|
|
||||||
server_name,
|
server_name,
|
||||||
min_mem,
|
|
||||||
max_mem,
|
|
||||||
port,
|
|
||||||
exec_user["user_id"],
|
exec_user["user_id"],
|
||||||
)
|
)
|
||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
exec_user["user_id"],
|
exec_user["user_id"],
|
||||||
f"created a {server_version} {str(server_type).capitalize()} "
|
"created a Bedrock " f'server named "{server_name}"',
|
||||||
f'server named "{server_name}"',
|
|
||||||
# Example: Admin created a 1.16.5 Bukkit server named "survival"
|
# Example: Admin created a 1.16.5 Bukkit server named "survival"
|
||||||
new_server_id,
|
new_server_id,
|
||||||
self.get_remote_ip(),
|
self.get_remote_ip(),
|
||||||
|
@ -378,7 +378,7 @@
|
|||||||
}
|
}
|
||||||
bootbox.confirm({
|
bootbox.confirm({
|
||||||
title: "{% raw translate('error', 'eulaTitle', data['lang']) %}",
|
title: "{% raw translate('error', 'eulaTitle', data['lang']) %}",
|
||||||
message: "{% raw translate('error', 'eulaMsg', data['lang']) %} <br><br><a href='https://account.mojang.com/documents/minecraft_eula' target='_blank'>EULA</a><br><br>{% raw translate('error', 'eulaAgree', data['lang']) %}",
|
message: "{% raw translate('error', 'eulaMsg', data['lang']) %}<a href='https://www.minecraft.net/en-us/eula' target='_blank'>Minecraft EULA</a>",
|
||||||
buttons: {
|
buttons: {
|
||||||
confirm: {
|
confirm: {
|
||||||
label: 'Yes',
|
label: 'Yes',
|
||||||
|
@ -186,7 +186,8 @@
|
|||||||
|
|
||||||
{% elif server['stats']['updating']%}
|
{% elif server['stats']['updating']%}
|
||||||
<!-- WHAT HAPPENED HERE -->
|
<!-- WHAT HAPPENED HERE -->
|
||||||
<a data-id="{{server['server_data']['server_id']}}" class="">{{ translate('serverTerm', 'updating',
|
<a data-id="{{server['server_data']['server_id']}}" class=""><i
|
||||||
|
class="fa fa-spinner fa-spin"></i> {{ translate('serverTerm', 'updating',
|
||||||
data['lang']) }}</i></a>
|
data['lang']) }}</i></a>
|
||||||
{% elif server['stats']['waiting_start']%}
|
{% elif server['stats']['waiting_start']%}
|
||||||
<!-- WHAT HAPPENED HERE -->
|
<!-- WHAT HAPPENED HERE -->
|
||||||
|
@ -67,7 +67,7 @@
|
|||||||
placeholder="{{ translate('serverConfig', 'serverPath', data['lang']) }}" required>
|
placeholder="{{ translate('serverConfig', 'serverPath', data['lang']) }}" required>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
{% if data['server_stats']['server_type'] != "minecraft-bedrock" %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="log_path">{{ translate('serverConfig', 'serverLogLocation', data['lang']) }} <small
|
<label for="log_path">{{ translate('serverConfig', 'serverLogLocation', data['lang']) }} <small
|
||||||
class="text-muted ml-1"> - {{ translate('serverConfig', 'serverLogLocationDesc', data['lang'])
|
class="text-muted ml-1"> - {{ translate('serverConfig', 'serverLogLocationDesc', data['lang'])
|
||||||
@ -76,6 +76,7 @@
|
|||||||
value="{{ data['server_stats']['server_id']['log_path'] }}"
|
value="{{ data['server_stats']['server_id']['log_path'] }}"
|
||||||
placeholder="{{ translate('serverConfig', 'serverLogLocation', data['lang']) }}" required>
|
placeholder="{{ translate('serverConfig', 'serverLogLocation', data['lang']) }}" required>
|
||||||
</div>
|
</div>
|
||||||
|
{% end %}
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="executable">{{ translate('serverConfig', 'serverExecutable', data['lang']) }} <small
|
<label for="executable">{{ translate('serverConfig', 'serverExecutable', data['lang']) }} <small
|
||||||
@ -138,6 +139,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if data['super_user'] %}
|
{% if data['super_user'] %}
|
||||||
|
{% if data['server_stats']['server_type'] != "minecraft-bedrock" %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="executable_update_url">{{ translate('serverConfig', 'exeUpdateURL', data['lang']) }}
|
<label for="executable_update_url">{{ translate('serverConfig', 'exeUpdateURL', data['lang']) }}
|
||||||
<small class="text-muted ml-1"> - {{ translate('serverConfig', 'exeUpdateURLDesc', data['lang'])
|
<small class="text-muted ml-1"> - {{ translate('serverConfig', 'exeUpdateURLDesc', data['lang'])
|
||||||
@ -146,6 +148,7 @@
|
|||||||
value="{{ data['server_stats']['server_id']['executable_update_url'] }}"
|
value="{{ data['server_stats']['server_id']['executable_update_url'] }}"
|
||||||
placeholder="{{ translate('serverConfig', 'exeUpdateURL', data['lang']) }}">
|
placeholder="{{ translate('serverConfig', 'exeUpdateURL', data['lang']) }}">
|
||||||
</div>
|
</div>
|
||||||
|
{% end %}
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="server_ip">{{ translate('serverConfig', 'serverIP', data['lang']) }} <small
|
<label for="server_ip">{{ translate('serverConfig', 'serverIP', data['lang']) }} <small
|
||||||
@ -250,14 +253,31 @@
|
|||||||
<button onclick="send_command(serverId, 'update_executable');" id="update_executable"
|
<button onclick="send_command(serverId, 'update_executable');" id="update_executable"
|
||||||
style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1 disabled">{{ translate('serverConfig',
|
style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1 disabled">{{ translate('serverConfig',
|
||||||
'update', data['lang']) }}</button>
|
'update', data['lang']) }}</button>
|
||||||
|
{% if data['server_stats']['updating'] %}
|
||||||
|
<button onclick="send_command(serverId, 'update_executable');" id="update_executable"
|
||||||
|
style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1 disabled">{{ translate('serverConfig',
|
||||||
|
'update', data['lang']) }} <i id="update-spinner" class="fa fa-spinner fa-spin"></i></button>
|
||||||
|
{% else %}
|
||||||
|
<button onclick="send_command(serverId, 'update_executable');" id="update_executable"
|
||||||
|
style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1 disabled">{{ translate('serverConfig',
|
||||||
|
'update', data['lang']) }} <i style="visibility: hidden;" id="update-spinner"
|
||||||
|
class="fa fa-spinner fa-spin"></i></button>
|
||||||
|
{% end %}
|
||||||
<a class="btn btn-sm btn-danger disabled">{{ translate('serverConfig', 'deleteServer', data['lang'])
|
<a class="btn btn-sm btn-danger disabled">{{ translate('serverConfig', 'deleteServer', data['lang'])
|
||||||
}}</a><br />
|
}}</a><br />
|
||||||
<small>{{ translate('serverConfig', 'stopBeforeDeleting', data['lang']) }}</small>
|
<small>{{ translate('serverConfig', 'stopBeforeDeleting', data['lang']) }}</small>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if not data['failed'] %}
|
{% if not data['failed'] %}
|
||||||
|
{% if data['server_stats']['updating'] %}
|
||||||
<button onclick="send_command(serverId, 'update_executable');" id="update_executable"
|
<button onclick="send_command(serverId, 'update_executable');" id="update_executable"
|
||||||
style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1">{{ translate('serverConfig',
|
style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1">{{ translate('serverConfig',
|
||||||
'update', data['lang']) }}</button>
|
'update', data['lang']) }} <i id="update-spinner" class="fa fa-spinner fa-spin"></i></button>
|
||||||
|
{% else %}
|
||||||
|
<button onclick="send_command(serverId, 'update_executable');" id="update_executable"
|
||||||
|
style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1">{{ translate('serverConfig',
|
||||||
|
'update', data['lang']) }} <i style="visibility: hidden;" id="update-spinner"
|
||||||
|
class="fa fa-spinner fa-spin"></i></button>
|
||||||
|
{% end %}
|
||||||
{% end %}
|
{% end %}
|
||||||
{% if not data['failed'] %}
|
{% if not data['failed'] %}
|
||||||
<button onclick="deleteConfirm()" class="btn btn-sm btn-danger">{{ translate('serverConfig',
|
<button onclick="deleteConfirm()" class="btn btn-sm btn-danger">{{ translate('serverConfig',
|
||||||
@ -353,6 +373,9 @@
|
|||||||
function send_command(serverId, command) {
|
function send_command(serverId, command) {
|
||||||
//<!-- this getCookie function is in base.html-->
|
//<!-- this getCookie function is in base.html-->
|
||||||
var token = getCookie("_xsrf");
|
var token = getCookie("_xsrf");
|
||||||
|
if (command == "update_executable") {
|
||||||
|
document.getElementById("update-spinner").style.visibility = "visible";
|
||||||
|
}
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "POST",
|
type: "POST",
|
||||||
@ -505,6 +528,12 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
webSocket.on('remove_spinner', function () {
|
||||||
|
document.getElementById("update-spinner").style.visibility = "hidden";
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{% end %}
|
{% end %}
|
@ -38,6 +38,16 @@
|
|||||||
<span class="d-block d-sm-none">
|
<span class="d-block d-sm-none">
|
||||||
{% include "parts/m_server_controls_list.html %}
|
{% include "parts/m_server_controls_list.html %}
|
||||||
</span>
|
</span>
|
||||||
|
<div class="col-2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="days">Metric Period</label>
|
||||||
|
<select required class="form-control form-control-lg select-css" id="days" name="days">
|
||||||
|
{% for value in data['options'] %}
|
||||||
|
<option value="{{value}}">{{value}} Day(s)</option>
|
||||||
|
{% end %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<button style="float: right; visibility: hidden;" class="btn btn-outline-success reset-button"
|
<button style="float: right; visibility: hidden;" class="btn btn-outline-success reset-button"
|
||||||
id="reset-button"><i class="fas fa-undo"></i> {{ translate('serverMetrics', 'resetZoom', data['lang'])
|
id="reset-button"><i class="fas fa-undo"></i> {{ translate('serverMetrics', 'resetZoom', data['lang'])
|
||||||
}}</button>
|
}}</button>
|
||||||
@ -69,6 +79,7 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
const serverId = new URLSearchParams(document.location.search).get('id')
|
||||||
var zoomed = false;
|
var zoomed = false;
|
||||||
//line
|
//line
|
||||||
var ctxL = document.getElementById("lineChart").getContext('2d');
|
var ctxL = document.getElementById("lineChart").getContext('2d');
|
||||||
@ -162,6 +173,10 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
$(window).ready(function () {
|
$(window).ready(function () {
|
||||||
|
$('#days').on("change", function () {
|
||||||
|
let days = $('#days').find(":selected").val();
|
||||||
|
window.location.href = "/panel/server_detail?id=" + serverId + "&days=" + days + "&subpage=metrics"
|
||||||
|
});
|
||||||
$('body').click(function () {
|
$('body').click(function () {
|
||||||
$('.hints').popover("hide");
|
$('.hints').popover("hide");
|
||||||
});
|
});
|
||||||
|
@ -55,7 +55,8 @@
|
|||||||
{% if data['permissions']['Commands'] in data['user_permissions'] %}
|
{% if data['permissions']['Commands'] in data['user_permissions'] %}
|
||||||
{% if data['server_stats']['updating']%}
|
{% if data['server_stats']['updating']%}
|
||||||
<div id="update_control_buttons" class="mt-4 flex-wrap d-flex justify-content-between justify-content-md-center align-items-center px-5 px-md-0" style="visibility: visible">
|
<div id="update_control_buttons" class="mt-4 flex-wrap d-flex justify-content-between justify-content-md-center align-items-center px-5 px-md-0" style="visibility: visible">
|
||||||
<button onclick="" id="start-btn" style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1 disabled">{{ translate('serverTerm', 'updating', data['lang']) }}</button>
|
<button onclick="" id="start-btn" style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1 disabled"><i
|
||||||
|
class="fa fa-spinner fa-spin"></i> {{ translate('serverTerm', 'updating', data['lang']) }}</button>
|
||||||
<button onclick="" id="restart-btn" style="max-width: 7rem;" class="btn btn-outline-primary m-1 flex-grow-1 disabled">{% raw translate('serverTerm', 'restart', data['lang']) %}</button>
|
<button onclick="" id="restart-btn" style="max-width: 7rem;" class="btn btn-outline-primary m-1 flex-grow-1 disabled">{% raw translate('serverTerm', 'restart', data['lang']) %}</button>
|
||||||
<button onclick="" id="stop-btn" style="max-width: 7rem;" class="btn btn-danger m-1 flex-grow-1 disabled">{{ translate('serverTerm', 'stop', data['lang']) }}</button>
|
<button onclick="" id="stop-btn" style="max-width: 7rem;" class="btn btn-danger m-1 flex-grow-1 disabled">{{ translate('serverTerm', 'stop', data['lang']) }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -7,445 +7,575 @@
|
|||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
<ul class="nav nav-tabs col-md-12 tab-simple-styled " role="tablist">
|
<ul class="nav nav-tabs col-md-12 tab-simple-styled " role="tablist">
|
||||||
<li class="nav-item term-nav-item">
|
<li class="nav-item term-nav-item">
|
||||||
<a class="nav-link" href="/server/step1" role="tab" aria-selected="false">
|
<a class="nav-link" href="/server/step1" role="tab" aria-selected="false">
|
||||||
<i class="fas fa-file-signature"></i>Minecraft-Java</a>
|
<i class="fas fa-file-signature"></i>Minecraft-Java</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item term-nav-item">
|
<li class="nav-item term-nav-item">
|
||||||
<a class="nav-link active" href="/server/bedrock_step1" role="tab" aria-selected="false">
|
<a class="nav-link active" href="/server/bedrock_step1" role="tab" aria-selected="false">
|
||||||
<i class="fas fa-file-signature"></i>Minecraft-Bedrock</a>
|
<i class="fas fa-file-signature"></i>Minecraft-Bedrock</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
<div class="d-none" id="overlay" onclick="hide(event)"></div>
|
<div class="d-none" id="overlay" onclick="hide(event)"></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6 grid-margin stretch-card">
|
{% if data['online'] %}
|
||||||
<div class="card">
|
<div class="col-sm-6 grid-margin stretch-card">
|
||||||
<div class="card-body">
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
<h4>{{ translate('serverWizard', 'importServer', data['lang']) }}</h4>
|
|
||||||
<br />
|
|
||||||
<p class="card-description">
|
|
||||||
|
|
||||||
<form method="post" class="server-wizard" onSubmit="wait_msg(true)">
|
|
||||||
{% raw xsrf_form_html() %}
|
|
||||||
<input type="hidden" value="import_jar" name="create_type">
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="server_name">{{ translate('serverWizard', 'serverName', data['lang']) }}</label>
|
|
||||||
<input type="text" class="form-control" id="server_name" name="server_name" value="" placeholder="{{ translate('serverWizard', 'myNewServer', data['lang']) }}" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="server">{{ translate('serverWizard', 'serverPath', data['lang']) }} <small>{{ translate('serverWizard', 'absoluteServerPath', data['lang']) }}</small></label>
|
|
||||||
<input type="text" class="form-control" id="server_path" name="server_path" placeholder="/var/opt/server" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="server_jar">{{ translate('serverWizard', 'serverJar', data['lang']) }}</label>
|
|
||||||
<input type="text" class="form-control" id="server_jar" name="server_jar" value="" placeholder="bedrock_server" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<h4>{{ translate('serverWizard', 'newServer', data['lang']) }}</h4>
|
||||||
|
<br />
|
||||||
|
<p class="card-description">
|
||||||
|
|
||||||
|
<form method="post" name="create_server" class="server-wizard" onSubmit="wait_msg()">
|
||||||
|
{% raw xsrf_form_html() %}
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-sm-12 col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="server_name">{{ translate('serverWizard', 'serverName', data['lang']) }}</label>
|
||||||
|
<input type="text" class="form-control" id="server_name" name="server_name"
|
||||||
|
placeholder="{{ translate('serverWizard', 'myNewServer', data['lang']) }}" required>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
</div>
|
||||||
<h4 class="card-title">{{ translate('serverWizard', 'quickSettings', data['lang']) }} <small style="text-transform: none;"> - {{ translate('serverWizard', 'quickSettingsDescription', data['lang']) }}</small></h4>
|
|
||||||
<hr>
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<div class="col-sm-12">
|
</div>
|
||||||
<div class="form-group">
|
|
||||||
<label for="port2">{{ translate('serverWizard', 'serverPort', data['lang']) }} <small></small></label>
|
<div class="col-sm-12">
|
||||||
<input type="number" class="form-control" id="port2" name="port" value="19132" step="1" min="1" required>
|
<div class="form-group">
|
||||||
|
<div id="accordion-1">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header p-2" id="Role-1">
|
||||||
|
<p class="mb-0 p-0" data-toggle="collapse" data-target="#collapseRole-1" aria-expanded="true"
|
||||||
|
aria-controls="collapseRole-1">
|
||||||
|
<i class="fas fa-chevron-down"></i> {{ translate('serverWizard', 'addRole', data['lang']) }}
|
||||||
|
<small style="text-transform: none;"> - {{ translate('serverWizard', 'autoCreate',
|
||||||
|
data['lang']) }}</small>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div id="collapseRole-1" class="collapse" aria-labelledby="Role-1" data-parent="">
|
||||||
<div class="col-sm-12">
|
<div class="card-body scroll">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div id="accordion-2">
|
{% for r in data['roles'] %}
|
||||||
<div class="card">
|
<span class="d-block menu-option"><label><input name="{{ r['role_id'] }}"
|
||||||
<div class="card-header p-2" id="Role-2">
|
type="checkbox">
|
||||||
<p class="mb-0 p-0" data-toggle="collapse" data-target="#collapseRole-2" aria-expanded="true" aria-controls="collapseRole-2">
|
{{ r['role_name'].capitalize() }}</label></span>
|
||||||
<i class="fas fa-chevron-down"></i> {{ translate('serverWizard', 'addRole', data['lang']) }} <small style="text-transform: none;"> - {{ translate('serverWizard', 'autoCreate', data['lang']) }}</small>
|
{% end %}
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div id="collapseRole-2" class="collapse" aria-labelledby="Role-2" data-parent="">
|
|
||||||
<div class="card-body scroll">
|
|
||||||
<div class="form-group">
|
|
||||||
{% for r in data['roles'] %}
|
|
||||||
<span class="d-block menu-option"><label><input name="{{ r['role_id'] }}" type="checkbox">
|
|
||||||
{{ r['role_name'].capitalize() }}</label></span>
|
|
||||||
{% end %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary mr-2">{{ translate('serverWizard', 'importServerButton', data['lang']) }}</button>
|
</div>
|
||||||
<button type="reset" class="btn btn-danger mr-2">{{ translate('serverWizard', 'resetForm', data['lang']) }}</button>
|
</div>
|
||||||
|
<button onclick="eula_confirm()" type="button" class="btn btn-primary mr-2">{{ translate('serverWizard',
|
||||||
</form>
|
'buildServer',
|
||||||
</p>
|
data['lang']) }}</button>
|
||||||
</div>
|
<button type="reset" class="btn btn-danger mr-2">{{ translate('serverWizard', 'resetForm', data['lang'])
|
||||||
|
}}</button>
|
||||||
</div>
|
</div>
|
||||||
|
</form>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6 grid-margin stretch-card">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
|
|
||||||
<h4>{{ translate('serverWizard', 'importZip', data['lang']) }}</h4>
|
|
||||||
<br />
|
|
||||||
<p class="card-description">
|
|
||||||
|
|
||||||
<form name="zip" method="post" class="server-wizard" onSubmit="wait_msg(true)">
|
|
||||||
{% raw xsrf_form_html() %}
|
|
||||||
<input type="hidden" value="import_zip" name="create_type">
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="server_name">{{ translate('serverWizard', 'serverName', data['lang']) }}</label>
|
|
||||||
<input type="text" class="form-control" id="server_name" name="server_name" value="" placeholder="{{ translate('serverWizard', 'myNewServer', data['lang']) }}" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="server">{{ translate('serverWizard', 'zipPath', data['lang']) }} <small>{{ translate('serverWizard', 'absoluteZipPath', data['lang']) }}</small></label>
|
|
||||||
<input type="text" class="form-control" id="server_path" name="server_path" placeholder="/var/opt/server.zip" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="server">{{ translate('serverWizard', 'selectRoot', data['lang']) }} <small>{{ translate('serverWizard', 'explainRoot', data['lang']) }}</small></label>
|
|
||||||
<br>
|
|
||||||
<button class="btn btn-primary mr-2" id="root_files_button" type="button">{{ translate('serverWizard', 'clickRoot', data['lang']) }}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="server_jar">{{ translate('serverWizard', 'serverJar', data['lang']) }}</label>
|
|
||||||
<input type="text" class="form-control" id="server_jar" name="server_jar" value="" placeholder="bedrock_server" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
{% end %}
|
||||||
|
<div class="col-sm-6 grid-margin stretch-card">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
|
||||||
|
<h4>{{ translate('serverWizard', 'importServer', data['lang']) }}</h4>
|
||||||
|
<br />
|
||||||
|
<p class="card-description">
|
||||||
|
|
||||||
|
<form method="post" class="server-wizard" onSubmit="wait_msg(true)">
|
||||||
|
{% raw xsrf_form_html() %}
|
||||||
|
<input type="hidden" value="import_jar" name="create_type">
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="server_name">{{ translate('serverWizard', 'serverName', data['lang']) }}</label>
|
||||||
|
<input type="text" class="form-control" id="server_name" name="server_name" value=""
|
||||||
|
placeholder="{{ translate('serverWizard', 'myNewServer', data['lang']) }}" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="server">{{ translate('serverWizard', 'serverPath', data['lang']) }} <small>{{
|
||||||
|
translate('serverWizard', 'absoluteServerPath', data['lang']) }}</small></label>
|
||||||
|
<input type="text" class="form-control" id="server_path" name="server_path"
|
||||||
|
placeholder="/var/opt/server" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="server_jar">{{ translate('serverWizard', 'serverJar', data['lang']) }}</label>
|
||||||
|
<input type="text" class="form-control" id="server_jar" name="server_jar" value=""
|
||||||
|
placeholder="bedrock_server" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col-sm-12">
|
</div>
|
||||||
<h4 class="card-title">{{ translate('serverWizard', 'quickSettings', data['lang']) }} <small style="text-transform: none;"> - {{ translate('serverWizard', 'quickSettingsDescription', data['lang']) }}</small></h4>
|
<br />
|
||||||
<hr>
|
<h4 class="card-title">{{ translate('serverWizard', 'quickSettings', data['lang']) }} <small
|
||||||
<div class="row">
|
style="text-transform: none;"> - {{ translate('serverWizard', 'quickSettingsDescription',
|
||||||
|
data['lang']) }}</small></h4>
|
||||||
|
<hr>
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="port3">{{ translate('serverWizard', 'serverPort', data['lang']) }} <small></small></label>
|
<label for="port2">{{ translate('serverWizard', 'serverPort', data['lang']) }}
|
||||||
<input type="number" class="form-control" id="port3" name="port" value="19132" step="1" min="1" required>
|
<small></small></label>
|
||||||
</div>
|
<input type="number" class="form-control" id="port2" name="port" value="19132" step="1" min="1"
|
||||||
|
required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<div id="accordion-2">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header p-2" id="Role-2">
|
||||||
|
<p class="mb-0 p-0" data-toggle="collapse" data-target="#collapseRole-2" aria-expanded="true"
|
||||||
|
aria-controls="collapseRole-2">
|
||||||
|
<i class="fas fa-chevron-down"></i> {{ translate('serverWizard', 'addRole', data['lang']) }}
|
||||||
|
<small style="text-transform: none;"> - {{ translate('serverWizard', 'autoCreate',
|
||||||
|
data['lang']) }}</small>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="collapseRole-2" class="collapse" aria-labelledby="Role-2" data-parent="">
|
||||||
<div class="col-sm-12">
|
<div class="card-body scroll">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div id="accordion-3">
|
{% for r in data['roles'] %}
|
||||||
<div class="card">
|
<span class="d-block menu-option"><label><input name="{{ r['role_id'] }}"
|
||||||
<div class="card-header p-2" id="Role-3">
|
type="checkbox">
|
||||||
<p class="mb-0 p-0" data-toggle="collapse" data-target="#collapseRole-3" aria-expanded="true" aria-controls="collapseRole-3">
|
{{ r['role_name'].capitalize() }}</label></span>
|
||||||
<i class="fas fa-chevron-down"></i> {{ translate('serverWizard', 'addRole', data['lang']) }} <small style="text-transform: none;"> - {{ translate('serverWizard', 'autoCreate', data['lang']) }}</small>
|
{% end %}
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div id="collapseRole-3" class="collapse" aria-labelledby="Role-3" data-parent="">
|
|
||||||
<div class="card-body scroll">
|
|
||||||
<div class="form-group">
|
|
||||||
{% for r in data['roles'] %}
|
|
||||||
<span class="d-block menu-option"><label><input name="{{ r['role_id'] }}" type="checkbox">
|
|
||||||
{{ r['role_name'].capitalize() }}</label></span>
|
|
||||||
{% end %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-12" style="visibility: hidden;">
|
</div>
|
||||||
<div class="form-group">
|
</div>
|
||||||
<input type="text" class="form-control" id="zip_root_path" name="zip_root_path">
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary mr-2">{{ translate('serverWizard', 'importServerButton',
|
||||||
|
data['lang']) }}</button>
|
||||||
|
<button type="reset" class="btn btn-danger mr-2">{{ translate('serverWizard', 'resetForm', data['lang'])
|
||||||
|
}}</button>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6 grid-margin stretch-card">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
|
||||||
|
<h4>{{ translate('serverWizard', 'importZip', data['lang']) }}</h4>
|
||||||
|
<br />
|
||||||
|
<p class="card-description">
|
||||||
|
|
||||||
|
<form name="zip" method="post" class="server-wizard" onSubmit="wait_msg(true)">
|
||||||
|
{% raw xsrf_form_html() %}
|
||||||
|
<input type="hidden" value="import_zip" name="create_type">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="server_name">{{ translate('serverWizard', 'serverName', data['lang']) }}</label>
|
||||||
|
<input type="text" class="form-control" id="server_name" name="server_name" value=""
|
||||||
|
placeholder="{{ translate('serverWizard', 'myNewServer', data['lang']) }}" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="server">{{ translate('serverWizard', 'zipPath', data['lang']) }} <small>{{
|
||||||
|
translate('serverWizard', 'absoluteZipPath', data['lang']) }}</small></label>
|
||||||
|
<input type="text" class="form-control" id="server_path" name="server_path"
|
||||||
|
placeholder="/var/opt/server.zip" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="server">{{ translate('serverWizard', 'selectRoot', data['lang']) }} <small>{{
|
||||||
|
translate('serverWizard', 'explainRoot', data['lang']) }}</small></label>
|
||||||
|
<br>
|
||||||
|
<button class="btn btn-primary mr-2" id="root_files_button" type="button">{{
|
||||||
|
translate('serverWizard', 'clickRoot', data['lang']) }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="server_jar">{{ translate('serverWizard', 'serverJar', data['lang']) }}</label>
|
||||||
|
<input type="text" class="form-control" id="server_jar" name="server_jar" value=""
|
||||||
|
placeholder="bedrock_server" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<h4 class="card-title">{{ translate('serverWizard', 'quickSettings', data['lang']) }} <small
|
||||||
|
style="text-transform: none;"> - {{ translate('serverWizard', 'quickSettingsDescription',
|
||||||
|
data['lang']) }}</small></h4>
|
||||||
|
<hr>
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="port3">{{ translate('serverWizard', 'serverPort', data['lang']) }}
|
||||||
|
<small></small></label>
|
||||||
|
<input type="number" class="form-control" id="port3" name="port" value="19132" step="1" min="1"
|
||||||
|
required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<div id="accordion-3">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header p-2" id="Role-3">
|
||||||
|
<p class="mb-0 p-0" data-toggle="collapse" data-target="#collapseRole-3" aria-expanded="true"
|
||||||
|
aria-controls="collapseRole-3">
|
||||||
|
<i class="fas fa-chevron-down"></i> {{ translate('serverWizard', 'addRole', data['lang'])
|
||||||
|
}} <small style="text-transform: none;"> - {{ translate('serverWizard', 'autoCreate',
|
||||||
|
data['lang']) }}</small>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div id="collapseRole-3" class="collapse" aria-labelledby="Role-3" data-parent="">
|
||||||
<div class="modal fade" id="dir_select" tabindex="-1" role="dialog" aria-labelledby="dir_select" aria-hidden="true">
|
<div class="card-body scroll">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="form-group">
|
||||||
<div class="modal-content">
|
{% for r in data['roles'] %}
|
||||||
<div class="modal-header">
|
<span class="d-block menu-option"><label><input name="{{ r['role_id'] }}"
|
||||||
<h5 class="modal-title" id="exampleModalLongTitle">{{ translate('serverWizard', 'selectZipDir', data['lang']) }}</h5>
|
type="checkbox">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
{{ r['role_name'].capitalize() }}</label></span>
|
||||||
<span aria-hidden="true">×</span>
|
{% end %}
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<div class="tree-ctx-item" id="main-tree-div" data-path="" style="overflow: scroll; max-height:75%;">
|
|
||||||
<input type="radio" id="main-tree-input" name="root_path" value="" checked>
|
|
||||||
<span id="main-tree" class="files-tree-title tree-caret-down root-dir" data-path="">
|
|
||||||
<i class="far fa-folder"></i>
|
|
||||||
<i class="far fa-folder-open"></i>
|
|
||||||
{{ translate('serverFiles', 'files', data['lang']) }}
|
|
||||||
</span>
|
|
||||||
</input>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{ translate('serverWizard', 'close', data['lang']) }}</button>
|
|
||||||
<button type="button" id="modal-okay" data-dismiss="modal" class="btn btn-primary">{{ translate('serverWizard', 'save', data['lang']) }}</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button id="zip_submit" type="submit" title="You must select server root dir first" disabled class="btn btn-primary mr-2">{{ translate('serverWizard', 'importServerButton', data['lang']) }}</button>
|
|
||||||
<button type="reset" class="btn btn-danger mr-2">{{ translate('serverWizard', 'resetForm', data['lang']) }}</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
<div class="col-sm-12" style="visibility: hidden;">
|
||||||
</p>
|
<div class="form-group">
|
||||||
</div>
|
<input type="text" class="form-control" id="zip_root_path" name="zip_root_path">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal fade" id="dir_select" tabindex="-1" role="dialog" aria-labelledby="dir_select"
|
||||||
|
aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLongTitle">{{ translate('serverWizard',
|
||||||
|
'selectZipDir', data['lang']) }}</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="tree-ctx-item" id="main-tree-div" data-path=""
|
||||||
|
style="overflow: scroll; max-height:75%;">
|
||||||
|
<input type="radio" id="main-tree-input" name="root_path" value="" checked>
|
||||||
|
<span id="main-tree" class="files-tree-title tree-caret-down root-dir" data-path="">
|
||||||
|
<i class="far fa-folder"></i>
|
||||||
|
<i class="far fa-folder-open"></i>
|
||||||
|
{{ translate('serverFiles', 'files', data['lang']) }}
|
||||||
|
</span>
|
||||||
|
</input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{
|
||||||
|
translate('serverWizard', 'close', data['lang']) }}</button>
|
||||||
|
<button type="button" id="modal-okay" data-dismiss="modal" class="btn btn-primary">{{
|
||||||
|
translate('serverWizard', 'save', data['lang']) }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button id="zip_submit" type="submit" title="You must select server root dir first" disabled
|
||||||
|
class="btn btn-primary mr-2">{{ translate('serverWizard', 'importServerButton', data['lang'])
|
||||||
|
}}</button>
|
||||||
|
<button type="reset" class="btn btn-danger mr-2">{{ translate('serverWizard', 'resetForm', data['lang'])
|
||||||
|
}}</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</form>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.scroll {
|
.scroll {
|
||||||
max-height: 12em;
|
max-height: 12em;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
.menu-btn {
|
|
||||||
|
.menu-btn {
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
padding: 2px 10px;
|
padding: 2px 10px;
|
||||||
}
|
}
|
||||||
.menu {
|
|
||||||
|
.menu {
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
z-index: 200;
|
z-index: 200;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background-color: #2a2c44;
|
background-color: #2a2c44;
|
||||||
}
|
}
|
||||||
.menu-option {
|
|
||||||
|
.menu-option {
|
||||||
padding: 6px 20px 6px;
|
padding: 6px 20px 6px;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
#overlay {
|
|
||||||
|
#overlay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<style>
|
<style>
|
||||||
/* Remove default bullets */
|
/* Remove default bullets */
|
||||||
.tree-view,
|
.tree-view,
|
||||||
.tree-nested {
|
.tree-nested {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Style the items */
|
/* Style the items */
|
||||||
.tree-item,
|
.tree-item,
|
||||||
.files-tree-title {
|
.files-tree-title {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
user-select: none; /* Prevent text selection */
|
user-select: none;
|
||||||
}
|
/* Prevent text selection */
|
||||||
|
}
|
||||||
|
|
||||||
/* Create the caret/arrow with a unicode, and style it */
|
/* Create the caret/arrow with a unicode, and style it */
|
||||||
.tree-caret .fa-folder {
|
.tree-caret .fa-folder {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
.tree-caret .fa-folder-open {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Rotate the caret/arrow icon when clicked on (using JavaScript) */
|
.tree-caret .fa-folder-open {
|
||||||
.tree-caret-down .fa-folder {
|
display: none;
|
||||||
display: none;
|
}
|
||||||
}
|
|
||||||
.tree-caret-down .fa-folder-open {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hide the nested list */
|
/* Rotate the caret/arrow icon when clicked on (using JavaScript) */
|
||||||
.tree-nested {
|
.tree-caret-down .fa-folder {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tree-caret-down .fa-folder-open {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide the nested list */
|
||||||
|
.tree-nested {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
{% end %}
|
{% end %}
|
||||||
|
|
||||||
{% block js%}
|
{% block js%}
|
||||||
<script>
|
<script>
|
||||||
document.getElementById("root_files_button").addEventListener("click", function(){
|
function eula_confirm() {
|
||||||
if(document.forms["zip"]["server_path"].value != ""){
|
bootbox.confirm({
|
||||||
if(document.getElementById('root_files_button').classList.contains('clicked')){
|
title: "{% raw translate('error', 'eulaTitle', data['lang']) %}",
|
||||||
|
message: "{% raw translate('error', 'eulaMsg', data['lang']) %}<a href='https://www.minecraft.net/en-us/eula' target='_blank'>Minecraft EULA</a> {% raw translate('error', 'privMsg', data['lang']) %}<a target='_blank' href='https://privacy.microsoft.com/en-us/privacystatement'>Microsoft Privacy Policy</a>",
|
||||||
|
buttons: {
|
||||||
|
confirm: {
|
||||||
|
label: "{% raw translate('error', 'agree', data['lang']) %}",
|
||||||
|
className: 'btn-info'
|
||||||
|
},
|
||||||
|
cancel: {
|
||||||
|
label: "{% raw translate('error', 'cancel', data['lang']) %}",
|
||||||
|
className: 'btn-secondary'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
callback: function (result) {
|
||||||
|
if (result == true) {
|
||||||
|
document.create_server.submit();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
document.getElementById("root_files_button").addEventListener("click", function () {
|
||||||
|
if (document.forms["zip"]["server_path"].value != "") {
|
||||||
|
if (document.getElementById('root_files_button').classList.contains('clicked')) {
|
||||||
document.getElementById('main-tree-div').innerHTML = '<input type="radio" id="main-tree-input" name="root_path" value="" checked><span id="main-tree" class="files-tree-title tree-caret-down root-dir" data-path=""><i class="far fa-folder"></i><i class="far fa-folder-open"></i>{{ translate('serverFiles', 'files', data['lang']) }}</span></input>'
|
document.getElementById('main-tree-div').innerHTML = '<input type="radio" id="main-tree-input" name="root_path" value="" checked><span id="main-tree" class="files-tree-title tree-caret-down root-dir" data-path=""><i class="far fa-folder"></i><i class="far fa-folder-open"></i>{{ translate('serverFiles', 'files', data['lang']) }}</span></input>'
|
||||||
}else{
|
} else {
|
||||||
document.getElementById('root_files_button').classList.add('clicked')
|
document.getElementById('root_files_button').classList.add('clicked')
|
||||||
}
|
}
|
||||||
path = document.forms["zip"]["server_path"].value;
|
path = document.forms["zip"]["server_path"].value;
|
||||||
console.log(document.forms["zip"]["server_path"].value)
|
console.log(document.forms["zip"]["server_path"].value)
|
||||||
var token = getCookie("_xsrf");
|
var token = getCookie("_xsrf");
|
||||||
var dialog = bootbox.dialog({
|
var dialog = bootbox.dialog({
|
||||||
message: '<p class="text-center mb-0"><i class="fa fa-spin fa-cog"></i> Please wait while we gather your files...</p>',
|
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
|
closeButton: false
|
||||||
});
|
});
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "POST",
|
type: "POST",
|
||||||
headers: {'X-XSRFToken': token},
|
headers: { 'X-XSRFToken': token },
|
||||||
url: '/ajax/unzip_server?id=-1&path='+path,
|
url: '/ajax/unzip_server?id=-1&path=' + path,
|
||||||
});
|
});
|
||||||
}else{
|
} else {
|
||||||
bootbox.alert("You must input a path before selecting this button");
|
bootbox.alert("You must input a path before selecting this button");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function dropDown(event) {
|
function dropDown(event) {
|
||||||
event.target.parentElement.children[1].classList.remove("d-none");
|
event.target.parentElement.children[1].classList.remove("d-none");
|
||||||
document.getElementById("overlay").classList.remove("d-none");
|
document.getElementById("overlay").classList.remove("d-none");
|
||||||
}
|
}
|
||||||
function hide(event) {
|
function hide(event) {
|
||||||
var items = document.getElementsByClassName('menu');
|
var items = document.getElementsByClassName('menu');
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
items[i].classList.add("d-none");
|
items[i].classList.add("d-none");
|
||||||
}
|
}
|
||||||
document.getElementById("overlay").classList.add("d-none");
|
document.getElementById("overlay").classList.add("d-none");
|
||||||
}
|
|
||||||
|
|
||||||
function wait_msg(importing){
|
|
||||||
bootbox.alert({
|
|
||||||
title: importing ? '{% raw translate("serverWizard", "importing", data['lang']) %}' : '{% raw translate("serverWizard", "downloading", data['lang']) %}',
|
|
||||||
message: '<i class="fas fa-cloud-download"></i> {% raw translate("serverWizard", "bePatient", data['lang']) %}',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function show_file_tree(){
|
function wait_msg(importing) {
|
||||||
|
bootbox.alert({
|
||||||
|
title: importing ? '{% raw translate("serverWizard", "importing", data['lang']) %}': '{% raw translate("serverWizard", "downloading", data['lang']) %}',
|
||||||
|
message: '<i class="fas fa-cloud-download"></i> {% raw translate("serverWizard", "bePatient", data['lang']) %}',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function show_file_tree() {
|
||||||
$("#dir_select").modal();
|
$("#dir_select").modal();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTreeView(path) {
|
function getTreeView(path) {
|
||||||
document.getElementById('zip_submit').disabled = false;
|
document.getElementById('zip_submit').disabled = false;
|
||||||
path = path
|
path = path
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "GET",
|
type: "GET",
|
||||||
url: '/ajax/get_zip_tree?id=-1&path='+path,
|
url: '/ajax/get_zip_tree?id=-1&path=' + path,
|
||||||
dataType: 'text',
|
dataType: 'text',
|
||||||
success: function(data){
|
success: function (data) {
|
||||||
console.log("got response:");
|
console.log("got response:");
|
||||||
console.log(data);
|
console.log(data);
|
||||||
|
|
||||||
dataArr = data.split('\n');
|
dataArr = data.split('\n');
|
||||||
serverDir = dataArr.shift(); // Remove & return first element (server directory)
|
serverDir = dataArr.shift(); // Remove & return first element (server directory)
|
||||||
text = dataArr.join('\n');
|
text = dataArr.join('\n');
|
||||||
|
|
||||||
try{
|
try {
|
||||||
document.getElementById('main-tree-div').innerHTML += text;
|
document.getElementById('main-tree-div').innerHTML += text;
|
||||||
document.getElementById('main-tree').parentElement.classList.add("clicked");
|
document.getElementById('main-tree').parentElement.classList.add("clicked");
|
||||||
}catch{
|
} catch {
|
||||||
document.getElementById('files-tree').innerHTML = text;
|
document.getElementById('files-tree').innerHTML = text;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
document.getElementsByClassName('files-tree-title')[0].setAttribute('data-path', serverDir);
|
|
||||||
document.getElementsByClassName('files-tree-title')[0].setAttribute('data-name', 'Files');
|
|
||||||
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getToggleMain(event) {
|
|
||||||
path = event.target.parentElement.getAttribute('data-path');
|
|
||||||
document.getElementById("files-tree").classList.toggle("d-block");
|
|
||||||
document.getElementById(path+"span").classList.toggle("tree-caret-down");
|
|
||||||
document.getElementById(path+"span").classList.toggle("tree-caret");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function getDirView(event) {
|
|
||||||
path = event.target.parentElement.getAttribute('data-path');
|
|
||||||
|
|
||||||
if (document.getElementById(path).classList.contains('clicked')){
|
|
||||||
|
|
||||||
var toggler = document.getElementById(path+"span");
|
|
||||||
|
|
||||||
if (toggler.classList.contains('files-tree-title')){
|
|
||||||
document.getElementById(path+"ul").classList.toggle("d-block");
|
|
||||||
document.getElementById(path+"span").classList.toggle("tree-caret-down");
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}else{
|
|
||||||
|
document.getElementsByClassName('files-tree-title')[0].setAttribute('data-path', serverDir);
|
||||||
|
document.getElementsByClassName('files-tree-title')[0].setAttribute('data-name', 'Files');
|
||||||
|
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getToggleMain(event) {
|
||||||
|
path = event.target.parentElement.getAttribute('data-path');
|
||||||
|
document.getElementById("files-tree").classList.toggle("d-block");
|
||||||
|
document.getElementById(path + "span").classList.toggle("tree-caret-down");
|
||||||
|
document.getElementById(path + "span").classList.toggle("tree-caret");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getDirView(event) {
|
||||||
|
path = event.target.parentElement.getAttribute('data-path');
|
||||||
|
|
||||||
|
if (document.getElementById(path).classList.contains('clicked')) {
|
||||||
|
|
||||||
|
var toggler = document.getElementById(path + "span");
|
||||||
|
|
||||||
|
if (toggler.classList.contains('files-tree-title')) {
|
||||||
|
document.getElementById(path + "ul").classList.toggle("d-block");
|
||||||
|
document.getElementById(path + "span").classList.toggle("tree-caret-down");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "GET",
|
type: "GET",
|
||||||
url: '/ajax/get_zip_dir?id=-1&path='+path,
|
url: '/ajax/get_zip_dir?id=-1&path=' + path,
|
||||||
dataType: 'text',
|
dataType: 'text',
|
||||||
success: function(data){
|
success: function (data) {
|
||||||
console.log("got response:");
|
console.log("got response:");
|
||||||
|
|
||||||
dataArr = data.split('\n');
|
dataArr = data.split('\n');
|
||||||
serverDir = dataArr.shift(); // Remove & return first element (server directory)
|
serverDir = dataArr.shift(); // Remove & return first element (server directory)
|
||||||
text = dataArr.join('\n');
|
text = dataArr.join('\n');
|
||||||
|
|
||||||
try{
|
try {
|
||||||
document.getElementById(path+"span").classList.add('tree-caret-down');
|
document.getElementById(path + "span").classList.add('tree-caret-down');
|
||||||
document.getElementById(path).innerHTML += text;
|
document.getElementById(path).innerHTML += text;
|
||||||
document.getElementById(path).classList.add("clicked");
|
document.getElementById(path).classList.add("clicked");
|
||||||
}catch{
|
} catch {
|
||||||
console.log("Bad")
|
console.log("Bad")
|
||||||
}
|
}
|
||||||
|
|
||||||
var toggler = document.getElementById(path);
|
var toggler = document.getElementById(path);
|
||||||
|
|
||||||
if (toggler.classList.contains('files-tree-title')){
|
if (toggler.classList.contains('files-tree-title')) {
|
||||||
document.getElementById(path+"span").addEventListener("click", function caretListener() {
|
document.getElementById(path + "span").addEventListener("click", function caretListener() {
|
||||||
document.getElementById(path+"ul").classList.toggle("d-block");
|
document.getElementById(path + "ul").classList.toggle("d-block");
|
||||||
document.getElementById(path+"span").classList.toggle("tree-caret-down");
|
document.getElementById(path + "span").classList.toggle("tree-caret-down");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (webSocket) {
|
if (webSocket) {
|
||||||
webSocket.on('send_temp_path', function (data) {
|
webSocket.on('send_temp_path', function (data) {
|
||||||
setTimeout(function(){
|
setTimeout(function () {
|
||||||
var x = document.querySelector('.bootbox');
|
var x = document.querySelector('.bootbox');
|
||||||
if (x) {
|
if (x) {
|
||||||
x.remove()
|
x.remove()
|
||||||
}
|
}
|
||||||
var x = document.querySelector('.modal-backdrop');
|
var x = document.querySelector('.modal-backdrop');
|
||||||
if (x) {
|
if (x) {
|
||||||
x.remove()
|
x.remove()
|
||||||
}
|
}
|
||||||
document.getElementById('main-tree-input').setAttribute('value', data.path)
|
document.getElementById('main-tree-input').setAttribute('value', data.path)
|
||||||
getTreeView(data.path);
|
getTreeView(data.path);
|
||||||
show_file_tree();
|
show_file_tree();
|
||||||
|
|
||||||
}, 5000);
|
}, 5000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
{% end %}
|
{% end %}
|
@ -168,7 +168,7 @@
|
|||||||
"embarassing": "Oh je, das ist peinlich.",
|
"embarassing": "Oh je, das ist peinlich.",
|
||||||
"error": "Fehler!",
|
"error": "Fehler!",
|
||||||
"eulaAgree": "Stimmen Sie zu?",
|
"eulaAgree": "Stimmen Sie zu?",
|
||||||
"eulaMsg": "Sie müssen der EULA zustimmen. Eine Kopie der Mojang EULA ist unter dieser Nachricht verlinkt.",
|
"eulaMsg": "Sie müssen der EULA zustimmen. Eine Kopie der Minecraft EULA ist unter dieser Nachricht verlinkt.",
|
||||||
"eulaTitle": "Der EULA zustimmen",
|
"eulaTitle": "Der EULA zustimmen",
|
||||||
"hereIsTheError": "Das ist der Fehler",
|
"hereIsTheError": "Das ist der Fehler",
|
||||||
"internet": "Wir haben festgestellt, dass der Rechner, auf dem Crafty läuft, keine Verbindung zum Internet hat. Client-Verbindungen zum Server können dadurch eingeschränkt sein.",
|
"internet": "Wir haben festgestellt, dass der Rechner, auf dem Crafty läuft, keine Verbindung zum Internet hat. Client-Verbindungen zum Server können dadurch eingeschränkt sein.",
|
||||||
|
@ -168,8 +168,11 @@
|
|||||||
"embarassing": "Oh my, well, this is embarrassing.",
|
"embarassing": "Oh my, well, this is embarrassing.",
|
||||||
"error": "Error!",
|
"error": "Error!",
|
||||||
"eulaAgree": "Do you agree?",
|
"eulaAgree": "Do you agree?",
|
||||||
"eulaMsg": "You must agree to the EULA. A copy of the Mojang EULA is linked under this message.",
|
"eulaMsg": "You must agree to the ",
|
||||||
|
"privMsg": "and the ",
|
||||||
"eulaTitle": "Agree To EULA",
|
"eulaTitle": "Agree To EULA",
|
||||||
|
"agree": "Agree",
|
||||||
|
"cancel": "Cancel",
|
||||||
"fileTooLarge": "Upload failed. File upload too large. Contact system administrator for assistance.",
|
"fileTooLarge": "Upload failed. File upload too large. Contact system administrator for assistance.",
|
||||||
"hereIsTheError": "Here is the error",
|
"hereIsTheError": "Here is the error",
|
||||||
"internet": "We have detected the machine running Crafty has no connection to the internet. Client connections to the server may be limited.",
|
"internet": "We have detected the machine running Crafty has no connection to the internet. Client connections to the server may be limited.",
|
||||||
|
@ -169,7 +169,7 @@
|
|||||||
"embarassing": "Oh por, bueno, esto es vergonzoso.",
|
"embarassing": "Oh por, bueno, esto es vergonzoso.",
|
||||||
"error": "Error!",
|
"error": "Error!",
|
||||||
"eulaAgree": "Estás de acuerdo?",
|
"eulaAgree": "Estás de acuerdo?",
|
||||||
"eulaMsg": "Debes aceptar el EULA. Una copia del EULA de Mojang esta vinculada debajo de este mensaje.",
|
"eulaMsg": "Debes aceptar el EULA. Una copia del EULA de Minecraft esta vinculada debajo de este mensaje.",
|
||||||
"eulaTitle": "Aceptar EULA",
|
"eulaTitle": "Aceptar EULA",
|
||||||
"fileTooLarge": "Subida fallida. Carga de archivo demasiado grande. Póngase en contacto con el administrador del sistema para obtener ayuda.",
|
"fileTooLarge": "Subida fallida. Carga de archivo demasiado grande. Póngase en contacto con el administrador del sistema para obtener ayuda.",
|
||||||
"hereIsTheError": "Aquí está el error.",
|
"hereIsTheError": "Aquí está el error.",
|
||||||
@ -537,4 +537,4 @@
|
|||||||
"userSettings": "Configuracion de Usuario.",
|
"userSettings": "Configuracion de Usuario.",
|
||||||
"uses": "Número de usos habilitados. (-1 == sin límite)."
|
"uses": "Número de usos habilitados. (-1 == sin límite)."
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -192,7 +192,7 @@
|
|||||||
"embarassing": "No, tämähän on noloa.",
|
"embarassing": "No, tämähän on noloa.",
|
||||||
"error": "Virhe!",
|
"error": "Virhe!",
|
||||||
"eulaAgree": "Oletko samaa mieltä?",
|
"eulaAgree": "Oletko samaa mieltä?",
|
||||||
"eulaMsg": "Sinun on hyväksyttävä EULA. Kopio Mojang EULA:sta on linkitetty tämän viestin alla.",
|
"eulaMsg": "Sinun on hyväksyttävä EULA. Kopio Minecraft EULA:sta on linkitetty tämän viestin alla.",
|
||||||
"eulaTitle": "Hyväksy EULA",
|
"eulaTitle": "Hyväksy EULA",
|
||||||
"fileTooLarge": "Lataus epäonnistui. Tiedosto on liian suuri. Ota yhteyttä järjestelmänvalvojaan saadaksesi apua.",
|
"fileTooLarge": "Lataus epäonnistui. Tiedosto on liian suuri. Ota yhteyttä järjestelmänvalvojaan saadaksesi apua.",
|
||||||
"hereIsTheError": "Tässä on virhe",
|
"hereIsTheError": "Tässä on virhe",
|
||||||
@ -560,4 +560,4 @@
|
|||||||
"userSettings": "Käyttäjäasetukset",
|
"userSettings": "Käyttäjäasetukset",
|
||||||
"uses": "Sallittujen käyttäkertojen määtä (-1 == Ei rajaa)"
|
"uses": "Sallittujen käyttäkertojen määtä (-1 == Ei rajaa)"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -168,7 +168,7 @@
|
|||||||
"embarassing": "Oulà, c'est embarrassant.",
|
"embarassing": "Oulà, c'est embarrassant.",
|
||||||
"error": "Erreur !",
|
"error": "Erreur !",
|
||||||
"eulaAgree": "Êtes-vous d'accord?",
|
"eulaAgree": "Êtes-vous d'accord?",
|
||||||
"eulaMsg": "Vous devez accepter le EULA. Une copie du CLUF de Mojang est liée sous ce message.",
|
"eulaMsg": "Vous devez accepter le EULA. Une copie du CLUF de Minecraft est liée sous ce message.",
|
||||||
"eulaTitle": "Accepter le EULA",
|
"eulaTitle": "Accepter le EULA",
|
||||||
"fileTooLarge": "Echec du chargement. Le fichier est trop gros. Demande de l'aide à l'administrateur système.",
|
"fileTooLarge": "Echec du chargement. Le fichier est trop gros. Demande de l'aide à l'administrateur système.",
|
||||||
"hereIsTheError": "Il y a une erreur",
|
"hereIsTheError": "Il y a une erreur",
|
||||||
@ -536,4 +536,4 @@
|
|||||||
"userSettings": "Paramètres Utilisateur",
|
"userSettings": "Paramètres Utilisateur",
|
||||||
"uses": "Nombre d'utilisation Authorisé (-1 == Illimité)"
|
"uses": "Nombre d'utilisation Authorisé (-1 == Illimité)"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -167,7 +167,7 @@
|
|||||||
"embarassing": "Och, dit is beskamsum.",
|
"embarassing": "Och, dit is beskamsum.",
|
||||||
"error": "Error!",
|
"error": "Error!",
|
||||||
"eulaAgree": "Binne jo akkoard?",
|
"eulaAgree": "Binne jo akkoard?",
|
||||||
"eulaMsg": "Jo moatte ynstimme mei de EULA. In kopy fan 'e Mojang EULA is keppele ûnder dit berjocht.",
|
"eulaMsg": "Jo moatte ynstimme mei de EULA. In kopy fan 'e Minecraft EULA is keppele ûnder dit berjocht.",
|
||||||
"eulaTitle": "Akseptearje mei EULA",
|
"eulaTitle": "Akseptearje mei EULA",
|
||||||
"hereIsTheError": "Hjir is de error",
|
"hereIsTheError": "Hjir is de error",
|
||||||
"internet": "Wy hawwe ûntdutsen dat de masine dy't Crafty draait gjin ferbining hat mei it ynternet. Clientferbiningen mei de server kinne beheind wêze.",
|
"internet": "Wy hawwe ûntdutsen dat de masine dy't Crafty draait gjin ferbining hat mei it ynternet. Clientferbiningen mei de server kinne beheind wêze.",
|
||||||
@ -529,4 +529,4 @@
|
|||||||
"userSettings": "Brûkersynstellingen",
|
"userSettings": "Brûkersynstellingen",
|
||||||
"uses": "Oantal gebrûk tastien (-1==Gjin limyt)"
|
"uses": "Oantal gebrûk tastien (-1==Gjin limyt)"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -167,7 +167,7 @@
|
|||||||
"embarassing": "Uhh, ovo je sramotno.",
|
"embarassing": "Uhh, ovo je sramotno.",
|
||||||
"error": "Greška!",
|
"error": "Greška!",
|
||||||
"eulaAgree": "Slažete li se?",
|
"eulaAgree": "Slažete li se?",
|
||||||
"eulaMsg": "Morate prihvatiti EULA-u. Poveznica Mojangove EULA-e se nalazi ispod ove poruke.",
|
"eulaMsg": "Morate prihvatiti EULA-u. Poveznica Minecraft EULA-e se nalazi ispod ove poruke.",
|
||||||
"eulaTitle": "Prihvatite EULA-u",
|
"eulaTitle": "Prihvatite EULA-u",
|
||||||
"hereIsTheError": "Ovdje je pogreška",
|
"hereIsTheError": "Ovdje je pogreška",
|
||||||
"internet": "Otkrili smo da uređaj koji pokreće Crafty nije povezan s internetom. Povezivanje klijenta s poslužiteljem može biti ograničeno.",
|
"internet": "Otkrili smo da uređaj koji pokreće Crafty nije povezan s internetom. Povezivanje klijenta s poslužiteljem može biti ograničeno.",
|
||||||
@ -529,4 +529,4 @@
|
|||||||
"userSettings": "Korisničke postavke",
|
"userSettings": "Korisničke postavke",
|
||||||
"uses": "Broj dopuštenih upotreba (-1==Bez ograničenja)"
|
"uses": "Broj dopuštenih upotreba (-1==Bez ograničenja)"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -168,7 +168,7 @@
|
|||||||
"embarassing": "Oh tidak, ini adalah hal yang memalukan",
|
"embarassing": "Oh tidak, ini adalah hal yang memalukan",
|
||||||
"error": "Error!",
|
"error": "Error!",
|
||||||
"eulaAgree": "Apakah anda setuju?",
|
"eulaAgree": "Apakah anda setuju?",
|
||||||
"eulaMsg": "Anda harus menyetujui EULA. Salinan Mojang EULA ditautkan di bawah pesan ini.",
|
"eulaMsg": "Anda harus menyetujui EULA. Salinan Minecraft EULA ditautkan di bawah pesan ini.",
|
||||||
"eulaTitle": "Setuju Ke EULA",
|
"eulaTitle": "Setuju Ke EULA",
|
||||||
"fileTooLarge": "Gagal menggungah. File yang ingin di unggah terlalu besar. Kontak administrator system untuk pengawasan",
|
"fileTooLarge": "Gagal menggungah. File yang ingin di unggah terlalu besar. Kontak administrator system untuk pengawasan",
|
||||||
"hereIsTheError": "Disini Error nya",
|
"hereIsTheError": "Disini Error nya",
|
||||||
@ -536,4 +536,4 @@
|
|||||||
"userSettings": "Pengaturan Pengguna",
|
"userSettings": "Pengaturan Pengguna",
|
||||||
"uses": "Jumlah penggunaan yang diizinkan (-1==No Limit)"
|
"uses": "Jumlah penggunaan yang diizinkan (-1==No Limit)"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -167,7 +167,7 @@
|
|||||||
"embarassing": "Oh my, well, this is embarrassing.",
|
"embarassing": "Oh my, well, this is embarrassing.",
|
||||||
"error": "Error!",
|
"error": "Error!",
|
||||||
"eulaAgree": "Do you agree?",
|
"eulaAgree": "Do you agree?",
|
||||||
"eulaMsg": "You must agree to the EULA. A copy of the Mojang EULA is linked under this message.",
|
"eulaMsg": "You must agree to the EULA. A copy of the Minecraft EULA is linked under this message.",
|
||||||
"eulaTitle": "Agree To EULA",
|
"eulaTitle": "Agree To EULA",
|
||||||
"hereIsTheError": "Here is the error",
|
"hereIsTheError": "Here is the error",
|
||||||
"internet": "We have detected the machine running Crafty has no connection to the internet. Client connections to the server may be limited.",
|
"internet": "We have detected the machine running Crafty has no connection to the internet. Client connections to the server may be limited.",
|
||||||
@ -529,4 +529,4 @@
|
|||||||
"userSettings": "Impostazioni Utente",
|
"userSettings": "Impostazioni Utente",
|
||||||
"uses": "Numero di usi permessi (-1==Nessun limite)"
|
"uses": "Numero di usi permessi (-1==Nessun limite)"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -168,7 +168,7 @@
|
|||||||
"embarassing": "Ak nu, tas ir apkaunojoši.",
|
"embarassing": "Ak nu, tas ir apkaunojoši.",
|
||||||
"error": "Kļūda!",
|
"error": "Kļūda!",
|
||||||
"eulaAgree": "Vai jūs piekrītat?",
|
"eulaAgree": "Vai jūs piekrītat?",
|
||||||
"eulaMsg": "Jums ir jāpiekrīt EULA. Kopija no Mojang EULA ir saitēta zem šī ziņojuma.",
|
"eulaMsg": "Jums ir jāpiekrīt EULA. Kopija no Minecraft EULA ir saitēta zem šī ziņojuma.",
|
||||||
"eulaTitle": "Piekrist EULA",
|
"eulaTitle": "Piekrist EULA",
|
||||||
"fileTooLarge": "Augšupielāde neizdevās. Faila augšupielāde ir pārāk liela. Sazinies ar sistēmas administratoru priekš palīdzības.",
|
"fileTooLarge": "Augšupielāde neizdevās. Faila augšupielāde ir pārāk liela. Sazinies ar sistēmas administratoru priekš palīdzības.",
|
||||||
"hereIsTheError": "Rekur ir kļūda",
|
"hereIsTheError": "Rekur ir kļūda",
|
||||||
@ -536,4 +536,4 @@
|
|||||||
"userSettings": "Lietotāju Iestatījumi",
|
"userSettings": "Lietotāju Iestatījumi",
|
||||||
"uses": "Dauzums, cik reizes lietot (-1==Bez Limita)"
|
"uses": "Dauzums, cik reizes lietot (-1==Bez Limita)"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -168,7 +168,7 @@
|
|||||||
"embarassing": "Oh, nou, dit is gênant.",
|
"embarassing": "Oh, nou, dit is gênant.",
|
||||||
"error": "Fout!",
|
"error": "Fout!",
|
||||||
"eulaAgree": "Bent u het eens?",
|
"eulaAgree": "Bent u het eens?",
|
||||||
"eulaMsg": "U moet akkoord gaan met de EULA. Een kopie van de Mojang EULA is gelinkt onder dit bericht.",
|
"eulaMsg": "U moet akkoord gaan met de EULA. Een kopie van de Minecraft EULA is gelinkt onder dit bericht.",
|
||||||
"eulaTitle": "Akkoord gaan met EULA",
|
"eulaTitle": "Akkoord gaan met EULA",
|
||||||
"fileTooLarge": "Uploaden mislukt. Bestand uploaden te groot. Neem contact op met de systeembeheerder voor assistentie",
|
"fileTooLarge": "Uploaden mislukt. Bestand uploaden te groot. Neem contact op met de systeembeheerder voor assistentie",
|
||||||
"hereIsTheError": "Hier is de fout",
|
"hereIsTheError": "Hier is de fout",
|
||||||
@ -536,4 +536,4 @@
|
|||||||
"userSettings": "Gebruikersinstellingen",
|
"userSettings": "Gebruikersinstellingen",
|
||||||
"uses": "Aantal toegestane gebruiken (-1==Geen Limiet)"
|
"uses": "Aantal toegestane gebruiken (-1==Geen Limiet)"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -167,7 +167,7 @@
|
|||||||
"embarassing": "Oh, oeps, dit is gênant.",
|
"embarassing": "Oh, oeps, dit is gênant.",
|
||||||
"error": "Error!",
|
"error": "Error!",
|
||||||
"eulaAgree": "Stem je in met de EULA?",
|
"eulaAgree": "Stem je in met de EULA?",
|
||||||
"eulaMsg": "Je moet instemmen met de EULA. Een kopie van de Mojang EULA is onder dit bericht gelinkt.",
|
"eulaMsg": "Je moet instemmen met de EULA. Een kopie van de Minecraft EULA is onder dit bericht gelinkt.",
|
||||||
"eulaTitle": "Instemmen met de EULA",
|
"eulaTitle": "Instemmen met de EULA",
|
||||||
"hereIsTheError": "Hier is de error",
|
"hereIsTheError": "Hier is de error",
|
||||||
"internet": "We hebben gedetecteerd dat de serverhost geen internetverbinding heeft. Client connecties zijn mogelijk gelimiteerd.",
|
"internet": "We hebben gedetecteerd dat de serverhost geen internetverbinding heeft. Client connecties zijn mogelijk gelimiteerd.",
|
||||||
@ -529,4 +529,4 @@
|
|||||||
"userSettings": "Gebruikersinstellingen",
|
"userSettings": "Gebruikersinstellingen",
|
||||||
"uses": "Aantal keer toegestaan (-1==Geen limiet)"
|
"uses": "Aantal keer toegestaan (-1==Geen limiet)"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -168,7 +168,7 @@
|
|||||||
"embarassing": "Oh, więc, to jest żenujące.",
|
"embarassing": "Oh, więc, to jest żenujące.",
|
||||||
"error": "Błąd!",
|
"error": "Błąd!",
|
||||||
"eulaAgree": "Czy się zgadzasz?",
|
"eulaAgree": "Czy się zgadzasz?",
|
||||||
"eulaMsg": "Musisz się zgodzić na EULA. Kopia EULA Mojangu jest zalinkowana pod tą wiadomością.",
|
"eulaMsg": "Musisz się zgodzić na EULA. Kopia EULA Minecraft jest zalinkowana pod tą wiadomością.",
|
||||||
"eulaTitle": "Zgódź się na EULA",
|
"eulaTitle": "Zgódź się na EULA",
|
||||||
"fileTooLarge": "Upload nie udany. Plik jest za duży. Skontaktuj się z administratorem dla pomocy.",
|
"fileTooLarge": "Upload nie udany. Plik jest za duży. Skontaktuj się z administratorem dla pomocy.",
|
||||||
"hereIsTheError": "Tu jest problem",
|
"hereIsTheError": "Tu jest problem",
|
||||||
@ -537,4 +537,4 @@
|
|||||||
"userSettings": "Ustawienia użytkownika",
|
"userSettings": "Ustawienia użytkownika",
|
||||||
"uses": "Ilość użyć (-1==Bez limitu)"
|
"uses": "Ilość użyć (-1==Bez limitu)"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -168,7 +168,7 @@
|
|||||||
"embarassing": "Oh. Bem, isso é constrangedor",
|
"embarassing": "Oh. Bem, isso é constrangedor",
|
||||||
"error": "Erro!",
|
"error": "Erro!",
|
||||||
"eulaAgree": "Você concorda?",
|
"eulaAgree": "Você concorda?",
|
||||||
"eulaMsg": "Você deve concordar com os Termos de Licença. Uma cópia dos Termos de Licença da Mojang está linkado abaixo desta mensagem.",
|
"eulaMsg": "Você deve concordar com os Termos de Licença. Uma cópia dos Termos de Licença da Minecraft está linkado abaixo desta mensagem.",
|
||||||
"eulaTitle": "Concordar com os Termos de Licença",
|
"eulaTitle": "Concordar com os Termos de Licença",
|
||||||
"fileTooLarge": "Upload falhou. Arquivo muito grande. Contato o administrador do sistema para assistência.",
|
"fileTooLarge": "Upload falhou. Arquivo muito grande. Contato o administrador do sistema para assistência.",
|
||||||
"hereIsTheError": "Aqui está o erro",
|
"hereIsTheError": "Aqui está o erro",
|
||||||
@ -537,4 +537,4 @@
|
|||||||
"userSettings": "Configurações do Usuário",
|
"userSettings": "Configurações do Usuário",
|
||||||
"uses": "Número de Usos Permitidos (-1==Sem Limite)"
|
"uses": "Número de Usos Permitidos (-1==Sem Limite)"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -168,7 +168,7 @@
|
|||||||
"embarassing": "哦,天哪,这太尴尬了。",
|
"embarassing": "哦,天哪,这太尴尬了。",
|
||||||
"error": "错误!",
|
"error": "错误!",
|
||||||
"eulaAgree": "你同意吗?",
|
"eulaAgree": "你同意吗?",
|
||||||
"eulaMsg": "你必须同意最终用户许可协议(EULA)。一份 Mojang EULA 副本的链接在此消息下方。",
|
"eulaMsg": "你必须同意最终用户许可协议(EULA)。一份 Minecraft EULA 副本的链接在此消息下方。",
|
||||||
"eulaTitle": "同意最终用户许可协议(EULA)",
|
"eulaTitle": "同意最终用户许可协议(EULA)",
|
||||||
"fileTooLarge": "上传失败。上传的文件过大。联系系统管理员以获取协助。",
|
"fileTooLarge": "上传失败。上传的文件过大。联系系统管理员以获取协助。",
|
||||||
"hereIsTheError": "错误如下",
|
"hereIsTheError": "错误如下",
|
||||||
@ -536,4 +536,4 @@
|
|||||||
"userSettings": "用户设置",
|
"userSettings": "用户设置",
|
||||||
"uses": "使用次数限制(-1==无限制)"
|
"uses": "使用次数限制(-1==无限制)"
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user