Merge branch 'dev' into refactor/backups

This commit is contained in:
amcmanu3 2024-06-24 12:52:47 -04:00
commit 7b1afec9cb
30 changed files with 110 additions and 78 deletions

View File

@ -3,11 +3,16 @@
### New features ### New features
TBD TBD
### Bug fixes ### Bug fixes
TBD - Fix zip imports so the root dir selection is functional ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/764))
- Fix bug where full access gives minimal access ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/768))
- Ensure audit.log exists or create it on Crafty startup ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/771))
### Tweaks ### Tweaks
TBD - Add info note to default creds file ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/760))
- Remove navigation label from sidebar ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/766))
- Add a thread dump to support logs ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/769))
- Remove text from status page and use symbols ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/770))
### Lang ### Lang
TBD - Add remaining `he_IL`, `th_TH` translations for 4.4.0 Release ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/761))
<br><br> <br><br>
## --- [4.4.0] - 2024/05/11 ## --- [4.4.0] - 2024/05/11

View File

@ -1,4 +1,5 @@
import os import os
import sys
import pathlib import pathlib
from pathlib import Path from pathlib import Path
from datetime import datetime from datetime import datetime
@ -251,6 +252,19 @@ class Controller:
# Copy crafty logs to archive dir # Copy crafty logs to archive dir
full_log_name = os.path.join(crafty_path, "logs") full_log_name = os.path.join(crafty_path, "logs")
FileHelpers.copy_dir(os.path.join(self.project_root, "logs"), full_log_name) FileHelpers.copy_dir(os.path.join(self.project_root, "logs"), full_log_name)
thread_dump = ""
for thread in threading.enumerate():
if sys.version_info >= (3, 8):
thread_dump += (
f"Name: {thread.name}\tIdentifier:"
f" {thread.ident}\tTID/PID: {thread.native_id}\n"
)
else:
print(f"Name: {thread.name}\tIdentifier: {thread.ident}")
with open(
os.path.join(temp_dir, "crafty_thread_dump.txt"), "a", encoding="utf-8"
) as f:
f.write(thread_dump)
self.support_scheduler.add_job( self.support_scheduler.add_job(
self.log_status, self.log_status,
"interval", "interval",

View File

@ -6,6 +6,7 @@ import nh3
import tornado.web import tornado.web
from app.classes.models.crafty_permissions import EnumPermissionsCrafty from app.classes.models.crafty_permissions import EnumPermissionsCrafty
from app.classes.models.server_permissions import EnumPermissionsServer
from app.classes.models.users import ApiKeys from app.classes.models.users import ApiKeys
from app.classes.shared.helpers import Helpers from app.classes.shared.helpers import Helpers
from app.classes.shared.file_helpers import FileHelpers from app.classes.shared.file_helpers import FileHelpers
@ -195,6 +196,8 @@ class BaseHandler(tornado.web.RequestHandler):
if api_key is not None: if api_key is not None:
superuser = superuser and api_key.full_access superuser = superuser and api_key.full_access
server_permissions_api_mask = api_key.server_permissions server_permissions_api_mask = api_key.server_permissions
if api_key.full_access:
server_permissions_api_mask = "1" * len(EnumPermissionsServer)
exec_user_role = set() exec_user_role = set()
if superuser: if superuser:
authorized_servers = self.controller.servers.get_all_defined_servers() authorized_servers = self.controller.servers.get_all_defined_servers()

View File

@ -41,7 +41,7 @@ async function getTreeView(path, unzip = false, upload = false) {
let responseData = await res.json(); let responseData = await res.json();
if (responseData.status === "ok") { if (responseData.status === "ok") {
console.log(responseData); console.log(responseData);
process_tree_response(responseData); process_tree_response(responseData, unzip);
let x = document.querySelector('.bootbox'); let x = document.querySelector('.bootbox');
if (x) { if (x) {
x.remove() x.remove()
@ -61,7 +61,7 @@ async function getTreeView(path, unzip = false, upload = false) {
} }
} }
function process_tree_response(response) { function process_tree_response(response, unzip) {
const styles = window.getComputedStyle(document.getElementById("lower_half")); const styles = window.getComputedStyle(document.getElementById("lower_half"));
//If this value is still hidden we know the user is executing a zip import and not an upload //If this value is still hidden we know the user is executing a zip import and not an upload
if (styles.visibility === "hidden") { if (styles.visibility === "hidden") {
@ -70,7 +70,9 @@ function process_tree_response(response) {
document.getElementById('upload_submit').disabled = false; document.getElementById('upload_submit').disabled = false;
} }
let path = response.data.root_path.path; let path = response.data.root_path.path;
$(".root-input").val(response.data.root_path.path); if (unzip) {
$(".root-input").val(response.data.root_path.path);
}
let text = `<ul class="tree-nested d-block" id="${path}ul">`; let text = `<ul class="tree-nested d-block" id="${path}ul">`;
Object.entries(response.data).forEach(([key, value]) => { Object.entries(response.data).forEach(([key, value]) => {
if (key === "root_path" || key === "db_stats") { if (key === "root_path" || key === "db_stats") {
@ -83,7 +85,7 @@ function process_tree_response(response) {
if (value.dir) { if (value.dir) {
text += `<li class="tree-item" id="${dpath}li" data-path="${dpath}"> text += `<li class="tree-item" id="${dpath}li" data-path="${dpath}">
<div id="${dpath}" data-path="${dpath}" data-name="${filename}" class="tree-caret tree-ctx-item tree-folder"> <div id="${dpath}" data-path="${dpath}" data-name="${filename}" class="tree-caret tree-ctx-item tree-folder">
<input type="radio" name="root_path" value="${dpath}"> <input type="radio" class="root-input" name="root_path" value="${dpath}">
<span id="${dpath}span" class="files-tree-title" data-path="${dpath}" data-name="${filename}" onclick="getDirView(event)"> <span id="${dpath}span" class="files-tree-title" data-path="${dpath}" data-name="${filename}" onclick="getDirView(event)">
<i style="color: var(--info);" class="far fa-folder"></i> <i style="color: var(--info);" class="far fa-folder"></i>
<i style="color: var(--info);" class="far fa-folder-open"></i> <i style="color: var(--info);" class="far fa-folder-open"></i>

View File

@ -63,9 +63,6 @@
<nav class="sidebar sidebar-offcanvas" id="sidebar"> <nav class="sidebar sidebar-offcanvas" id="sidebar">
<ul class="nav"> <ul class="nav">
<li class="nav-item nav-category" style="margin-top:10px;">{{ translate('sidebar', 'navigation', data['lang']) }}
</li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="/panel/dashboard"> <a class="nav-link" href="/panel/dashboard">
<i class="fa-solid fa-diagram-project"></i>&nbsp; <i class="fa-solid fa-diagram-project"></i>&nbsp;

View File

@ -64,7 +64,7 @@
<span class="text-warning"><i class="fas fa-exclamation-triangle"></i></span> <span class="text-warning"><i class="fas fa-exclamation-triangle"></i></span>
</td> </td>
<td id="server_motd_{{ server['stats']['server_id']['server_id'] }}"> <td id="server_motd_{{ server['stats']['server_id']['server_id'] }}">
<span class="text-warning">Crafty can't get infos from this Server </span> <span class="text-warning"><i class="fa-solid fa-link-slash"></i> </span>
</td> </td>
<td id="server_version_{{ server['stats']['server_id']['server_id'] }}"> <td id="server_version_{{ server['stats']['server_id']['server_id'] }}">
<span class="text-warning"><i class="fas fa-question"></i></i></span> <span class="text-warning"><i class="fas fa-question"></i></i></span>
@ -148,7 +148,7 @@
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<div id="m_server_motd_{{ server['stats']['server_id']['server_id'] }}"> <div id="m_server_motd_{{ server['stats']['server_id']['server_id'] }}">
<span class="text-warning"><i class="fas fa-exclamation-triangle"></i> Crafty can't get infos from <span class="text-warning"><i class="fas fa-exclamation-triangle"></i> Crafty can't get info from
this Server </span> this Server </span>
</div> </div>
<div id="m_server_version_{{ server['stats']['server_id']['server_id'] }}"></div> <div id="m_server_version_{{ server['stats']['server_id']['server_id'] }}"></div>
@ -223,9 +223,9 @@
} }
else { else {
server_players.innerHTML = `<span class="text-warning"><i class="fas fa-exclamation-triangle"></i></span>`; 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_motd.innerHTML = `<span class="text-warning"><i class="fa-solid fa-link-slash"></i> </span>`;
server_version.innerHTML = `<span class="text-warning"><i class="fas fa-question"></i></i></span>`; server_version.innerHTML = `<span class="text-warning"><i class="fas fa-question"></i></i></span>`;
m_server_motd.innerHTML = `<span class="text-warning"><i class="fas fa-exclamation-triangle"></i> Crafty can't get infos from this Server </span>`; m_server_motd.innerHTML = `<span class="text-warning"><i class="fas fa-exclamation-triangle"></i> <i class="fa-solid fa-link-slash"></i> </span>`;
} }
/* Update Online Status */ /* Update Online Status */

View File

@ -246,11 +246,6 @@
</div> </div>
</div> </div>
</div> </div>
<div style="visibility: hidden;">
<div class="form-group">
<input type="text" class="form-control" id="zip_root_path" name="zip_root_path">
</div>
</div>
<div class="modal fade" id="dir_select" tabindex="-1" role="dialog" aria-labelledby="dir_select" <div class="modal fade" id="dir_select" tabindex="-1" role="dialog" aria-labelledby="dir_select"
aria-hidden="true"> aria-hidden="true">
<div class="modal-dialog" role="document"> <div class="modal-dialog" role="document">
@ -378,11 +373,6 @@
</div> </div>
</div> </div>
</div> </div>
<div style="visibility: hidden;">
<div class="form-group">
<input type="text" class="form-control" id="zip_root_path" name="zip_root_path">
</div>
</div>
<div class="modal fade" id="dir_upload_select" tabindex="-1" role="dialog" aria-labelledby="dir_select" <div class="modal fade" id="dir_upload_select" tabindex="-1" role="dialog" aria-labelledby="dir_select"
aria-hidden="true"> aria-hidden="true">
<div class="modal-dialog" role="document"> <div class="modal-dialog" role="document">
@ -591,7 +581,7 @@
message: '<p class="text-center mb-0"><i class="fa fa-spin fa-cog"></i> Please wait while we gather your files...</p>', message: '<p class="text-center mb-0"><i class="fa fa-spin fa-cog"></i> Please wait while we gather your files...</p>',
closeButton: false closeButton: false
}); });
setTimeout(function(){ setTimeout(function () {
getDirView(); getDirView();
}, 2000); }, 2000);
} else { } else {
@ -640,7 +630,7 @@
message: '<p class="text-center mb-0"><i class="fa fa-spin fa-cog"></i> Please wait while we gather your files...</p>', message: '<p class="text-center mb-0"><i class="fa fa-spin fa-cog"></i> Please wait while we gather your files...</p>',
closeButton: false closeButton: false
}); });
setTimeout(function(){ setTimeout(function () {
getDirView(); getDirView();
}, 2000); }, 2000);
} else { } else {
@ -796,7 +786,13 @@
wait_msg(true); wait_msg(true);
e.preventDefault(); e.preventDefault();
let jarForm = document.getElementById("import-zip"); let jarForm = document.getElementById("import-zip");
var checkedRadio = $('.root-input:checked');
let zip_root_path = ""
if (checkedRadio.length > 0) {
// Get the value of the checked radio button
var checkedValue = checkedRadio.val();
zip_root_path = checkedValue; // Return the checked value if needed
}
let formData = new FormData(jarForm); let formData = new FormData(jarForm);
//Create an object from the form data entries //Create an object from the form data entries
let formDataObject = Object.fromEntries(formData.entries()); let formDataObject = Object.fromEntries(formData.entries());
@ -813,7 +809,7 @@
"minecraft_bedrock_create_data": { "minecraft_bedrock_create_data": {
"create_type": "import_server", "create_type": "import_server",
"import_server_create_data": { "import_server_create_data": {
"existing_server_path": formDataObject.root_path, "existing_server_path": zip_root_path,
"executable": formDataObject.server_jar, "executable": formDataObject.server_jar,
} }
} }
@ -834,6 +830,13 @@
//Create an object from the form data entries //Create an object from the form data entries
let formDataObject = Object.fromEntries(formData.entries()); let formDataObject = Object.fromEntries(formData.entries());
console.log(formDataObject); console.log(formDataObject);
var checkedRadio = $('.root-input:checked');
let zip_root_path = ""
if (checkedRadio.length > 0) {
// Get the value of the checked radio button
var checkedValue = checkedRadio.val();
zip_root_path = checkedValue; // Return the checked value if needed
}
let send_data = { let send_data = {
"name": formDataObject.name, "name": formDataObject.name,
"roles": calcRoles(), "roles": calcRoles(),
@ -846,7 +849,7 @@
"minecraft_bedrock_create_data": { "minecraft_bedrock_create_data": {
"create_type": "import_server", "create_type": "import_server",
"import_server_create_data": { "import_server_create_data": {
"existing_server_path": formDataObject.root_path, "existing_server_path": zip_root_path,
"executable": formDataObject.server_jar, "executable": formDataObject.server_jar,
} }
} }

View File

@ -437,11 +437,6 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col-sm-12" style="visibility: hidden;" hidden>
<div class="form-group">
<input type="text" class="form-control" id="zip_root_path" name="zip_root_path">
</div>
</div>
<div class="modal fade" id="dir_select" tabindex="-1" role="dialog" aria-labelledby="dir_select" <div class="modal fade" id="dir_select" tabindex="-1" role="dialog" aria-labelledby="dir_select"
aria-hidden="true"> aria-hidden="true">
<div class="modal-dialog" role="document"> <div class="modal-dialog" role="document">
@ -588,11 +583,6 @@
</div> </div>
</div> </div>
</div> </div>
<div style="visibility: hidden;">
<div class="form-group">
<input type="text" class="form-control" id="zip_root_path" name="zip_root_path">
</div>
</div>
<div class="modal fade" id="dir_upload_select" tabindex="-1" role="dialog" aria-labelledby="dir_select" <div class="modal fade" id="dir_upload_select" tabindex="-1" role="dialog" aria-labelledby="dir_select"
aria-hidden="true"> aria-hidden="true">
<div class="modal-dialog" role="document"> <div class="modal-dialog" role="document">
@ -1035,6 +1025,13 @@
//Create an object from the form data entries //Create an object from the form data entries
let formDataObject = Object.fromEntries(formData.entries()); let formDataObject = Object.fromEntries(formData.entries());
console.log(formDataObject); console.log(formDataObject);
var checkedRadio = $('.root-input:checked');
let zip_root_path = ""
if (checkedRadio.length > 0) {
// Get the value of the checked radio button
var checkedValue = checkedRadio.val();
zip_root_path = checkedValue; // Return the checked value if needed
}
let send_data = { let send_data = {
"name": formDataObject.name, "name": formDataObject.name,
"roles": calcRoles(), "roles": calcRoles(),
@ -1047,7 +1044,7 @@
"minecraft_java_create_data": { "minecraft_java_create_data": {
"create_type": "import_server", "create_type": "import_server",
"import_server_create_data": { "import_server_create_data": {
"existing_server_path": formDataObject.root_path, "existing_server_path": zip_root_path,
"jarfile": formDataObject.server_jar, "jarfile": formDataObject.server_jar,
"mem_min": formDataObject.mem_min, "mem_min": formDataObject.mem_min,
"mem_max": formDataObject.mem_max, "mem_max": formDataObject.mem_max,
@ -1071,6 +1068,13 @@
//Create an object from the form data entries //Create an object from the form data entries
let formDataObject = Object.fromEntries(formData.entries()); let formDataObject = Object.fromEntries(formData.entries());
console.log(formDataObject); console.log(formDataObject);
var checkedRadio = $('.root-input:checked');
let zip_root_path = ""
if (checkedRadio.length > 0) {
// Get the value of the checked radio button
var checkedValue = checkedRadio.val();
zip_root_path = checkedValue; // Return the checked value if needed
}
let send_data = { let send_data = {
"name": formDataObject.name, "name": formDataObject.name,
"roles": calcRoles(), "roles": calcRoles(),
@ -1083,7 +1087,7 @@
"minecraft_java_create_data": { "minecraft_java_create_data": {
"create_type": "import_server", "create_type": "import_server",
"import_server_create_data": { "import_server_create_data": {
"existing_server_path": formDataObject.root_path, "existing_server_path": zip_root_path,
"jarfile": formDataObject.server_jar, "jarfile": formDataObject.server_jar,
"mem_min": formDataObject.mem_min, "mem_min": formDataObject.mem_min,
"mem_max": formDataObject.mem_max, "mem_max": formDataObject.mem_max,

View File

@ -635,7 +635,6 @@
"dashboard": "Ovládací panel", "dashboard": "Ovládací panel",
"documentation": "Dokumentace", "documentation": "Dokumentace",
"inApp": "V lokalní dokumentaci", "inApp": "V lokalní dokumentaci",
"navigation": "Navigace",
"newServer": "Vytvořit nový server", "newServer": "Vytvořit nový server",
"servers": "Servery" "servers": "Servery"
}, },
@ -714,4 +713,4 @@
"webhook_body": "Webhook Body", "webhook_body": "Webhook Body",
"webhooks": "Webhooky" "webhooks": "Webhooky"
} }
} }

View File

@ -616,7 +616,6 @@
"dashboard": "Dashboard", "dashboard": "Dashboard",
"documentation": "Dokumentation", "documentation": "Dokumentation",
"inApp": "In-App-Dokumentation", "inApp": "In-App-Dokumentation",
"navigation": "Navigation",
"newServer": "Neuen Server erstellen", "newServer": "Neuen Server erstellen",
"servers": "Server" "servers": "Server"
}, },
@ -695,4 +694,4 @@
"webhook_body": "Webhook-Inhalt", "webhook_body": "Webhook-Inhalt",
"webhooks": "Webhooks" "webhooks": "Webhooks"
} }
} }

View File

@ -612,7 +612,6 @@
"dashboard": "Dashboard", "dashboard": "Dashboard",
"documentation": "Documentation", "documentation": "Documentation",
"inApp": "In App Docs", "inApp": "In App Docs",
"navigation": "Navigation",
"newServer": "Create New Server", "newServer": "Create New Server",
"servers": "Servers" "servers": "Servers"
}, },
@ -691,4 +690,4 @@
"webhook_body": "Webhook Body", "webhook_body": "Webhook Body",
"webhooks": "Webhooks" "webhooks": "Webhooks"
} }
} }

View File

@ -616,7 +616,6 @@
"dashboard": "Panel de control", "dashboard": "Panel de control",
"documentation": "Documentación", "documentation": "Documentación",
"inApp": "Documentación de la Aplicación", "inApp": "Documentación de la Aplicación",
"navigation": "Navegación",
"newServer": "Crear nuevo Servidor", "newServer": "Crear nuevo Servidor",
"servers": "Servidores" "servers": "Servidores"
}, },
@ -695,4 +694,4 @@
"webhook_body": "Cuerpo del Webhook", "webhook_body": "Cuerpo del Webhook",
"webhooks": "Webhooks" "webhooks": "Webhooks"
} }
} }

