mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
Adding MOTD on Status Page
This commit is contained in:
parent
a05b3a8634
commit
3ff3d0ccf1
@ -1,9 +1,12 @@
|
||||
from app.classes.shared.helpers import Helpers
|
||||
import struct
|
||||
import socket
|
||||
import base64
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
import logging.config
|
||||
from app.classes.shared.console import console
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -25,8 +28,26 @@ class Server:
|
||||
description = self.description
|
||||
if 'extra' in description.keys():
|
||||
for e in description['extra']:
|
||||
#Conversion format code needed only for Java Version
|
||||
lines.append(get_code_format("reset"))
|
||||
if "bold" in e.keys():
|
||||
lines.append(get_code_format("bold"))
|
||||
if "italic" in e.keys():
|
||||
lines.append(get_code_format("italic"))
|
||||
if "underlined" in e.keys():
|
||||
lines.append(get_code_format("underlined"))
|
||||
if "strikethrough" in e.keys():
|
||||
lines.append(get_code_format("strikethrough"))
|
||||
if "obfuscated" in e.keys():
|
||||
lines.append(get_code_format("obfuscated"))
|
||||
if "color" in e.keys():
|
||||
lines.append(get_code_format(e['color']))
|
||||
#Then append the text
|
||||
if "text" in e.keys():
|
||||
lines.append(e['text'])
|
||||
if e['text'] == '\n':
|
||||
lines.append("§§")
|
||||
else:
|
||||
lines.append(e['text'])
|
||||
|
||||
total_text = " ".join(lines)
|
||||
self.description = total_text
|
||||
@ -70,6 +91,26 @@ class Player:
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def get_code_format(format_name):
|
||||
root_dir = os.path.abspath(os.path.curdir)
|
||||
format_file = os.path.join(root_dir, 'app', 'config', 'motd_format.json')
|
||||
try:
|
||||
with open(format_file, "r", encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
|
||||
if format_name in data.keys():
|
||||
return data.get(format_name)
|
||||
else:
|
||||
logger.error("Format MOTD Error: format name {} does not exist".format(format_name))
|
||||
console.error("Format MOTD Error: format name {} does not exist".format(format_name))
|
||||
return ""
|
||||
|
||||
except Exception as e:
|
||||
logger.critical("Config File Error: Unable to read {} due to {}".format(format_file, e))
|
||||
console.critical("Config File Error: Unable to read {} due to {}".format(format_file, e))
|
||||
|
||||
return ""
|
||||
|
||||
|
||||
# For the rest of requests see wiki.vg/Protocol
|
||||
def ping(ip, port):
|
||||
|
@ -4,6 +4,7 @@ import time
|
||||
import psutil
|
||||
import logging
|
||||
import datetime
|
||||
import base64
|
||||
|
||||
|
||||
from app.classes.shared.helpers import helper
|
||||
@ -145,12 +146,19 @@ class Stats:
|
||||
logger.info("Unable to read json from ping_obj: {}".format(e))
|
||||
pass
|
||||
|
||||
try:
|
||||
server_icon = base64.encodebytes(ping_obj.icon)
|
||||
except Exception as e:
|
||||
server_icon = False
|
||||
logger.info("Unable to read the server icon : {}".format(e))
|
||||
|
||||
ping_data = {
|
||||
'online': online_stats.get("online", 0),
|
||||
'max': online_stats.get('max', 0),
|
||||
'players': online_stats.get('players', 0),
|
||||
'server_description': ping_obj.description,
|
||||
'server_version': ping_obj.version
|
||||
'server_version': ping_obj.version,
|
||||
'server_icon': server_icon
|
||||
}
|
||||
|
||||
return ping_data
|
||||
@ -246,6 +254,62 @@ class Stats:
|
||||
server_stats_list.append(server_stats)
|
||||
|
||||
return server_stats_list
|
||||
|
||||
def get_raw_server_stats(self, server_id):
|
||||
|
||||
server_stats = {}
|
||||
server = self.controller.get_server_obj(server_id)
|
||||
|
||||
logger.debug('Getting stats for server: {}'.format(server_id))
|
||||
|
||||
# get our server object, settings and data dictionaries
|
||||
server_obj = self.controller.get_server_obj(server_id)
|
||||
server_obj.reload_server_settings()
|
||||
server_settings = self.controller.get_server_settings(server_id)
|
||||
server_data = self.controller.get_server_data(server_id)
|
||||
|
||||
# world data
|
||||
world_name = server_settings.get('level-name', 'Unknown')
|
||||
world_path = os.path.join(server_data.get('path', None), world_name)
|
||||
|
||||
# process stats
|
||||
p_stats = self._get_process_stats(server_obj.PID)
|
||||
|
||||
# TODO: search server properties file for possible override of 127.0.0.1
|
||||
internal_ip = server_data.get('server_ip', "127.0.0.1")
|
||||
server_port = server_settings.get('server-port', "25565")
|
||||
|
||||
logger.debug("Pinging server '{}' on {}:{}".format(server.name, internal_ip, server_port))
|
||||
int_mc_ping = ping(internal_ip, int(server_port))
|
||||
|
||||
int_data = False
|
||||
ping_data = {}
|
||||
|
||||
# if we got a good ping return, let's parse it
|
||||
if int_mc_ping:
|
||||
int_data = True
|
||||
ping_data = self.parse_server_ping(int_mc_ping)
|
||||
|
||||
server_stats = {
|
||||
'id': server_id,
|
||||
'started': server_obj.get_start_time(),
|
||||
'running': server_obj.check_running(),
|
||||
'cpu': p_stats.get('cpu_usage', 0),
|
||||
'mem': p_stats.get('memory_usage', 0),
|
||||
"mem_percent": p_stats.get('mem_percentage', 0),
|
||||
'world_name': world_name,
|
||||
'world_size': self.get_world_size(world_path),
|
||||
'server_port': server_port,
|
||||
'int_ping_results': int_data,
|
||||
'online': ping_data.get("online", False),
|
||||
"max": ping_data.get("max", False),
|
||||
'players': ping_data.get("players", False),
|
||||
'desc': ping_data.get("server_description", False),
|
||||
'version': ping_data.get("server_version", False),
|
||||
'icon': ping_data.get("server_icon", False)
|
||||
}
|
||||
|
||||
return server_stats
|
||||
|
||||
def record_stats(self):
|
||||
stats_to_send = self.get_node_stats()
|
||||
|
@ -97,6 +97,14 @@ class Controller:
|
||||
server_obj = self.get_server_obj(server_id)
|
||||
server_obj.reload_server_settings()
|
||||
|
||||
def get_server_settings(self, server_id):
|
||||
for s in self.servers_list:
|
||||
if int(s['server_id']) == int(server_id):
|
||||
return s['server_settings']
|
||||
|
||||
logger.warning("Unable to find server object for server id {}".format(server_id))
|
||||
return False
|
||||
|
||||
def get_server_obj(self, server_id):
|
||||
for s in self.servers_list:
|
||||
if int(s['server_id']) == int(server_id):
|
||||
@ -104,6 +112,14 @@ class Controller:
|
||||
|
||||
logger.warning("Unable to find server object for server id {}".format(server_id))
|
||||
return False
|
||||
|
||||
def get_server_data(self, server_id):
|
||||
for s in self.servers_list:
|
||||
if int(s['server_id']) == int(server_id):
|
||||
return s['server_data_obj']
|
||||
|
||||
logger.warning("Unable to find server object for server id {}".format(server_id))
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def list_defined_servers():
|
||||
@ -184,14 +200,6 @@ class Controller:
|
||||
server_list = db_helper.get_authorized_servers(userId)
|
||||
return server_list
|
||||
|
||||
def get_server_data(self, server_id):
|
||||
for s in self.servers_list:
|
||||
if int(s['server_id']) == int(server_id):
|
||||
return s['server_data_obj']
|
||||
|
||||
logger.warning("Unable to find server object for server id {}".format(server_id))
|
||||
return False
|
||||
|
||||
def list_running_servers(self):
|
||||
running_servers = []
|
||||
|
||||
|
@ -26,6 +26,10 @@ class StatusHandler(BaseHandler):
|
||||
def get(self):
|
||||
page_data = {}
|
||||
page_data['servers'] = db_helper.get_all_servers_stats()
|
||||
for srv in page_data['servers']:
|
||||
server_data = srv.get('server_data', False)
|
||||
server_id = server_data.get('server_id', False)
|
||||
srv['raw_ping_result'] = self.controller.stats.get_raw_server_stats(server_id)
|
||||
|
||||
template = 'public/status.html'
|
||||
|
||||
@ -37,6 +41,10 @@ class StatusHandler(BaseHandler):
|
||||
def post(self):
|
||||
page_data = {}
|
||||
page_data['servers'] = db_helper.get_all_servers_stats()
|
||||
for srv in page_data['servers']:
|
||||
server_data = srv.get('server_data', False)
|
||||
server_id = server_data.get('server_id', False)
|
||||
srv['raw_ping_result'] = self.controller.stats.get_raw_server_stats(server_id)
|
||||
|
||||
template = 'public/status.html'
|
||||
|
||||
|
BIN
app/frontend/static/assets/images/pack.png
Normal file
BIN
app/frontend/static/assets/images/pack.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
125
app/frontend/static/assets/js/motd.js
Normal file
125
app/frontend/static/assets/js/motd.js
Normal file
@ -0,0 +1,125 @@
|
||||
var obfuscators = [];
|
||||
var styleMap = {
|
||||
'§0': 'color:#000000',
|
||||
'§1': 'color:#0000AA',
|
||||
'§2': 'color:#00AA00',
|
||||
'§3': 'color:#00AAAA',
|
||||
'§4': 'color:#AA0000',
|
||||
'§5': 'color:#AA00AA',
|
||||
'§6': 'color:#FFAA00',
|
||||
'§7': 'color:#AAAAAA',
|
||||
'§8': 'color:#555555',
|
||||
'§9': 'color:#5555FF',
|
||||
'§a': 'color:#55FF55',
|
||||
'§b': 'color:#55FFFF',
|
||||
'§c': 'color:#FF5555',
|
||||
'§d': 'color:#FF55FF',
|
||||
'§e': 'color:#FFFF55',
|
||||
'§f': 'color:#FFFFFF',
|
||||
'§l': 'font-weight:bold',
|
||||
'§m': 'text-decoration:line-through',
|
||||
'§n': 'text-decoration:underline',
|
||||
'§o': 'font-style:italic',
|
||||
};
|
||||
function obfuscate(string, elem) {
|
||||
var magicSpan,
|
||||
currNode;
|
||||
if(string.indexOf('<br>') > -1) {
|
||||
elem.innerHTML = string;
|
||||
for(var j = 0, len = elem.childNodes.length; j < len; j++) {
|
||||
currNode = elem.childNodes[j];
|
||||
if(currNode.nodeType === 3) {
|
||||
magicSpan = document.createElement('span');
|
||||
magicSpan.innerHTML = currNode.nodeValue;
|
||||
elem.replaceChild(magicSpan, currNode);
|
||||
init(magicSpan);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
init(elem, string);
|
||||
}
|
||||
function init(el, str) {
|
||||
var i = 0,
|
||||
obsStr = str || el.innerHTML,
|
||||
len = obsStr.length;
|
||||
obfuscators.push( window.setInterval(function () {
|
||||
if(i >= len) i = 0;
|
||||
obsStr = replaceRand(obsStr, i);
|
||||
el.innerHTML = obsStr;
|
||||
i++;
|
||||
}, 0) );
|
||||
}
|
||||
function randInt(min, max) {
|
||||
return Math.floor( Math.random() * (max - min + 1) ) + min;
|
||||
}
|
||||
function replaceRand(string, i) {
|
||||
var randChar = String.fromCharCode( randInt(64, 95) );
|
||||
return string.substr(0, i) + randChar + string.substr(i + 1, string.length);
|
||||
}
|
||||
}
|
||||
function applyCode(string, codes) {
|
||||
var elem = document.createElement('span'),
|
||||
obfuscated = false;
|
||||
string = string.replace(/\x00*/g, '');
|
||||
for(var i = 0, len = codes.length; i < len; i++) {
|
||||
elem.style.cssText += styleMap[codes[i]] + ';';
|
||||
if(codes[i] === '§k') {
|
||||
obfuscate(string, elem);
|
||||
obfuscated = true;
|
||||
}
|
||||
}
|
||||
if(!obfuscated) elem.innerHTML = string;
|
||||
return elem;
|
||||
}
|
||||
function parseStyle(string) {
|
||||
var codes = string.match(/§.{1}/g) || [],
|
||||
indexes = [],
|
||||
apply = [],
|
||||
tmpStr,
|
||||
deltaIndex,
|
||||
noCode,
|
||||
final = document.createDocumentFragment(),
|
||||
i;
|
||||
string = string.replace(/\n|\\n/g, '<br>');
|
||||
for(i = 0, len = codes.length; i < len; i++) {
|
||||
indexes.push( string.indexOf(codes[i]) );
|
||||
string = string.replace(codes[i], '\x00\x00');
|
||||
}
|
||||
if(indexes[0] !== 0) {
|
||||
final.appendChild( applyCode( string.substring(0, indexes[0]), [] ) );
|
||||
}
|
||||
for(i = 0; i < len; i++) {
|
||||
indexDelta = indexes[i + 1] - indexes[i];
|
||||
if(indexDelta === 2) {
|
||||
while(indexDelta === 2) {
|
||||
apply.push ( codes[i] );
|
||||
i++;
|
||||
indexDelta = indexes[i + 1] - indexes[i];
|
||||
}
|
||||
apply.push ( codes[i] );
|
||||
} else {
|
||||
apply.push( codes[i] );
|
||||
}
|
||||
if( apply.lastIndexOf('§r') > -1) {
|
||||
apply = apply.slice( apply.lastIndexOf('§r') + 1 );
|
||||
}
|
||||
tmpStr = string.substring( indexes[i], indexes[i + 1] );
|
||||
final.appendChild( applyCode(tmpStr, apply) );
|
||||
}
|
||||
return final;
|
||||
}
|
||||
function clearObfuscators() {
|
||||
var i = obfuscators.length;
|
||||
for(;i--;) {
|
||||
clearInterval(obfuscators[i]);
|
||||
}
|
||||
obfuscators = [];
|
||||
}
|
||||
function initParser(input, output) {
|
||||
clearObfuscators();
|
||||
var input = document.getElementById(input),
|
||||
output = document.getElementById(output),
|
||||
parsed = parseStyle( input.innerHTML );
|
||||
output.innerHTML = '';
|
||||
output.appendChild(parsed);
|
||||
}
|
@ -32,9 +32,14 @@
|
||||
<td>
|
||||
{{ server['stats']['online'] }} / {{ server['stats']['max'] }} {{ translate('dashboard', 'max') }}<br />
|
||||
</td>
|
||||
<td id="input_motd">
|
||||
<td>
|
||||
{% if server['stats']['desc'] != 'False' %}
|
||||
{{ server['stats']['desc'] }} <br />
|
||||
{% 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']['desc'] }}</span> <br />
|
||||
{% end %}
|
||||
</td>
|
||||
<td>
|
||||
@ -48,7 +53,7 @@
|
||||
</td>
|
||||
{% end %}
|
||||
<td>
|
||||
{% if server['stats']['running'] %}
|
||||
{% if server['stats']['int_ping_results'] %}
|
||||
<span class="text-success"><i class="fas fa-signal"></i> {{ translate('dashboard', 'online') }}</span>
|
||||
{% else %}
|
||||
<span class="text-danger"><i class="fas fa-ban"></i> {{ translate('dashboard', 'offline') }}</span>
|
||||
@ -67,11 +72,11 @@
|
||||
|
||||
{% block js %}
|
||||
|
||||
<!-- <script src="/static/assets/js/motd.js"></script>
|
||||
<script src="/static/assets/js/motd.js"></script>
|
||||
<script>
|
||||
//$(document).ready(function () {
|
||||
// initParser('input_motd', 'output_motd');
|
||||
//}());
|
||||
</script> -->
|
||||
$(document).ready(function () {
|
||||
initParser('input_motd', 'input_motd');
|
||||
}());
|
||||
</script>
|
||||
|
||||
{% end %}
|
Loading…
Reference in New Issue
Block a user