Merge branch 'dev' into enhancement/pretzel-next-run

This commit is contained in:
Zedifus 2022-08-05 01:27:18 +01:00
commit a0b599bbd2
9 changed files with 327 additions and 161 deletions

View File

@ -5,6 +5,10 @@
TBD
### Bug fixes
- Fix SU status not sticking on user creation ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/410))
- Handle Missing Java From Win Registry ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/413))
- Disable restart while server is backing up ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/414))
- Fix server creation with serverjars API ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/415))
- Fix API Key delete confirmations ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/416))
### Tweaks
TBD
### Lang

View File

@ -51,7 +51,7 @@ class ServerJars:
def get_serverjar_data(self):
data = self._read_cache()
return data.get("servers")
return data.get("types")
def _check_api_alive(self):
logger.info("Checking serverjars.com API status")
@ -70,6 +70,39 @@ class ServerJars:
logger.error("unable to contact serverjars.com api")
return False
def manual_refresh_cache(self):
cache_file = self.helper.serverjar_cache
# debug override
# cache_old = True
# if the API is down... we bomb out
if not self._check_api_alive():
return False
logger.info("Manual Refresh requested.")
now = datetime.now()
data = {
"last_refreshed": now.strftime("%m/%d/%Y, %H:%M:%S"),
"types": {},
}
jar_types = self._get_server_type_list()
data["types"].update(jar_types)
for s in data["types"]:
data["types"].update({s: dict.fromkeys(data["types"].get(s), {})})
for j in data["types"].get(s):
versions = self._get_jar_details(j, s)
data["types"][s].update({j: versions})
# save our cache
try:
with open(cache_file, "w", encoding="utf-8") as f:
f.write(json.dumps(data, indent=4))
logger.info("Cache file refreshed")
except Exception as e:
logger.error(f"Unable to update serverjars.com cache file: {e}")
def refresh_cache(self):
cache_file = self.helper.serverjar_cache
@ -88,22 +121,18 @@ class ServerJars:
if cache_old:
logger.info("Cache file is over 1 day old, refreshing")
now = datetime.now()
data = {"last_refreshed": now.strftime("%m/%d/%Y, %H:%M:%S"), "servers": {}}
data = {
"last_refreshed": now.strftime("%m/%d/%Y, %H:%M:%S"),
"types": {},
}
jar_types = self._get_server_type_list()
# for each jar type
for j in jar_types:
# for each server
for s in jar_types.get(j):
# jar versions for this server
versions = self._get_jar_details(s)
# add these versions (a list) to the dict with
# a key of the server type
data["servers"].update({s: versions})
data["types"].update(jar_types)
for s in data["types"]:
data["types"].update({s: dict.fromkeys(data["types"].get(s), {})})
for j in data["types"].get(s):
versions = self._get_jar_details(j, s)
data["types"][s].update({j: versions})
# save our cache
try:
with open(cache_file, "w", encoding="utf-8") as f:
@ -113,8 +142,8 @@ class ServerJars:
except Exception as e:
logger.error(f"Unable to update serverjars.com cache file: {e}")
def _get_jar_details(self, jar_type="servers"):
url = f"/api/fetchAll/{jar_type}"
def _get_jar_details(self, server_type, jar_type="servers"):
url = f"/api/fetchAll/{jar_type}/{server_type}"
response = self._get_api_result(url)
temp = []
for v in response:
@ -127,19 +156,19 @@ class ServerJars:
response = self._get_api_result(url)
return response
def download_jar(self, server, version, path, server_id):
def download_jar(self, jar, server, version, path, server_id):
update_thread = threading.Thread(
name=f"server_download-{server_id}-{server}-{version}",
target=self.a_download_jar,
daemon=True,
args=(server, version, path, server_id),
args=(jar, server, version, path, server_id),
)
update_thread.start()
def a_download_jar(self, server, version, path, server_id):
def a_download_jar(self, jar, server, version, path, server_id):
# delaying download for server register to finish
time.sleep(3)
fetch_url = f"{self.base_url}/api/fetchJar/{server}/{version}"
fetch_url = f"{self.base_url}/api/fetchJar/{jar}/{server}/{version}"
server_users = PermissionsServers.get_server_user_list(server_id)
# We need to make sure the server is registered before

View File