View File

@ -520,7 +520,6 @@
"credits": "Hyvitykset", "credits": "Hyvitykset",
"dashboard": "Kojelauta", "dashboard": "Kojelauta",
"documentation": "Dokumentaatio", "documentation": "Dokumentaatio",
"navigation": "Navigaatio",
"newServer": "Luo uusi palvelin", "newServer": "Luo uusi palvelin",
"servers": "Palvelimet" "servers": "Palvelimet"
}, },

View File

@ -616,7 +616,6 @@
"dashboard": "Tableau de Bord", "dashboard": "Tableau de Bord",
"documentation": "Documentation", "documentation": "Documentation",
"inApp": "Documentation Interne", "inApp": "Documentation Interne",
"navigation": "Navigation",
"newServer": "Créer un Nouveau Serveur", "newServer": "Créer un Nouveau Serveur",
"servers": "Serveurs" "servers": "Serveurs"
}, },
@ -695,4 +694,4 @@
"webhook_body": "Corps du Webhook", "webhook_body": "Corps du Webhook",
"webhooks": "Webhooks" "webhooks": "Webhooks"
} }
} }

View File

@ -489,7 +489,6 @@
"credits": "Credits", "credits": "Credits",
"dashboard": "Dashboard", "dashboard": "Dashboard",
"documentation": "Dokumintaasje", "documentation": "Dokumintaasje",
"navigation": "Navigaasje",
"newServer": "Nije server oanmeitsje", "newServer": "Nije server oanmeitsje",
"servers": "Servers" "servers": "Servers"
}, },

