Merge branch 'dev' into bugfix/correct-tag-styles

This commit is contained in:
Zedifus 2021-11-23 23:30:02 +00:00
commit f309107174
14 changed files with 143 additions and 26 deletions

View File

@ -15,6 +15,7 @@ import zipfile
import pathlib import pathlib
import shutil import shutil
from requests import get from requests import get
from contextlib import suppress
from datetime import datetime from datetime import datetime
from socket import gethostname from socket import gethostname
@ -373,9 +374,10 @@ class Helpers:
logger.critical("Unable to write to {} directory!".format(self.root_dir)) logger.critical("Unable to write to {} directory!".format(self.root_dir))
sys.exit(1) sys.exit(1)
# ensure the log directory is there # ensure the log directory is there
try: try:
os.makedirs(os.path.join(self.root_dir, 'logs')) with suppress(FileExistsError):
os.makedirs(os.path.join(self.root_dir, 'logs'))
except Exception as e: except Exception as e:
console.error("Failed to make logs directory with error: {} ".format(e)) console.error("Failed to make logs directory with error: {} ".format(e))

View File

@ -223,7 +223,7 @@ class Controller:
# download the jar # download the jar
server_jar_obj.download_jar(server, version, full_jar_path, name) server_jar_obj.download_jar(server, version, full_jar_path, name)
new_id = self.register_server(name, server_id, server_dir, backup_path, server_command, server_file, server_log_file, server_stop) new_id = self.register_server(name, server_id, server_dir, backup_path, server_command, server_file, server_log_file, server_stop, port)
return new_id return new_id
@staticmethod @staticmethod
@ -253,6 +253,16 @@ class Controller:
server_path = helper.get_os_understandable_path(server_path) server_path = helper.get_os_understandable_path(server_path)
dir_util.copy_tree(server_path, new_server_dir) dir_util.copy_tree(server_path, new_server_dir)
has_properties = False
for item in os.listdir(new_server_dir):
if str(item) == 'server.properties':
has_properties = True
if not has_properties:
logger.info("No server.properties found on zip file import. Creating one with port selection of {}".format(str(port)))
with open(os.path.join(new_server_dir, "server.properties"), "w") as f:
f.write("server-port={}".format(port))
f.close()
full_jar_path = os.path.join(new_server_dir, server_jar) full_jar_path = os.path.join(new_server_dir, server_jar)
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), helper.float_to_string(max_mem),
@ -317,7 +327,7 @@ class Controller:
server_log_file, server_stop, port) server_log_file, server_stop, port)
return new_id return new_id
def register_server(self, name: str, server_uuid: str, server_dir: str, backup_path: str, server_command: str, server_file: str, server_log_file: str, server_stop: str, server_port=25565): def register_server(self, name: str, server_uuid: str, server_dir: str, backup_path: str, server_command: str, server_file: str, server_log_file: str, server_stop: str, server_port: int):
# put data in the db # put data in the db
new_id = self.servers.create_server(name, server_uuid, server_dir, backup_path, server_command, server_file, server_log_file, server_stop, server_port) new_id = self.servers.create_server(name, server_uuid, server_dir, backup_path, server_command, server_file, server_log_file, server_stop, server_port)

View File

