Merge branch 'dev_websocket_server_status' into 'dev'

Adding Websocket for server details

See merge request crafty-controller/crafty-commander!144
This commit is contained in:
Silversthorn 2022-01-21 23:04:26 +00:00
commit 9cc149c7e8
33 changed files with 1611 additions and 1131 deletions

View File

@ -175,7 +175,7 @@ class Controller:
tempZipStorage += '.zip'
websocket_helper.broadcast_user(exec_user['user_id'], 'send_logs_bootbox', {
})
self.users.set_support_path(exec_user['user_id'], tempZipStorage)
@staticmethod
@ -287,9 +287,9 @@ class Controller:
return False
if helper.is_os_windows():
server_command = 'java -Xms{}M -Xmx{}M -jar {} nogui'.format(helper.float_to_string(min_mem),
server_command = 'java -Xms{}M -Xmx{}M -jar "{}" nogui'.format(helper.float_to_string(min_mem),
helper.float_to_string(max_mem),
'"'+full_jar_path+'"')
full_jar_path)
else:
server_command = 'java -Xms{}M -Xmx{}M -jar {} nogui'.format(helper.float_to_string(min_mem),
helper.float_to_string(max_mem),
@ -471,7 +471,7 @@ class Controller:
if helper.check_path_exists(self.servers.get_server_data_by_id(server_id)['backup_path']):
shutil.rmtree(helper.get_os_understandable_path(self.servers.get_server_data_by_id(server_id)['backup_path']))
#Cleanup scheduled tasks
try:
helpers_management.delete_scheduled_task_by_server(server_id)

View File

@ -1,4 +1,5 @@
from datetime import timedelta
from http import server
import os
import sys
import json
@ -80,7 +81,7 @@ class TasksManager:
logger.info("Reload from DB called. Current enabled schedules: ")
for item in jobs:
logger.info("JOB: {}".format(item))
def command_watcher(self):
while True:
# select any commands waiting to be processed
@ -285,8 +286,7 @@ class TasksManager:
logger.info("Scheduling Serverjars.com cache refresh service every 12 hours")
self.scheduler.add_job(server_jar_obj.refresh_cache, 'interval', hours=12, id="serverjars")
@staticmethod
def realtime():
def realtime(self):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
@ -311,7 +311,69 @@ class TasksManager:
'mem_percent': host_stats.get('mem_percent'),
'mem_usage': host_stats.get('mem_usage')
})
time.sleep(4)
servers = self.controller.servers_list
servers_ping = []
for srv in servers:
server_data = srv.get('server_data_obj', False)
if server_data:
server_id = server_data.get('server_id', False)
srv['raw_ping_result'] = self.controller.stats.get_raw_server_stats(server_id)
if ("{}".format(srv['raw_ping_result'].get('icon')) == "b''"):
srv['raw_ping_result']['icon'] = False
servers_ping.append({
'id': srv['raw_ping_result'].get('id'),
'started': srv['raw_ping_result'].get('started'),
'running': srv['raw_ping_result'].get('running'),
'cpu': srv['raw_ping_result'].get('cpu'),
'mem': srv['raw_ping_result'].get('mem'),
'mem_percent': srv['raw_ping_result'].get('mem_percent'),
'world_name': srv['raw_ping_result'].get('world_name'),
'world_size': srv['raw_ping_result'].get('world_size'),
'server_port': srv['raw_ping_result'].get('server_port'),
'int_ping_results': srv['raw_ping_result'].get('int_ping_results'),
'online': srv['raw_ping_result'].get('online'),
'max': srv['raw_ping_result'].get('max'),
'players': srv['raw_ping_result'].get('players'),
'desc': srv['raw_ping_result'].get('desc'),
'version': srv['raw_ping_result'].get('version'),
'icon': srv['raw_ping_result'].get('icon')
})
if (len(websocket_helper.clients) > 0):
websocket_helper.broadcast_page_params(
'/panel/server_detail',
{
'id': str(server_id)
},
'update_server_details',
{
'id': srv['raw_ping_result'].get('id'),
'started': srv['raw_ping_result'].get('started'),
'running': srv['raw_ping_result'].get('running'),
'cpu': srv['raw_ping_result'].get('cpu'),
'mem': srv['raw_ping_result'].get('mem'),
'mem_percent': srv['raw_ping_result'].get('mem_percent'),
'world_name': srv['raw_ping_result'].get('world_name'),
'world_size': srv['raw_ping_result'].get('world_size'),
'server_port': srv['raw_ping_result'].get('server_port'),
'int_ping_results': srv['raw_ping_result'].get('int_ping_results'),
'online': srv['raw_ping_result'].get('online'),
'max': srv['raw_ping_result'].get('max'),
'players': srv['raw_ping_result'].get('players'),
'desc': srv['raw_ping_result'].get('desc'),
'version': srv['raw_ping_result'].get('version'),
'icon': srv['raw_ping_result'].get('icon')
}
)
if (len(servers_ping) > 0) & (len(websocket_helper.clients) > 0):
try:
websocket_helper.broadcast_page('/panel/dashboard', 'update_server_status', servers_ping)
websocket_helper.broadcast_page('/status', 'update_server_status', servers_ping)
except:
console.warning("Can't broadcast server status to websocket")
time.sleep(5)
def log_watcher(self):
self.controller.servers.check_for_old_logs()

View File