View File

@ -184,6 +184,8 @@
"error": { "error": {
"agree": "מסכים", "agree": "מסכים",
"bedrockError": "הורדות Bedrock אינן זמינות. אנא בדוק", "bedrockError": "הורדות Bedrock אינן זמינות. אנא בדוק",
"bigBucket1": "בדיקת הבריאות של Big Bucket נכשלה. אנא בדוק",
"bigBucket2": "כדי לקבל את המידע המעודכן ביותר.",
"cancel": "בטל", "cancel": "בטל",
"contact": "בבקשה צרו קשר עם תמיכת פאנל קראפטי באמצעות דיסקורד", "contact": "בבקשה צרו קשר עם תמיכת פאנל קראפטי באמצעות דיסקורד",
"craftyStatus": "דף המצב של Crafty", "craftyStatus": "דף המצב של Crafty",
@ -206,6 +208,7 @@
"portReminder": "זיהינו שזו הפעם הראשונה ש-{} מופעל. הקפידו להעביר את היציאה {} דרך הנתב/חומת האש שלכם כדי להפוך אותה לנגישה מרחוק מהאינטרנט.", "portReminder": "זיהינו שזו הפעם הראשונה ש-{} מופעל. הקפידו להעביר את היציאה {} דרך הנתב/חומת האש שלכם כדי להפוך אותה לנגישה מרחוק מהאינטרנט.",
"privMsg": "וה", "privMsg": "וה",
"return": "חזרה לפאנל", "return": "חזרה לפאנל",
"selfHost": "אם אתה מארח בעצמך את הריפו הזה, אנא בדוק את הכתובת שלך או התייעץ עם מדריך פתרון הבעיות שלנו.",
"serverJars1": "API של צנצנות השרת אינו נגיש. אנא בדוק", "serverJars1": "API של צנצנות השרת אינו נגיש. אנא בדוק",
"serverJars2": "למידע מעודכן ביותר.", "serverJars2": "למידע מעודכן ביותר.",
"start-error": "השרת {} לא הצליח להתחיל עם קוד שגיאה: {}", "start-error": "השרת {} לא הצליח להתחיל עם קוד שגיאה: {}",
@ -613,12 +616,12 @@
"dashboard": "פאנל", "dashboard": "פאנל",
"documentation": "ויקיפדייה", "documentation": "ויקיפדייה",
"inApp": "מסמכים באפליקציה", "inApp": "מסמכים באפליקציה",
"navigation": "ניווט",
"newServer": "צור שרת חדש", "newServer": "צור שרת חדש",
"servers": "שרתים" "servers": "שרתים"
}, },
"startup": { "startup": {
"almost": "מסיימים. תחזיקו חזק...", "almost": "מסיימים. תחזיקו חזק...",
"cache": "מרענן את קובץ המטמון של Big Bucket",
"internals": "הגדרה והפעלה של הרכיבים הפנימיים של Crafty", "internals": "הגדרה והפעלה של הרכיבים הפנימיים של Crafty",
"internet": "בודק את חיבור האינטרנט", "internet": "בודק את חיבור האינטרנט",
"server": "אתחול ", "server": "אתחול ",
@ -691,4 +694,4 @@
"webhook_body": "גוף ה-Webhook", "webhook_body": "גוף ה-Webhook",
"webhooks": "Webhooks" "webhooks": "Webhooks"
} }
} }