@ -193,6 +193,33 @@ class Server:
logger.info("Launching Server {} with command {}".format(self.name, self.server_command)) logger.info("Launching Server {} with command {}".format(self.name, self.server_command))
console.info("Launching Server {} with command {}".format(self.name, self.server_command)) console.info("Launching Server {} with command {}".format(self.name, self.server_command))
if helper.check_file_exists(os.path.join(self.settings['path'], 'eula.txt')):
f = open(os.path.join(self.settings['path'], 'eula.txt'), 'r')
line = f.readline().lower()
if line == 'eula=true':
e_flag = True
elif line == 'eula = true':
e_flag = True
elif line == 'eula= true':
e_flag = True
elif line == 'eula =true':
e_flag = True
else:
e_flag = False
else:
e_flag = False
if e_flag == False:
websocket_helper.broadcast('send_eula_bootbox', {
'id': self.server_id
})
return False
f.close()
if helper.is_os_windows(): if helper.is_os_windows():
logger.info("Windows Detected") logger.info("Windows Detected")
creationflags=subprocess.CREATE_NEW_CONSOLE creationflags=subprocess.CREATE_NEW_CONSOLE
@ -346,7 +373,7 @@ class Server:
if self.settings['crash_detection']: if self.settings['crash_detection']:
logger.warning("The server {} has crashed and will be restarted. Restarting server".format(name)) logger.warning("The server {} has crashed and will be restarted. Restarting server".format(name))
console.warning("The server {} has crashed and will be restarted. Restarting server".format(name)) console.warning("The server {} has crashed and will be restarted. Restarting server".format(name))
self.run_threaded_server() self.run_threaded_server('en_EN')
return True return True
else: else:
logger.critical( logger.critical(
@ -420,6 +447,13 @@ class Server:
console.info("Removing old crash detection watcher thread") console.info("Removing old crash detection watcher thread")
schedule.clear(self.name) schedule.clear(self.name)
def agree_eula(self, user_lang):
file = os.path.join(self.server_path, 'eula.txt')
f = open(file, 'w')
f.write('eula=true')
f.close
self.run_threaded_server(user_lang)
def is_backup_running(self): def is_backup_running(self):
if self.is_backingup: if self.is_backingup:
return True return True

View File

@ -207,6 +207,10 @@ class AjaxHandler(BaseHandler):
except Exception as e: except Exception as e:
logger.error("Could not find PID for requested termsig. Full error: {}".format(e)) logger.error("Could not find PID for requested termsig. Full error: {}".format(e))
return return
elif page == "eula":
server_id = self.get_argument('id', None)
svr = self.controller.get_server_obj(server_id)
svr.agree_eula(self.controller.users.get_user_lang_by_id(user_data['user_id']))
@tornado.web.authenticated @tornado.web.authenticated
def delete(self, page): def delete(self, page):

View File

@ -987,7 +987,10 @@ class PanelHandler(BaseHandler):
else: else:
self.set_status(404) self.set_status(404)
page_data = []
page_data['lang'] = tornado.locale.get("en_EN")
self.render( self.render(
"public/404.html", "public/404.html",
translate=self.translator.translate, translate=self.translator.translate,
data=page_data
) )

View File

@ -40,6 +40,7 @@ class PublicHandler(BaseHandler):
def get(self, page=None): def get(self, page=None):
error = bleach.clean(self.get_argument('error', "Invalid Login!")) error = bleach.clean(self.get_argument('error', "Invalid Login!"))
error_msg = bleach.clean(self.get_argument('error_msg', ''))
page_data = { page_data = {
'version': helper.get_version_string(), 'version': helper.get_version_string(),
@ -75,6 +76,7 @@ class PublicHandler(BaseHandler):
template, template,
data=page_data, data=page_data,
translate=self.translator.translate, translate=self.translator.translate,
error_msg = error_msg
) )
def post(self, page=None): def post(self, page=None):
@ -89,18 +91,18 @@ class PublicHandler(BaseHandler):
# if we don't have a user # if we don't have a user
if not user_data: if not user_data:
next_page = "/public/error?error=Login Failed" error_msg = "Inncorrect username or password. Please try again."
self.clear_cookie("user") self.clear_cookie("user")
self.clear_cookie("user_data") self.clear_cookie("user_data")
self.redirect(next_page) self.redirect('/public/login?error_msg={}'.format(error_msg))
return return
# if they are disabled # if they are disabled
if not user_data.enabled: if not user_data.enabled:
next_page = "/public/error?error=Login Failed" error_msg = "User account disabled. Please contact your system administrator for more info."
self.clear_cookie("user") self.clear_cookie("user")
self.clear_cookie("user_data") self.clear_cookie("user_data")
self.redirect(next_page) self.redirect('/public/login?error_msg={}'.format(error_msg))
return return
login_result = helper.verify_pass(entered_password, user_data.password) login_result = helper.verify_pass(entered_password, user_data.password)
@ -132,9 +134,10 @@ class PublicHandler(BaseHandler):
else: else:
self.clear_cookie("user") self.clear_cookie("user")
self.clear_cookie("user_data") self.clear_cookie("user_data")
error_msg = "Inncorrect username or password. Please try again."
# log this failed login attempt # log this failed login attempt
self.controller.management.add_to_audit_log(user_data.user_id, "Tried to log in", 0, self.get_remote_ip()) self.controller.management.add_to_audit_log(user_data.user_id, "Tried to log in", 0, self.get_remote_ip())
self.redirect('/public/error?error=Login Failed') self.redirect('/public/login?error_msg={}'.format(error_msg))
else: else:
self.redirect("/public/login") self.redirect("/public/login")

View File

@ -10449,10 +10449,10 @@ pre {
padding-right: 80px; } padding-right: 80px; }
.sidebar > .nav:not(.sub-menu) > .nav-item:hover:not(.nav-profile):not(.hover-open) > .nav-link:not([aria-expanded="true"]):before { .sidebar > .nav:not(.sub-menu) > .nav-item:hover:not(.nav-profile):not(.hover-open) > .nav-link:not([aria-expanded="true"]):before {
border-color: #0b0b0b; } border-color: #0b0b0b; }
.sidebar > .nav:not(.sub-menu) > .nav-item:hover:not(.nav-profile):not(.hover-open) > .nav-link:not([aria-expanded="true"]) .menu-title { .sidebar > .nav:not(.sub-menu) > .nav-item:hover:not(.nav-profile):not(.hover-open) > .nav-link:not([aria-expanded="true"]) {
color: #0b0b0b; }
.sidebar > .nav:not(.sub-menu) > .nav-item:hover:not(.nav-profile):not(.hover-open) > .nav-link:not([aria-expanded="true"]) .menu-arrow::before {
color: #0b0b0b; } color: #0b0b0b; }
.sidebar > .nav:not(.sub-menu) > .nav-item:hover:not(.nav-profile):not(.hover-open) > .nav-link:not([aria-expanded="true"]) .menu-arrow:before {
color: #b9c0d3; }
/* style for off-canvas menu*/ /* style for off-canvas menu*/
@media screen and (max-width: 991px) { @media screen and (max-width: 991px) {

View File

@ -237,6 +237,57 @@ if (webSocket) {
}); });
} }
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){
console.log("got response:");
console.log(data);
location.reload();
}
});
}
function warn(message) { function warn(message) {
var closeEl = document.createElement('span'); var closeEl = document.createElement('span');

View File

@ -94,7 +94,7 @@
<br> <br>
<h7>{{ translate('dashboard', 'no-servers', data['lang']) }} {{ translate('dashboard', 'newServer', data['lang']) }}.</h7> <h7>{{ translate('dashboard', 'no-servers', data['lang']) }} {{ translate('dashboard', 'newServer', data['lang']) }}.</h7>
</div> </div>
{% end %} {% end %}
{% if len(data['servers']) > 0 %} {% if len(data['servers']) > 0 %}
<table class="table table-hover"> <table class="table table-hover">
@ -180,7 +180,7 @@
{{ 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' %} {% if server['stats']['desc'] != 'False' %}
<span id="input_motd_{{ server['stats']['server_id']['server_id'] }}" class="input_motd">{{ server['stats']['desc'] }}</span> <br /> {{ server['stats']['desc'] }} <br />
{% end %} {% end %}
{% if server['stats']['version'] != 'False' %} {% if server['stats']['version'] != 'False' %}
@ -221,18 +221,13 @@
{% end %} {% end %}
{% block js %} {% block js %}
<script src="/static/assets/js/motd.js"></script>
<script> <script>
$(document).ready(function(){ $(document).ready(function(){
$('[data-toggle="popover"]').popover(); $('[data-toggle="popover"]').popover();
if($(window).width() < 1000){ if($(window).width() < 1000){
$('.too_small').popover("show"); $('.too_small').popover("show");
} }
var all_motds = Array.from(document.getElementsByClassName('input_motd'));
for (element of all_motds) {
initParser(element.id, element.id);
};
}); });
$(window).ready(function(){ $(window).ready(function(){
$('body').click(function(){ $('body').click(function(){
@ -345,7 +340,7 @@ $( document ).ready(function() {
title: '{% raw translate("dashboard", "killing", data['lang']) %}', title: '{% raw translate("dashboard", "killing", data['lang']) %}',
message: '<p><i class="fa fa-spin fa-spinner"></i> Loading...</p>' message: '<p><i class="fa fa-spin fa-spinner"></i> Loading...</p>'
}); });
dialog.init(function(){ dialog.init(function(){
setTimeout(function(){ setTimeout(function(){
location.reload(); location.reload();

View File

@ -71,6 +71,11 @@
<div class="form-group"> <div class="form-group">
<button class="login-input btn btn-primary submit-btn btn-block">{{ translate('login', 'login', data['lang']) }}</button> <button class="login-input btn btn-primary submit-btn btn-block">{{ translate('login', 'login', data['lang']) }}</button>
</div> </div>
{% if error_msg is not None %}
<fieldset style="color: red; text-align: center;">
<span>{{error_msg}}</span>
</fieldset>
{% end %}
<div class="form-group d-flex justify-content-between"> <div class="form-group d-flex justify-content-between">
<div class="form-check form-check-flat mt-0"> <div class="form-check form-check-flat mt-0">
&nbsp; &nbsp;

View File

@ -13,7 +13,10 @@
"error": "Error!", "error": "Error!",
"start-error": "Server {} failed to start with error code: {}", "start-error": "Server {} failed to start with error code: {}",
"closedPort": "We have detected port {} may not be open on the host network or a firewall is blocking it. Remote client connections to the server may be limited.", "closedPort": "We have detected port {} may not be open on the host network or a firewall is blocking it. Remote client connections to the server may be limited.",
"internet": "We have detected the machine running Crafty has no connection to the internet. Client connections to the server may be limited." "internet": "We have detected the machine running Crafty has no connection to the internet. Client connections to the server may be limited.",
"eulaTitle": "Agree To EULA",
"eulaMsg": "You must agree to the EULA. A copy of the Mojang EULA is linked under this message.",
"eulaAgree": "Do you agree?"
}, },
"404": { "404": {
"contact": "Contact Crafty Control Support via Discord", "contact": "Contact Crafty Control Support via Discord",

View File

@ -13,7 +13,10 @@
"error": "Virhe!", "error": "Virhe!",
"start-error": "Palvelin {} ei käynnistynyt virhekoodilla: {}", "start-error": "Palvelin {} ei käynnistynyt virhekoodilla: {}",
"closedPort": "Olemme havainneet, että portti {} ei ehkä ole auki isäntäverkossa tai palomuuri estää sen. Etäasiakkaan yhteydet palvelimeen voivat olla rajallisia.", "closedPort": "Olemme havainneet, että portti {} ei ehkä ole auki isäntäverkossa tai palomuuri estää sen. Etäasiakkaan yhteydet palvelimeen voivat olla rajallisia.",
"internet": "Olemme havainneet, että Crafty -koneella ei ole Internet -yhteyttä. Asiakasyhteydet palvelimelle voivat olla rajalliset." "internet": "Olemme havainneet, että Crafty -koneella ei ole Internet -yhteyttä. Asiakasyhteydet palvelimelle voivat olla rajalliset.",
"eulaTitle": "Hyväksy EULA",
"eulaMsg": "Sinun on hyväksyttävä EULA. Kopio Mojang EULA:sta on linkitetty tämän viestin alla.",
"eulaAgree": "Oletko samaa mieltä?"
}, },
"404": { "404": {
"contact": "Ota yhteyttä Crafty Control -tukeen Discordin kautta", "contact": "Ota yhteyttä Crafty Control -tukeen Discordin kautta",

View File

@ -13,7 +13,10 @@
"error": "Erreur !", "error": "Erreur !",
"start-error": "Le serveur {} n'a pas pu démarrer avec le code d'erreur : {}", "start-error": "Le serveur {} n'a pas pu démarrer avec le code d'erreur : {}",
"closedPort": "Nous avons détecté que le port {} n'est peut-être pas ouvert sur le réseau hôte ou qu'un pare-feu le bloque. Les connexions des clients distants au serveur peuvent être limitées.", "closedPort": "Nous avons détecté que le port {} n'est peut-être pas ouvert sur le réseau hôte ou qu'un pare-feu le bloque. Les connexions des clients distants au serveur peuvent être limitées.",
"internet": "Nous avons détecté que la machine exécutant Crafty n'a pas de connexion à Internet. Les connexions client au serveur peuvent être limitées." "internet": "Nous avons détecté que la machine exécutant Crafty n'a pas de connexion à Internet. Les connexions client au serveur peuvent être limitées.",
"eulaTitle": "Accepter le EULA",
"eulaMsg": "Vous devez accepter le EULA. Une copie du CLUF de Mojang est liée sous ce message.",
"eulaAgree": "Êtes-vous d'accord?"
}, },
"404": { "404": {
"contact": "Contacter le Support de Crafty Control via Discord", "contact": "Contacter le Support de Crafty Control via Discord",

View File

@ -1,6 +1,7 @@
argon2-cffi~=20.1 argon2-cffi~=20.1
bleach~=3.1 bleach~=3.1
colorama~=0.4 colorama~=0.4
cryptography~=3.4
peewee~=3.13 peewee~=3.13
pexpect~=4.8 pexpect~=4.8
psutil~=5.7 psutil~=5.7