@ -1,153 +1,162 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
{% block meta %}{% end %}
<title>{% block title %}{{ _('Default') }}{% end %}</title>
<!-- plugins:css -->
<link rel="stylesheet" href="/static/assets/vendors/mdi/css/materialdesignicons.min.css">
<link rel="stylesheet" href="/static/assets/vendors/flag-icon-css/css/flag-icon.min.css">
<link rel="stylesheet" href="/static/assets/vendors/ti-icons/css/themify-icons.css">
<link rel="stylesheet" href="/static/assets/vendors/typicons/typicons.css">
<link rel="stylesheet" href="/static/assets/vendors/fontawesome5/css/all.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs4/dt-1.10.22/fh-3.1.7/r-2.2.6/sc-2.0.3/sp-1.2.2/datatables.min.css"/>
<link rel="stylesheet" href="/static/assets/vendors/css/vendor.bundle.base.css">
<link rel="stylesheet" href="/static/assets/css/crafty.css">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
{% block meta %}{% end %}
<title>{% block title %}{{ _('Default') }}{% end %}</title>
<!-- endinject -->
<!-- plugins:css -->
<link rel="stylesheet" href="/static/assets/vendors/mdi/css/materialdesignicons.min.css">
<link rel="stylesheet" href="/static/assets/vendors/flag-icon-css/css/flag-icon.min.css">
<link rel="stylesheet" href="/static/assets/vendors/ti-icons/css/themify-icons.css">
<link rel="stylesheet" href="/static/assets/vendors/typicons/typicons.css">
<link rel="stylesheet" href="/static/assets/vendors/fontawesome5/css/all.css">
<link rel="stylesheet" type="text/css"
href="https://cdn.datatables.net/v/bs4/dt-1.10.22/fh-3.1.7/r-2.2.6/sc-2.0.3/sp-1.2.2/datatables.min.css" />
<link rel="stylesheet" href="/static/assets/vendors/css/vendor.bundle.base.css">
<link rel="stylesheet" href="/static/assets/css/crafty.css">
<!-- Plugin css for this page -->
<link rel="stylesheet" href="/static/assets/vendors/jvectormap/jquery-jvectormap.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!-- End Plugin css for this page -->
<!-- endinject -->
<!-- Layout styles -->
<link rel="stylesheet" href="/static/assets/css/dark/style.css">
<!-- End Layout styles -->
<!-- Plugin css for this page -->
<link rel="stylesheet" href="/static/assets/vendors/jvectormap/jquery-jvectormap.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!-- End Plugin css for this page -->
<link rel="shortcut icon" type="image/svg+xml" href="/static/assets/images/logo_small.svg">
<link rel="alternate icon" href="/static/assets/images/favicon.png" />
<link rel="stylesheet" href="/static/assets/css/crafty.css">
<!-- Layout styles -->
<link rel="stylesheet" href="/static/assets/css/dark/style.css">
<!-- End Layout styles -->
</head>
<link rel="shortcut icon" type="image/svg+xml" href="/static/assets/images/logo_small.svg">
<link rel="alternate icon" href="/static/assets/images/favicon.png" />
<link rel="stylesheet" href="/static/assets/css/crafty.css">
<body class="dark-theme">
<div class="container-scroller">
<!-- partial:partials/_navbar.html -->
<nav class="navbar default-layout col-lg-12 col-12 p-0 fixed-top d-flex flex-row">
<div class="text-center navbar-brand-wrapper d-flex align-items-top justify-content-center">
<a class="navbar-brand brand-logo" href="/panel/dashboard">
<img src="/static/assets/images/logo_long.svg" alt="logo" /> </a>
<a class="navbar-brand brand-logo-mini" href="/panel/dashboard">
<img src="/static/assets/images/logo_small.svg" alt="logo" /> </a>
</div>
<div class="navbar-menu-wrapper d-flex align-items-center">
<button class="navbar-toggler navbar-toggler align-self-center" type="button" data-toggle="minimize">
<span class="mdi mdi-menu"></span>
</button>
</head>
<body class="dark-theme">
<div class="container-scroller">
<!-- partial:partials/_navbar.html -->
<nav class="navbar default-layout col-lg-12 col-12 p-0 fixed-top d-flex flex-row">
<div class="text-center navbar-brand-wrapper d-flex align-items-top justify-content-center">
<a class="navbar-brand brand-logo" href="/panel/dashboard">
<img src="/static/assets/images/logo_long.svg" alt="logo" /> </a>
<a class="navbar-brand brand-logo-mini" href="/panel/dashboard">
<img src="/static/assets/images/logo_small.svg" alt="logo" /> </a>
</div>
<div class="navbar-menu-wrapper d-flex align-items-center">
<button class="navbar-toggler navbar-toggler align-self-center" type="button" data-toggle="minimize">
<span class="mdi mdi-menu"></span>
</button>
{% include notify.html %}
<button class="navbar-toggler navbar-toggler-right d-lg-none align-self-center" type="button" data-toggle="offcanvas">
<span class="mdi mdi-menu"></span>
</button>
</div>
</nav>
{% include main_menu.html %}
<div class="main-panel">
<div class="warnings">
<noscript class="noscript-warning" style="padding: 20px; background-color: rgb(247, 151, 15);">
<div>{% raw translate('base', 'doesNotWorkWithoutJavascript', data['lang']) %}</div>
</noscript>
</div>
{% block content %}
{% end %}
{% include footer.html %}
</div>
<!-- main-panel ends -->
<button class="navbar-toggler navbar-toggler-right d-lg-none align-self-center" type="button"
data-toggle="offcanvas">
<span class="mdi mdi-menu"></span>
</button>
</div>
<!-- page-body-wrapper ends -->
</nav>
{% include main_menu.html %}
<div class="main-panel">
<div class="warnings">
<noscript class="noscript-warning" style="padding: 20px; background-color: rgb(247, 151, 15);">
<div>{% raw translate('base', 'doesNotWorkWithoutJavascript', data['lang']) %}</div>
</noscript>
</div>
{% block content %}
{% end %}
{% include footer.html %}
</div>
<!-- main-panel ends -->
</div>
<!-- page-body-wrapper ends -->
</div>
<style>
.notifications {
position: fixed;
width: 200px;
top: 70px;
right: 0px;
}
.notification {
position: relative;
box-sizing: border-box;
padding: 0.5rem;
padding-left: 0.7rem;
width: 180px;
margin-left: 10px;
margin-right: 10px;
background: #282a40;
transition: right 0.75s, opacity 0.75s, top 0.75s;
right: -6rem;
opacity: 0.1;
margin-bottom: 1rem;
z-index: 999;
top: 0px;
}
.notification.active {
right: 0rem;
opacity: 1;
}
.notification.remove {
right: 0rem;
opacity: 0.1;
top: -2rem;
}
.notification p {
margin: 0px;
width: calc(160.8px - 16px);
z-index: inherit;
}
.notification span {
position: absolute;
right: 0.5rem;
top: 0.46rem;
cursor: pointer;
font-weight: bold;
line-height: 20px;
font-size: 22px;
user-select: none;
z-index: inherit;
}
</style>
<div class="notifications"></div>
<style>
.notifications {
position: fixed;
width: 200px;
top: 70px;
right: 0px;
}
.notification {
position: relative;
box-sizing: border-box;
padding: 0.5rem;
padding-left: 0.7rem;
width: 180px;
margin-left: 10px;
margin-right: 10px;
background: #282a40;
transition: right 0.75s, opacity 0.75s, top 0.75s;
right: -6rem;
opacity: 0.1;
margin-bottom: 1rem;
z-index: 999;
top: 0px;
}
.notification.active {
right: 0rem;
opacity: 1;
}
.notification.remove {
right: 0rem;
opacity: 0.1;
top: -2rem;
}
.notification p {
margin: 0px;
width: calc(160.8px - 16px);
z-index: inherit;
}
.notification span {
position: absolute;
right: 0.5rem;
top: 0.46rem;
cursor: pointer;
font-weight: bold;
line-height: 20px;
font-size: 22px;
user-select: none;
z-index: inherit;
}
</style>
<div class="notifications"></div>
<script src="/static/assets/vendors/js/vendor.bundle.base.js"></script>
<script src="/static/assets/js/shared/off-canvas.js"></script>
<script src="/static/assets/js/shared/hoverable-collapse.js"></script>
<script src="/static/assets/js/shared/misc.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.10.22/fh-3.1.7/r-2.2.6/sc-2.0.3/sp-1.2.2/datatables.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/5.4.0/bootbox.min.js"></script>
<script src="/static/assets/vendors/js/vendor.bundle.base.js"></script>
<script src="/static/assets/js/shared/off-canvas.js"></script>
<script src="/static/assets/js/shared/hoverable-collapse.js"></script>
<script src="/static/assets/js/shared/misc.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.10.22/fh-3.1.7/r-2.2.6/sc-2.0.3/sp-1.2.2/datatables.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/5.4.0/bootbox.min.js"></script>
<script type="text/javascript" src="/static/assets/js/motd.js"></script>
<script>
$.extend($.fn.dataTable.defaults, {
language: {% raw translate('datatables', 'i18n', data['lang']) %}
<script>
$.extend($.fn.dataTable.defaults, {
language: {% raw translate('datatables', 'i18n', data['lang']) %}
})
//used to get cookies from browser - this is part of tornados xsrf protection - it's for extra security
function getCookie(name) {
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return r ? r[1] : undefined;
//used to get cookies from browser - this is part of tornados xsrf protection - it's for extra security
function getCookie(name) {
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return r ? r[1] : undefined;
}
// tool tips
@ -156,13 +165,13 @@
})
// Notify
$(document).ready(function(){
$("#notificationDropdown").click(function(){
$.get("/ajax/announcements", function(data){
$(document).ready(function () {
$("#notificationDropdown").click(function () {
$.get("/ajax/announcements", function (data) {
console.log(data);
bootbox.alert({
title: "Notifications",
message: data,
title: "Notifications",
message: data,
});
});
@ -170,146 +179,150 @@
});
// {% if request.protocol == 'https' %}
let usingWebSockets = true;
let usingWebSockets = true;
let listenEvents = [];
let listenEvents = [];
try {
pageQueryParams = 'page_query_params=' + encodeURIComponent(location.search)
page = 'page=' + encodeURIComponent(location.pathname)
var wsInternal = new WebSocket('wss://' + location.host + '/ws?' + page + '&' + pageQueryParams);
wsInternal.onopen = function() {
console.log('opened WebSocket connection:', wsInternal)
};
wsInternal.onmessage = function (rawMessage) {
var message = JSON.parse(rawMessage.data);
try {
pageQueryParams = 'page_query_params=' + encodeURIComponent(location.search)
page = 'page=' + encodeURIComponent(location.pathname)
var wsInternal = new WebSocket('wss://' + location.host + '/ws?' + page + '&' + pageQueryParams);
wsInternal.onopen = function () {
console.log('opened WebSocket connection:', wsInternal)
};
wsInternal.onmessage = function (rawMessage) {
var message = JSON.parse(rawMessage.data);
console.log('got message: ', message)
console.log('got message: ', message)
listenEvents
.filter(listenedEvent => listenedEvent.event == message.event)
.forEach(listenedEvent => listenedEvent.callback(message.data))
};
wsInternal.onerror = function (errorEvent) {
console.error('WebSocket Error', errorEvent);
};
wsInternal.onclose = function (closeEvent) {
console.log('Closed WebSocket', closeEvent);
};
listenEvents
.filter(listenedEvent => listenedEvent.event == message.event)
.forEach(listenedEvent => listenedEvent.callback(message.data))
};
wsInternal.onerror = function (errorEvent) {
console.error('WebSocket Error', errorEvent);
};
wsInternal.onclose = function (closeEvent) {
console.log('Closed WebSocket', closeEvent);
};
webSocket = {
on: function (event, callback) {
console.log('registered ' + event + ' event');
listenEvents.push({ event: event, callback: callback })
},
emit: function (event, data) {
var message = {
event: event,
data: data
}
wsInternal.send(JSON.stringify(message));
webSocket = {
on: function (event, callback) {
console.log('registered ' + event + ' event');
listenEvents.push({ event: event, callback: callback })
},
emit: function (event, data) {
var message = {
event: event,
data: data
}
wsInternal.send(JSON.stringify(message));
}
} catch (error) {
console.error('Error while making websocket helpers', error);
usingWebSockets = false;
}
} catch (error) {
console.error('Error while making websocket helpers', error);
usingWebSockets = false;
}
// {% else %}
let usingWebSockets = false;
warn('WebSockets are not supported in Crafty if not using the https protocol')
var webSocket;
let usingWebSockets = false;
warn('WebSockets are not supported in Crafty if not using the https protocol')
var webSocket;
// {% end%}
if (webSocket) {
webSocket.on('send_start_error', function (start_error) {
var x = document.querySelector('.bootbox');
if(x){
x.remove()}
var x = document.querySelector('.modal-backdrop');
if(x){
x.remove()}
bootbox.alert({
message: start_error.error,
callback: function () {
location.reload();
}
})
});
}
if (webSocket) {
webSocket.on('send_logs_bootbox', function (server_id) {
var x = document.querySelector('.bootbox');
if(x){
x.remove()}
var x = document.querySelector('.modal-backdrop');
if(x){
x.remove()}
bootbox.alert({
title: "{{ translate('notify', 'downloadLogs', data['lang']) }}",
message: "{{ translate('notify', 'finishedPreparing', data['lang']) }}",
buttons: {
ok: {
label: 'Download',
className: 'btn-info'
if (webSocket) {
webSocket.on('send_start_error', function (start_error) {
var x = document.querySelector('.bootbox');
if (x) {
x.remove()
}
},
callback: function(){
console.log("in callback")
location.href="/panel/download_support_package";
}
});
});
}
if (webSocket) {
webSocket.on('send_eula_bootbox', function (server_id) {
var x = document.querySelector('.bootbox');
if(x){
x.remove()}
var x = document.querySelector('.modal-backdrop');
if(x){
x.remove()}
bootbox.confirm({
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']) %}',
buttons: {
confirm: {
label: 'Yes',
className: 'btn-info'
},
cancel: {
label: 'No',
className: 'btn-secondary'
var x = document.querySelector('.modal-backdrop');
if (x) {
x.remove()
}
},
callback: function (result) {
if(result == true){
eulaAgree(server_id.id)
}
else {
location.reload()
}
bootbox.alert({
message: start_error.error,
callback: function () {
location.reload();
}
})
});
}
if (webSocket) {
webSocket.on('send_logs_bootbox', function (server_id) {
var x = document.querySelector('.bootbox');
if (x) {
x.remove()
}
var x = document.querySelector('.modal-backdrop');
if (x) {
x.remove()
}
bootbox.alert({
title: "{{ translate('notify', 'downloadLogs', data['lang']) }}",
message: "{{ translate('notify', 'finishedPreparing', data['lang']) }}",
buttons: {
ok: {
label: 'Download',
className: 'btn-info'
}
},
callback: function () {
console.log("in callback")
location.href = "/panel/download_support_package";
}
});
});
}
})
});
}
function eulaAgree (server_id, command){
<!-- this getCookie function is in base.html-->
if (webSocket) {
webSocket.on('send_eula_bootbox', function (server_id) {
var x = document.querySelector('.bootbox');
if (x) {
x.remove()
}
var x = document.querySelector('.modal-backdrop');
if (x) {
x.remove()
}
bootbox.confirm({
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']) %}',
buttons: {
confirm: {
label: 'Yes',
className: 'btn-info'
},
cancel: {
label: 'No',
className: 'btn-secondary'
}
},
callback: function (result) {
if (result == true) {
eulaAgree(server_id.id)
}
else {
location.reload()
}
}
})
});
}
function eulaAgree(server_id, command) {
//< !--this getCookie function is in base.html-- >
var token = getCookie("_xsrf");
$.ajax({
type: "POST",
headers: {'X-XSRFToken': token},
url: '/ajax/eula?id='+ server_id,
success: function(data){
headers: { 'X-XSRFToken': token },
url: '/ajax/eula?id=' + server_id,
success: function (data) {
console.log("got response:");
console.log(data);
location.reload();
}
});
}
@ -332,7 +345,7 @@ if (webSocket) {
closeEl.style.lineHeight = '20px';
closeEl.style.cursor = 'pointer';
closeEl.addEventListener('click', function () {this.parentElement.style.display='none';});
closeEl.addEventListener('click', function () { this.parentElement.style.display = 'none'; });
var parentEl = document.createElement('div');
@ -360,7 +373,7 @@ if (webSocket) {
paragraphEl.textContent = message;
closeEl.innerHTML = '&times;';
closeEl.addEventListener('click', function () {closeNotification(this)});
closeEl.addEventListener('click', function () { closeNotification(this) });
var parentEl = document.createElement('div');
parentEl.appendChild(paragraphEl);
@ -388,25 +401,26 @@ if (webSocket) {
}
webSocket.on('notification', notify);
$(document).ready(function(){
$('#support_logs').click(function(){
$(document).ready(function () {
$('#support_logs').click(function () {
var dialog = bootbox.dialog({
message: '<p class="text-center mb-0"><i class="fa fa-spin fa-cog"></i>{{ translate('notify', 'preparingLogs', data['lang']) }}</p>',
closeButton: false
});
setTimeout(function () {
location.href = "/panel/support_logs";
}, 6000);
});
setTimeout(function(){
location.href="/panel/support_logs";
}, 6000);
});
});
});
</script>
</script>
{% block js %}
<!-- Custom js for base.html page partial pages -->
<!-- End custom js for base.html page -->
{% end %}
{% block js %}
<!-- Custom js for this page -->
<!-- End custom js for this page -->
{% end %}
</body>
</body>
</html>

View File

@ -1,7 +1,6 @@
{% extends ../base.html %}
{% block meta %}
<!-- <meta http-equiv="refresh" content="60">-->
{% end %}
{% block title %}Crafty Controller - Blank Page{% end %}

View File

@ -1,8 +1,6 @@
{% extends ../base.html %}
{% block meta %}
<!-- <meta http-equiv="refresh" content="60">-->
{% end %}
{% block title %}Crafty Controller - Activity Logs{% end %}
@ -93,7 +91,7 @@ $( document ).ready(function() {
if($(window).width() < 1000){
$('.too_small').popover("show");
}
});
$(window).ready(function(){
$('body').click(function(){

View File

@ -1,7 +1,6 @@
{% extends ../base.html %}
{% block meta %}
<!-- <meta http-equiv="refresh" content="60">-->
{% end %}
{% block title %}Crafty Controller - Contribute{% end %}
@ -73,7 +72,7 @@
<div class="media-body">
<p class="card-text">
Thank you for your interest in contributing to Aracdia Technology's Crafty Controller.
Thank you for your interest in contributing to Aracdia Technology's Crafty Controller.
We are always thinking of new ways for our community to contribute to this awesome project. <br><br> If you don't see
a contribution method that peaks your interest now please check back soon.
</p>

View File

@ -1,7 +1,6 @@
{% extends ../base.html %}
{% block meta %}
<!-- <meta http-equiv="refresh" content="60">-->
{% end %}
{% block title %}Crafty Controller - Credits{% end %}

View File

@ -1,7 +1,6 @@
{% extends ../base.html %}
{% block meta %}
<meta http-equiv="refresh" content="60">
{% end %}
{% block title %}Crafty Controller - {{ translate('dashboard', 'dashboard', data['lang']) }}{% end %}
@ -10,7 +9,7 @@
<div class="content-wrapper">
<!-- Page Title Header Starts-->
<!-- Page Title Header Starts-->
<div class="row page-title-header">
<div class="col-12">
<div class="page-header">
@ -29,16 +28,21 @@
<div class="col-lg-4 col-md-6">
<div class="d-flex">
<div class="wrapper">
<h5 class="mb-1 font-weight-medium text-primary"> {{ translate('dashboard', 'host', data['lang']) }}</h5>
<h5 class="mb-1 font-weight-medium text-primary"> {{ translate('dashboard', 'host', data['lang']) }}
</h5>
<h3 class="mb-0 font-weight-semibold"> <i class="fas fa-chart-line"></i></h3>
</div>
<div class="wrapper my-auto ml-auto ml-lg-4">
<p id="cpu_data" class="mb-0 text-success" data-toggle="tooltip" data-placement="top" data-html="true" title="{% raw translate('dashboard', 'cpuCores', data['lang']) %}: {{ data.get('hosts_data').get('cpu_cores') }} <br /> {% raw translate('dashboard', 'cpuCurFreq', data['lang']) %}: {{ data.get('hosts_data').get('cpu_cur_freq') }} <br /> {% raw translate('dashboard', 'cpuMaxFreq', data['lang']) %}: {{ data.get('hosts_data').get('cpu_max_freq') }}" >
{{ translate('dashboard', 'cpuUsage', data['lang']) }}: <span id="cpu_usage">{{ data.get('hosts_data').get('cpu_usage') }}</span>
<p id="cpu_data" class="mb-0 text-success" data-toggle="tooltip" data-placement="top" data-html="true"
title="{% raw translate('dashboard', 'cpuCores', data['lang']) %}: {{ data.get('hosts_data').get('cpu_cores') }} <br /> {% raw translate('dashboard', 'cpuCurFreq', data['lang']) %}: {{ data.get('hosts_data').get('cpu_cur_freq') }} <br /> {% raw translate('dashboard', 'cpuMaxFreq', data['lang']) %}: {{ data.get('hosts_data').get('cpu_max_freq') }}">
{{ translate('dashboard', 'cpuUsage', data['lang']) }}: <span id="cpu_usage">{{
data.get('hosts_data').get('cpu_usage') }}</span>
</p>
<p id="mem_usage" class="mb-0 text-danger" data-toggle="tooltip" data-placement="top" title="{{ translate('dashboard', 'memUsage', data['lang']) }}: {{ data.get('hosts_data').get('mem_usage') }}" >
{{ translate('dashboard', 'memUsage', data['lang']) }}: <span id="mem_percent">{{ data.get('hosts_data').get('mem_percent') }}%</span>
<p id="mem_usage" class="mb-0 text-danger" data-toggle="tooltip" data-placement="top"
title="{{ translate('dashboard', 'memUsage', data['lang']) }}: {{ data.get('hosts_data').get('mem_usage') }}">
{{ translate('dashboard', 'memUsage', data['lang']) }}: <span id="mem_percent">{{
data.get('hosts_data').get('mem_percent') }}%</span>
</p>
</div>
</div>
@ -46,20 +50,24 @@
<div class="col-lg-4 col-md-6 mt-md-0 mt-4">
<div class="d-flex">
<div class="wrapper">
<h5 class="mb-1 font-weight-medium text-primary">{{ translate('dashboard', 'servers', data['lang']) }}</h5>
<h5 class="mb-1 font-weight-medium text-primary">{{ translate('dashboard', 'servers', data['lang']) }}
</h5>
<h3 class="mb-0 font-weight-semibold">{{ data['server_stats']['total'] }}</h3>
</div>
<div class="wrapper my-auto ml-auto ml-lg-4">
<p class="mb-0 text-success">{{ data['server_stats']['running'] }} {{ translate('dashboard', 'online', data['lang']).lower() }}</p>
<p class="mb-0 text-warning"> {{ data['server_stats']['stopped'] }} {{ translate('dashboard', 'offline', data['lang']).lower() }}</p>
<p class="mb-0 text-success">{{ data['server_stats']['running'] }} {{ translate('dashboard', 'online',
data['lang']).lower() }}</p>
<p class="mb-0 text-warning"> {{ data['server_stats']['stopped'] }} {{ translate('dashboard',
'offline', data['lang']).lower() }}</p>
</div>
</div>
</div>
<div class="col-lg-4 col-md-6 mt-md-0 mt-4">
<div class="d-flex">
<div class="wrapper">
<h5 class="mb-1 font-weight-medium text-primary">{{ translate('dashboard', 'players', data['lang']) }}</h5>
<h5 class="mb-1 font-weight-medium text-primary">{{ translate('dashboard', 'players', data['lang']) }}
</h5>
<h3 class="mb-0 font-weight-semibold">{{ data['num_players'] }}</h3>
</div>
@ -79,24 +87,29 @@
<div class="col-md-12 col-lg-12 grid-margin stretch-card">
<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-server"></i> &nbsp;{{ translate('dashboard', 'allServers', data['lang']) }}</h4>
<h4 class="card-title"><i class="fas fa-server"></i> &nbsp;{{ translate('dashboard', 'allServers',
data['lang']) }}</h4>
{% if len(data['servers']) > 0 %}
<span class="too_small" title="{{ translate('dashboard', 'cannotSeeOnMobile', data['lang']) }}", data-content="{{ translate('dashboard', 'cannotSeeOnMobile2', data['lang']) }}", data-placement="top"></span>
<span class="too_small" title="{{ translate('dashboard', 'cannotSeeOnMobile', data['lang']) }}" ,
data-content="{{ translate('dashboard', 'cannotSeeOnMobile2', data['lang']) }}" ,
data-placement="top"></span>
{% end %}
<div><a class="nav-link" href="/server/step1"><i class="fas fa-plus-circle"></i> &nbsp; {{ translate('dashboard', 'newServer', data['lang']) }}</a></div>
<div><a class="nav-link" href="/server/step1"><i class="fas fa-plus-circle"></i> &nbsp; {{
translate('dashboard', 'newServer', data['lang']) }}</a></div>
</div>
<div class="card-body">
<div class="table-responsive">
{% if len(data['servers']) == 0%}
<div style="text-align: center; color: grey;">
<h1>{{ translate('dashboard', 'welcome', data['lang']) }}</h1>
<br>
<h7>{{ translate('dashboard', 'no-servers', data['lang']) }} {{ translate('dashboard', 'newServer', data['lang']) }}.</h7>
</div>
{% end %}
{% if len(data['servers']) > 0 %}
{% if len(data['servers']) == 0%}
<div style="text-align: center; color: grey;">
<h1>{{ translate('dashboard', 'welcome', data['lang']) }}</h1>
<br>
<h7>{{ translate('dashboard', 'no-servers', data['lang']) }} {{ translate('dashboard', 'newServer',
data['lang']) }}.</h7>
</div>
{% end %}
{% if len(data['servers']) > 0 %}
<table class="table table-hover">
<thead>
<tr class="rounded">
@ -121,24 +134,37 @@
<td id="controls{{server['server_data']['server_id']}}" class="actions_serverlist">
{% if server['user_command_permission'] %}
{% if server['stats']['running'] %}
<a class="stop_button" data-id="{{server['server_data']['server_id']}}" data-toggle="tooltip" title={{ translate('dashboard', 'stop', data['lang']) }}> <i class="fas fa-stop"></i></a> &nbsp;
<a class="restart_button" data-id="{{server['server_data']['server_id']}}" data-toggle="tooltip" title={{ translate('dashboard', 'restart', data['lang']) }}> <i class="fas fa-sync"></i></a> &nbsp;
<a class="kill_button" data-id="{{server['server_data']['server_id']}}" class="kill_button" data-toggle="tooltip" title={{ translate('dashboard', 'kill', data['lang']) }}> <i class="fas fa-skull"></i></a> &nbsp;
{% elif server['stats']['updating']%}
<a data-id="{{server['server_data']['server_id']}}" class="">{{ translate('serverTerm', 'updating', data['lang']) }}</i></a>
{% elif server['stats']['waiting_start']%}
<a data-id="{{server['server_data']['server_id']}}" class="" title={{ translate('dashboard', 'delay-explained', data['lang'])}}>{{ translate('dashboard', 'starting', data['lang']) }}</i></a>
{% else %}
<a data-id="{{server['server_data']['server_id']}}" class="play_button"><i class="fas fa-play" data-toggle="tooltip" title={{ translate('dashboard', 'start', data['lang']) }}></i></a> &nbsp;
<a data-id="{{server['server_data']['server_id']}}" class="clone_button"> <i class="fas fa-clone" data-toggle="tooltip" title={{ translate('dashboard', 'clone', data['lang']) }}></i></a>&nbsp;
<a class="kill_button" data-id="{{server['server_data']['server_id']}}" class="kill_button" data-toggle="tooltip" title={{ translate('dashboard', 'kill', data['lang']) }}> <i class="fas fa-skull"></i></a> &nbsp;
{% end %}
{% if server['stats']['running'] %}
<a class="stop_button" data-id="{{server['server_data']['server_id']}}" data-toggle="tooltip"
title={{ translate('dashboard', 'stop' , data['lang']) }}> <i class="fas fa-stop"></i></a> &nbsp;
<a class="restart_button" data-id="{{server['server_data']['server_id']}}" data-toggle="tooltip"
title={{ translate('dashboard', 'restart' , data['lang']) }}> <i class="fas fa-sync"></i></a>
&nbsp;
<a class="kill_button" data-id="{{server['server_data']['server_id']}}" class="kill_button"
data-toggle="tooltip" title={{ translate('dashboard', 'kill' , data['lang']) }}> <i
class="fas fa-skull"></i></a> &nbsp;
{% elif server['stats']['updating']%}
<a data-id="{{server['server_data']['server_id']}}" class="">{{ translate('serverTerm', 'updating',
data['lang']) }}</i></a>
{% elif server['stats']['waiting_start']%}
<a data-id="{{server['server_data']['server_id']}}" class="" title={{
translate('dashboard', 'delay-explained' , data['lang'])}}>{{ translate('dashboard', 'starting',
data['lang']) }}</i></a>
{% else %}
<a data-id="{{server['server_data']['server_id']}}" class="play_button"><i class="fas fa-play"
data-toggle="tooltip" title={{ translate('dashboard', 'start' , data['lang']) }}></i></a> &nbsp;
<a data-id="{{server['server_data']['server_id']}}" class="clone_button"> <i class="fas fa-clone"
data-toggle="tooltip" title={{ translate('dashboard', 'clone' , data['lang']) }}></i></a>&nbsp;
<a class="kill_button" data-id="{{server['server_data']['server_id']}}" class="kill_button"
data-toggle="tooltip" title={{ translate('dashboard', 'kill' , data['lang']) }}> <i
class="fas fa-skull"></i></a> &nbsp;
{% end %}
{% end %}
</td>
<td>
<div class="progress mb-1" data-toggle="tooltip" data-placement="top" title="{{server['stats']['cpu']}}">
<td id="server_cpu_{{server['server_data']['server_id']}}">
<div class="progress mb-1" data-toggle="tooltip" data-placement="top"
title="{{server['stats']['cpu']}}">
<div class="progress-bar
{% if server['stats']['cpu'] <= 33 %}
bg-success
@ -147,13 +173,15 @@
{% else %}
bg-danger
{% end %}
" role="progressbar" style="width: {{server['stats']['cpu']}}%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
" role="progressbar" style="width: {{server['stats']['cpu']}}%" aria-valuenow="0"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
{{server['stats']['cpu']}}%
</td>
<td>
<div class="progress mb-1" data-toggle="tooltip" data-placement="top" title="{{server['stats']['mem']}}">
<td id="server_mem_{{server['server_data']['server_id']}}">
<div class="progress mb-1" data-toggle="tooltip" data-placement="top"
title="{{server['stats']['mem']}}">
<div class="progress-bar
{% if server['stats']['mem_percent'] <= 33 %}
bg-success
@ -162,38 +190,42 @@
{% else %}
bg-danger
{% end %}
" role="progressbar" style="width: {{server['stats']['mem_percent']}}%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
" role="progressbar" style="width: {{server['stats']['mem_percent']}}%" aria-valuenow="0"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
{{server['stats']['mem_percent']}}% -
{% if server['stats']['mem'] == 0 %}
0 MB
0 MB
{% else %}
{{server['stats']['mem']}}
{{server['stats']['mem']}}
{% end %}
</td>
<td>
<td id="server_world_{{server['server_data']['server_id']}}">
{{ server['stats']['world_name'] }} : {{ server['stats']['world_size'] }}
</td>
<td>
<td id="server_desc_{{server['server_data']['server_id']}}">
{% if server['stats']['int_ping_results'] %}
{{ server['stats']['online'] }} / {{ server['stats']['max'] }} {{ translate('dashboard', 'max', data['lang']) }}<br />
{{ server['stats']['online'] }} / {{ server['stats']['max'] }} {{ translate('dashboard', 'max',
data['lang']) }} <br />
{% if server['stats']['desc'] != 'False' %}
{{ server['stats']['desc'] }} <br />
{% end %}
{% if server['stats']['desc'] != 'False' %}
{{ server['stats']['desc'] }} <br />
{% end %}
{% if server['stats']['version'] != 'False' %}
{{ server['stats']['version'] }}
{% end %}
{% if server['stats']['version'] != 'False' %}
{{ server['stats']['version'] }}
{% end %}
{% end %}
</td>
<td>
<td id="server_running_status_{{server['server_data']['server_id']}}">
{% if server['stats']['running'] %}
<i class="fas fa-thumbs-up"></i> <span class="text-success">{{ translate('dashboard', 'online', data['lang']) }}</span>
<i class="fas fa-thumbs-up"></i> <span class="text-success">{{ translate('dashboard', 'online',
data['lang']) }}</span>
{% else %}
<i class="fas fa-thumbs-down"></i> <span class="text-danger">{{ translate('dashboard', 'offline', data['lang']) }}</span>
<i class="fas fa-thumbs-down"></i> <span class="text-danger">{{ translate('dashboard', 'offline',
data['lang']) }}</span>
{% end %}
</td>
</tr>
@ -212,192 +244,303 @@
</div>
<!-- content-wrapper ends -->
<style>
.popover-body{
color: white !important;;
}
.popover-body {
color: white !important;
;
}
</style>
{% end %}
{% block js %}
<script src="/static/assets/js/motd.js"></script>
<script>
$(document).ready(function(){
$('[data-toggle="popover"]').popover();
if($(window).width() < 1000){
$('.too_small').popover("show");
function display_motd() {
var all_motds = Array.from(document.getElementsByClassName('input_motd'));
for (element of all_motds) {
initParser(element.id, element.id);
};
}
});
$(window).ready(function(){
$('body').click(function(){
$('.too_small').popover("hide");
$(document).ready(function () {
$('[data-toggle="popover"]').popover();
if ($(window).width() < 1000) {
$('.too_small').popover("show");
}
});
$(window).ready(function () {
$('body').click(function () {
$('.too_small').popover("hide");
});
});
$(window).resize(function() {
// This will execute whenever the window is resized
if($(window).width() < 1000){
$('.too_small').popover("show");
}
else{
$('.too_small').popover("hide");
} // New width
});
});
$(window).resize(function () {
// This will execute whenever the window is resized
if ($(window).width() < 1000) {
$('.too_small').popover("show");
}
else {
$('.too_small').popover("hide");
} // New width
});
</script>
<script>
function send_command (server_id, command){
/* this getCookie function is in base.html */
var token = getCookie("_xsrf");
function send_command(server_id, command) {
/* this getCookie function is in base.html */
var token = getCookie("_xsrf");
$.ajax({
type: "POST",
headers: {'X-XSRFToken': token},
url: '/server/command?command=' + command + '&id=' + server_id,
success: function(data){
console.log("got response:");
console.log(data);
setTimeout(function(){
if (command != 'start_server'){
$.ajax({
type: "POST",
headers: { 'X-XSRFToken': token },
url: '/server/command?command=' + command + '&id=' + server_id,
success: function (data) {
console.log("got response:");
console.log(data);
/*setTimeout(function () {
if (command != 'start_server') {
location.reload();
}
}, 10000);
}, 10000);*/
}
});
}
function send_kill(server_id) {
/* this getCookie function is in base.html */
var token = getCookie("_xsrf");
$.ajax({
type: "POST",
headers: { 'X-XSRFToken': token },
url: '/ajax/kill?id=' + server_id,
success: function (data) {
console.log("got response:");
console.log(data);
/*setTimeout(function () {
location.reload();
}, 10000);*/
}
});
}
function update_one_server_status(server) {
server_cpu = document.getElementById('server_cpu_' + server.id);
server_mem = document.getElementById('server_mem_' + server.id);
server_world = document.getElementById('server_world_' + server.id);
server_desc = document.getElementById('server_desc_' + server.id);
server_online_status = document.getElementById('server_running_status_' + server.id);
console.log("Received Data : " + server.id + ": " + server);
/* TODO Update each element */
/* Update CPU */
cpu_status = "";
if (server.cpu <= 33)
{
cpu_status = "bg-success";
}
});
}
function send_kill (server_id){
/* this getCookie function is in base.html */
var token = getCookie("_xsrf");
$.ajax({
type: "POST",
headers: {'X-XSRFToken': token},
url: '/ajax/kill?id=' + server_id,
success: function(data){
console.log("got response:");
console.log(data);
setTimeout(function(){
location.reload();
}, 10000);
else if (server.cpu > 33 && server.cpu <= 66)
{
cpu_status = "bg-warning";
}
});
}
else
{
cpu_status = "bg-danger";
}
server_cpu.innerHTML = `<div class="progress mb-1" data-toggle="tooltip" data-placement="top" title="`+ server.cpu +`"><div class="progress-bar `+ cpu_status + `" role="progressbar" style="width: `+ server.cpu + `%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div></div>`+ server.cpu +`%`;
$( document ).ready(function() {
console.log('ready for JS!')
$( ".play_button" ).click(function() {
server_id = $(this).attr("data-id");
send_command(server_id, 'start_server');
bootbox.alert({
backdrop: true,
title: '{% raw translate("dashboard", "sendingCommand", data['lang']) %}',
message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> &nbsp; {% raw translate("dashboard", "bePatientStart", data['lang']) %} </div>'
/* Update Memory */
mem_status = "";
total_mem = "";
if (server.mem_percent <= 33)
{
mem_status = "bg-success";
} else if (server.mem_percent > 33 && server.mem_percent <= 66)
{
mem_status = "bg-warning";
}
else
{
mem_status = "bg-danger";
}
if (server.mem == 0)
{
total_mem = "0 MB";
}
else
{
total_mem = server.mem;
}
server_mem.innerHTML = `<div class="progress mb-1" data-toggle="tooltip" data-placement="top" title="`+ server_mem +`"><div class="progress-bar `+ mem_status + `" role="progressbar" style="width: `+ server.mem_percent + `%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div></div>`+ server.mem_percent +`% - ` + total_mem;
/* Update World Infos */
server_world.innerHTML = server.world_name + ` : ` + server.world_size
/* Update Server Infos */
if (server.int_ping_results) {
/* Update Players */
if (server.players) {
server_desc.innerHTML = server.online + ` / ` + server.max + ` {{ translate('dashboard', 'max', data['lang']) }}<br />`
server_infos = "";
server_infos = server.online + " / " + server.max + "{{ translate('dashboard', 'max', data['lang']) }}<br />"
}
/* Update Motd */
var motd = "";
if (server.desc) {
motd = `<span id="input_motd_` + server.id + `" class="input_motd">` + server.desc + `</span>`;
server_infos = server_infos + motd + "<br />";
}
/* Version */
if (server.version) {
server_infos = server_infos + server.version
}
server_desc.innerHTML = server_infos;
}
/* Update Online Status */
var online_status = "";
if (server.running) {
online_status = `<span class="text-success"><i class="fas fa-signal"></i> {{ translate('dashboard', 'online', data['lang'])}}</span>`;
}
else {
online_status = `<span class="text-danger"><i class="fas fa-ban"></i> {{ translate('dashboard', 'offline', data['lang'])}}</span>`;
}
server_online_status.innerHTML = online_status;
}
function update_servers_status(data) {
console.log(data);
for (server of data) {
update_one_server_status(server);
}
display_motd();
}
$(document).ready(function () {
console.log('ready for JS!')
$(".play_button").click(function () {
server_id = $(this).attr("data-id");
send_command(server_id, 'start_server');
bootbox.alert({
backdrop: true,
title: '{% raw translate("dashboard", "sendingCommand", data['lang']) %}',
message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> &nbsp; {% raw translate("dashboard", "bePatientStart", data['lang']) %} </div>'
});
});
$( ".stop_button" ).click(function() {
console.log("stopping server");
server_id = $(this).attr("data-id");
send_command(server_id, 'stop_server');
bootbox.alert({
backdrop: true,
title: '{% raw translate("dashboard", "sendingCommand", data['lang']) %}',
message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> &nbsp; {% raw translate("dashboard", "bePatientStop", data['lang']) %} </div>'
});
});
$( ".restart_button" ).click(function() {
server_id = $(this).attr("data-id");
send_command(server_id, 'restart_server');
bootbox.alert({
backdrop: true,
title: '{% raw translate("dashboard", "sendingCommand", data['lang']) %}',
message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> &nbsp; {% raw translate("dashboard", "bePatientRestart", data['lang']) %} </div>'
$(".stop_button").click(function () {
console.log("stopping server");
server_id = $(this).attr("data-id");
send_command(server_id, 'stop_server');
bootbox.alert({
backdrop: true,
title: '{% raw translate("dashboard", "sendingCommand", data['lang']) %}',
message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> &nbsp; {% raw translate("dashboard", "bePatientStop", data['lang']) %} </div>'
});
});
$( ".kill_button" ).click(function() {
});
$(".restart_button").click(function () {
server_id = $(this).attr("data-id");
send_command(server_id, 'restart_server');
bootbox.alert({
backdrop: true,
title: '{% raw translate("dashboard", "sendingCommand", data['lang']) %}',
message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> &nbsp; {% raw translate("dashboard", "bePatientRestart", data['lang']) %} </div>'
});
});
$(".kill_button").click(function () {
server_id = $(this).attr("data-id");
bootbox.confirm({
message: "This will kill the server process and all it's subprocesses. Killing a process can potentially corrupt files. Only do this in extreme circumstances. Are you sure you would like to continue?",
buttons: {
confirm: {
message: "This will kill the server process and all it's subprocesses. Killing a process can potentially corrupt files. Only do this in extreme circumstances. Are you sure you would like to continue?",
buttons: {
confirm: {
label: '{% raw translate("dashboard", "kill", data['lang']) %}',
className: 'btn-danger'
},
cancel: {
},
cancel: {
label: '{% raw translate("panelConfig", "cancel", data['lang']) %}',
className: 'btn-secondary'
}
},
callback: function (result) {
if(result){
send_kill(server_id);
var dialog = bootbox.dialog({
title: '{% raw translate("dashboard", "killing", data['lang']) %}',
message: '<p><i class="fa fa-spin fa-spinner"></i> Loading...</p>'
});
dialog.init(function(){
setTimeout(function(){
location.reload();
}, 15000);
});
}
}
});
});
if (webSocket) {
cpu_data = document.getElementById('cpu_data');
cpu_usage = document.getElementById('cpu_usage');
mem_usage = document.getElementById('mem_usage');
mem_percent = document.getElementById('mem_percent');
}
},
callback: function (result) {
if (result) {
send_kill(server_id);
var dialog = bootbox.dialog({
title: '{% raw translate("dashboard", "killing", data['lang']) %}',
message: '<p><i class="fa fa-spin fa-spinner"></i> Loading...</p>'
});
webSocket.on('update_host_stats', function (hostStats) {
var cpuDataTitle = `{% raw translate('dashboard', 'cpuCores', data['lang']) %}: ${hostStats.cpu_cores} <br /> {% raw translate("dashboard", "cpuCurFreq", data['lang']) %}: ${hostStats.cpu_cur_freq} <br /> {% raw translate("dashboard", "cpuMaxFreq", data['lang']) %}: ${hostStats.cpu_max_freq}`;
cpu_data.setAttribute('data-original-title', cpuDataTitle);
cpu_usage.textContent = hostStats.cpu_usage;
mem_usage.setAttribute('data-original-title', `{% raw translate("dashboard", "memUsage", data['lang']) %}: ${hostStats.mem_usage}`);
mem_percent.textContent = hostStats.mem_percent + '%';
dialog.init(function () {
setTimeout(function () {
location.reload();
}, 15000);
});
}
}
});
});
}
if (webSocket) {
cpu_data = document.getElementById('cpu_data');
cpu_usage = document.getElementById('cpu_usage');
mem_usage = document.getElementById('mem_usage');
mem_percent = document.getElementById('mem_percent');
webSocket.on('update_host_stats', function (hostStats) {
var cpuDataTitle = `{% raw translate('dashboard', 'cpuCores', data['lang']) %}: ${hostStats.cpu_cores} <br /> {% raw translate("dashboard", "cpuCurFreq", data['lang']) %}: ${hostStats.cpu_cur_freq} <br /> {% raw translate("dashboard", "cpuMaxFreq", data['lang']) %}: ${hostStats.cpu_max_freq}`;
cpu_data.setAttribute('data-original-title', cpuDataTitle);
cpu_usage.textContent = hostStats.cpu_usage;
mem_usage.setAttribute('data-original-title', `{% raw translate("dashboard", "memUsage", data['lang']) %}: ${hostStats.mem_usage}`);
mem_percent.textContent = hostStats.mem_percent + '%';
});
}
if (webSocket) {
webSocket.on('send_start_reload', function () {
location.reload()
});
}
webSocket.on('send_start_reload', function () {
location.reload()
});
}
if (webSocket) {
webSocket.on('update_button_status', function (updateButton) {
var id = 'controls';
var dataId = updateButton.server_id;
var string = updateButton.string
var id = id.concat(updateButton.server_id);
if (updateButton.isUpdating){
console.log(updateButton.isUpdating)
document.getElementById(id).innerHTML = string;
}
else{
window.location.reload()
if (webSocket) {
webSocket.on('update_button_status', function (updateButton) {
var id = 'controls';
var dataId = updateButton.server_id;
var string = updateButton.string
var id = id.concat(updateButton.server_id);
if (updateButton.isUpdating) {
console.log(updateButton.isUpdating)
document.getElementById(id).innerHTML = string;
}
});
}
else {
window.location.reload()
}
});
}
$( ".clone_button" ).click(function() {
server_id = $(this).attr("data-id");
send_command(server_id, 'clone_server');
bootbox.alert({
backdrop: true,
title: '{% raw translate("dashboard", "sendingCommand", data['lang']) %}',
message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> &nbsp; {% raw translate("dashboard", "bePatientClone", data['lang']) %} </div>'
if (webSocket) {
webSocket.on('update_server_status', update_servers_status);
}
$(".clone_button").click(function () {
server_id = $(this).attr("data-id");
send_command(server_id, 'clone_server');
bootbox.alert({
backdrop: true,
title: '{% raw translate("dashboard", "sendingCommand", data['lang']) %}',
message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> &nbsp; {% raw translate("dashboard", "bePatientClone", data['lang']) %} </div>'
});
});
});
});
</script>
{% end %}

View File

@ -1,7 +1,6 @@
{% extends ../base.html %}
{% block meta %}
<!-- <meta http-equiv="refresh" content="60">-->
{% end %}
{% block title %}Crafty Controller - {{ translate('panelConfig', 'pageTitle', data['lang']) }}{% end %}

View File

@ -1,7 +1,6 @@
{% extends ../base.html %}
{% block meta %}
<!-- <meta http-equiv="refresh" content="60">-->
{% end %}
{% block title %}Crafty Controller - {{ translate('rolesConfig', 'pageTitle', data['lang']) }}{% end %}
@ -58,7 +57,7 @@
{% raw xsrf_form_html() %}
<input type="hidden" name="id" value="{{ data['role']['role_id'] }}">
<input type="hidden" name="subpage" value="config">
<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-user-tag"></i> {{ translate('rolesConfig', 'roleTitle', data['lang']) }}</h4>
@ -70,7 +69,7 @@
</div>
</div>
</div>
<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-server"></i> {{ translate('rolesConfig', 'roleServers', data['lang']) }} <small class="text-muted ml-1"> {{ translate('rolesConfig', 'serversDesc', data['lang']) }}</small> </h4>
@ -105,12 +104,12 @@
</div>
</div>
</div>
<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-user-lock"></i> {{ translate('rolesConfig', 'rolePerms', data['lang']) }}<small class="text-muted ml-1"> - {{ translate('rolesConfig', 'permsServer', data['lang']) }} </small></h4>
</div>
<div class="card-body">
<div class="card-body">
<div class="form-group">
<div class="table-responsive">
<table class="table table-hover">

View File

@ -1,7 +1,6 @@
{% extends ../base.html %}
{% block meta %}
<!-- <meta http-equiv="refresh" content="60">-->
{% end %}
{% block title %}Crafty Controller - Edit User{% end %}

View File

@ -1,7 +1,6 @@
{% extends ../base.html %}
{% block meta %}
<!-- <meta http-equiv="refresh" content="60">-->
{% end %}
{% block title %}Crafty Controller - Edit User API Keys{% end %}

View File

@ -1,56 +1,52 @@
<div class="row">
<div class="col-sm-12 grid-margin">
<div class="card">
<div class="card-body pt-3 pb-3">
<div class="row">
<div class="col-sm-4 mr-2">
{% if data['server_stats']['running'] %}
<b>{{ translate('serverStats', 'serverStatus', data['lang']) }}:</b> <span class="text-success">{{ translate('serverStats', 'online', data['lang']) }}</span><br />
<b>{{ translate('serverStats', 'serverStarted', data['lang']) }}:</b> <span id="started">{{ data['server_stats']['started'] }} ({{ translate('serverStats', 'serverTime', data['lang']) }})</span><br />
<b>{{ translate('serverStats', 'serverUptime', data['lang']) }}:</b> <span id="uptime">{{ translate('serverStats', 'errorCalculatingUptime', data['lang']) }}</span>
{% else %}
<b>{{ translate('serverStats', 'serverStatus', data['lang']) }}:</b> <span class="text-danger">{{ translate('serverStats', 'offline', data['lang']) }}</span><br />
<b>{{ translate('serverStats', 'serverStarted', data['lang']) }}:</b> <span class="text-danger">{{ translate('serverStats', 'offline', data['lang']) }}</span><br />
<b>{{ translate('serverStats', 'serverUptime', data['lang']) }}:</b> <span class="text-danger">{{ translate('serverStats', 'offline', data['lang']) }}</span>
{% end %}
<br>
<b>{{ translate('serverStats', 'serverTimeZone', data['lang']) }}:</b> <span class="text-info">{{ data['serverTZ'] }}</span>
</div>
<div class="col-sm-3 mr-2">
<b>{{ translate('serverStats', 'cpuUsage', data['lang']) }}:</b> {{ data['server_stats']['cpu'] }}% <br />
<b>{{ translate('serverStats', 'memUsage', data['lang']) }}:</b> {{ data['server_stats']['mem'] }} <br />
{% if data['server_stats']['int_ping_results'] %}
<b>{{ translate('serverStats', 'players', data['lang']) }}:</b> {{ data['server_stats']['online'] }} / {{ data['server_stats']['max'] }}<br />
{% else %}
<b>{{ translate('serverStats', 'players', data['lang']) }}:</b> 0/0<br />
{% end %}
</div>
<div class="col-sm-3 mr-2">
{% if data['server_stats']['version'] != 'False' %}
<b>{{ translate('serverStats', 'version', data['lang']) }}:</b> {{ data['server_stats']['version'] }} <br />
<b>{{ translate('serverStats', 'description', data['lang']) }}:</b> <span id="input_motd" class="input_motd">{{ data['server_stats']['desc'] }}</span> <br />
{% else %}
<b>{{ translate('serverStats', 'version', data['lang']) }}:</b> {{ translate('serverStats', 'unableToConnect', data['lang']) }} <br />
<b>{{ translate('serverStats', 'description', data['lang']) }}:</b> {{ translate('serverStats', 'unableToConnect', data['lang']) }} <br />
{% end %}
</div>
</div>
<div class="col-sm-12 grid-margin">
<div class="card">
<div class="card-body pt-3 pb-3">
<div class="row">
<div class="col-sm-4 mr-2">
{% if data['server_stats']['running'] %}
<b>{{ translate('serverStats', 'serverStatus', data['lang']) }}:</b> <span id="status" class="text-success">{{ translate('serverStats', 'online', data['lang']) }}</span><br />
<b>{{ translate('serverStats', 'serverStarted', data['lang']) }}:</b> <span id="started">{{ data['server_stats']['started'] }} ({{ translate('serverStats', 'serverTime', data['lang']) }})</span><br />
<b>{{ translate('serverStats', 'serverUptime', data['lang']) }}:</b> <span id="uptime">{{ translate('serverStats', 'errorCalculatingUptime', data['lang']) }}</span>
{% else %}
<b>{{ translate('serverStats', 'serverStatus', data['lang']) }}:</b> <span id="status" class="text-danger">{{ translate('serverStats', 'offline', data['lang']) }}</span><br />
<b>{{ translate('serverStats', 'serverStarted', data['lang']) }}:</b> <span id="started" class="text-danger">{{ translate('serverStats', 'offline', data['lang']) }}</span><br />
<b>{{ translate('serverStats', 'serverUptime', data['lang']) }}:</b> <span id="uptime" class="text-danger">{{ translate('serverStats', 'offline', data['lang']) }}</span>
{% end %}
<br>
<b>{{ translate('serverStats', 'serverTimeZone', data['lang']) }}:</b> <span class="text-info">{{ data['serverTZ'] }}</span>
</div>
<div class="col-sm-3 mr-2">
<b>{{ translate('serverStats', 'cpuUsage', data['lang']) }}:</b> <span id="cpu">{{ data['server_stats']['cpu'] }}%</span> <br />
<b>{{ translate('serverStats', 'memUsage', data['lang']) }}:</b> <span id="mem" >{{ data['server_stats']['mem'] }}</span> <br />
{% if data['server_stats']['int_ping_results'] %}
<b>{{ translate('serverStats', 'players', data['lang']) }}:</b> <span id="players" >{{ data['server_stats']['online'] }} / {{ data['server_stats']['max'] }}</span><br />
{% else %}
<b>{{ translate('serverStats', 'players', data['lang']) }}:</b> <span id="players" >0/0</span><br />
{% end %}
</div>
<div class="col-sm-3 mr-2">
{% if data['server_stats']['version'] != 'False' %}
<b>{{ translate('serverStats', 'version', data['lang']) }}:</b> <span id="version">{{ data['server_stats']['version'] }}</span><br />
<b>{{ translate('serverStats', 'description', data['lang']) }}:</b> <span id="input_motd" class="input_motd">{{ data['server_stats']['desc'] }}</span> <br />
{% else %}
<b>{{ translate('serverStats', 'version', data['lang']) }}:</b> <span id="version">{{ translate('serverStats', 'unableToConnect', data['lang']) }}</span> <br />
<b>{{ translate('serverStats', 'description', data['lang']) }}:</b> <span id="input_motd" class="input_motd">{{ translate('serverStats', 'unableToConnect', data['lang']) }}</span> <br />
{% end %}
</div>
</div>
</div>
</div>
</div>
</div>
<script src="/static/assets/vendors/moment/moment.min.js" type="text/javascript" charset="utf-8"></script>
<script src="/static/assets/js/motd.js"></script>
<script>
function durationToHumanizedString (duration) {
function durationToHumanizedString(duration) {
duration._data.months += duration._data.years * 12;
// 30.45833333333 = average month length, calculate with (31+28.5+31+30+31+30+31+31+30+31+30+31) / 12
duration._data.days += duration._data.months * 30.45833333333;
@ -64,7 +60,7 @@
output = Object.entries(obj)
.map(([type, num]) => {
// make them strings
// make them strings
returnData = num + ' ' + type;
// remove the s in the end if the data is -1 or 1
if (num == -1 || num == 1)
@ -73,27 +69,28 @@
})
.map((v, i, a) => // example input: [1,2,3], output: "1, 2 and 3"
v + (i !== a.length - 1
? i !== a.length - 2
? i !== a.length - 2
? ', '
: ' and '
: '')).join('');
return output;
}
let uptime = document.querySelector('#uptime');
let started = document.querySelector('#started');
let startedUTC;
let startedLocal;
let uptimeLoop;
document.body.onload = (() => {
console.log('calculateTime');
let uptime = document.querySelector('#uptime');
let started = document.querySelector('#started');
let startedUTC;
let startedLocal;
if (started != null) {
startedUTC = '{{ data['server_stats']['started'] }}';
startedUTC = '{{ data['server_stats']['started'] }}';
if (startedUTC != 'False') {
console.log('started utc:', startedUTC);
startedUTC = moment.utc(startedUTC, 'YYYY-MM-DD HH:mm:ss');
let browserUTCOffset = moment().utcOffset(); // This is in minutes
var browserUTCOffset = moment().utcOffset(); // This is in minutes
startedLocal = startedUTC.utcOffset(browserUTCOffset);
startedLocalFormatted = startedLocal.format('YYYY-MM-DD HH:mm:ss');
@ -104,23 +101,108 @@
}
var calculateUptime = () => {
var msdiff = moment()
.diff(startedLocal);
var msdiff = moment().diff(startedLocal);
var diff = moment.duration(msdiff);
uptime.textContent = durationToHumanizedString(diff);
}
if (uptime != null && started != null) {
console.log('startedLocal', startedLocal)
if (startedLocal) {
calculateUptime()
var uptimeLoop = setInterval(calculateUptime, 1000)
calculateUptime();
uptimeLoop = setInterval(calculateUptime, 1000);
}
}
initParser('input_motd', 'input_motd');
});
function update_server_details(server) {
server_status = document.getElementById('status');
server_started = document.getElementById('started');
server_uptime = document.getElementById('uptime');
server_cpu = document.getElementById('cpu');
server_mem = document.getElementById('mem');
server_players = document.getElementById('players');
server_version = document.getElementById('version');
server_input_motd = document.getElementById('input_motd');
/* TODO Update each element */
if (server.running)
{
if (server.int_ping_results)
{
server_status.setAttribute("class", "text-success");
server_status.innerHTML = `{{ translate('serverStats', 'online', data['lang']) }}`;
}
else
{
server_status.setAttribute("class", "text-warning");
server_status.innerHTML = `{{ translate('serverStats', 'starting', data['lang']) }}`;
}
startedUTC = server.started;
startedUTC = moment.utc(startedUTC, 'YYYY-MM-DD HH:mm:ss');
var browserUTCOffset = moment().utcOffset(); // This is in minutes
startedLocal = startedUTC.utcOffset(browserUTCOffset);
startedLocalFormatted = startedLocal.format('YYYY-MM-DD HH:mm:ss');
server_started.setAttribute("class", "");
server_started.innerHTML = startedLocalFormatted +` ({{ translate('serverStats', 'serverTime', data['lang']) }})`;
server_uptime.setAttribute("class", "");
if (!uptimeLoop) {
var calculateUptime = () => {
var msdiff = moment().diff(startedLocal);
var diff = moment.duration(msdiff);
uptime.textContent = durationToHumanizedString(diff);
}
uptimeLoop = setInterval(calculateUptime, 1000);
}
}
else
{
server_status.setAttribute("class", "text-danger");
server_status.innerHTML = `{{ translate('serverStats', 'offline', data['lang']) }}`;
server_started.setAttribute("class", "text-danger");
server_started.innerHTML = `{{ translate('serverStats', 'offline', data['lang']) }}`;
clearInterval(uptimeLoop);
uptimeLoop = null;
server_uptime.setAttribute("class", "text-danger");
server_uptime.innerHTML = `{{ translate('serverStats', 'offline', data['lang']) }}`;
}
server_cpu.innerHTML = server.cpu + ` %`;
server_mem.innerHTML = server.mem;
if (server.int_ping_results)
{
server_players.innerHTML = server.online + `/` + server.max;
}
else
{
server_players.innerHTML = `0/0`;
}
if (server.version)
{
server_version.innerHTML = server.version;
server_input_motd.innerHTML = server.desc;
}
else
{
server_version.innerHTML = `{{ translate('serverStats', 'unableToConnect', data['lang']) }}`;
server_input_motd.innerHTML = `{{ translate('serverStats', 'unableToConnect', data['lang']) }}`;
}
initParser('input_motd', 'input_motd');
}
$(window).ready(function () {
console.log("ready!");
//if (webSocket) {
webSocket.on('update_server_details', update_server_details);
//}
});
</script>

View File

@ -1,7 +1,6 @@
{% extends ../base.html %}
{% block meta %}
<!-- <meta http-equiv="refresh" content="60">-->
{% end %}
{% block title %}Crafty Controller - {{ translate('serverDetails', 'serverDetails', data['lang']) }}{% end %}
@ -33,7 +32,7 @@
<div class="card">
<div class="card-body pt-0">
{% include "parts/server_controls_list.html %}
<div class="row">
<div class="col-md-6 col-sm-12">
<style>
@ -86,7 +85,7 @@
<li class="playerItem banned">
<h3>{{ translate('serverPlayerManagement', 'loadingBannedPlayers', data['lang']) }}</h3>
</li>
</ul>
</div>
</div>

View File

@ -1,7 +1,6 @@
{% extends ../base.html %}
{% block meta %}
<!-- <meta http-equiv="refresh" content="60">-->
{% end %}
{% block title %}Crafty Controller - {{ translate('serverDetails', 'serverDetails', data['lang']) }}{% end %}
@ -65,7 +64,7 @@
<div class="card">
<div class="card-body">
<h4 class="card-title">{{ translate('serverBackups', 'currentBackups', data['lang']) }}</h4>
</div>
</div>
<div class="text-center">
@ -231,7 +230,7 @@
}
});
});
$( ".restore_button" ).click(function() {
var file_to_restore = $(this).data("file");

View File

@ -1,7 +1,6 @@
{% extends ../base.html %}
{% block meta %}
<!-- <meta http-equiv="refresh" content="60">-->
{% end %}
{% block title %}Crafty Controller - {{ translate('serverDetails', 'serverDetails', data['lang']) }}{% end %}
@ -10,14 +9,15 @@
<div class="content-wrapper">
<!-- Page Title Header Starts-->
<!-- Page Title Header Starts-->
<div class="row page-title-header">
<div class="col-12">
<div class="page-header">
<h4 class="page-title">
{{ translate('serverDetails', 'serverDetails', data['lang']) }} - {{ data['server_stats']['server_id']['server_name'] }}
<br />
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
{{ translate('serverDetails', 'serverDetails', data['lang']) }} - {{
data['server_stats']['server_id']['server_name'] }}
<br />
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
</h4>
</div>
</div>
@ -25,132 +25,187 @@
</div>
<!-- Page Title Header Ends-->
{% include "parts/details_stats.html" %}
{% include "parts/details_stats.html" %}
<div class="row">
<div class="col-sm-12 grid-margin">
<div class="card">
<div class="card-body pt-0">
{% include "parts/server_controls_list.html %}
{% include "parts/server_controls_list.html %}
<div class="row">
<div class="col-md-6 col-sm-12">
<form class="forms-sample" method="post" action="/panel/server_detail">
{% raw xsrf_form_html() %}
<input type="hidden" name="id" value="{{ data['server_stats']['server_id']['server_id'] }}">
<input type="hidden" name="subpage" value="config">
<div class="row">
<div class="col-md-6 col-sm-12">
<form class="forms-sample" method="post" action="/panel/server_detail">
{% raw xsrf_form_html() %}
<input type="hidden" name="id" value="{{ data['server_stats']['server_id']['server_id'] }}">
<input type="hidden" name="subpage" value="config">
<div class="form-group">
<label for="server_name">{{ translate('serverConfig', 'serverName', data['lang']) }} <small class="text-muted ml-1"> - {{ translate('serverConfig', 'serverNameDesc', data['lang']) }}</small> </label>
<input type="text" class="form-control" name="server_name" id="server_name" value="{{ data['server_stats']['server_id']['server_name'] }}" placeholder="{{ translate('serverConfig', 'serverName', data['lang']) }}" required>
</div>
<div class="form-group">
{% if data['super_user'] %}
<label for="server_path">{{ translate('serverConfig', 'serverPath', data['lang']) }} <small class="text-muted ml-1"> - {{ translate('serverConfig', 'serverPathDesc', data['lang']) }}</small> </label>
<input type="text" class="form-control" name="server_path" id="server_path" value="{{ data['server_stats']['server_id']['path'] }}" placeholder="{{ translate('serverConfig', 'serverPath', data['lang']) }}" required>
</div>
<div class="form-group">
<label for="log_path">{{ translate('serverConfig', 'serverLogLocation', data['lang']) }} <small class="text-muted ml-1"> - {{ translate('serverConfig', 'serverLogLocationDesc', data['lang']) }}</small> </label>
<input type="text" class="form-control" name="log_path" id="log_path" value="{{ data['server_stats']['server_id']['log_path'] }}" placeholder="{{ translate('serverConfig', 'serverLogLocation', data['lang']) }}" required>
</div>
<div class="form-group">
<label for="executable">{{ translate('serverConfig', 'serverExecutable', data['lang']) }} <small class="text-muted ml-1"> - {{ translate('serverConfig', 'serverExecutableDesc', data['lang']) }}</small> </label>
<input type="text" class="form-control" name="executable" id="executable" value="{{ data['server_stats']['server_id']['executable'] }}" placeholder="{{ translate('serverConfig', 'serverExecutable', data['lang']) }}" required>
</div>
<div class="form-group">
<label for="execution_command">{{ translate('serverConfig', 'serverExecutionCommand', data['lang']) }} <small class="text-muted ml-1"> - {{ translate('serverConfig', 'serverExecutionCommandDesc', data['lang']) }}</small> </label>
<input type="text" class="form-control" name="execution_command" id="execution_command" value="{{ data['server_stats']['server_id']['execution_command'] }}" placeholder="{{ translate('serverConfig', 'serverExecutionCommand', data['lang']) }}" required>
{% end %}
</div>
<div class="form-group">
<label for="stop_command">{{ translate('serverConfig', 'serverStopCommand', data['lang']) }} <small class="text-muted ml-1"> - {{ translate('serverConfig', 'serverStopCommandDesc', data['lang']) }}</small> </label>
<input type="text" class="form-control" name="stop_command" id="stop_command" value="{{ data['server_stats']['server_id']['stop_command'] }}" placeholder="{{ translate('serverConfig', 'serverStopCommand', data['lang']) }}" required>
</div>
<div class="form-group">
<label for="auto_start_delay">{{ translate('serverConfig', 'serverAutostartDelay', data['lang']) }} <small class="text-muted ml-1"> - {{ translate('serverConfig', 'serverAutostartDelayDesc', data['lang']) }}</small> </label>
<input type="number" class="form-control" name="auto_start_delay" id="auto_start_delay" value="{{ data['server_stats']['server_id']['auto_start_delay'] }}" step="1" max="999" min="10" required>
</div>
{% if data['super_user'] %}
<div class="form-group">
<label for="executable_update_url">{{ translate('serverConfig', 'exeUpdateURL', data['lang']) }} <small class="text-muted ml-1"> - {{ translate('serverConfig', 'exeUpdateURLDesc', data['lang']) }}</small> </label>
<input type="text" class="form-control" name="executable_update_url" id="executable_update_url" value="{{ data['server_stats']['server_id']['executable_update_url'] }}" placeholder="{{ translate('serverConfig', 'exeUpdateURL', data['lang']) }}">
</div>
<div class="form-group">
<label for="server_ip">{{ translate('serverConfig', 'serverIP', data['lang']) }} <small class="text-muted ml-1">- {{ translate('serverConfig', 'serverIPDesc', data['lang']) }}</small> </label>
<input type="text" class="form-control" name="server_ip" id="server_ip" value="{{ data['server_stats']['server_id']['server_ip'] }}" required>
</div>
<div class="form-group">
<label for="server_port">{{ translate('serverConfig', 'serverPort', data['lang']) }} <small class="text-muted ml-1"> - {{ translate('serverConfig', 'serverPortDesc', data['lang']) }} </small> </label>
<input type="number" class="form-control" name="server_port" id="server_port" value="{{ data['server_stats']['server_id']['server_port'] }}" step="1" max="65566" min="1" required>
</div>
{% end %}
<div class="form-group">
<label for="logs_delete_after">{{ translate('serverConfig', 'removeOldLogsAfter', data['lang']) }} <small class="text-muted ml-1"> - {{ translate('serverConfig', 'removeOldLogsAfterDesc', data['lang']) }}</small> </label>
<input type="number" class="form-control" name="logs_delete_after" id="logs_delete_after" value="{{ data['server_stats']['server_id']['logs_delete_after'] }}" step="1" max="365" min="0" required>
</div>
<div class="form-check-flat">
<label for="auto_start" class="form-check-label ml-4 mb-4">
{% if data['server_stats']['server_id']['auto_start'] %}
<input type="checkbox" class="form-check-input" id="auto_start" name="auto_start" checked="" value="1">{{ translate('serverConfig', 'serverAutoStart', data['lang']) }}
{% else %}
<input type="checkbox" class="form-check-input" id="auto_start" name="auto_start" value="1">{{ translate('serverConfig', 'serverAutoStart', data['lang']) }}
{% end %}
</label>
<label for="crash_detection" class="form-check-label ml-4 mb-4">
{% if data['server_stats']['server_id']['crash_detection'] %}
<input type="checkbox" class="form-check-input" id="crash_detection" name="crash_detection" checked="" value="1">{{ translate('serverConfig', 'serverCrashDetection', data['lang']) }}
{% else %}
<input type="checkbox" class="form-check-input" id="crash_detection" name="crash_detection" value="1" >{{ translate('serverConfig', 'serverCrashDetection', data['lang']) }}
{% end %}
</label>
</div>
<button type="submit" class="btn btn-success mr-2"><i class="fas fa-save"></i> {{ translate('serverConfig', 'save', data['lang']) }}</button>
<button type="reset" class="btn btn-light"><i class="fas fa-times"></i> {{ translate('serverConfig', 'cancel', data['lang']) }}</button>
</form>
<div class="form-group">
<label for="server_name">{{ translate('serverConfig', 'serverName', data['lang']) }} <small
class="text-muted ml-1"> - {{ translate('serverConfig', 'serverNameDesc', data['lang']) }}</small>
</label>
<input type="text" class="form-control" name="server_name" id="server_name"
value="{{ data['server_stats']['server_id']['server_name'] }}"
placeholder="{{ translate('serverConfig', 'serverName', data['lang']) }}" required>
</div>
<div class="col-md-6 col-sm-12">
<div class="card">
<div class="card-body">
<h4 class="card-title">{{ translate('serverConfigHelp', 'title', data['lang']) }}</h4>
<p class="card-description"> {{ translate('serverConfigHelp', 'desc', data['lang']) }}</p>
<blockquote class="blockquote">
<p class="mb-0">
{% raw translate('serverConfigHelp', 'perms', data['lang']) %}
</p>
</blockquote>
</div>
</div>
<div class="text-center">
{% if data['server_stats']['running'] %}
<button onclick="send_command(server_id, 'update_executable');" id="update_executable" style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1 disabled">{{ translate('serverConfig', 'update', data['lang']) }}</button>
<a class="btn btn-sm btn-danger disabled">{{ translate('serverConfig', 'deleteServer', data['lang']) }}</a><br />
<small>{{ translate('serverConfig', 'stopBeforeDeleting', data['lang']) }}</small>
{% else %}
<button onclick="send_command(server_id, 'update_executable');" id="update_executable" style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1">{{ translate('serverConfig', 'update', data['lang']) }}</button>
<button onclick="deleteConfirm()" class="btn btn-sm btn-danger">{{ translate('serverConfig', 'deleteServer', data['lang']) }}</button>
{% end %}
<div class="form-group">
{% if data['super_user'] %}
<label for="server_path">{{ translate('serverConfig', 'serverPath', data['lang']) }} <small
class="text-muted ml-1"> - {{ translate('serverConfig', 'serverPathDesc', data['lang']) }}</small>
</label>
<input type="text" class="form-control" name="server_path" id="server_path"
value="{{ data['server_stats']['server_id']['path'] }}"
placeholder="{{ translate('serverConfig', 'serverPath', data['lang']) }}" required>
</div>
</div>
<div class="form-group">
<label for="log_path">{{ translate('serverConfig', 'serverLogLocation', data['lang']) }} <small
class="text-muted ml-1"> - {{ translate('serverConfig', 'serverLogLocationDesc', data['lang'])
}}</small> </label>
<input type="text" class="form-control" name="log_path" id="log_path"
value="{{ data['server_stats']['server_id']['log_path'] }}"
placeholder="{{ translate('serverConfig', 'serverLogLocation', data['lang']) }}" required>
</div>
<div class="form-group">
<label for="executable">{{ translate('serverConfig', 'serverExecutable', data['lang']) }} <small
class="text-muted ml-1"> - {{ translate('serverConfig', 'serverExecutableDesc', data['lang'])
}}</small> </label>
<input type="text" class="form-control" name="executable" id="executable"
value="{{ data['server_stats']['server_id']['executable'] }}"
placeholder="{{ translate('serverConfig', 'serverExecutable', data['lang']) }}" required>
</div>
<div class="form-group">
<label for="execution_command">{{ translate('serverConfig', 'serverExecutionCommand', data['lang']) }}
<small class="text-muted ml-1"> - {{ translate('serverConfig', 'serverExecutionCommandDesc',
data['lang']) }}</small> </label>
<input type="text" class="form-control" name="execution_command" id="execution_command"
value="{{ data['server_stats']['server_id']['execution_command'] }}"
placeholder="{{ translate('serverConfig', 'serverExecutionCommand', data['lang']) }}" required>
{% end %}
</div>
<div class="form-group">
<label for="stop_command">{{ translate('serverConfig', 'serverStopCommand', data['lang']) }} <small
class="text-muted ml-1"> - {{ translate('serverConfig', 'serverStopCommandDesc', data['lang'])
}}</small> </label>
<input type="text" class="form-control" name="stop_command" id="stop_command"
value="{{ data['server_stats']['server_id']['stop_command'] }}"
placeholder="{{ translate('serverConfig', 'serverStopCommand', data['lang']) }}" required>
</div>
<div class="form-group">
<label for="auto_start_delay">{{ translate('serverConfig', 'serverAutostartDelay', data['lang']) }}
<small class="text-muted ml-1"> - {{ translate('serverConfig', 'serverAutostartDelayDesc',
data['lang']) }}</small> </label>
<input type="number" class="form-control" name="auto_start_delay" id="auto_start_delay"
value="{{ data['server_stats']['server_id']['auto_start_delay'] }}" step="1" max="999" min="10"
required>
</div>
{% if data['super_user'] %}
<div class="form-group">
<label for="executable_update_url">{{ translate('serverConfig', 'exeUpdateURL', data['lang']) }}
<small class="text-muted ml-1"> - {{ translate('serverConfig', 'exeUpdateURLDesc', data['lang'])
}}</small> </label>
<input type="text" class="form-control" name="executable_update_url" id="executable_update_url"
value="{{ data['server_stats']['server_id']['executable_update_url'] }}"
placeholder="{{ translate('serverConfig', 'exeUpdateURL', data['lang']) }}">
</div>
<div class="form-group">
<label for="server_ip">{{ translate('serverConfig', 'serverIP', data['lang']) }} <small
class="text-muted ml-1">- {{ translate('serverConfig', 'serverIPDesc', data['lang']) }}</small>
</label>
<input type="text" class="form-control" name="server_ip" id="server_ip"
value="{{ data['server_stats']['server_id']['server_ip'] }}" required>
</div>
<div class="form-group">
<label for="server_port">{{ translate('serverConfig', 'serverPort', data['lang']) }} <small
class="text-muted ml-1"> - {{ translate('serverConfig', 'serverPortDesc', data['lang']) }}
</small> </label>
<input type="number" class="form-control" name="server_port" id="server_port"
value="{{ data['server_stats']['server_id']['server_port'] }}" step="1" max="65566" min="1"
required>
</div>
{% end %}
<div class="form-group">
<label for="logs_delete_after">{{ translate('serverConfig', 'removeOldLogsAfter', data['lang']) }}
<small class="text-muted ml-1"> - {{ translate('serverConfig', 'removeOldLogsAfterDesc',
data['lang']) }}</small> </label>
<input type="number" class="form-control" name="logs_delete_after" id="logs_delete_after"
value="{{ data['server_stats']['server_id']['logs_delete_after'] }}" step="1" max="365" min="0"
required>
</div>
<div class="form-check-flat">
<label for="auto_start" class="form-check-label ml-4 mb-4">
{% if data['server_stats']['server_id']['auto_start'] %}
<input type="checkbox" class="form-check-input" id="auto_start" name="auto_start" checked=""
value="1">{{ translate('serverConfig', 'serverAutoStart', data['lang']) }}
{% else %}
<input type="checkbox" class="form-check-input" id="auto_start" name="auto_start" value="1">{{
translate('serverConfig', 'serverAutoStart', data['lang']) }}
{% end %}
</label>
<label for="crash_detection" class="form-check-label ml-4 mb-4">
{% if data['server_stats']['server_id']['crash_detection'] %}
<input type="checkbox" class="form-check-input" id="crash_detection" name="crash_detection"
checked="" value="1">{{ translate('serverConfig', 'serverCrashDetection', data['lang']) }}
{% else %}
<input type="checkbox" class="form-check-input" id="crash_detection" name="crash_detection"
value="1">{{ translate('serverConfig', 'serverCrashDetection', data['lang']) }}
{% end %}
</label>
</div>
<button type="submit" class="btn btn-success mr-2"><i class="fas fa-save"></i> {{
translate('serverConfig', 'save', data['lang']) }}</button>
<button type="reset" class="btn btn-light"><i class="fas fa-times"></i> {{ translate('serverConfig',
'cancel', data['lang']) }}</button>
</form>
</div>
<div class="col-md-6 col-sm-12">
<div class="card">
<div class="card-body">
<h4 class="card-title">{{ translate('serverConfigHelp', 'title', data['lang']) }}</h4>
<p class="card-description"> {{ translate('serverConfigHelp', 'desc', data['lang']) }}</p>
<blockquote class="blockquote">
<p class="mb-0">
{% raw translate('serverConfigHelp', 'perms', data['lang']) %}
</p>
</blockquote>
</div>
</div>
<div class="text-center">
{% if data['server_stats']['running'] %}
<button onclick="send_command(server_id, 'update_executable');" id="update_executable"
style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1 disabled">{{ translate('serverConfig',
'update', data['lang']) }}</button>
<a class="btn btn-sm btn-danger disabled">{{ translate('serverConfig', 'deleteServer', data['lang'])
}}</a><br />
<small>{{ translate('serverConfig', 'stopBeforeDeleting', data['lang']) }}</small>
{% else %}
<button onclick="send_command(server_id, 'update_executable');" id="update_executable"
style="max-width: 7rem;" class="btn btn-warning m-1 flex-grow-1">{{ translate('serverConfig',
'update', data['lang']) }}</button>
<button onclick="deleteConfirm()" class="btn btn-sm btn-danger">{{ translate('serverConfig',
'deleteServer', data['lang']) }}</button>
{% end %}
</div>
</div>
</div>
</div>
</div>
</div>
@ -167,154 +222,154 @@
<script>
//used to get cookies from browser - this is part of tornados xsrf protection - it's for extra security
function getCookie(name) {
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return r ? r[1] : undefined;
}
//used to get cookies from browser - this is part of tornados xsrf protection - it's for extra security
function getCookie(name) {
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return r ? r[1] : undefined;
}
$( document ).ready(function() {
console.log( "ready!" );
$(document).ready(function () {
console.log("ready!");
});
function deleteServerE(callback) {
var token = getCookie("_xsrf")
$.ajax({
type: "DELETE",
headers: { 'X-XSRFToken': token },
url: '/ajax/delete_server?id={{ data['server_stats']['server_id']['server_id'] }}',
data: {
},
success: function (data) {
console.log("got response:");
console.log(data);
},
});
function deleteServerE(callback) {
var token = getCookie("_xsrf")
$.ajax({
type: "DELETE",
headers: {'X-XSRFToken': token},
url: '/ajax/delete_server?id={{ data['server_stats']['server_id']['server_id'] }}',
data: {
},
success: function(data){
console.log("got response:");
console.log(data);
},
});
}
function deleteServerFilesE(path, callback) {
var token = getCookie("_xsrf")
$.ajax({
type: "DELETE",
headers: {'X-XSRFToken': token},
url: '/ajax/delete_server_files?id={{ data['server_stats']['server_id']['server_id'] }}',
data: {
},
success: function(data){
console.log("got response:");
console.log(data);
},
});
}
let server_id = '{{ data['server_stats']['server_id']['server_id'] }}';
function send_command (server_id, command){
<!-- this getCookie function is in base.html-->
var token = getCookie("_xsrf");
$.ajax({
type: "POST",
headers: {'X-XSRFToken': token},
url: '/server/command?command=' + command + '&id=' + server_id,
success: function(data){
console.log("got response:");
console.log(data);
setTimeout(function(){ location.reload(); }, 10000);
}
});
if(command != "delete_server" && command != "delete_server_files"){
bootbox.alert({
backdrop: true,
title: '{% raw translate("serverConfig", "sendingRequest", data['lang']) %}',
message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> &nbsp; {% raw translate("serverConfig", "bePatientUpdate", data['lang']) %} </div>'
}
function deleteServerFilesE(path, callback) {
var token = getCookie("_xsrf")
$.ajax({
type: "DELETE",
headers: { 'X-XSRFToken': token },
url: '/ajax/delete_server_files?id={{ data['server_stats']['server_id']['server_id'] }}',
data: {
},
success: function (data) {
console.log("got response:");
console.log(data);
},
});
}
let server_id = '{{ data['server_stats']['server_id']['server_id'] }}';
function send_command(server_id, command) {
//<!-- this getCookie function is in base.html-->
var token = getCookie("_xsrf");
$.ajax({
type: "POST",
headers: { 'X-XSRFToken': token },
url: '/server/command?command=' + command + '&id=' + server_id,
success: function (data) {
console.log("got response:");
console.log(data);
setTimeout(function () { location.reload(); }, 10000);
}
});
if (command != "delete_server" && command != "delete_server_files") {
bootbox.alert({
backdrop: true,
title: '{% raw translate("serverConfig", "sendingRequest", data['lang']) %}',
message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> &nbsp; {% raw translate("serverConfig", "bePatientUpdate", data['lang']) %} </div>'
});
}
}
function deleteServer (){
path = "{{data['server_stats']['server_id']['path']}}";
name = "{{data['server_stats']['server_id']['server_name']}}";
bootbox.dialog({
size: "",
title: "{% raw translate('serverConfig', 'deleteFilesQuestion', data['lang']) %}",
closeButton: false,
message: "{% raw translate('serverConfig', 'deleteFilesQuestionMessage', data['lang']) %}",
buttons: {
files: {
label: "{{ translate('serverConfig', 'yesDeleteFiles', data['lang']) }}",
className: 'btn-danger',
callback: function(){
deleteServerFilesE();
setTimeout(function(){ window.location = '/panel/dashboard'; }, 5000);
bootbox.dialog({
backdrop: true,
title: '{% raw translate("serverConfig", "sendingDelete", data['lang']) %}',
message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> &nbsp; {% raw translate("serverConfig", "bePatientDeleteFiles", data['lang']) %} </div>',
closeButton: false
})
function deleteServer() {
path = "{{data['server_stats']['server_id']['path']}}";
name = "{{data['server_stats']['server_id']['server_name']}}";
bootbox.dialog({
size: "",
title: "{% raw translate('serverConfig', 'deleteFilesQuestion', data['lang']) %}",
closeButton: false,
message: "{% raw translate('serverConfig', 'deleteFilesQuestionMessage', data['lang']) %}",
buttons: {
files: {
label: "{{ translate('serverConfig', 'yesDeleteFiles', data['lang']) }}",
className: 'btn-danger',
callback: function () {
deleteServerFilesE();
setTimeout(function () { window.location = '/panel/dashboard'; }, 5000);
bootbox.dialog({
backdrop: true,
title: '{% raw translate("serverConfig", "sendingDelete", data['lang']) %}',
message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> &nbsp; {% raw translate("serverConfig", "bePatientDeleteFiles", data['lang']) %} </div>',
closeButton: false
})
return;
}
},
noFiles: {
label: "{{ translate('serverConfig', 'noDeleteFiles', data['lang']) }}",
className: 'btn-outline-danger',
callback: function(){
deleteServerE()
setTimeout(function(){ window.location = '/panel/dashboard'; }, 5000);
bootbox.dialog({
backdrop: true,
title: '{% raw translate("serverConfig", "sendingDelete", data['lang']) %}',
message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> &nbsp; {% raw translate("serverConfig", "bePatientDelete", data['lang']) %} </div>',
closeButton: false
})
return;
}
},
cancel: {
label: "{{ translate('serverConfig', 'cancel', data['lang']) }}",
className: 'btn-secondary',
callback: function(){
return;
}
return;
}
},
callback: function(result) {
},
noFiles: {
label: "{{ translate('serverConfig', 'noDeleteFiles', data['lang']) }}",
className: 'btn-outline-danger',
callback: function () {
deleteServerE()
setTimeout(function () { window.location = '/panel/dashboard'; }, 5000);
bootbox.dialog({
backdrop: true,
title: '{% raw translate("serverConfig", "sendingDelete", data['lang']) %}',
message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> &nbsp; {% raw translate("serverConfig", "bePatientDelete", data['lang']) %} </div>',
closeButton: false
})
return;
}
});
}
function deleteConfirm (){
path = "{{data['server_stats']['server_id']['path']}}";
name = "{{data['server_stats']['server_id']['server_name']}}";
bootbox.confirm({
size: "",
title: "{% raw translate('serverConfig', 'deleteServerQuestion', data['lang']) %}",
closeButton: false,
message: "{% raw translate('serverConfig', 'deleteServerQuestionMessage', data['lang']) %}",
buttons: {
confirm: {
label: "{{ translate('serverConfig', 'yesDelete', data['lang']) }}",
className: 'btn-danger',
},
cancel: {
label: "{{ translate('serverConfig', 'noDelete', data['lang']) }}",
className: 'btn-link',
}
},
callback: function(result) {
if (!result){
return;
return;}
else{
deleteServer();
}
},
cancel: {
label: "{{ translate('serverConfig', 'cancel', data['lang']) }}",
className: 'btn-secondary',
callback: function () {
return;
}
});
}
}
},
callback: function (result) {
}
});
}
function deleteConfirm() {
path = "{{data['server_stats']['server_id']['path']}}";
name = "{{data['server_stats']['server_id']['server_name']}}";
bootbox.confirm({
size: "",
title: "{% raw translate('serverConfig', 'deleteServerQuestion', data['lang']) %}",
closeButton: false,
message: "{% raw translate('serverConfig', 'deleteServerQuestionMessage', data['lang']) %}",
buttons: {
confirm: {
label: "{{ translate('serverConfig', 'yesDelete', data['lang']) }}",
className: 'btn-danger',
},
cancel: {
label: "{{ translate('serverConfig', 'noDelete', data['lang']) }}",
className: 'btn-link',
}
},
callback: function (result) {
if (!result) {
return;
return;
}
else {
deleteServer();
}
}
});
}
</script>

View File

@ -1,7 +1,6 @@
{% extends ../base.html %}
{% block meta %}
<!-- <meta http-equiv="refresh" content="60">-->
{% end %}
{% block title %}Crafty Controller - {{ translate('serverDetails', 'serverDetails', data['lang']) }}{% end %}
@ -557,7 +556,7 @@
xmlHttpRequest.addEventListener('error', (e) => {
console.error('Error while uploading file', file.name + '.', 'Event:', e)
}, false);
xmlHttpRequest.send(file);
}
@ -637,7 +636,7 @@
}
});
var fileList = document.getElementById("files");
fileList.addEventListener("change", function (e) {
@ -672,7 +671,7 @@
}catch{
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');
@ -724,7 +723,7 @@
setTimeout(function () {setTreeViewContext()}, 1000);
var toggler = document.getElementById(path);
if (toggler.classList.contains('files-tree-title')){
document.getElementById(path+"span").addEventListener("click", function caretListener() {
document.getElementById(path+"ul").classList.toggle("d-block");

View File

@ -1,7 +1,6 @@
{% extends ../base.html %}
{% block meta %}
<!-- <meta http-equiv="refresh" content="60">-->
{% end %}
{% block title %}Crafty Controller - {{ translate('serverDetails', 'serverDetails', data['lang']) }}{% end %}

View File

@ -1,7 +1,6 @@
{% extends ../base.html %}
{% block meta %}
<!-- <meta http-equiv="refresh" content="60">-->
{% end %}
{% block title %}Crafty Controller - {{ translate('serverDetails', 'serverDetails', data['lang']) }}{% end %}

View File

@ -1,7 +1,6 @@
{% extends ../base.html %}
{% block meta %}
<!-- <meta http-equiv="refresh" content="60">-->
{% end %}
{% block title %}Crafty Controller - {{ translate('serverDetails', 'serverDetails', data['lang']) }}{% end %}
@ -205,7 +204,7 @@
</div>
<style>
/* Hide scrollbar for Chrome, Safari and Opera */
td::-webkit-scrollbar {
display: none;
@ -246,7 +245,7 @@ $( document ).ready(function() {
document.getElementById('schedule_table_wrapper').hidden = true;
document.getElementById('mini_schedule_table_wrapper').hidden = false;
}
});
$(window).ready(function(){
$('body').click(function(){

View File

@ -1,7 +1,6 @@
{% extends ../base.html %}
{% block meta %}
<!-- <meta http-equiv="refresh" content="60">-->
{% end %}
{% block title %}Crafty Controller - {{ translate('serverDetails', 'serverDetails', data['lang']) }}{% end %}
@ -10,14 +9,14 @@
<div class="content-wrapper">
<!-- Page Title Header Starts-->
<!-- Page Title Header Starts-->
<div class="row page-title-header">
<div class="col-12">
<div class="page-header">
<h4 class="page-title">
{{ translate('serverDetails', 'serverDetails', data['lang']) }} - {{ data['server_stats']['server_id']['server_name'] }}
<br />
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
<br />
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
</h4>
</div>
</div>
@ -25,66 +24,67 @@
</div>
<!-- Page Title Header Ends-->
{% include "parts/details_stats.html %}
{% include "parts/details_stats.html %}
<div class="row">
<div class="col-sm-12 grid-margin">
<div class="card">
<div class="card-body pt-0">
{% include "parts/server_controls_list.html %}
<div class="col-md-12">
<div class="input-group">
<div id="virt_console" class="" style="width: 100%; font-size: .8em; padding: 5px 10px; border: 1px solid #383e5d; background-color:#2a2c44;height:500px; overflow: scroll;"></div>
</div>
<br />
{% include "parts/server_controls_list.html %}
<div style="gap: 0.5rem;" class="input-group flex-wrap">
<input style="min-width: 10rem;" type="text" class="form-control" id="server_command" name="server_command" placeholder="{{ translate('serverTerm', 'commandInput', data['lang']) }}" autofocus="">
<span class="input-group-btn ml-5">
<button id="submit" class="btn btn-sm btn-info" type="button">{{ translate('serverTerm', 'sendCommand', data['lang']) }}</button>
</span>
</div>
{% if data['permissions']['Commands'] in data['user_permissions'] %}
{% 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">
<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="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>
</div>
{% elif data['waiting_start'] %}
<div id="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; white-space: nowrap;" class="btn btn-secondary m-1 flex-grow-1 disabled" data-toggle="tooltip" title="{{ translate('serverTerm', 'delay-explained', data['lang'])}}">{{ translate('serverTerm', 'starting', 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>
</div>
{% else %}
<div id="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="send_command(server_id, 'start_server');" id="start-btn" style="max-width: 7rem;" class="btn btn-primary m-1 flex-grow-1">{{ translate('serverTerm', 'start', data['lang']) }}</button>
<button onclick="send_command(server_id, 'restart_server');" id="restart-btn" style="max-width: 7rem;" class="btn btn-outline-primary m-1 flex-grow-1">{% raw translate('serverTerm', 'restart', data['lang']) %}</button>
<button onclick="send_command(server_id, 'stop_server');" id="stop-btn" style="max-width: 7rem;" class="btn btn-danger m-1 flex-grow-1">{{ translate('serverTerm', 'stop', data['lang']) }}</button>
</div>
{% end %}
{% end %}
<div class="col-md-12">
<div class="input-group">
<div id="virt_console" class="" style="width: 100%; font-size: .8em; padding: 5px 10px; border: 1px solid #383e5d; background-color:#2a2c44;height:500px; overflow: scroll;"></div>
</div>
<br />
<div style="gap: 0.5rem;" class="input-group flex-wrap">
<input style="min-width: 10rem;" type="text" class="form-control" id="server_command" name="server_command" placeholder="{{ translate('serverTerm', 'commandInput', data['lang']) }}" autofocus="">
<span class="input-group-btn ml-5">
<button id="submit" class="btn btn-sm btn-info" type="button">{{ translate('serverTerm', 'sendCommand',
data['lang']) }}</button>
</span>
</div>
{% if data['permissions']['Commands'] in data['user_permissions'] %}
{% 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">
<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="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>
</div>
{% elif data['waiting_start'] %}
<div id="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; white-space: nowrap;" class="btn btn-secondary m-1 flex-grow-1 disabled" data-toggle="tooltip" title="{{ translate('serverTerm', 'delay-explained', data['lang'])}}">{{ translate('serverTerm', 'starting', 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>
</div>
{% else %}
<div id="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="send_command(server_id, 'start_server');" id="start-btn" style="max-width: 7rem;" class="btn btn-primary m-1 flex-grow-1">{{ translate('serverTerm', 'start', data['lang']) }}</button>
<button onclick="send_command(server_id, 'restart_server');" id="restart-btn" style="max-width: 7rem;" class="btn btn-outline-primary m-1 flex-grow-1">{% raw translate('serverTerm', 'restart', data['lang']) %}</button>
<button onclick="send_command(server_id, 'stop_server');" id="stop-btn" style="max-width: 7rem;" class="btn btn-danger m-1 flex-grow-1">{{ translate('serverTerm', 'stop', data['lang']) }}</button>
</div>
{% end %}
{% end %}
</div>
</div>
</div>
</div>
</div>
</div>
<style>
#virt_console::-webkit-scrollbar {
display: none;
}
/* Hide scrollbar for IE, Edge and Firefox */
#virt_console {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
#virt_console::-webkit-scrollbar {
display: none;
}
/* Hide scrollbar for IE, Edge and Firefox */
#virt_console {
-ms-overflow-style: none;
/* IE and Edge */
scrollbar-width: none;
/* Firefox */
}
</style>
<!-- content-wrapper ends -->
@ -93,188 +93,182 @@
{% block js %}
<script>
function send_command (server_id, command){
if (command == 'start_server'){
startBtn.setAttribute('disabled', 'disabled');
restartBtn.removeAttribute('disabled');
stopBtn.removeAttribute('disabled');
}
if (command == 'stop_server'){
startBtn.removeAttribute('disabled');
restartBtn.setAttribute('disabled', 'disabled');
stopBtn.setAttribute('disabled', 'disabled');
}
<!-- this getCookie function is in base.html-->
var token = getCookie("_xsrf");
$.ajax({
type: "POST",
headers: {'X-XSRFToken': token},
url: '/server/command?command=' + command + '&id=' + server_id,
success: function(data){
console.log("got response:");
console.log(data);
setTimeout(function(){
if (command != 'start_server'){
location.reload();
}
}, 10000);
}
});
}
if (webSocket) {
webSocket.on('update_button_status', function (updateButton) {
if (updateButton.isUpdating){
if(updateButton.server_id == '{{ data['server_stats']['server_id']['server_id'] }}') {
console.log(updateButton.isUpdating)
document.getElementById('control_buttons').innerHTML = '<button onclick="" id="start-btn" style="max-width: 7rem;" class="btn btn-primary m-1 flex-grow-1">{{ 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">{% 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>';
}
}
else{
if (updateButton.server_id == '{{ data['server_stats']['server_id']['server_id'] }}') {
window.location.reload()
document.getElementById('update_control_buttons').innerHTML = '<button onclick="send_command(server_id, "start_server");" id="start-btn" style="max-width: 7rem;" class="btn btn-primary m-1 flex-grow-1">{{ translate("serverTerm", "start", data['lang']) }}</button><button onclick="send_command(server_id, "restart_server");" id="restart-btn" style="max-width: 7rem;" class="btn btn-outline-primary m-1 flex-grow-1">{% 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>';
}
}
});
}
// Convert running to lower case (example: 'True' converts to 'true') and
// then to boolean via JSON.parse()
let online = JSON.parse('{{ data['server_stats']['running'] }}'.toLowerCase());
let startBtn = document.querySelector('#start-btn');
let restartBtn = document.querySelector('#restart-btn');
let stopBtn = document.querySelector('#stop-btn');
{% if data['permissions']['Commands'] in data['user_permissions'] %}
if (online) {
function send_command(server_id, command) {
if (command == 'start_server') {
startBtn.setAttribute('disabled', 'disabled');
restartBtn.removeAttribute('disabled');
stopBtn.removeAttribute('disabled');
} else {
}
if (command == 'stop_server') {
startBtn.removeAttribute('disabled');
restartBtn.setAttribute('disabled', 'disabled');
stopBtn.setAttribute('disabled', 'disabled');
}
{% end %}
//<!-- this getCookie function is in base.html-->
var token = getCookie("_xsrf");
let server_id = '{{ data['server_stats']['server_id']['server_id'] }}';
function get_server_log(){
$.ajax({
type: 'GET',
url: '/ajax/server_log?id={{ data['server_stats']['server_id']['server_id'] }}',
dataType: 'text',
success: function (data) {
console.log('Got Log From Server')
$('#virt_console').html(data);
scrollConsole();
},
});
}
function new_line_handler(data) {
$('#virt_console').append(data.line)
const elem = document.getElementById('virt_console');
const scrollDiff = (elem.scrollHeight - elem.scrollTop) - elem.clientHeight;
if (!$("#stop_scroll").is(':checked') && scrollDiff < 450) {
scrollConsole()
}
}
//used to get cookies from browser - this is part of tornados xsrf protection - it's for extra security
function getCookie(name) {
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return r ? r[1] : undefined;
}
$( document ).ready(function() {
console.log( "ready!" );
get_server_log()
webSocket.on('vterm_new_line', new_line_handler)
});
$('#server_command').on('keydown', function (e) {
if (e.which == 13){
$(this).attr("disabled", "disabled"); //Disable textbox to prevent multiple submit
send_command_to_server()
$(this).removeAttr("disabled"); //Enable the textbox again if needed.
$(this).focus();
}
else if (e.which == 38) {
e.preventDefault();
$('#server_command').val(cmdHistory.getPrev());
} else if (e.which == 40) {
e.preventDefault();
$('#server_command').val(cmdHistory.getNext());
}
});
$("#submit").click(function(e) {
e.preventDefault();
send_command_to_server();
});
function scrollConsole(){
var logview = $('#virt_console');
if(logview.length)
logview.scrollTop(logview[0].scrollHeight - logview.height());
}
function send_command_to_server(){
var server_command = $("#server_command").val()
console.log(server_command)
cmdHistory.push(server_command);
var token = getCookie("_xsrf")
data_to_send = { command :server_command, }
console.log('sending command: ' + server_command)
$.ajax({
type: "POST",
headers: {'X-XSRFToken': token},
url: '/ajax/send_command?id={{ data['server_stats']['server_id']['server_id'] }}',
data: data_to_send,
success: function(data){
console.log("got response:");
console.log(data);
$("#server_command").val('')
},
});
}
const cmdHistory = {
history: [],
current: 0,
push: function(cmd) {
this.history.push(cmd);
this.current = this.history.length - 1;
},
getPrev: function() {
const prevCommand = this.history[this.current];
this.current--;
if (this.current < 0) this.current = 0;
return prevCommand;
},
getNext: function() {
this.current++;
if (this.current > (this.history.length - 1)) {
this.current = (this.history.length - 1);
return '';
}
const nextCommand = this.history[this.current];
return nextCommand;
$.ajax({
type: "POST",
headers: { 'X-XSRFToken': token },
url: '/server/command?command=' + command + '&id=' + server_id,
success: function (data) {
console.log("got response:");
console.log(data);
}
});
}
if (webSocket) {
webSocket.on('update_button_status', function (updateButton) {
if (updateButton.isUpdating) {
if (updateButton.server_id == '{{ data['server_stats']['server_id']['server_id'] }}') {
console.log(updateButton.isUpdating)
document.getElementById('control_buttons').innerHTML = '<button onclick="" id="start-btn" style="max-width: 7rem;" class="btn btn-primary m-1 flex-grow-1">{{ 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">{% 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>';
}
}
else {
if (updateButton.server_id == '{{ data['server_stats']['server_id']['server_id'] }}') {
window.location.reload()
document.getElementById('update_control_buttons').innerHTML = '<button onclick="send_command(server_id, "start_server");" id="start-btn" style="max-width: 7rem;" class="btn btn-primary m-1 flex-grow-1">{{ translate("serverTerm", "start", data['lang']) }}</button><button onclick="send_command(server_id, "restart_server");" id="restart-btn" style="max-width: 7rem;" class="btn btn-outline-primary m-1 flex-grow-1">{% 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>';
}
}
});
}
// Convert running to lower case (example: 'True' converts to 'true') and
// then to boolean via JSON.parse()
let online = JSON.parse('{{ data['server_stats']['running'] }}'.toLowerCase());
let startBtn = document.querySelector('#start-btn');
let restartBtn = document.querySelector('#restart-btn');
let stopBtn = document.querySelector('#stop-btn');
{% if data['permissions']['Commands'] in data['user_permissions'] %}
if (online) {
startBtn.setAttribute('disabled', 'disabled');
restartBtn.removeAttribute('disabled');
stopBtn.removeAttribute('disabled');
} else {
startBtn.removeAttribute('disabled');
restartBtn.setAttribute('disabled', 'disabled');
stopBtn.setAttribute('disabled', 'disabled');
}
{% end %}
let server_id = '{{ data['server_stats']['server_id']['server_id'] }}';
function get_server_log() {
$.ajax({
type: 'GET',
url: '/ajax/server_log?id={{ data['server_stats']['server_id']['server_id'] }}',
dataType: 'text',
success: function (data) {
console.log('Got Log From Server')
$('#virt_console').html(data);
scrollConsole();
},
});
}
function new_line_handler(data) {
$('#virt_console').append(data.line)
const elem = document.getElementById('virt_console');
const scrollDiff = (elem.scrollHeight - elem.scrollTop) - elem.clientHeight;
if (!$("#stop_scroll").is(':checked') && scrollDiff < 450) {
scrollConsole()
}
}
//used to get cookies from browser - this is part of tornados xsrf protection - it's for extra security
function getCookie(name) {
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return r ? r[1] : undefined;
}
$(document).ready(function () {
console.log("ready!");
get_server_log()
webSocket.on('vterm_new_line', new_line_handler)
});
$('#server_command').on('keydown', function (e) {
if (e.which == 13) {
$(this).attr("disabled", "disabled"); //Disable textbox to prevent multiple submit
send_command_to_server()
$(this).removeAttr("disabled"); //Enable the textbox again if needed.
$(this).focus();
}
else if (e.which == 38) {
e.preventDefault();
$('#server_command').val(cmdHistory.getPrev());
} else if (e.which == 40) {
e.preventDefault();
$('#server_command').val(cmdHistory.getNext());
}
});
$("#submit").click(function (e) {
e.preventDefault();
send_command_to_server();
});
function scrollConsole() {
var logview = $('#virt_console');
if (logview.length)
logview.scrollTop(logview[0].scrollHeight - logview.height());
}
function send_command_to_server() {
var server_command = $("#server_command").val()
console.log(server_command)
cmdHistory.push(server_command);
var token = getCookie("_xsrf")
data_to_send = { command: server_command, }
console.log('sending command: ' + server_command)
$.ajax({
type: "POST",
headers: { 'X-XSRFToken': token },
url: '/ajax/send_command?id={{ data['server_stats']['server_id']['server_id'] }}',
data: data_to_send,
success: function (data) {
console.log("got response:");
console.log(data);
$("#server_command").val('')
},
});
}
const cmdHistory = {
history: [],
current: 0,
push: function (cmd) {
this.history.push(cmd);
this.current = this.history.length - 1;
},
getPrev: function () {
const prevCommand = this.history[this.current];
this.current--;
if (this.current < 0) this.current = 0;
return prevCommand;
},
getNext: function () {
this.current++;
if (this.current > (this.history.length - 1)) {
this.current = (this.history.length - 1);
return '';
}
const nextCommand = this.history[this.current];
return nextCommand;
}
}
</script>

View File

@ -1,7 +1,6 @@
{% extends ../public_base.html %}
{% block meta %}
<meta http-equiv="refresh" content="30">
{% end %}
{% block title %}Crafty Controller - {{ translate('dashboard', 'dashboard', data['lang']) }}{% end %}
@ -24,40 +23,49 @@
<tbody>
{% for server in data['servers'] %}
<tr>
<td>
<td id="server_name_{{ server['stats']['server_id']['server_id'] }}">
<i class="fas fa-server"></i>
{{ server['server_data']['server_name'] }}
{{ server['server_data']['server_name'] }}
</td>
{% if server['stats']['int_ping_results'] != 'False' %}
<td>
{{ server['stats']['online'] }} / {{ server['stats']['max'] }} {{ translate('dashboard', 'max', data['lang']) }}<br />
</td>
<td>
{% if server['stats']['desc'] != 'False' %}
{% if server['raw_ping_result']['icon'] %}
<img src="data:image/png;base64,{% raw server['raw_ping_result']['icon'] %}" alt="icon"/>
{% else %}
<img src="/static/assets/images/pack.png" alt="icon" />
{% end %}
<span id="input_motd_{{ server['stats']['server_id']['server_id'] }}" class="input_motd">{{ server['stats']['desc'] }}</span> <br />
{% end %}
</td>
<td>
{% if server['stats']['version'] != 'False' %}
{{ server['stats']['version'] }}
{% end %}
{% if server['stats']['int_ping_results'] != 'False' %}
<td id="server_players_{{ server['stats']['server_id']['server_id'] }}">
{{ server['stats']['online'] }} / {{ server['stats']['max'] }} {{ translate('dashboard', 'max',
data['lang']) }}<br />
</td>
<td id="server_motd_{{ server['stats']['server_id']['server_id'] }}">
{% if server['stats']['desc'] != 'False' %}
{% if server['raw_ping_result']['icon'] %}
<img src="data:image/png;base64,{% raw server['raw_ping_result']['icon'] %}" alt="icon" />
{% else %}
<td colspan="3">
<!-- TODO: translate the following text -->
<span class="text-warning"><i class="fas fa-exclamation-triangle"></i> Crafty can't get infos from this Server </span>
</td>
<img src="/static/assets/images/pack.png" alt="icon" />
{% end %}
<td>
<span id="input_motd_{{ server['stats']['server_id']['server_id'] }}" class="input_motd">{{
server['stats']['desc'] }}</span> <br />
{% end %}
</td>
<td id="server_version_{{ server['stats']['server_id']['server_id'] }}">
{% if server['stats']['version'] != 'False' %}
{{ server['stats']['version'] }}
{% end %}
</td>
{% else %}
<td id="server_players_{{ server['stats']['server_id']['server_id'] }}">
<span class="text-warning"><i class="fas fa-exclamation-triangle"></i></span>
</td>
<td id="server_motd_{{ server['stats']['server_id']['server_id'] }}">
<span class="text-warning">Crafty can't get infos from this Server </span>
</td>
<td id="server_version_{{ server['stats']['server_id']['server_id'] }}">
<span class="text-warning"><i class="fas fa-question"></i></i></span>
</td>
{% end %}
<td id="server_online_status_{{ server['stats']['server_id']['server_id'] }}">
{% if server['stats']['running'] %}
<span class="text-success"><i class="fas fa-signal"></i> {{ translate('dashboard', 'online', data['lang']) }}</span>
<span class="text-success"><i class="fas fa-signal"></i> {{ translate('dashboard', 'online', data['lang'])
}}</span>
{% else %}
<span class="text-danger"><i class="fas fa-ban"></i> {{ translate('dashboard', 'offline', data['lang']) }}</span>
<span class="text-danger"><i class="fas fa-ban"></i> {{ translate('dashboard', 'offline', data['lang'])
}}</span>
{% end %}
</td>
</tr>
@ -73,14 +81,83 @@
{% block js %}
<script src="/static/assets/js/motd.js"></script>
<script>
$(document).ready(function () {
var all_motds = Array.from(document.getElementsByClassName('input_motd'));
for (element of all_motds) {
initParser(element.id, element.id);
};
}());
</script>
<script src="/static/assets/js/motd.js"></script>
<script>
function display_motd() {
var all_motds = Array.from(document.getElementsByClassName('input_motd'));
for (element of all_motds) {
initParser(element.id, element.id);
};
}
function update_one_server_status(server) {
server_players = document.getElementById('server_players_' + server.id);
server_motd = document.getElementById('server_motd_' + server.id);
server_version = document.getElementById('server_version_' + server.id);
server_online_status = document.getElementById('server_online_status_' + server.id);
/* TODO Update each element */
if (server.int_ping_results) {
/* Update Players */
if (server.players)
{
server_players.innerHTML = server.online + ` / ` + server.max + ` {{ translate('dashboard', 'max', data['lang']) }}<br />`
}
/* Update Motd */
var motd = "";
if (server.desc) {
if (server.icon) {
motd = `<img src="data:image/png;base64,` + server.icon + `" alt="icon" /> `;
}
else {
motd = `<img src="/static/assets/images/pack.png" alt="icon" /> `;
}
motd = motd + `<span id="input_motd_` + server.id + `" class="input_motd">` + server.desc + `</span> <br />`;
server_motd.innerHTML = motd;
}
/* Version */
if (server.version)
{
server_version.innerHTML = server.version
}
}
else {
server_players.innerHTML = `<span class="text-warning"><i class="fas fa-exclamation-triangle"></i></span>`;
server_motd.innerHTML = `<span class="text-warning">Crafty can't get infos from this Server </span>`;
server_version.innerHTML = `<span class="text-warning"><i class="fas fa-question"></i></i></span>`
}
/* Update Online Status */
var online_status = "";
if (server.running) {
online_status = `<span class="text-success"><i class="fas fa-signal"></i> {{ translate('dashboard', 'online', data['lang'])}}</span>`;
}
else {
online_status = `<span class="text-danger"><i class="fas fa-ban"></i> {{ translate('dashboard', 'offline', data['lang'])}}</span>`;
}
server_online_status.innerHTML = online_status;
}
function update_servers_status(data) {
for (server of data) {
update_one_server_status(server);
}
display_motd();
}
$(document).ready(function () {
console.log("ready!");
display_motd()
if (webSocket)
{
webSocket.on('update_server_status', update_servers_status);
}
}());
</script>
{% end %}

View File

@ -1,60 +1,118 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
{% block meta %}{% end %}
<title>{% block title %}{{ _('Default') }}{% end %}</title>
<!-- plugins:css -->
<link rel="stylesheet" href="/static/assets/vendors/mdi/css/materialdesignicons.min.css">
<link rel="stylesheet" href="/static/assets/vendors/flag-icon-css/css/flag-icon.min.css">
<link rel="stylesheet" href="/static/assets/vendors/ti-icons/css/themify-icons.css">
<link rel="stylesheet" href="/static/assets/vendors/typicons/typicons.css">
<link rel="stylesheet" href="/static/assets/vendors/css/vendor.bundle.base.css">
<link rel="stylesheet" href="/static/assets/vendors/fontawesome5/css/all.css">
<!-- endinject -->
<!-- Plugin css for this page -->
<!-- End Plugin css for this page -->
<!-- Layout styles -->
<link rel="stylesheet" href="/static/assets/css/dark/style.css">
<!-- End Layout styles -->
<link rel="shortcut icon" type="image/svg+xml" href="/static/assets/images/logo_small.svg">
<link rel="alternate icon" href="/static/assets/images/favicon.png" />
</head>
<body class="dark-theme">
<div class="container-scroller">
<div class="container-fluid page-body-wrapper full-page-wrapper">
<div class="content-wrapper d-flex align-items-center auth auth-bg-1 theme-one">
<div class="row w-100">
<div class="mx-auto">
<div class="auto-form-wrapper">
{% block content %}
{% end %}
</div>
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
{% block meta %}{% end %}
<title>{% block title %}{{ _('Default') }}{% end %}</title>
<!-- plugins:css -->
<link rel="stylesheet" href="/static/assets/vendors/mdi/css/materialdesignicons.min.css">
<link rel="stylesheet" href="/static/assets/vendors/flag-icon-css/css/flag-icon.min.css">
<link rel="stylesheet" href="/static/assets/vendors/ti-icons/css/themify-icons.css">
<link rel="stylesheet" href="/static/assets/vendors/typicons/typicons.css">
<link rel="stylesheet" href="/static/assets/vendors/css/vendor.bundle.base.css">
<link rel="stylesheet" href="/static/assets/vendors/fontawesome5/css/all.css">
<!-- endinject -->
<!-- Plugin css for this page -->
<!-- End Plugin css for this page -->
<!-- Layout styles -->
<link rel="stylesheet" href="/static/assets/css/dark/style.css">
<!-- End Layout styles -->
<link rel="shortcut icon" type="image/svg+xml" href="/static/assets/images/logo_small.svg">
<link rel="alternate icon" href="/static/assets/images/favicon.png" />
</head>
<body class="dark-theme">
<div class="container-scroller">
<div class="container-fluid page-body-wrapper full-page-wrapper">
<div class="content-wrapper d-flex align-items-center auth auth-bg-1 theme-one">
<div class="row w-100">
<div class="mx-auto">
<div class="auto-form-wrapper">
{% block content %}
{% end %}
</div>
</div>
</div>
<!-- content-wrapper ends -->
</div>
<!-- page-body-wrapper ends -->
<!-- content-wrapper ends -->
</div>
<!-- container-scroller -->
<!-- plugins:js -->
<script src="/static/assets/vendors/js/vendor.bundle.base.js"></script>
<!-- endinject -->
<!-- inject:js -->
<script src="/static/assets/js/shared/off-canvas.js"></script>
<script src="/static/assets/js/shared/hoverable-collapse.js"></script>
<script src="/static/assets/js/shared/misc.js"></script>
<script src="/static/assets/js/shared/settings.js"></script>
<script src="/static/assets/js/shared/todolist.js"></script>
<!-- endinject -->
{% block js %}
<!-- Custom js for this page -->
<!-- End custom js for this page -->
{% end %}
</body>
<!-- page-body-wrapper ends -->
</div>
<!-- container-scroller -->
<!-- plugins:js -->
<script src="/static/assets/vendors/js/vendor.bundle.base.js"></script>
<!-- endinject -->
<!-- inject:js -->
<script src="/static/assets/js/shared/off-canvas.js"></script>
<script src="/static/assets/js/shared/hoverable-collapse.js"></script>
<script src="/static/assets/js/shared/misc.js"></script>
<script src="/static/assets/js/shared/settings.js"></script>
<script src="/static/assets/js/shared/todolist.js"></script>
<!-- endinject -->
<script>
// {% if request.protocol == 'https' %}
let usingWebSockets = true;
let listenEvents = [];
try {
pageQueryParams = 'page_query_params=' + encodeURIComponent(location.search)
page = 'page=' + encodeURIComponent(location.pathname)
var wsInternal = new WebSocket('wss://' + location.host + '/ws?' + page + '&' + pageQueryParams);
wsInternal.onopen = function () {
console.log('opened WebSocket connection:', wsInternal)
};
wsInternal.onmessage = function (rawMessage) {
var message = JSON.parse(rawMessage.data);
console.log('got message: ', message)
listenEvents
.filter(listenedEvent => listenedEvent.event == message.event)
.forEach(listenedEvent => listenedEvent.callback(message.data))
};
wsInternal.onerror = function (errorEvent) {
console.error('WebSocket Error', errorEvent);
};
wsInternal.onclose = function (closeEvent) {
console.log('Closed WebSocket', closeEvent);
};
webSocket = {
on: function (event, callback) {
console.log('registered ' + event + ' event');
listenEvents.push({ event: event, callback: callback })
},
emit: function (event, data) {
var message = {
event: event,
data: data
}
wsInternal.send(JSON.stringify(message));
}
}
} catch (error) {
console.error('Error while making websocket helpers', error);
usingWebSockets = false;
}
// {% else %}
let usingWebSockets = false;
warn('WebSockets are not supported in Crafty if not using the https protocol')
var webSocket;
// {% end%}
</script>
{% block js %}
<!-- Custom js for this page -->
<!-- End custom js for this page -->
{% end %}
</body>
</html>

View File

@ -122,6 +122,7 @@
"serverStats": {
"online": "Online",
"offline": "Offline",
"starting": "Verzögerter Start",
"serverStatus": "Server Status",
"serverStarted": "Server gestartet",
"serverUptime": "Server-Betriebszeit",

View File

@ -129,6 +129,7 @@
"serverStats": {
"online": "Online",
"offline": "Offline",
"starting": "Delayed-Start",
"serverStatus": "Server Status",
"serverStarted": "Server Started",
"serverUptime": "Server Uptime",

View File

@ -123,6 +123,7 @@
"serverStats": {
"online": "En línea",
"offline": "Desconectado",
"starting": "Inicio-retrasado",
"serverStatus": "Estado del Servidor",
"serverStarted": "Servidor Iniciado",
"serverUptime": "Actividad del Servidor",

View File

@ -133,6 +133,7 @@
"serverStats": {
"online": "Päällä",
"offline": "Pois päältä",
"starting": "Myöhästynyt lähtö",
"serverStatus": "Palvelimen tila",
"serverStarted": "Palvelin käynnistyi",
"serverUptime": "Palvelimen käyttöaika",

View File

@ -123,6 +123,7 @@
"serverStats": {
"online": "En Ligne",
"offline": "Hors Ligne",
"starting": "Démarrage en cours",
"serverStatus": "Statut du Serveur",
"serverStarted": "Serveur Démarré",
"serverUptime": "Serveur Disponible depuis",

View File

@ -122,6 +122,7 @@
"serverStats": {
"online": "Na mreži",
"offline": "Izvan mreže",
"starting": "Odgođeno pokretanje",
"serverStatus": "Status poslužitelja",
"serverStarted": "Poslužitelj pokrenut",
"serverUptime": "Vrijeme rada poslužitelja",

View File

@ -122,6 +122,7 @@
"serverStats": {
"online": "Online",
"offline": "Offline",
"starting": "Avvio ritardato",
"serverStatus": "Stato del server",
"serverStarted": "Server Avviato",
"serverUptime": "Tempo di esecuzione",

View File

@ -123,6 +123,7 @@
"serverStats": {
"online": "Turnd on",
"offline": "Turnd off",
"starting": "I waitz b4 I start",
"serverStatus": "Servr Status",
"serverStarted": "Servr Started",
"serverUptime": "How longz servr been awaek",

View File

@ -122,6 +122,7 @@
"serverStats": {
"online": "Online",
"offline": "Offline",
"starting": "Vertraagde start",
"serverStatus": "Server Status",
"serverStarted": "Server gestart",
"serverUptime": "Server Uptime",

View File

@ -123,6 +123,7 @@
"serverStats": {
"online": "运行中",
"offline": "已停止",
"starting": "延迟启动",
"serverStatus": "服务器状态",
"serverStarted": "服务器已启动",
"serverUptime": "服务器正常运行时间",