View File

@ -489,7 +489,6 @@
"credits": "Zasluge", "credits": "Zasluge",
"dashboard": "Upravljačka ploča", "dashboard": "Upravljačka ploča",
"documentation": "Dokumentacija", "documentation": "Dokumentacija",
"navigation": "Navigacija",
"newServer": "Stvorite novi poslužitelj", "newServer": "Stvorite novi poslužitelj",
"servers": "Poslužitelji" "servers": "Poslužitelji"
}, },

View File

@ -496,7 +496,6 @@
"credits": "Kredit", "credits": "Kredit",
"dashboard": "Dasbor", "dashboard": "Dasbor",
"documentation": "Documentasi", "documentation": "Documentasi",
"navigation": "Navigasi",
"newServer": "Membuat Server Baru", "newServer": "Membuat Server Baru",
"servers": "Server" "servers": "Server"
}, },

View File

@ -616,7 +616,6 @@
"dashboard": "Pannello di controllo", "dashboard": "Pannello di controllo",
"documentation": "Documentazione", "documentation": "Documentazione",
"inApp": "Documenti in app", "inApp": "Documenti in app",
"navigation": "Navigazione",
"newServer": "Crea un Nuovo Server", "newServer": "Crea un Nuovo Server",
"servers": "Servers" "servers": "Servers"
}, },
@ -695,4 +694,4 @@
"webhook_body": "Corpo del Webhook", "webhook_body": "Corpo del Webhook",
"webhooks": "Webhook" "webhooks": "Webhook"
} }
} }