@ -422,6 +422,7 @@ class Controller:
def create_jar_server(
self,
jar: str,
server: str,
version: str,
name: str,
@ -493,7 +494,7 @@ class Controller:
# download the jar
self.server_jars.download_jar(
server, version, os.path.join(server_dir, server_file), new_id
jar, server, version, os.path.join(server_dir, server_file), new_id
)
return new_id

View File

@ -247,11 +247,20 @@ class ServerInstance:
"Oracle Java detected. Changing start command to avoid re-exec."
)
which_java_raw = self.helper.which_java()
java_path = which_java_raw + "\\bin\\java"
try:
java_path = which_java_raw + "\\bin\\java"
except TypeError:
logger.warning(
"Could not find java in the registry even though"
" Oracle java is installed. Re-exec expected, but we have no"
" other options. CPU stats will not work for process."
)
java_path = ""
if str(which_java_raw) != str(self.helper.get_servers_root_dir) or str(
self.helper.get_servers_root_dir
) in str(which_java_raw):
self.server_command[0] = java_path
if java_path != "":
self.server_command[0] = java_path
else:
logger.critcal(
"Possible attack detected. User attempted to exec "
@ -647,6 +656,13 @@ class ServerInstance:
self.helper.websocket_helper.broadcast_user(user, "send_start_reload", {})
def restart_threaded_server(self, user_id):
bu_conf = HelpersManagement.get_backup_config(self.server_id)
if self.is_backingup and bu_conf["shutdown"]:
logger.info(
"Restart command detected. Supressing - server has"
" backup shutdown enabled and server is currently backing up."
)
return
# if not already running, let's just start
if not self.check_running():
self.run_threaded_server(user_id)

View File

@ -454,6 +454,14 @@ class AjaxHandler(BaseHandler):
self.helper.backup_select(path, exec_user["user_id"])
return
elif page == "jar_cache":
if not superuser:
self.redirect("/panel/error?error=Not a super user")
return
self.controller.server_jars.manual_refresh_cache()
return
@tornado.web.authenticated
def delete(self, page):
api_key, _, exec_user = self.current_user

View File

@ -96,6 +96,7 @@ class ServerHandler(BaseHandler):
"user_data": exec_user,
"user_role": exec_user_role,
"roles": list_roles,
"super_user": exec_user["superuser"],
"user_crafty_permissions": exec_user_crafty_permissions,
"crafty_permissions": {
"Server_Creation": EnumPermissionsCrafty.SERVER_CREATION,
@ -386,14 +387,20 @@ class ServerHandler(BaseHandler):
# deletes temp dir
FileHelpers.del_dirs(zip_path)
else:
if len(server_parts) != 2:
if len(server_parts) != 3:
self.redirect("/panel/error?error=Invalid server data")
return
server_type, server_version = server_parts
jar_type, 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, min_mem, max_mem, port
jar_type,
server_type,
server_version,
server_name,
min_mem,
max_mem,
port,
)
self.controller.management.add_to_audit_log(
exec_user["user_id"],

View File

@ -15,7 +15,7 @@
<div class="page-header">
<h4 class="page-title">
{{ translate('apiKeys', 'pageTitle', data['lang']) }} - {{ data['user']['user_id'] }}
<br/>
<br />
<small>UID: {{ data['user']['user_id'] }}</small>
</h4>
</div>
@ -32,14 +32,12 @@
<ul class="nav nav-tabs col-md-12 tab-simple-styled " role="tablist">
<li class="nav-item">
<a class="nav-link" href="/panel/edit_user?id={{ data['user']['user_id'] }}&subpage=config"
role="tab"
aria-selected="false">
role="tab" aria-selected="false">
<i class="fas fa-cogs"></i>{{ translate('apiKeys', 'config', data['lang']) }}</a>
</li>
<li class="nav-item">
<a class="nav-link active" href="/panel/edit_user_apikeys?id={{ data['user']['user_id'] }}"
role="tab"
aria-selected="true">
role="tab" aria-selected="true">
<i class="fas fa-key"></i>{{ translate('apiKeys', 'apiKeys', data['lang']) }}</a>
</li>
</ul>
@ -48,56 +46,60 @@
<div class="col-md-7 col-sm-12">
<div class="card">
<div class="card-header header-sm d-flex justify-content-between align-items-center">
<h4 class="card-title"><i class="fas fa-key"></i>{{ translate('apiKeys', 'apiKeys', data['lang']) }}</h4>
<h4 class="card-title"><i class="fas fa-key"></i>{{ translate('apiKeys', 'apiKeys',
data['lang']) }}</h4>
</div>
<div class="card-body">
<div class="form-group">
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr class="rounded">
<!--<th>ID</th>-->
<th>{{ translate('apiKeys', 'name', data['lang']) }}</th>
<th>{{ translate('apiKeys', 'created', data['lang']) }}</th>
<th>{{ translate('apiKeys', 'superUser', data['lang']) }}</th>
<th>{{ translate('apiKeys', 'perms', data['lang']) }}</th>
<th>{{ translate('apiKeys', 'buttons', data['lang']) }}</th>
</tr>
<tr class="rounded">
<!--<th>ID</th>-->
<th>{{ translate('apiKeys', 'name', data['lang']) }}</th>
<th>{{ translate('apiKeys', 'created', data['lang']) }}</th>
<th>{{ translate('apiKeys', 'superUser', data['lang']) }}</th>
<th>{{ translate('apiKeys', 'perms', data['lang']) }}</th>
<th>{{ translate('apiKeys', 'buttons', data['lang']) }}</th>
</tr>
</thead>
<tbody>
{% for apikey in data['api_keys'] %}
<tr>
<!--<td>{-{ apikey.token_id }-}</td>-->
<td>{{ apikey.name }}</td>
<td>{{ apikey.created.strftime('%d/%m/%Y %H:%M:%S') }}</td>
<td>
{% if apikey.superuser %}
<span class="text-success">
<i class="fas fa-check-square"></i> {{ translate('apiKeys', 'yes', data['lang']) }}
</span>
{% else %}
<span class="text-danger">
<i class="far fa-times-square"></i> {{ translate('apiKeys', 'no', data['lang']) }}
</span>
{% end %}
</td>
<td>{{ translate('apiKeys', 'server', data['lang']) }} {{ apikey.server_permissions }}
{{ translate('apiKeys', 'crafty', data['lang']) }} {{ apikey.crafty_permissions }}</td>
<td>
<button
class="btn btn-danger delete-api-key"
{% for apikey in data['api_keys'] %}
<tr>
<!--<td>{-{ apikey.token_id }-}</td>-->
<td>{{ apikey.name }}</td>
<td>{{ apikey.created.strftime('%d/%m/%Y %H:%M:%S') }}</td>
<td>
{% if apikey.superuser %}
<span class="text-success">
<i class="fas fa-check-square"></i> {{
translate('apiKeys', 'yes', data['lang']) }}
</span>
{% else %}
<span class="text-danger">
<i class="far fa-times-square"></i> {{
translate('apiKeys', 'no', data['lang']) }}
</span>
{% end %}
</td>
<td>{{ translate('apiKeys', 'server', data['lang']) }} {{
apikey.server_permissions }}
{{ translate('apiKeys', 'crafty', data['lang']) }} {{
apikey.crafty_permissions }}</td>
<td>
<button class="btn btn-danger delete-api-key"
data-key-id="{{ apikey.token_id }}"
data-key-name="{{ apikey.name }}"
>{{ translate('panelConfig', 'delete', data['lang']) }}</button>
<button
class="btn btn-outline-primary get-a-token"
data-key-name="{{ apikey.name }}">{{
translate('panelConfig', 'delete', data['lang'])
}}</button>
<button class="btn btn-outline-primary get-a-token"
data-key-id="{{ apikey.token_id }}"
data-key-name="{{ apikey.name }}"
>{{ translate('apiKeys', 'getToken', data['lang']) }}
</button>
</td>
</tr>
{% end %}
data-key-name="{{ apikey.name }}">{{
translate('apiKeys', 'getToken', data['lang']) }}
</button>
</td>
</tr>
{% end %}
</tbody>
</table>
</div>
@ -109,68 +111,69 @@
<div class="col-md-5 col-sm-12">
<div class="card">
<div class="card-header header-sm d-flex justify-content-between align-items-center">
<h4 class="card-title"><i class="fas fa-plus"></i> {{ translate('apiKeys', 'createNew', data['lang']) }}</h4>
<h4 class="card-title"><i class="fas fa-plus"></i> {{ translate('apiKeys',
'createNew', data['lang']) }}</h4>
</div>
<div class="card-body">
<form id="user_form" class="forms-sample" method="post"
action="/panel/edit_user_apikeys">
action="/panel/edit_user_apikeys">
{% raw xsrf_form_html() %}
<input type="hidden" name="id" value="{{ data['user']['user_id'] }}">
<div class="form-group">
<label class="form-label" for="username">{{ translate('apiKeys', 'name', data['lang']) }}<small
class="text-muted ml-1"> - {{ translate('apiKeys', 'nameDesc', data['lang']) }}</small> </label>
<label class="form-label" for="username">{{ translate('apiKeys', 'name',
data['lang']) }}<small class="text-muted ml-1"> - {{
translate('apiKeys', 'nameDesc', data['lang']) }}</small> </label>
<input type="text" class="form-control" name="name" id="name"
placeholder="API Key">
placeholder="API Key">
</div>
<table class="table table-hover mb-3">
<thead>
<tr class="rounded">
<th>{{ translate('apiKeys', 'permName', data['lang']) }}</th>
<th>{{ translate('apiKeys', 'auth', data['lang']) }}</th>
</tr>
<tr class="rounded">
<th>{{ translate('apiKeys', 'permName', data['lang']) }}</th>
<th>{{ translate('apiKeys', 'auth', data['lang']) }}</th>
</tr>
</thead>
<tbody>
{% for permission in data['server_permissions_all'] %}
<tr>
<td><label
for="permission_{{ permission.name }}">{{ permission.name }}</label>
</td>
<td>
<input type="checkbox" class=""
id="permission_{{ permission.name }}"
name="permission_{{ permission.name }}" value="1">
</td>
</tr>
{% end %}
{% for permission in data['crafty_permissions_all'] %}
<tr>
<td><label
for="permission_{{ permission.name }}">{{ permission.name }}</label>
</td>
<td>
<input type="checkbox" class=""
id="permission_{{ permission.name }}"
name="permission_{{ permission.name }}" value="1">
</td>
</tr>
{% end %}
{% for permission in data['server_permissions_all'] %}
<tr>
<td><label for="permission_{{ permission.name }}">{{ permission.name
}}</label>
</td>
<td>
<input type="checkbox" class=""
id="permission_{{ permission.name }}"
name="permission_{{ permission.name }}" value="1">
</td>
</tr>
{% end %}
{% for permission in data['crafty_permissions_all'] %}
<tr>
<td><label for="permission_{{ permission.name }}">{{ permission.name
}}</label>
</td>
<td>
<input type="checkbox" class=""
id="permission_{{ permission.name }}"
name="permission_{{ permission.name }}" value="1">
</td>
</tr>
{% end %}
</tbody>
</table>
<label for="superuser">Superuser</label>
<input type="checkbox" class="" id="superuser"
name="superuser" value="1">
<input type="checkbox" class="" id="superuser" name="superuser" value="1">
<br/>
<br />
<button type="submit" class="btn btn-success mr-2"><i class="fas fa-plus"></i>
Create
</button>
<button type="reset" class="btn btn-light"><i
class="fas fa-undo-alt"></i> {{ translate('panelConfig', 'cancel', data['lang']) }}
<button type="reset" class="btn btn-light"><i class="fas fa-undo-alt"></i> {{
translate('panelConfig', 'cancel', data['lang']) }}
</button>
</form>
</div>
@ -216,15 +219,17 @@
}
},
callback: function (result) {
var token = getCookie("_xsrf")
$.ajax({
type: "DELETE",
headers: {'X-XSRFToken': token},
url: '/panel/remove_apikey?id=' + keyId,
success: function (data) {
location.reload();
},
});
if (result) {
var token = getCookie("_xsrf")
$.ajax({
type: "DELETE",
headers: { 'X-XSRFToken': token },
url: '/panel/remove_apikey?id=' + keyId,
success: function (data) {
location.reload();
},
});
}
}
});
})
@ -234,7 +239,7 @@
var token = getCookie("_xsrf")
$.ajax({
type: "POST",
headers: {'X-XSRFToken': token},
headers: { 'X-XSRFToken': token },
url: '/panel/get_token?id=' + keyId,
success: function (data) {
bootbox.alert({

View File

@ -32,13 +32,32 @@
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<label for="server_type">{{ translate('serverWizard', 'serverType', data['lang']) }}</label>
<select required class="form-control form-control-lg select-css" id="server_type" name="server_type"
onchange="serverTypeChange(this)">
<option value="">{{ translate('serverWizard', 'selectType', data['lang']) }}</option>
{% for s in data['server_types'] %}
<option value="{{ s }}">{{ s.capitalize() }}</option>
<label for="server_jar">{{ translate('serverWizard', 'serverType', data['lang'])
}}</label>
{% if data['super_user'] %}
<select style="width: 90%;" required class="form-control form-control-lg select-css" id="server_jar"
name="server_jar" onchange="serverJarChange(this)">
{% else %}
<select required class="form-control form-control-lg select-css" id="server_jar" name="server_jar"
onchange="serverJarChange(this)">
{% end %}
<option value="None">{{ translate('serverWizard', 'selectType', data['lang']) }}</option>
{% for s in data['server_types'] %}
<option value="{{ s }}">{{ s.capitalize() }}</option>
{% end %}
</select>
{% if data['super_user'] %}
&nbsp;&nbsp;<i onclick="refreshCache()" id="refresh-cache" class="refresh-class fas fa-sync"></i>
{% end %}
</div>
</div>
<div class="col-sm-12">
<div class="form-group">
<label for="server_type">{{ translate('serverWizard', 'serverSelect', data['lang']) }}</label>
<select required class="form-control form-control-lg select-css" id="server_type" name="server_type"
onchange="serverTypeChange(this)">
<option value="">{{ translate('serverWizard', 'selectServer', data['lang']) }}</option>
</select>
</div>
</div>
@ -56,14 +75,14 @@
<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>
placeholder="{{ translate('serverWizard', 'myNewServer', data['lang']) }}" required>
</div>
</div>
</div>
<br />
<h4 class="card-title">{{ translate('serverWizard', 'quickSettings', data['lang']) }} <small
style="text-transform: none;"> - {{ translate('serverWizard', 'quickSettingsDescription',
style="text-transform: none;"> - {{ translate('serverWizard', 'quickSettingsDescription',
data['lang']) }}</small></h4>
<hr>
<div class="row">
@ -73,7 +92,7 @@
<label for="min_memory1">{{ translate('serverWizard', 'minMem', data['lang']) }} <small> - {{
translate('serverWizard', 'sizeInGB', data['lang']) }}</small></label>
<input type="number" class="form-control" id="min_memory1" name="min_memory" value="1" step="0.5"
min="0.5" required>
min="0.5" required>
</div>
</div>
@ -82,7 +101,7 @@
<label for="max_memory1">{{ translate('serverWizard', 'maxMem', data['lang']) }} <small> - {{
translate('serverWizard', 'sizeInGB', data['lang']) }}</small></label>
<input type="number" class="form-control" id="max_memory1" name="max_memory" value="2" step="0.5"
min="0.5" required>
min="0.5" required>
</div>
</div>
@ -91,7 +110,7 @@
<label for="port1">{{ translate('serverWizard', 'serverPort', data['lang']) }} <small> - {{
translate('serverWizard', 'defaultPort', data['lang']) }}</small></label>
<input type="number" class="form-control" id="port1" name="port" value="25565" step="1" min="1"
required>
required>
</div>
</div>
<div class="col-sm-12">
@ -100,7 +119,7 @@
<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">
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>
@ -111,7 +130,7 @@
<div class="form-group">
{% for r in data['roles'] %}
<span class="d-block menu-option"><label><input name="{{ r['role_id'] }}"
type="checkbox">&nbsp;
type="checkbox">&nbsp;
{{ r['role_name'].capitalize() }}</label></span>
{% end %}
</div>
@ -152,7 +171,7 @@
<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>
placeholder="{{ translate('serverWizard', 'myNewServer', data['lang']) }}" required>
</div>
</div>
@ -161,7 +180,7 @@
<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>
placeholder="/var/opt/server" required>
</div>
</div>
@ -169,7 +188,7 @@
<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="paper.jar" required>
placeholder="paper.jar" required>
</div>
</div>
@ -178,7 +197,7 @@
</div>
<br />
<h4 class="card-title">{{ translate('serverWizard', 'quickSettings', data['lang']) }} <small
style="text-transform: none;"> - {{ translate('serverWizard', 'quickSettingsDescription',
style="text-transform: none;"> - {{ translate('serverWizard', 'quickSettingsDescription',
data['lang']) }}</small></h4>
<hr>
<div class="row">
@ -188,7 +207,7 @@
<label for="min_memory2">{{ translate('serverWizard', 'minMem', data['lang']) }} <small> - {{
translate('serverWizard', 'sizeInGB', data['lang']) }}</small></label>
<input type="number" class="form-control" id="min_memory2" name="min_memory" value="1" step="0.5"
min="0.5" required>
min="0.5" required>
</div>
</div>
@ -197,7 +216,7 @@
<label for="max_memory2">{{ translate('serverWizard', 'maxMem', data['lang']) }} <small> - {{
translate('serverWizard', 'sizeInGB', data['lang']) }}</small></label>
<input type="number" class="form-control" id="max_memory2" name="max_memory" value="2" step="0.5"
min="0.5" required>
min="0.5" required>
</div>
</div>
@ -206,7 +225,7 @@
<label for="port2">{{ translate('serverWizard', 'serverPort', data['lang']) }} <small> - {{
translate('serverWizard', 'defaultPort', data['lang']) }}</small></label>
<input type="number" class="form-control" id="port2" name="port" value="25565" step="1" min="1"
required>
required>
</div>
</div>
<div class="col-sm-12">
@ -215,7 +234,7 @@
<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">
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>
@ -226,7 +245,7 @@
<div class="form-group">
{% for r in data['roles'] %}
<span class="d-block menu-option"><label><input name="{{ r['role_id'] }}"
type="checkbox">&nbsp;
type="checkbox">&nbsp;
{{ r['role_name'].capitalize() }}</label></span>
{% end %}
</div>
@ -266,7 +285,7 @@
<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>
placeholder="{{ translate('serverWizard', 'myNewServer', data['lang']) }}" required>
</div>
</div>
@ -275,7 +294,7 @@
<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>
placeholder="/var/opt/server.zip" required>
</div>
</div>
@ -294,7 +313,7 @@
<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="paper.jar" required>
placeholder="paper.jar" required>
</div>
</div>
</div>
@ -303,7 +322,7 @@
<div class="col-sm-3">
<h4 class="card-title">{{ translate('serverWizard', 'quickSettings', data['lang']) }} <small
style="text-transform: none;"> - {{ translate('serverWizard', 'quickSettingsDescription',
style="text-transform: none;"> - {{ translate('serverWizard', 'quickSettingsDescription',
data['lang']) }}</small></h4>
<hr>
<div class="row">
@ -313,7 +332,7 @@
<label for="min_memory3">{{ translate('serverWizard', 'minMem', data['lang']) }} <small> - {{
translate('serverWizard', 'sizeInGB', data['lang']) }}</small></label>
<input type="number" class="form-control" id="min_memory3" name="min_memory" value="1" step="0.5"
min="0.5" required>
min="0.5" required>
</div>
</div>
@ -322,7 +341,7 @@
<label for="max_memory3">{{ translate('serverWizard', 'maxMem', data['lang']) }} <small> - {{
translate('serverWizard', 'sizeInGB', data['lang']) }}</small></label>
<input type="number" class="form-control" id="max_memory3" name="max_memory" value="2" step="0.5"
min="0.5" required>
min="0.5" required>
</div>
</div>
@ -331,7 +350,7 @@
<label for="port3">{{ translate('serverWizard', 'serverPort', data['lang']) }} <small> - {{
translate('serverWizard', 'defaultPort', data['lang']) }}</small></label>
<input type="number" class="form-control" id="port3" name="port" value="25565" step="1" min="1"
required>
required>
</div>
</div>
@ -341,7 +360,7 @@
<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">
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>
@ -352,7 +371,7 @@
<div class="form-group">
{% for r in data['roles'] %}
<span class="d-block menu-option"><label><input name="{{ r['role_id'] }}"
type="checkbox">&nbsp;
type="checkbox">&nbsp;
{{ r['role_name'].capitalize() }}</label></span>
{% end %}
</div>
@ -368,7 +387,7 @@
</div>
</div>
<div class="modal fade" id="dir_select" tabindex="-1" role="dialog" aria-labelledby="dir_select"
aria-hidden="true">
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
@ -380,7 +399,7 @@
</div>
<div class="modal-body">
<div class="tree-ctx-item" id="main-tree-div" data-path=""
style="overflow: scroll; max-height:75%;">
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>
@ -401,7 +420,7 @@
</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'])
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>
@ -414,6 +433,10 @@
</div>
</div>
<style>
.refresh-class:hover {
cursor: grab;
}
.scroll {
max-height: 12em;
overflow-y: auto;
@ -673,6 +696,25 @@
});
}
function refreshCache() {
var token = getCookie("_xsrf")
document.getElementById("refresh-cache").classList.add("fa-spin")
$.ajax({
type: "POST",
headers: { 'X-XSRFToken': token },
url: '/ajax/jar_cache',
success: function () {
document.getElementById("refresh-cache").classList.remove("fa-sync");
document.getElementById("refresh-cache").classList.remove("fa-spin");
document.getElementById("refresh-cache").classList.add("fa-check");
setTimeout(function () {
location.reload();
}, 2000);
},
});
}
</script>
<script type="text/javascript">
var text = '{% raw data["js_server_types"] %}';
@ -682,11 +724,21 @@
*/
function serverTypeChange(selectObj) {
// get the index of the selected option
var idx = selectObj.selectedIndex;
var idx = document.getElementById('server_type').selectedIndex;
// get the value of the selected option
var which = selectObj.options[idx].value;
var cSelect = document.getElementById("server");
try {
var which = document.getElementById('server_type').options[idx].value;
} catch {
while (cSelect.options.length > 0) {
cSelect.remove(0);
}
return;
}
let server_type = which.split('|')[0];
let server = which.split('|')[1];
// use the selected option value to retrieve the list of items from the serverTypesLists array
cList = serverTypesLists[which];
let cList = serverTypesLists[server_type];
// get the country select element via its known id
var cSelect = document.getElementById("server");
// remove the current options from the country select
@ -696,7 +748,7 @@
}
var newOption;
// create new options ordered by ascending
cList.forEach(type => {
cList[server].forEach(type => {
newOption = document.createElement("option");
newOption.value = which + "|" + type; // assumes option string and value are the same
newOption.text = type;
@ -709,5 +761,47 @@
}
})
}
function serverJarChange(selectObj) {
let type_select = document.getElementById('server_jar')
let tidx = type_select.selectedIndex;
let val = type_select.options[tidx].value;
if (val == 'None') {
var jcSelect = document.getElementById("server_type");
while (jcSelect.options.length > 0) {
jcSelect.remove(0);
}
serverTypeChange(selectObj);
return;
}
// get the index of the selected option
var jidx = selectObj.selectedIndex;
// get the value of the selected option
var jwhich = selectObj.options[jidx].value;
// use the selected option value to retrieve the list of items from the serverTypesLists array
jcList = Object.keys(serverTypesLists[jwhich]);
// get the country select element via its known id
var jcSelect = document.getElementById("server_type");
// remove the current options from the country select
var jlen = jcSelect.options.length;
while (jcSelect.options.length > 0) {
jcSelect.remove(0);
}
var jnewOption;
// create new options ordered by ascending
jcList.forEach(type => {
jnewOption = document.createElement("option");
jnewOption.value = jwhich + "|" + type; // assumes option string and value are the same
jnewOption.text = type;
// add the new option
try {
jcSelect.add(jnewOption); // this will fail in DOM browsers but is needed for IE
}
catch (e) {
jcSelect.appendChild(jnewOption);
}
})
serverTypeChange(selectObj);
}
</script>
{% end %}

View File

@ -480,7 +480,8 @@
"save": "Save",
"selectRole": "Select Role(s)",
"selectRoot": "Select Archive Root Dir",
"selectType": "Select a Type",
"selectType": "Server Type (Vanilla, Servers, Modded, etc.)",
"selectServer": "Select a Server",
"selectVersion": "Select a Version",
"selectZipDir": "Select the directory in the archive you want us to unzip files from",
"serverJar": "Server Executable File",
@ -488,6 +489,7 @@
"serverPath": "Server Path",
"serverPort": "Server Port",
"serverType": "Server Type",
"serverSelect": "Server Select",
"serverVersion": "Server Version",
"sizeInGB": "Size in GB",
"zipPath": "Server Path"