mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
Merge branch 'dev' into refactor/server_ids
This commit is contained in:
commit
0a3512a18e
@ -44,7 +44,7 @@ black:
|
||||
# Code Climate/Quality Checking [https://pylint.pycqa.org/en/latest/]
|
||||
pylint:
|
||||
stage: lint
|
||||
image: registry.gitlab.com/pipeline-components/pylint:0.21.1
|
||||
image: registry.gitlab.com/pipeline-components/pylint:latest
|
||||
tags:
|
||||
- docker
|
||||
rules:
|
||||
|
@ -3,6 +3,7 @@
|
||||
### New features
|
||||
- Use Papermc Group's API for `paper` & `folia` builds in server builder ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/688))
|
||||
- Allow omission of player count from Dashboard (e.g. for proxy servers) ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/692))
|
||||
- Add lockout user for forgot password ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/694))
|
||||
### Refactor
|
||||
- Refactor subpage perm checks ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/695))
|
||||
### Bug fixes
|
||||
@ -15,6 +16,7 @@
|
||||
### Tweaks
|
||||
- Refactor Forge server initialisation flow for newer versions ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/687))
|
||||
- Remove scroll bars from player management ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/693))
|
||||
- Add warning to wizard for unsupported mc ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/701))
|
||||
### Lang
|
||||
- Update `zh_CN, pl_PL, nl_BE, lv_LV, he_IL, fr_FR, de_DE, lol_EN` translations for `4.2.3` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/696))
|
||||
- New `uk_UA, tr_TR, th_TH` translations for `4.2.3` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/696))
|
||||
|
@ -1,5 +1,9 @@
|
||||
import logging
|
||||
import typing as t
|
||||
import datetime
|
||||
from datetime import timedelta
|
||||
from zoneinfo import ZoneInfo
|
||||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
from app.classes.models.servers import HelperServers
|
||||
|
||||
from app.classes.models.users import HelperUsers
|
||||
@ -8,6 +12,7 @@ from app.classes.models.crafty_permissions import (
|
||||
PermissionsCrafty,
|
||||
EnumPermissionsCrafty,
|
||||
)
|
||||
from app.classes.shared.console import Console
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -22,6 +27,8 @@ class UsersController:
|
||||
self.helper = helper
|
||||
self.users_helper = users_helper
|
||||
self.authentication = authentication
|
||||
self.scheduler = BackgroundScheduler(timezone="Etc/UTC")
|
||||
self.scheduler.start()
|
||||
|
||||
_permissions_props = {
|
||||
"name": {
|
||||
@ -169,7 +176,8 @@ class UsersController:
|
||||
# create sets to store role data
|
||||
added_roles = set()
|
||||
removed_roles = set()
|
||||
|
||||
if user_data.get("username", None) == "anti-lockout-user":
|
||||
raise ValueError("Invalid Username")
|
||||
# search for changes in user data
|
||||
for key in user_data:
|
||||
if key == "user_id":
|
||||
@ -245,6 +253,8 @@ class UsersController:
|
||||
superuser: bool = False,
|
||||
theme="default",
|
||||
):
|
||||
if username == "anti-lockout-user":
|
||||
raise ValueError("Username is not valid")
|
||||
return self.users_helper.add_user(
|
||||
username,
|
||||
manager,
|
||||
@ -353,3 +363,37 @@ class UsersController:
|
||||
|
||||
def delete_user_api_key(self, key_id: str):
|
||||
return self.users_helper.delete_user_api_key(key_id)
|
||||
|
||||
# **********************************************************************************
|
||||
# Lockout Methods
|
||||
# **********************************************************************************
|
||||
def start_anti_lockout(self):
|
||||
lockout_pass = self.helper.create_pass()
|
||||
self.users_helper.add_user(
|
||||
"anti-lockout-user",
|
||||
None,
|
||||
password=lockout_pass,
|
||||
email="",
|
||||
enabled=True,
|
||||
superuser=True,
|
||||
theme="anti-lockout",
|
||||
)
|
||||
|
||||
Console.yellow(
|
||||
f"""
|
||||
Anti-lockout recovery account enabled!
|
||||
{'/' * 74}
|
||||
Username: anti-lockout-user
|
||||
Password: {lockout_pass}
|
||||
{'/' * 74}"""
|
||||
)
|
||||
self.scheduler.add_job(
|
||||
self.stop_anti_lockout,
|
||||
"date",
|
||||
id="anti-lockout-watcher",
|
||||
run_date=datetime.datetime.now(ZoneInfo("Etc/UTC")) + timedelta(hours=1),
|
||||
)
|
||||
|
||||
def stop_anti_lockout(self):
|
||||
self.scheduler.remove_all_jobs()
|
||||
self.users_helper.remove_user(self.get_id_by_name("anti-lockout-user"))
|
||||
|
@ -103,7 +103,9 @@ class HelperUsers:
|
||||
|
||||
@staticmethod
|
||||
def get_all_users():
|
||||
query = Users.select().where(Users.username != "system")
|
||||
query = Users.select().where(
|
||||
Users.username != "system", Users.username != "anti-lockout-user"
|
||||
)
|
||||
return query
|
||||
|
||||
@staticmethod
|
||||
|
@ -12,6 +12,7 @@ from app.classes.shared.file_helpers import FileHelpers
|
||||
from app.classes.shared.main_controller import Controller
|
||||
from app.classes.shared.translation import Translation
|
||||
from app.classes.shared.main_models import DatabaseShortcuts
|
||||
from app.classes.models.users import DoesNotExist
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
auth_log = logging.getLogger("auth")
|
||||
@ -91,7 +92,10 @@ class BaseHandler(tornado.web.RequestHandler):
|
||||
t.Dict[str, t.Any]: The token's payload.
|
||||
t.Dict[str, t.Any]: The user's data from the database.
|
||||
"""
|
||||
return self.controller.authentication.check(self.get_cookie("token"))
|
||||
try:
|
||||
return self.controller.authentication.check(self.get_cookie("token"))
|
||||
except DoesNotExist:
|
||||
return None
|
||||
|
||||
def autobleach(self, name, text):
|
||||
for r in self.redactables:
|
||||
|
@ -302,6 +302,8 @@ class PanelHandler(BaseHandler):
|
||||
"Could not capture time zone from system. Falling back to Europe/London"
|
||||
)
|
||||
tz = "Europe/London"
|
||||
if exec_user["username"] == "anti-lockout-user":
|
||||
page = "panel_config"
|
||||
|
||||
page_data: t.Dict[str, t.Any] = {
|
||||
# todo: make this actually pull and compare version data
|
||||
|
@ -61,7 +61,11 @@ class PublicHandler(BaseHandler):
|
||||
template = "public/offline.html"
|
||||
|
||||
elif page == "logout":
|
||||
exec_user = self.get_current_user()
|
||||
self.clear_cookie("token")
|
||||
# Delete anti-lockout-user on lockout...it's one time use
|
||||
if exec_user[2]["username"] == "anti-lockout-user":
|
||||
self.controller.users.stop_anti_lockout()
|
||||
# self.clear_cookie("user")
|
||||
# self.clear_cookie("user_data")
|
||||
self.redirect("/login")
|
||||
|
@ -79,6 +79,7 @@ from app.classes.web.routes.api.crafty.stats.stats import ApiCraftyHostStatsHand
|
||||
from app.classes.web.routes.api.crafty.clogs.index import ApiCraftyLogIndexHandler
|
||||
from app.classes.web.routes.api.crafty.imports.index import ApiImportFilesIndexHandler
|
||||
from app.classes.web.routes.api.crafty.exe_cache import ApiCraftyJarCacheIndexHandler
|
||||
from app.classes.web.routes.api.crafty.antilockout.index import ApiCraftyLockoutHandler
|
||||
|
||||
|
||||
def api_handlers(handler_args):
|
||||
@ -94,6 +95,11 @@ def api_handlers(handler_args):
|
||||
ApiAuthInvalidateTokensHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/crafty/resetPass/?",
|
||||
ApiCraftyLockoutHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/crafty/announcements/?",
|
||||
ApiAnnounceIndexHandler,
|
||||
|
24
app/classes/web/routes/api/crafty/antilockout/index.py
Normal file
24
app/classes/web/routes/api/crafty/antilockout/index.py
Normal file
@ -0,0 +1,24 @@
|
||||
import logging
|
||||
from app.classes.web.base_api_handler import BaseApiHandler
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ApiCraftyLockoutHandler(BaseApiHandler):
|
||||
def get(self):
|
||||
if self.controller.users.get_id_by_name("anti-lockout-user"):
|
||||
return self.finish_json(
|
||||
425, {"status": "error", "data": "Lockout recovery already in progress"}
|
||||
)
|
||||
self.controller.users.start_anti_lockout()
|
||||
lockout_msg = (
|
||||
"Lockout account has been activated for 1 hour."
|
||||
" Please find temporary credentials in the terminal"
|
||||
)
|
||||
return self.finish_json(
|
||||
200,
|
||||
{
|
||||
"status": "ok",
|
||||
"data": lockout_msg,
|
||||
},
|
||||
)
|
@ -55,6 +55,49 @@ root,
|
||||
--font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
}
|
||||
|
||||
:root.anti-lockout {
|
||||
/*CHANGE THESE FOR THEMES*/
|
||||
--tooltip-bg: rgb(215, 82, 0);
|
||||
--select-bg: #b8772c;
|
||||
--ram-bg: #4d4d4e;
|
||||
--base-text: white;
|
||||
--outline: #c73929;
|
||||
--card-banner-bg: #de7c26;
|
||||
--deep-bg: #912f2f;
|
||||
--dropdown-bg: #c83b3b;
|
||||
/*END THEME VARIATION*/
|
||||
--blue: #00aeef;
|
||||
--indigo: #6610f2;
|
||||
--purple: #ab8ce4;
|
||||
--pink: #E91E63;
|
||||
--red: #ff0017;
|
||||
--orange: #fb9678;
|
||||
--yellow: #ffd500;
|
||||
--green: #3bd949;
|
||||
--teal: #58d8a3;
|
||||
--cyan: #57c7d4;
|
||||
--white: #ffffff;
|
||||
--white-smoke: #f3f5f6;
|
||||
--gray: #6c757d;
|
||||
--gray-light: #8ba2b5;
|
||||
--gray-lightest: #f7f7f9;
|
||||
--primary: #dbc900;
|
||||
--secondary: #dde4eb;
|
||||
--success: #adff84;
|
||||
--info: #dbc900;
|
||||
--warning: #ffaf00;
|
||||
--danger: #ff6258;
|
||||
--light: #fbfbfb;
|
||||
--dark: #252C46;
|
||||
--breakpoint-xs: 0;
|
||||
--breakpoint-sm: 576px;
|
||||
--breakpoint-md: 768px;
|
||||
--breakpoint-lg: 992px;
|
||||
--breakpoint-xl: 1200px;
|
||||
--font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
}
|
||||
|
||||
:root.light {
|
||||
/*CHANGE THESE FOR THEMES*/
|
||||
--tooltip-bg: white;
|
||||
@ -322,7 +365,7 @@ sup {
|
||||
}
|
||||
|
||||
a {
|
||||
color: #007bff;
|
||||
color: var(--primary);
|
||||
text-decoration: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ data['lang_page'] }}" class="{{data['user_data'].get('theme', 'default')}}">
|
||||
<html lang="{{ data['lang_page'] }}" class="{{data['user_data'].get('theme', 'default')}}" data-username="{{data['user_data'].get('username', None)}}">
|
||||
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
@ -256,8 +256,9 @@
|
||||
|
||||
const sendWssError = () => wsOpen || warn(
|
||||
'WebSockets are required for Crafty to work. This websocket connection has been closed. Are you using a reverse proxy?',
|
||||
'https://docs.craftycontrol.com/pages/getting-started/proxies/',
|
||||
'wssError'
|
||||
link='https://docs.craftycontrol.com/pages/getting-started/proxies/',
|
||||
link_msg="See our documentation for details",
|
||||
className='wssError'
|
||||
)
|
||||
|
||||
function startWebSocket() {
|
||||
@ -459,7 +460,7 @@
|
||||
}
|
||||
|
||||
|
||||
function warn(message, link = null, className = null) {
|
||||
function warn(message, link = null, link_msg=null, className = null, bg_color="#f7970f") {
|
||||
var closeEl = document.createElement('span');
|
||||
var strongEL = document.createElement('strong');
|
||||
var msgEl = document.createElement('div');
|
||||
@ -481,14 +482,14 @@
|
||||
var parentEl = document.createElement('div');
|
||||
|
||||
parentEl.style.padding = '20px';
|
||||
parentEl.style.backgroundColor = '#f7970f';
|
||||
parentEl.style.backgroundColor = bg_color;
|
||||
|
||||
parentEl.appendChild(closeEl);
|
||||
parentEl.appendChild(msgEl);
|
||||
if (link) {
|
||||
let linkEl = document.createElement('a')
|
||||
linkEl.href = link;
|
||||
linkEl.innerHTML = "See our documentation for details.";
|
||||
linkEl.innerHTML = link_msg;
|
||||
linkEl.style.color = 'white';
|
||||
linkEl.style.textDecoration = 'underline';
|
||||
linkEl.target = "_blank";
|
||||
@ -580,6 +581,15 @@
|
||||
|
||||
$(document).ready(function () {
|
||||
console.log('%c[Crafty Controller] %cReady for JS!', 'font-weight: 900; color: #800080;', 'font-weight: 900; color: #eee;');
|
||||
if ($(document.documentElement).data("username") === "anti-lockout-user"){
|
||||
warn(
|
||||
'⚠️You are in a recovery account. Access is limited!',
|
||||
link='/logout',
|
||||
link_msg="Click here to log out after you change your password. ⚠️",
|
||||
className='anti-lockout',
|
||||
bg_color='#6887dc'
|
||||
)
|
||||
}
|
||||
$('#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>",
|
||||
|
@ -281,7 +281,7 @@
|
||||
|
||||
<style>
|
||||
.clickable {
|
||||
color: #007bff;
|
||||
color: var(--primary);
|
||||
}
|
||||
.clickable:hover {
|
||||
cursor: pointer;
|
||||
|
@ -112,8 +112,8 @@
|
||||
<div class="form-check form-check-flat mt-0">
|
||||
|
||||
</div>
|
||||
<a href="#" class="text-small forgot-password ">{{ translate('login', 'forgotPassword',
|
||||
data['lang']) }}</a>
|
||||
<button onclick="resetPass()" id="#resetPass" form="" class="btn btn-outline-primary btn-sm forgot-password ">{{ translate('login', 'forgotPassword',
|
||||
data['lang']) }}</button>
|
||||
</div>
|
||||
|
||||
<div class="text-block text-center my-3">
|
||||
@ -146,6 +146,7 @@
|
||||
<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>
|
||||
<script src="../static/assets/vendors/js/bootbox.min.js"></script>
|
||||
<!-- endinject -->
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
@ -160,8 +161,24 @@
|
||||
});
|
||||
}
|
||||
});
|
||||
async function resetPass(){
|
||||
let res = await fetch(`/api/v2/crafty/resetPass/`, {
|
||||
method: 'GET',
|
||||
});
|
||||
let responseData = await res.json();
|
||||
console.log(responseData);
|
||||
bootbox.alert(responseData.data)
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
<style>
|
||||
.modal-content {
|
||||
background-color: rgb(34, 36, 55) !important;
|
||||
color: lightgray;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -107,7 +107,8 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span data-html="true" class="version-hint text-center"
|
||||
data-content="⚠️ {{ translate('serverWizard', 'unsupported', data['lang']) }} ⚠️" , data-placement="right"></span>
|
||||
<div class="col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="server_name">{{ translate('serverWizard', 'serverName', data['lang']) }}</label>
|
||||
@ -1233,6 +1234,20 @@
|
||||
}
|
||||
})
|
||||
}
|
||||
$("#server").change(function (){
|
||||
let selected_version = $("#server :selected").text().split(".");
|
||||
if(parseInt(selected_version[0]) === 1 && parseInt(selected_version[1]) < 8 ){
|
||||
$('[data-toggle="popover"]').popover();
|
||||
if ($(window).width() < 1000) {
|
||||
$('.version-hint').attr("data-placement", "top")
|
||||
} else {
|
||||
$('.version-hint').attr("data-placement", "right")
|
||||
}
|
||||
$('.version-hint').popover("show");
|
||||
}else{
|
||||
$('.version-hint').popover("hide");
|
||||
}
|
||||
});
|
||||
|
||||
function serverJarChange(selectObj) {
|
||||
const type_select = document.getElementById('server_jar')
|
||||
|
@ -579,6 +579,7 @@
|
||||
"serverUpload": "Als Zip-Datei Gepackten Server hochladen",
|
||||
"serverVersion": "Server Version",
|
||||
"sizeInGB": "Größe in GB",
|
||||
"unsupported": "Minecraft-Versionen vor 1.8 sind nicht vollständig auf Kompatibilität getestet. Bei einer Installation verhalten diese sich möglicherweise nicht wie erwartet.",
|
||||
"uploadButton": "Hochladen",
|
||||
"uploadZip": "Zip-Datei für Serverimport hochladen",
|
||||
"zipPath": "Server Pfad"
|
||||
|
@ -578,6 +578,7 @@
|
||||
"serverUpload": "Upload Zipped Server",
|
||||
"serverVersion": "Server Version",
|
||||
"sizeInGB": "Size in GB",
|
||||
"unsupported": "Minecraft versions lower than 1.8 are not supported by Crafty. You may still install it. Results will vary.",
|
||||
"uploadButton": "Upload",
|
||||
"uploadZip": "Upload Zip File For Server Import",
|
||||
"zipPath": "Server Path"
|
||||
|
@ -579,6 +579,7 @@
|
||||
"serverUpload": "Charger le fichier Zippé",
|
||||
"serverVersion": "Version du Serveur",
|
||||
"sizeInGB": "Taille en GB",
|
||||
"unsupported": "Les versions Minecraft inférieures à 1.8 ne sont pas supportées par Crafty. Elles peuvent être installées, mais leur fonctionnement peut varier.",
|
||||
"uploadButton": "Chargement",
|
||||
"uploadZip": "Charger le fichier pour l'importation du Serveur",
|
||||
"zipPath": "Chemin du Serveur"
|
||||
|
@ -579,6 +579,7 @@
|
||||
"serverUpload": "העלה שרת מכווץ",
|
||||
"serverVersion": "גרסת השרת",
|
||||
"sizeInGB": "גודל ב-GB",
|
||||
"unsupported": "גרסאות מיינקראפט מתחת ל1.8 לא נתמכות על ידי קראפטי. אפשר להתקין אותם אבל הביצועים לא יהיו עקביים.",
|
||||
"uploadButton": "העלה",
|
||||
"uploadZip": "העלה קובץ Zip לייבוא שרת",
|
||||
"zipPath": "נתיב שרת"
|
||||
|
@ -579,6 +579,7 @@
|
||||
"serverUpload": "UPLOADZ ZIPPED SERVR",
|
||||
"serverVersion": "SERVR VERZHUN",
|
||||
"sizeInGB": "SIEZ IN GIGABITEZ",
|
||||
"unsupported": "MINECRAFTZ OLDR THAN 1.8 NOT FRENDS WIF CWAFTY. U CAN STILL TRY INSTALLIN'. IT MIGHT WORKS, MIGHT NOT.",
|
||||
"uploadButton": "UPLOADZ",
|
||||
"uploadZip": "UPLOADZ ZIP FISH FOR SERVR BRING IN",
|
||||
"zipPath": "WER IZ ZIP FISH (PETH)"
|
||||
|
@ -580,6 +580,7 @@
|
||||
"serverUpload": "Augšupielādē Saspiestu (Zipotu) Serveri",
|
||||
"serverVersion": "Servera Versija",
|
||||
"sizeInGB": "lielums, GB",
|
||||
"unsupported": "Minecraft versijas zem 1.8 netiek atbalstītas iekš Crafty. Jūs tāpat variet tās instalēt, bet rezultāti atškirsies.",
|
||||
"uploadButton": "Augšupielādēt",
|
||||
"uploadZip": "Augšupielādē Zip Failu Priekš Serveru Importa",
|
||||
"zipPath": "Servera Ceļš"
|
||||
|
@ -579,6 +579,7 @@
|
||||
"serverUpload": "Gezipt bestand uploaden",
|
||||
"serverVersion": "Serverversie",
|
||||
"sizeInGB": "Grootte in GB",
|
||||
"unsupported": "Minecraft-versies lager dan 1.8 worden niet ondersteund door Crafty. Je kunt het nog steeds installeren. De resultaten kunnen variëren.",
|
||||
"uploadButton": "Uploaden",
|
||||
"uploadZip": "Upload zip-bestand voor serverimport",
|
||||
"zipPath": "Serverpad"
|
||||
|
@ -578,6 +578,7 @@
|
||||
"serverUpload": "Wgraj ZIP Serwera",
|
||||
"serverVersion": "Wersja serwera",
|
||||
"sizeInGB": "Wielkość w GB",
|
||||
"unsupported": "Wersje Minecrafta poniżej 1.8 nie są wspierane przez Crafty. Mimo to możesz je zainstalować - jednakże nie jesteśmy w stanie zagwarantować ich działanie.",
|
||||
"uploadButton": "Wgraj",
|
||||
"uploadZip": "Wgraj plik Zip dla imprtowania serwera",
|
||||
"zipPath": "Server Path"
|
||||
|
@ -578,6 +578,7 @@
|
||||
"serverUpload": "อัปโหลดเซิร์ฟเวอร์ซิป",
|
||||
"serverVersion": "เวอร์ชันเซิร์ฟเวอร์",
|
||||
"sizeInGB": "ขนาดเป็นกิกะไบต์",
|
||||
"unsupported": "Crafty ไม่รองรับ Minecraft เวอร์ชั่นต่ำกว่า 1.8 คุณยังสามารถติดตั้งได้ ผลลัพธ์จะแตกต่างกันออกไป",
|
||||
"uploadButton": "อัปโหลด",
|
||||
"uploadZip": "อัปโหลดไฟล์ซิปสำหรับการนำเข้าเซิร์ฟเวอร์",
|
||||
"zipPath": "เส้นทางเซิร์ฟเวอร์"
|
||||
|
@ -578,6 +578,7 @@
|
||||
"serverUpload": "Sıkıştırılmış Sunucu Yükle",
|
||||
"serverVersion": "Sunucu Sürümü",
|
||||
"sizeInGB": "GB cinsinden boyut",
|
||||
"unsupported": "Minecraft'ın 1.8'den eski sürümleri Crafty tarafından desteklenmemektedir. Yine de yükleyebilirsiniz. Sonuçlar değişkenlik gösterecektir.",
|
||||
"uploadButton": "Dosya Yükle",
|
||||
"uploadZip": "Sunucu İçe Aktarımı İçin Zip Dosyası Yükle",
|
||||
"zipPath": "Sunucu Konumu"
|
||||
|
@ -578,6 +578,7 @@
|
||||
"serverUpload": "Вивантажити архівований сервер",
|
||||
"serverVersion": "Версія сервера",
|
||||
"sizeInGB": "Об'єм пам'яті в ГБ",
|
||||
"unsupported": "Minecraft версії старіші ніж 1.8, не підтримуються Crafty. Ви все ще можете встановити їх, але результат буде непередбачуваний.",
|
||||
"uploadButton": "Вивантажити",
|
||||
"uploadZip": "Вивантажити архів(.zip) для імпорту сервера",
|
||||
"zipPath": "Шлях архіву сервера"
|
||||
|
@ -579,6 +579,7 @@
|
||||
"serverUpload": "上传打包为 Zip 文件的服务器",
|
||||
"serverVersion": "服务器版本",
|
||||
"sizeInGB": "大小(以 GB 为单位)",
|
||||
"unsupported": "Crafty 不支持低于 1.8 的 Minecraft 版本。你仍可以安装,但结果无法保证。",
|
||||
"uploadButton": "上传",
|
||||
"uploadZip": "上传 Zip 文件以导入服务器",
|
||||
"zipPath": "服务器路径"
|
||||
|
2
main.py
2
main.py
@ -390,6 +390,8 @@ if __name__ == "__main__":
|
||||
# Master config.json in helpers.py
|
||||
Console.info("Checking for remote changes to config.json")
|
||||
controller.get_config_diff()
|
||||
# Delete anti-lockout-user
|
||||
controller.users.stop_anti_lockout()
|
||||
Console.info("Remote change complete.")
|
||||
|
||||
# startup the web server
|
||||
|
Loading…
Reference in New Issue
Block a user