View File

@ -616,7 +616,6 @@
"dashboard": "DASHBORD", "dashboard": "DASHBORD",
"documentation": "DOCUMENTASHUN", "documentation": "DOCUMENTASHUN",
"inApp": "IN APPZ DOCS", "inApp": "IN APPZ DOCS",
"navigation": "NAVIGASHUN",
"newServer": "CONSTWUCT A SERVR", "newServer": "CONSTWUCT A SERVR",
"servers": "SERVRS" "servers": "SERVRS"
}, },
@ -695,4 +694,4 @@
"webhook_body": "WEBHOOK FISH", "webhook_body": "WEBHOOK FISH",
"webhooks": "WEBHOOKZ" "webhooks": "WEBHOOKZ"
} }
} }

View File

@ -617,7 +617,6 @@
"dashboard": "Panelis", "dashboard": "Panelis",
"documentation": "Dokumentācija", "documentation": "Dokumentācija",
"inApp": "Iebūvētā dokumentācija", "inApp": "Iebūvētā dokumentācija",
"navigation": "Navigācija",
"newServer": "Izveidot Jaunu Serveri", "newServer": "Izveidot Jaunu Serveri",
"servers": "Serveri" "servers": "Serveri"
}, },
@ -696,4 +695,4 @@
"webhook_body": "Webhook Saturs", "webhook_body": "Webhook Saturs",
"webhooks": "Webhooki" "webhooks": "Webhooki"
} }
} }

View File

@ -616,7 +616,6 @@
"dashboard": "Dashboard", "dashboard": "Dashboard",
"documentation": "Documentatie", "documentation": "Documentatie",
"inApp": "In-app documentatie", "inApp": "In-app documentatie",
"navigation": "Navigatie",
"newServer": "Nieuwe server maken", "newServer": "Nieuwe server maken",
"servers": "Servers" "servers": "Servers"
}, },
@ -695,4 +694,4 @@
"webhook_body": "Webhook-body", "webhook_body": "Webhook-body",
"webhooks": "Webhooks" "webhooks": "Webhooks"
} }
} }

View File

@ -489,7 +489,6 @@
"credits": "Credits", "credits": "Credits",
"dashboard": "Dashboard", "dashboard": "Dashboard",
"documentation": "Documentatie", "documentation": "Documentatie",
"navigation": "Navigatie",
"newServer": "Nieuwe server maken", "newServer": "Nieuwe server maken",
"servers": "Servers" "servers": "Servers"
}, },

View File

@ -615,7 +615,6 @@
"dashboard": "Panel", "dashboard": "Panel",
"documentation": "Dokumentacja", "documentation": "Dokumentacja",
"inApp": "Dokumentacja w Aplikacji", "inApp": "Dokumentacja w Aplikacji",
"navigation": "Nawigacja",
"newServer": "Stwórz nowy serwer", "newServer": "Stwórz nowy serwer",
"servers": "Serwery" "servers": "Serwery"
}, },
@ -694,4 +693,4 @@
"webhook_body": "Treść Webhooka", "webhook_body": "Treść Webhooka",
"webhooks": "Webhooki" "webhooks": "Webhooki"
} }
} }

View File

@ -497,7 +497,6 @@
"credits": "Créditos", "credits": "Créditos",
"dashboard": "Painel de Controle", "dashboard": "Painel de Controle",
"documentation": "Documentação", "documentation": "Documentação",
"navigation": "Navegação",
"newServer": "Criar Novo Servidor", "newServer": "Criar Novo Servidor",
"servers": "Servidores" "servers": "Servidores"
}, },

View File

@ -184,6 +184,8 @@
"error": { "error": {
"agree": "ยอมรับ", "agree": "ยอมรับ",
"bedrockError": "การดาวน์โหลดเวอร์ชั่น Bedrock ไม่พร้อมใช้งาน โปรดตรวจสอบ", "bedrockError": "การดาวน์โหลดเวอร์ชั่น Bedrock ไม่พร้อมใช้งาน โปรดตรวจสอบ",
"bigBucket1": "การตรวจสอบสุขภาพ Big Bucket ล้มเหลว โปรดตรวจสอบ",
"bigBucket2": "สำหรับข้อมูลล่าสุด",
"cancel": "ยกเลิก", "cancel": "ยกเลิก",
"contact": "ติดต่อฝ่ายสนับสนุน Crafty Control ผ่านดิสคอร์ด", "contact": "ติดต่อฝ่ายสนับสนุน Crafty Control ผ่านดิสคอร์ด",
"craftyStatus": "หน้าสถานะของ Crafty", "craftyStatus": "หน้าสถานะของ Crafty",
@ -206,6 +208,7 @@
"portReminder": "เราตรวจพบว่านี่เป็นครั้งแรกที่มีการเรียกใช้ {} ตรวจสอบให้แน่ใจว่าได้ Forward port {} ผ่านเราเตอร์/ไฟร์วอลล์ของคุณเพื่อให้สามารถเข้าถึงได้จากอินเทอร์เน็ตจากระยะไกล", "portReminder": "เราตรวจพบว่านี่เป็นครั้งแรกที่มีการเรียกใช้ {} ตรวจสอบให้แน่ใจว่าได้ Forward port {} ผ่านเราเตอร์/ไฟร์วอลล์ของคุณเพื่อให้สามารถเข้าถึงได้จากอินเทอร์เน็ตจากระยะไกล",
"privMsg": "และ ", "privMsg": "และ ",
"return": "ย้อนกลับไปยังแผงควบคุม", "return": "ย้อนกลับไปยังแผงควบคุม",
"selfHost": "หากคุณโฮสต์ repo นี้ด้วยตนเอง โปรดตรวจสอบที่อยู่ของคุณ หรือศึกษาคู่มือแก้ปัญหาของเรา",
"serverJars1": "ไม่สามารถเข้าถึงเซิร์ฟเวอร์ JARs API กรุณาตรวจสอบ", "serverJars1": "ไม่สามารถเข้าถึงเซิร์ฟเวอร์ JARs API กรุณาตรวจสอบ",
"serverJars2": "เพื่อข้อมูลที่ทันสมัยที่สุด", "serverJars2": "เพื่อข้อมูลที่ทันสมัยที่สุด",
"start-error": "เซิร์ฟเวอร์ {} ไม่สามารถเริ่มต้นได้เนื่องจากรหัสข้อผิดพลาด: {}", "start-error": "เซิร์ฟเวอร์ {} ไม่สามารถเริ่มต้นได้เนื่องจากรหัสข้อผิดพลาด: {}",
@ -612,12 +615,12 @@
"dashboard": "แผงควบคุม", "dashboard": "แผงควบคุม",
"documentation": "เอกสารประกอบ", "documentation": "เอกสารประกอบ",
"inApp": "เอกสารประกอบภายในแอป", "inApp": "เอกสารประกอบภายในแอป",
"navigation": "เมนูนำทาง",
"newServer": "สร้างเซิร์ฟเวอร์ใหม่", "newServer": "สร้างเซิร์ฟเวอร์ใหม่",
"servers": "เซิร์ฟเวอร์" "servers": "เซิร์ฟเวอร์"
}, },
"startup": { "startup": {
"almost": "เสร็จสิ้นการทำงาน. รอซักครู่...", "almost": "เสร็จสิ้นการทำงาน. รอซักครู่...",
"cache": "กำลังรีเฟรชไฟล์แคช Big Bucket",
"internals": "กำหนดค่าและเริ่มการทำงานภายในของ Crafty", "internals": "กำหนดค่าและเริ่มการทำงานภายในของ Crafty",
"internet": "กำลังตรวจสอบการเชื่อมต่ออินเทอร์เน็ต", "internet": "กำลังตรวจสอบการเชื่อมต่ออินเทอร์เน็ต",
"server": "กำลังเริ่มต้นการทำงาน ", "server": "กำลังเริ่มต้นการทำงาน ",
@ -690,4 +693,4 @@
"webhook_body": "ภายใน Webhook", "webhook_body": "ภายใน Webhook",
"webhooks": "Webhooks" "webhooks": "Webhooks"
} }
} }

View File

@ -615,7 +615,6 @@
"dashboard": "Arayüz", "dashboard": "Arayüz",
"documentation": "Dokümantasyon", "documentation": "Dokümantasyon",
"inApp": "Uygulama İçi Dokümanlar", "inApp": "Uygulama İçi Dokümanlar",
"navigation": "Navigasyon",
"newServer": "Yeni Sunucu Oluştur", "newServer": "Yeni Sunucu Oluştur",
"servers": "Sunucular" "servers": "Sunucular"
}, },
@ -694,4 +693,4 @@
"webhook_body": "Webhook Gövdesi", "webhook_body": "Webhook Gövdesi",
"webhooks": "Webhooklar" "webhooks": "Webhooklar"
} }
} }

View File

@ -615,7 +615,6 @@
"dashboard": "Панель", "dashboard": "Панель",
"documentation": "Документація", "documentation": "Документація",
"inApp": "Швидка документація", "inApp": "Швидка документація",
"navigation": "Навігація",
"newServer": "Створити новий сервер", "newServer": "Створити новий сервер",
"servers": "Сервери" "servers": "Сервери"
}, },
@ -694,4 +693,4 @@
"webhook_body": "Код Вебхука", "webhook_body": "Код Вебхука",
"webhooks": "Вебхуки" "webhooks": "Вебхуки"
} }
} }

View File

@ -616,7 +616,6 @@
"dashboard": "仪表板", "dashboard": "仪表板",
"documentation": "文档", "documentation": "文档",
"inApp": "内置文档", "inApp": "内置文档",
"navigation": "导航栏",
"newServer": "创建新服务器", "newServer": "创建新服务器",
"servers": "服务器" "servers": "服务器"
}, },
@ -695,4 +694,4 @@
"webhook_body": "Webhook 消息体Body", "webhook_body": "Webhook 消息体Body",
"webhooks": "Webhook" "webhooks": "Webhook"
} }
} }

19
main.py
View File

@ -278,6 +278,15 @@ def setup_logging(debug=True):
encoding="utf-8", encoding="utf-8",
).close() ).close()
if not helper.check_file_exists(
os.path.join(APPLICATION_PATH, "logs", "audit.log")
):
open(
os.path.join(APPLICATION_PATH, "logs", "audit.log"),
"a",
encoding="utf-8",
).close()
if os.path.exists(logging_config_file): if os.path.exists(logging_config_file):
# open our logging config file # open our logging config file
with open(logging_config_file, "rt", encoding="utf-8") as f: with open(logging_config_file, "rt", encoding="utf-8") as f:
@ -367,7 +376,15 @@ if __name__ == "__main__":
encoding="utf-8", encoding="utf-8",
) as cred_file: ) as cred_file:
cred_file.write( cred_file.write(
json.dumps({"username": "admin", "password": PASSWORD}, indent=4) json.dumps(
{
"username": "admin",
"password": PASSWORD,
"info": "This is NOT where you change your password."
" This file is only a means to give you a default password.",
},
indent=4,
)
) )
os.chmod( os.chmod(
os.path.join(APPLICATION_PATH, "app", "config", "default-creds.txt"), 0o600 os.path.join(APPLICATION_PATH, "app", "config", "default-creds.txt"), 0o600