mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
Merge branch 'dev' into tweak/support-logs-zip-comment
This commit is contained in:
commit
51d123e9eb
11
CHANGELOG.md
11
CHANGELOG.md
@ -1,11 +1,16 @@
|
||||
# Changelog
|
||||
## --- [4.0.11] - 2022/TBD
|
||||
### New features
|
||||
TBD
|
||||
- Add server import status indicators ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/433))
|
||||
- Users can now be assigned as manager of other users/roles ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/434))
|
||||
- Add variable shutdown timeouts ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/435))
|
||||
- Add server metrics graph ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/436))
|
||||
### Bug fixes
|
||||
TBD
|
||||
- Fix creation quota not refilling after server delete ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/434))
|
||||
- Add missing bedrock dependency (libcurl.so.4) ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/437))
|
||||
### Tweaks
|
||||
TBD
|
||||
- Make imports threaded ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/433))
|
||||
- Add 'Created By' Field to servers ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/434))
|
||||
### Lang
|
||||
TBD
|
||||
<br><br>
|
||||
|
@ -15,6 +15,7 @@ RUN apt-get update \
|
||||
&& apt-get -y --no-install-recommends install \
|
||||
sudo \
|
||||
gcc \
|
||||
libcurl4 \
|
||||
python3 \
|
||||
python3-dev \
|
||||
python3-pip \
|
||||
|
@ -60,26 +60,6 @@ class CraftyPermsController:
|
||||
permissions_list = PermissionsCrafty.get_permissions(permissions_mask)
|
||||
return permissions_list
|
||||
|
||||
@staticmethod
|
||||
def add_server_creation(user_id):
|
||||
"""Increase the "Server Creation" counter for this user
|
||||
|
||||
Args:
|
||||
user_id (int): The modifiable user's ID
|
||||
|
||||
Returns:
|
||||
int: The new count of servers created by this user
|
||||
"""
|
||||
return PermissionsCrafty.add_server_creation(user_id)
|
||||
|
||||
@staticmethod
|
||||
def add_user_creation(user_id):
|
||||
return PermissionsCrafty.add_user_creation(user_id)
|
||||
|
||||
@staticmethod
|
||||
def add_role_creation(user_id):
|
||||
return PermissionsCrafty.add_role_creation(user_id)
|
||||
|
||||
@staticmethod
|
||||
def get_api_key_permissions_list(key: ApiKeys):
|
||||
return PermissionsCrafty.get_api_key_permissions_list(key)
|
||||
|
@ -64,8 +64,8 @@ class RolesController:
|
||||
HelperRoles.update_role(role_id, up_data)
|
||||
|
||||
@staticmethod
|
||||
def add_role(role_name):
|
||||
return HelperRoles.add_role(role_name)
|
||||
def add_role(role_name, manager):
|
||||
return HelperRoles.add_role(role_name, manager)
|
||||
|
||||
class RoleServerJsonType(t.TypedDict):
|
||||
server_id: t.Union[str, int]
|
||||
@ -92,6 +92,7 @@ class RolesController:
|
||||
def add_role_advanced(
|
||||
name: str,
|
||||
servers: t.Iterable[RoleServerJsonType],
|
||||
manager: int,
|
||||
) -> int:
|
||||
"""Add a role with a name and a list of servers
|
||||
|
||||
@ -102,7 +103,7 @@ class RolesController:
|
||||
Returns:
|
||||
int: The new role's ID
|
||||
"""
|
||||
role_id: t.Final[int] = HelperRoles.add_role(name)
|
||||
role_id: t.Final[int] = HelperRoles.add_role(name, manager)
|
||||
for server in servers:
|
||||
PermissionsServers.get_or_create(
|
||||
role_id, server["server_id"], server["permissions"]
|
||||
@ -114,6 +115,7 @@ class RolesController:
|
||||
role_id: t.Union[str, int],
|
||||
role_name: t.Optional[str],
|
||||
servers: t.Optional[t.Iterable[RoleServerJsonType]],
|
||||
manager: int,
|
||||
) -> None:
|
||||
"""Update a role with a name and a list of servers
|
||||
|
||||
@ -152,6 +154,7 @@ class RolesController:
|
||||
up_data = {
|
||||
"role_name": role_name,
|
||||
"last_update": Helpers.get_time_as_string(),
|
||||
"manager": manager,
|
||||
}
|
||||
# TODO: do the last_update on the db side
|
||||
HelperRoles.update_role(role_id, up_data)
|
||||
|
@ -4,6 +4,7 @@ import time
|
||||
import json
|
||||
import pathlib
|
||||
import typing as t
|
||||
import datetime
|
||||
|
||||
from app.classes.controllers.roles_controller import RolesController
|
||||
from app.classes.shared.file_helpers import FileHelpers
|
||||
@ -51,6 +52,7 @@ class ServersController(metaclass=Singleton):
|
||||
server_log_file: str,
|
||||
server_stop: str,
|
||||
server_type: str,
|
||||
created_by: int,
|
||||
server_port: int = 25565,
|
||||
server_host: str = "127.0.0.1",
|
||||
) -> int:
|
||||
@ -85,6 +87,7 @@ class ServersController(metaclass=Singleton):
|
||||
server_log_file,
|
||||
server_stop,
|
||||
server_type,
|
||||
created_by,
|
||||
server_port,
|
||||
server_host,
|
||||
)
|
||||
@ -102,25 +105,32 @@ class ServersController(metaclass=Singleton):
|
||||
server_instance.update_server_instance()
|
||||
return ret
|
||||
|
||||
def get_history_stats(self, server_id):
|
||||
max_age = self.helper.get_setting("history_max_age")
|
||||
now = datetime.datetime.now()
|
||||
minimum_to_exist = now - datetime.timedelta(days=max_age)
|
||||
srv = ServersController().get_server_instance_by_id(server_id)
|
||||
return srv.stats_helper.get_history_stats(server_id, minimum_to_exist)
|
||||
|
||||
@staticmethod
|
||||
def update_unloaded_server(server_obj):
|
||||
ret = HelperServers.update_server(server_obj)
|
||||
return ret
|
||||
|
||||
@staticmethod
|
||||
def set_download(server_id):
|
||||
def set_import(server_id):
|
||||
srv = ServersController().get_server_instance_by_id(server_id)
|
||||
return srv.stats_helper.set_download()
|
||||
return srv.stats_helper.set_import()
|
||||
|
||||
@staticmethod
|
||||
def finish_download(server_id):
|
||||
def finish_import(server_id):
|
||||
srv = ServersController().get_server_instance_by_id(server_id)
|
||||
return srv.stats_helper.finish_download()
|
||||
return srv.stats_helper.finish_import()
|
||||
|
||||
@staticmethod
|
||||
def get_download_status(server_id):
|
||||
def get_import_status(server_id):
|
||||
server = ServersController().get_server_instance_by_id(server_id)
|
||||
return server.stats_helper.get_download_status()
|
||||
return server.stats_helper.get_import_status()
|
||||
|
||||
def remove_server(self, server_id):
|
||||
roles_list = PermissionsServers.get_roles_from_server(server_id)
|
||||
|
@ -1,7 +1,9 @@
|
||||
import logging
|
||||
import typing as t
|
||||
from app.classes.models.servers import HelperServers
|
||||
|
||||
from app.classes.models.users import HelperUsers
|
||||
from app.classes.models.roles import HelperRoles
|
||||
from app.classes.models.crafty_permissions import (
|
||||
PermissionsCrafty,
|
||||
EnumPermissionsCrafty,
|
||||
@ -132,6 +134,18 @@ class UsersController:
|
||||
def set_support_path(user_id, support_path):
|
||||
HelperUsers.set_support_path(user_id, support_path)
|
||||
|
||||
@staticmethod
|
||||
def get_managed_users(exec_user_id):
|
||||
return HelperUsers.get_managed_users(exec_user_id)
|
||||
|
||||
@staticmethod
|
||||
def get_managed_roles(exec_user_id):
|
||||
return HelperUsers.get_managed_roles(exec_user_id)
|
||||
|
||||
@staticmethod
|
||||
def get_created_servers(exec_user_id):
|
||||
return HelperServers.get_total_owned_servers(exec_user_id)
|
||||
|
||||
def update_user(self, user_id: str, user_data=None, user_crafty_data=None):
|
||||
if user_crafty_data is None:
|
||||
user_crafty_data = {}
|
||||
@ -206,6 +220,7 @@ class UsersController:
|
||||
def add_user(
|
||||
self,
|
||||
username,
|
||||
manager,
|
||||
password,
|
||||
email="default@example.com",
|
||||
enabled: bool = True,
|
||||
@ -213,6 +228,7 @@ class UsersController:
|
||||
):
|
||||
return self.users_helper.add_user(
|
||||
username,
|
||||
manager,
|
||||
password=password,
|
||||
email=email,
|
||||
enabled=enabled,
|
||||
@ -236,6 +252,10 @@ class UsersController:
|
||||
)
|
||||
|
||||
def remove_user(self, user_id):
|
||||
for user in self.get_managed_users(user_id):
|
||||
self.update_user(user.user_id, {"manager": None})
|
||||
for role in HelperUsers.get_managed_roles(user_id):
|
||||
HelperRoles.update_role(role.role_id, {"manager": None})
|
||||
return self.users_helper.remove_user(user_id)
|
||||
|
||||
@staticmethod
|
||||
|
@ -175,7 +175,7 @@ class ServerJars:
|
||||
# we submit a db update for it's stats.
|
||||
while True:
|
||||
try:
|
||||
ServersController.set_download(server_id)
|
||||
ServersController.set_import(server_id)
|
||||
for user in server_users:
|
||||
self.helper.websocket_helper.broadcast_user(
|
||||
user, "send_start_reload", {}
|
||||
@ -190,7 +190,7 @@ class ServerJars:
|
||||
try:
|
||||
with open(path, "wb") as output:
|
||||
shutil.copyfileobj(r.raw, output)
|
||||
ServersController.finish_download(server_id)
|
||||
ServersController.finish_import(server_id)
|
||||
|
||||
for user in server_users:
|
||||
self.helper.websocket_helper.broadcast_user(
|
||||
@ -203,7 +203,7 @@ class ServerJars:
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Unable to save jar to {path} due to error:{e}")
|
||||
ServersController.finish_download(server_id)
|
||||
ServersController.finish_import(server_id)
|
||||
server_users = PermissionsServers.get_server_user_list(server_id)
|
||||
for user in server_users:
|
||||
self.helper.websocket_helper.broadcast_user(
|
||||
|
@ -9,6 +9,7 @@ from peewee import (
|
||||
)
|
||||
|
||||
from app.classes.models.base_model import BaseModel
|
||||
from app.classes.models.servers import HelperServers
|
||||
from app.classes.models.users import Users, ApiKeys, HelperUsers
|
||||
from app.classes.shared.permission_helper import PermissionHelper
|
||||
|
||||
@ -23,9 +24,6 @@ class UserCrafty(BaseModel):
|
||||
limit_server_creation = IntegerField(default=-1)
|
||||
limit_user_creation = IntegerField(default=0)
|
||||
limit_role_creation = IntegerField(default=0)
|
||||
created_server = IntegerField(default=0)
|
||||
created_user = IntegerField(default=0)
|
||||
created_role = IntegerField(default=0)
|
||||
|
||||
class Meta:
|
||||
table_name = "user_crafty"
|
||||
@ -107,9 +105,6 @@ class PermissionsCrafty:
|
||||
UserCrafty.limit_server_creation: 0,
|
||||
UserCrafty.limit_user_creation: 0,
|
||||
UserCrafty.limit_role_creation: 0,
|
||||
UserCrafty.created_server: 0,
|
||||
UserCrafty.created_user: 0,
|
||||
UserCrafty.created_role: 0,
|
||||
}
|
||||
).execute()
|
||||
user_crafty = PermissionsCrafty.get_user_crafty(user_id)
|
||||
@ -159,11 +154,16 @@ class PermissionsCrafty:
|
||||
|
||||
@staticmethod
|
||||
def get_created_quantity_list(user_id):
|
||||
user_crafty = PermissionsCrafty.get_user_crafty(user_id)
|
||||
quantity_list = {
|
||||
EnumPermissionsCrafty.SERVER_CREATION.name: user_crafty.created_server,
|
||||
EnumPermissionsCrafty.USER_CONFIG.name: user_crafty.created_user,
|
||||
EnumPermissionsCrafty.ROLES_CONFIG.name: user_crafty.created_role,
|
||||
EnumPermissionsCrafty.SERVER_CREATION.name: HelperServers.get_total_owned_servers( # pylint: disable=line-too-long
|
||||
user_id
|
||||
),
|
||||
EnumPermissionsCrafty.USER_CONFIG.name: HelperUsers.get_managed_users(
|
||||
user_id
|
||||
).count(),
|
||||
EnumPermissionsCrafty.ROLES_CONFIG.name: HelperUsers.get_managed_roles(
|
||||
user_id
|
||||
).count(),
|
||||
}
|
||||
return quantity_list
|
||||
|
||||
@ -183,31 +183,6 @@ class PermissionsCrafty:
|
||||
or limit_list[permission.name] == -1
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def add_server_creation(user_id: int):
|
||||
"""Increase the "Server Creation" counter for this user
|
||||
|
||||
Args:
|
||||
user_id (int): The modifiable user's ID
|
||||
"""
|
||||
UserCrafty.update(created_server=UserCrafty.created_server + 1).where(
|
||||
UserCrafty.user_id == user_id
|
||||
).execute()
|
||||
|
||||
@staticmethod
|
||||
def add_user_creation(user_id):
|
||||
user_crafty = PermissionsCrafty.get_user_crafty(user_id)
|
||||
user_crafty.created_user += 1
|
||||
UserCrafty.save(user_crafty)
|
||||
return user_crafty.created_user
|
||||
|
||||
@staticmethod
|
||||
def add_role_creation(user_id):
|
||||
user_crafty = PermissionsCrafty.get_user_crafty(user_id)
|
||||
user_crafty.created_role += 1
|
||||
UserCrafty.save(user_crafty)
|
||||
return user_crafty.created_role
|
||||
|
||||
@staticmethod
|
||||
def get_api_key_permissions_list(key: ApiKeys):
|
||||
user = HelperUsers.get_user(key.user_id)
|
||||
|
@ -6,6 +6,7 @@ from peewee import (
|
||||
DoesNotExist,
|
||||
AutoField,
|
||||
DateTimeField,
|
||||
IntegerField,
|
||||
)
|
||||
from playhouse.shortcuts import model_to_dict
|
||||
|
||||
@ -22,6 +23,7 @@ class Roles(BaseModel):
|
||||
created = DateTimeField(default=datetime.datetime.now)
|
||||
last_update = DateTimeField(default=datetime.datetime.now)
|
||||
role_name = CharField(default="", unique=True, index=True)
|
||||
manager = IntegerField(null=True)
|
||||
|
||||
class Meta:
|
||||
table_name = "roles"
|
||||
@ -71,11 +73,12 @@ class HelperRoles:
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def add_role(role_name):
|
||||
def add_role(role_name, manager):
|
||||
role_id = Roles.insert(
|
||||
{
|
||||
Roles.role_name: role_name.lower(),
|
||||
Roles.created: Helpers.get_time_as_string(),
|
||||
Roles.manager: manager,
|
||||
}
|
||||
).execute()
|
||||
return role_id
|
||||
|
@ -53,7 +53,7 @@ class ServerStats(Model):
|
||||
waiting_start = BooleanField(default=False)
|
||||
first_run = BooleanField(default=True)
|
||||
crashed = BooleanField(default=False)
|
||||
downloading = BooleanField(default=False)
|
||||
importing = BooleanField(default=False)
|
||||
|
||||
class Meta:
|
||||
table_name = "server_stats"
|
||||
@ -137,6 +137,14 @@ class HelperServerStats:
|
||||
)
|
||||
return server_data
|
||||
|
||||
def get_history_stats(self, server_id, max_age):
|
||||
return (
|
||||
ServerStats.select()
|
||||
.where(ServerStats.created > max_age)
|
||||
.where(ServerStats.server_id == server_id)
|
||||
.execute(self.database)
|
||||
)
|
||||
|
||||
def insert_server_stats(self, server_stats):
|
||||
server_id = server_stats.get("id", 0)
|
||||
|
||||
@ -207,26 +215,26 @@ class HelperServerStats:
|
||||
ServerStats.server_id == self.server_id
|
||||
).execute(self.database)
|
||||
|
||||
def set_download(self):
|
||||
def set_import(self):
|
||||
# self.select_database(self.server_id)
|
||||
ServerStats.update(downloading=True).where(
|
||||
ServerStats.update(importing=True).where(
|
||||
ServerStats.server_id == self.server_id
|
||||
).execute(self.database)
|
||||
|
||||
def finish_download(self):
|
||||
def finish_import(self):
|
||||
# self.select_database(self.server_id)
|
||||
ServerStats.update(downloading=False).where(
|
||||
ServerStats.update(importing=False).where(
|
||||
ServerStats.server_id == self.server_id
|
||||
).execute(self.database)
|
||||
|
||||
def get_download_status(self):
|
||||
def get_import_status(self):
|
||||
# self.select_database(self.server_id)
|
||||
download_status = (
|
||||
import_status = (
|
||||
ServerStats.select()
|
||||
.where(ServerStats.server_id == self.server_id)
|
||||
.get(self.database)
|
||||
)
|
||||
return download_status.downloading
|
||||
return import_status.importing
|
||||
|
||||
def server_crash_reset(self):
|
||||
if self.server_id is None:
|
||||
@ -249,7 +257,6 @@ class HelperServerStats:
|
||||
def set_update(self, value):
|
||||
if self.server_id is None:
|
||||
return
|
||||
|
||||
# self.select_database(self.server_id)
|
||||
try:
|
||||
# Checks if server even exists
|
||||
|
@ -38,6 +38,8 @@ class Servers(BaseModel):
|
||||
logs_delete_after = IntegerField(default=0)
|
||||
type = CharField(default="minecraft-java")
|
||||
show_status = BooleanField(default=1)
|
||||
created_by = IntegerField(default=-100)
|
||||
shutdown_timeout = IntegerField(default=60)
|
||||
|
||||
class Meta:
|
||||
table_name = "servers"
|
||||
@ -64,6 +66,7 @@ class HelperServers:
|
||||
server_log_file: str,
|
||||
server_stop: str,
|
||||
server_type: str,
|
||||
created_by: int,
|
||||
server_port: int = 25565,
|
||||
server_host: str = "127.0.0.1",
|
||||
) -> int:
|
||||
@ -105,6 +108,7 @@ class HelperServers:
|
||||
Servers.stop_command: server_stop,
|
||||
Servers.backup_path: backup_path,
|
||||
Servers.type: server_type,
|
||||
Servers.created_by: created_by,
|
||||
}
|
||||
).execute()
|
||||
|
||||
@ -112,6 +116,10 @@ class HelperServers:
|
||||
def get_server_obj(server_id):
|
||||
return Servers.get_by_id(server_id)
|
||||
|
||||
@staticmethod
|
||||
def get_total_owned_servers(user_id):
|
||||
return Servers.select().where(Servers.created_by == user_id).count()
|
||||
|
||||
@staticmethod
|
||||
def get_server_type_by_id(server_id):
|
||||
server_type = Servers.select().where(Servers.server_id == server_id).get()
|
||||
|
@ -6,6 +6,7 @@ from peewee import (
|
||||
ForeignKeyField,
|
||||
CharField,
|
||||
AutoField,
|
||||
IntegerField,
|
||||
DateTimeField,
|
||||
BooleanField,
|
||||
CompositeKey,
|
||||
@ -40,6 +41,7 @@ class Users(BaseModel):
|
||||
server_order = CharField(default="")
|
||||
preparing = BooleanField(default=False)
|
||||
hints = BooleanField(default=True)
|
||||
manager = IntegerField(default=None, null=True)
|
||||
|
||||
class Meta:
|
||||
table_name = "users"
|
||||
@ -138,6 +140,16 @@ class HelperUsers:
|
||||
user_query = Users.select().where(Users.user_id == user_id)
|
||||
return user_query
|
||||
|
||||
@staticmethod
|
||||
def get_managed_users(exec_user_id):
|
||||
user_query = Users.select().where(Users.manager == exec_user_id)
|
||||
return user_query
|
||||
|
||||
@staticmethod
|
||||
def get_managed_roles(exec_user_id):
|
||||
roles_query = Roles.select().where(Roles.manager == exec_user_id)
|
||||
return roles_query
|
||||
|
||||
@staticmethod
|
||||
def get_user(user_id):
|
||||
if user_id == 0:
|
||||
@ -192,6 +204,7 @@ class HelperUsers:
|
||||
def add_user(
|
||||
self,
|
||||
username: str,
|
||||
manager: str,
|
||||
password: str = None,
|
||||
email: t.Optional[str] = None,
|
||||
enabled: bool = True,
|
||||
@ -209,6 +222,7 @@ class HelperUsers:
|
||||
Users.enabled: enabled,
|
||||
Users.superuser: superuser,
|
||||
Users.created: Helpers.get_time_as_string(),
|
||||
Users.manager: manager,
|
||||
}
|
||||
).execute()
|
||||
return user_id
|
||||
@ -229,6 +243,7 @@ class HelperUsers:
|
||||
Users.enabled: enabled,
|
||||
Users.superuser: superuser,
|
||||
Users.created: Helpers.get_time_as_string(),
|
||||
Users.manager: None,
|
||||
}
|
||||
).execute()
|
||||
return user_id
|
||||
|
@ -27,10 +27,15 @@ class FileHelpers:
|
||||
FileHelpers.del_dirs(sub)
|
||||
else:
|
||||
# Delete file if it is a file:
|
||||
sub.unlink()
|
||||
|
||||
# This removes the top-level folder:
|
||||
path.rmdir()
|
||||
try:
|
||||
sub.unlink()
|
||||
except:
|
||||
logger.error(f"Unable to delete file {sub}")
|
||||
try:
|
||||
# This removes the top-level folder:
|
||||
path.rmdir()
|
||||
except:
|
||||
logger.error("Unable to remove top level")
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
|
216
app/classes/shared/import_helper.py
Normal file
216
app/classes/shared/import_helper.py
Normal file
@ -0,0 +1,216 @@
|
||||
import os
|
||||
import time
|
||||
import shutil
|
||||
import logging
|
||||
import threading
|
||||
|
||||
from app.classes.controllers.server_perms_controller import PermissionsServers
|
||||
from app.classes.controllers.servers_controller import ServersController
|
||||
from app.classes.shared.helpers import Helpers
|
||||
from app.classes.shared.file_helpers import FileHelpers
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ImportHelpers:
|
||||
allowed_quotes = ['"', "'", "`"]
|
||||
|
||||
def __init__(self, helper, file_helper):
|
||||
self.file_helper: FileHelpers = file_helper
|
||||
self.helper: Helpers = helper
|
||||
|
||||
def import_jar_server(self, server_path, new_server_dir, port, new_id):
|
||||
import_thread = threading.Thread(
|
||||
target=self.import_threaded_jar_server,
|
||||
daemon=True,
|
||||
args=(server_path, new_server_dir, port, new_id),
|
||||
name=f"{new_id}_import",
|
||||
)
|
||||
import_thread.start()
|
||||
|
||||
def import_threaded_jar_server(self, server_path, new_server_dir, port, new_id):
|
||||
for item in os.listdir(server_path):
|
||||
if not item == "db_stats":
|
||||
try:
|
||||
if os.path.isdir(os.path.join(server_path, item)):
|
||||
FileHelpers.copy_dir(
|
||||
os.path.join(server_path, item),
|
||||
os.path.join(new_server_dir, item),
|
||||
)
|
||||
else:
|
||||
FileHelpers.copy_file(
|
||||
os.path.join(server_path, item),
|
||||
os.path.join(new_server_dir, item),
|
||||
)
|
||||
except shutil.Error as ex:
|
||||
logger.error(f"Server import failed with error: {ex}")
|
||||
|
||||
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(
|
||||
f"No server.properties found on zip file import. "
|
||||
f"Creating one with port selection of {str(port)}"
|
||||
)
|
||||
with open(
|
||||
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
||||
) as file:
|
||||
file.write(f"server-port={port}")
|
||||
file.close()
|
||||
time.sleep(5)
|
||||
ServersController.finish_import(new_id)
|
||||
server_users = PermissionsServers.get_server_user_list(new_id)
|
||||
for user in server_users:
|
||||
self.helper.websocket_helper.broadcast_user(user, "send_start_reload", {})
|
||||
|
||||
def import_java_zip_server(self, temp_dir, new_server_dir, port, new_id):
|
||||
import_thread = threading.Thread(
|
||||
target=self.import_threaded_java_zip_server,
|
||||
daemon=True,
|
||||
args=(temp_dir, new_server_dir, port, new_id),
|
||||
name=f"{new_id}_java_zip_import",
|
||||
)
|
||||
import_thread.start()
|
||||
|
||||
def import_threaded_java_zip_server(self, temp_dir, new_server_dir, port, new_id):
|
||||
has_properties = False
|
||||
# extracts archive to temp directory
|
||||
for item in os.listdir(temp_dir):
|
||||
if str(item) == "server.properties":
|
||||
has_properties = True
|
||||
try:
|
||||
if not os.path.isdir(os.path.join(temp_dir, item)):
|
||||
FileHelpers.move_file(
|
||||
os.path.join(temp_dir, item), os.path.join(new_server_dir, item)
|
||||
)
|
||||
else:
|
||||
if item != "db_stats":
|
||||
FileHelpers.move_dir(
|
||||
os.path.join(temp_dir, item),
|
||||
os.path.join(new_server_dir, item),
|
||||
)
|
||||
except Exception as ex:
|
||||
logger.error(f"ERROR IN ZIP IMPORT: {ex}")
|
||||
if not has_properties:
|
||||
logger.info(
|
||||
f"No server.properties found on zip file import. "
|
||||
f"Creating one with port selection of {str(port)}"
|
||||
)
|
||||
with open(
|
||||
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
||||
) as file:
|
||||
file.write(f"server-port={port}")
|
||||
file.close()
|
||||
|
||||
server_users = PermissionsServers.get_server_user_list(new_id)
|
||||
ServersController.finish_import(new_id)
|
||||
for user in server_users:
|
||||
self.helper.websocket_helper.broadcast_user(user, "send_start_reload", {})
|
||||
# deletes temp dir
|
||||
FileHelpers.del_dirs(temp_dir)
|
||||
|
||||
def import_bedrock_server(
|
||||
self, server_path, new_server_dir, port, full_jar_path, new_id
|
||||
):
|
||||
import_thread = threading.Thread(
|
||||
target=self.import_threaded_bedrock_server,
|
||||
daemon=True,
|
||||
args=(server_path, new_server_dir, port, full_jar_path, new_id),
|
||||
name=f"{new_id}_bedrock_import",
|
||||
)
|
||||
import_thread.start()
|
||||
|
||||
def import_threaded_bedrock_server(
|
||||
self, server_path, new_server_dir, port, full_jar_path, new_id
|
||||
):
|
||||
for item in os.listdir(server_path):
|
||||
if not item == "db_stats":
|
||||
try:
|
||||
if os.path.isdir(os.path.join(server_path, item)):
|
||||
FileHelpers.copy_dir(
|
||||
os.path.join(server_path, item),
|
||||
os.path.join(new_server_dir, item),
|
||||
)
|
||||
else:
|
||||
FileHelpers.copy_file(
|
||||
os.path.join(server_path, item),
|
||||
os.path.join(new_server_dir, item),
|
||||
)
|
||||
except shutil.Error as ex:
|
||||
logger.error(f"Server import failed with error: {ex}")
|
||||
|
||||
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(
|
||||
f"No server.properties found on zip file import. "
|
||||
f"Creating one with port selection of {str(port)}"
|
||||
)
|
||||
with open(
|
||||
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
||||
) as file:
|
||||
file.write(f"server-port={port}")
|
||||
file.close()
|
||||
if os.name != "nt":
|
||||
if Helpers.check_file_exists(full_jar_path):
|
||||
os.chmod(full_jar_path, 0o2760)
|
||||
ServersController.finish_import(new_id)
|
||||
server_users = PermissionsServers.get_server_user_list(new_id)
|
||||
for user in server_users:
|
||||
self.helper.websocket_helper.broadcast_user(user, "send_start_reload", {})
|
||||
|
||||
def import_bedrock_zip_server(
|
||||
self, temp_dir, new_server_dir, full_jar_path, port, new_id
|
||||
):
|
||||
import_thread = threading.Thread(
|
||||
target=self.import_threaded_bedrock_zip_server,
|
||||
daemon=True,
|
||||
args=(temp_dir, new_server_dir, full_jar_path, port, new_id),
|
||||
name=f"{new_id}_bedrock_import",
|
||||
)
|
||||
import_thread.start()
|
||||
|
||||
def import_threaded_bedrock_zip_server(
|
||||
self, temp_dir, new_server_dir, full_jar_path, port, new_id
|
||||
):
|
||||
has_properties = False
|
||||
# extracts archive to temp directory
|
||||
for item in os.listdir(temp_dir):
|
||||
if str(item) == "server.properties":
|
||||
has_properties = True
|
||||
try:
|
||||
if not os.path.isdir(os.path.join(temp_dir, item)):
|
||||
FileHelpers.move_file(
|
||||
os.path.join(temp_dir, item), os.path.join(new_server_dir, item)
|
||||
)
|
||||
else:
|
||||
if item != "db_stats":
|
||||
FileHelpers.move_dir(
|
||||
os.path.join(temp_dir, item),
|
||||
os.path.join(new_server_dir, item),
|
||||
)
|
||||
except Exception as ex:
|
||||
logger.error(f"ERROR IN ZIP IMPORT: {ex}")
|
||||
if not has_properties:
|
||||
logger.info(
|
||||
f"No server.properties found on zip file import. "
|
||||
f"Creating one with port selection of {str(port)}"
|
||||
)
|
||||
with open(
|
||||
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
||||
) as file:
|
||||
file.write(f"server-port={port}")
|
||||
file.close()
|
||||
ServersController.finish_import(new_id)
|
||||
server_users = PermissionsServers.get_server_user_list(new_id)
|
||||
for user in server_users:
|
||||
self.helper.websocket_helper.broadcast_user(user, "send_start_reload", {})
|
||||
if os.name != "nt":
|
||||
if Helpers.check_file_exists(full_jar_path):
|
||||
os.chmod(full_jar_path, 0o2760)
|
||||
# deletes temp dir
|
||||
FileHelpers.del_dirs(temp_dir)
|
@ -29,15 +29,17 @@ from app.classes.shared.authentication import Authentication
|
||||
from app.classes.shared.console import Console
|
||||
from app.classes.shared.helpers import Helpers
|
||||
from app.classes.shared.file_helpers import FileHelpers
|
||||
from app.classes.shared.import_helper import ImportHelpers
|
||||
from app.classes.minecraft.serverjars import ServerJars
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Controller:
|
||||
def __init__(self, database, helper, file_helper):
|
||||
def __init__(self, database, helper, file_helper, import_helper):
|
||||
self.helper: Helpers = helper
|
||||
self.file_helper: FileHelpers = file_helper
|
||||
self.import_helper: ImportHelpers = import_helper
|
||||
self.server_jars: ServerJars = ServerJars(helper)
|
||||
self.users_helper: HelperUsers = HelperUsers(database, self.helper)
|
||||
self.roles_helper: HelperRoles = HelperRoles(database)
|
||||
@ -247,7 +249,7 @@ class Controller:
|
||||
except:
|
||||
return {"percent": 0, "total_files": 0}
|
||||
|
||||
def create_api_server(self, data: dict):
|
||||
def create_api_server(self, data: dict, user_id):
|
||||
server_fs_uuid = Helpers.create_uuid()
|
||||
new_server_path = os.path.join(self.helper.servers_dir, server_fs_uuid)
|
||||
backup_path = os.path.join(self.helper.backup_path, server_fs_uuid)
|
||||
@ -310,7 +312,9 @@ class Controller:
|
||||
# TODO: Copy files from the zip file to the new server directory
|
||||
server_file = create_data["jarfile"]
|
||||
raise Exception("Not yet implemented")
|
||||
_create_server_properties_if_needed(create_data["server_properties_port"])
|
||||
_create_server_properties_if_needed(
|
||||
create_data["server_properties_port"],
|
||||
)
|
||||
|
||||
min_mem = create_data["mem_min"]
|
||||
max_mem = create_data["mem_max"]
|
||||
@ -406,6 +410,7 @@ class Controller:
|
||||
server_log_file=log_location,
|
||||
server_stop=stop_command,
|
||||
server_port=monitoring_port,
|
||||
created_by=user_id,
|
||||
server_host=monitoring_host,
|
||||
server_type=monitoring_type,
|
||||
)
|
||||
@ -432,6 +437,7 @@ class Controller:
|
||||
min_mem: int,
|
||||
max_mem: int,
|
||||
port: int,
|
||||
user_id: int,
|
||||
):
|
||||
server_id = Helpers.create_uuid()
|
||||
server_dir = os.path.join(self.helper.servers_dir, server_id)
|
||||
@ -492,6 +498,7 @@ class Controller:
|
||||
server_log_file,
|
||||
server_stop,
|
||||
port,
|
||||
user_id,
|
||||
server_type="minecraft-java",
|
||||
)
|
||||
|
||||
@ -527,6 +534,7 @@ class Controller:
|
||||
min_mem: int,
|
||||
max_mem: int,
|
||||
port: int,
|
||||
user_id: int,
|
||||
):
|
||||
server_id = Helpers.create_uuid()
|
||||
new_server_dir = os.path.join(self.helper.servers_dir, server_id)
|
||||
@ -540,25 +548,6 @@ class Controller:
|
||||
Helpers.ensure_dir_exists(new_server_dir)
|
||||
Helpers.ensure_dir_exists(backup_path)
|
||||
server_path = Helpers.get_os_understandable_path(server_path)
|
||||
try:
|
||||
FileHelpers.copy_dir(server_path, new_server_dir, True)
|
||||
except shutil.Error as ex:
|
||||
logger.error(f"Server import failed with error: {ex}")
|
||||
|
||||
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(
|
||||
f"No server.properties found on zip file import. "
|
||||
f"Creating one with port selection of {str(port)}"
|
||||
)
|
||||
with open(
|
||||
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
||||
) as file:
|
||||
file.write(f"server-port={port}")
|
||||
file.close()
|
||||
|
||||
full_jar_path = os.path.join(new_server_dir, server_jar)
|
||||
|
||||
@ -587,8 +576,11 @@ class Controller:
|
||||
server_log_file,
|
||||
server_stop,
|
||||
port,
|
||||
user_id,
|
||||
server_type="minecraft-java",
|
||||
)
|
||||
ServersController.set_import(new_id)
|
||||
self.import_helper.import_jar_server(server_path, new_server_dir, port, new_id)
|
||||
return new_id
|
||||
|
||||
def import_zip_server(
|
||||
@ -599,6 +591,7 @@ class Controller:
|
||||
min_mem: int,
|
||||
max_mem: int,
|
||||
port: int,
|
||||
user_id: int,
|
||||
):
|
||||
server_id = Helpers.create_uuid()
|
||||
new_server_dir = os.path.join(self.helper.servers_dir, server_id)
|
||||
@ -612,32 +605,6 @@ class Controller:
|
||||
temp_dir = Helpers.get_os_understandable_path(zip_path)
|
||||
Helpers.ensure_dir_exists(new_server_dir)
|
||||
Helpers.ensure_dir_exists(backup_path)
|
||||
has_properties = False
|
||||
# extracts archive to temp directory
|
||||
for item in os.listdir(temp_dir):
|
||||
if str(item) == "server.properties":
|
||||
has_properties = True
|
||||
try:
|
||||
if not os.path.isdir(os.path.join(temp_dir, item)):
|
||||
FileHelpers.move_file(
|
||||
os.path.join(temp_dir, item), os.path.join(new_server_dir, item)
|
||||
)
|
||||
else:
|
||||
FileHelpers.move_dir(
|
||||
os.path.join(temp_dir, item), os.path.join(new_server_dir, item)
|
||||
)
|
||||
except Exception as ex:
|
||||
logger.error(f"ERROR IN ZIP IMPORT: {ex}")
|
||||
if not has_properties:
|
||||
logger.info(
|
||||
f"No server.properties found on zip file import. "
|
||||
f"Creating one with port selection of {str(port)}"
|
||||
)
|
||||
with open(
|
||||
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
||||
) as file:
|
||||
file.write(f"server-port={port}")
|
||||
file.close()
|
||||
|
||||
full_jar_path = os.path.join(new_server_dir, server_jar)
|
||||
|
||||
@ -667,8 +634,13 @@ class Controller:
|
||||
server_log_file,
|
||||
server_stop,
|
||||
port,
|
||||
user_id,
|
||||
server_type="minecraft-java",
|
||||
)
|
||||
ServersController.set_import(new_id)
|
||||
self.import_helper.import_java_zip_server(
|
||||
temp_dir, new_server_dir, port, new_id
|
||||
)
|
||||
return new_id
|
||||
|
||||
# **********************************************************************************
|
||||
@ -676,7 +648,12 @@ class Controller:
|
||||
# **********************************************************************************
|
||||
|
||||
def import_bedrock_server(
|
||||
self, server_name: str, server_path: str, server_exe: str, port: int
|
||||
self,
|
||||
server_name: str,
|
||||
server_path: str,
|
||||
server_exe: str,
|
||||
port: int,
|
||||
user_id: int,
|
||||
):
|
||||
server_id = Helpers.create_uuid()
|
||||
new_server_dir = os.path.join(self.helper.servers_dir, server_id)
|
||||
@ -690,25 +667,6 @@ class Controller:
|
||||
Helpers.ensure_dir_exists(new_server_dir)
|
||||
Helpers.ensure_dir_exists(backup_path)
|
||||
server_path = Helpers.get_os_understandable_path(server_path)
|
||||
try:
|
||||
FileHelpers.copy_dir(server_path, new_server_dir, True)
|
||||
except shutil.Error as ex:
|
||||
logger.error(f"Server import failed with error: {ex}")
|
||||
|
||||
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(
|
||||
f"No server.properties found on zip file import. "
|
||||
f"Creating one with port selection of {str(port)}"
|
||||
)
|
||||
with open(
|
||||
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
||||
) as file:
|
||||
file.write(f"server-port={port}")
|
||||
file.close()
|
||||
|
||||
full_jar_path = os.path.join(new_server_dir, server_exe)
|
||||
|
||||
@ -730,15 +688,22 @@ class Controller:
|
||||
server_log_file,
|
||||
server_stop,
|
||||
port,
|
||||
user_id,
|
||||
server_type="minecraft-bedrock",
|
||||
)
|
||||
if os.name != "nt":
|
||||
if Helpers.check_file_exists(full_jar_path):
|
||||
os.chmod(full_jar_path, 0o2760)
|
||||
ServersController.set_import(new_id)
|
||||
self.import_helper.import_bedrock_server(
|
||||
server_path, new_server_dir, port, full_jar_path, new_id
|
||||
)
|
||||
return new_id
|
||||
|
||||
def import_bedrock_zip_server(
|
||||
self, server_name: str, zip_path: str, server_exe: str, port: int
|
||||
self,
|
||||
server_name: str,
|
||||
zip_path: str,
|
||||
server_exe: str,
|
||||
port: int,
|
||||
user_id: int,
|
||||
):
|
||||
server_id = Helpers.create_uuid()
|
||||
new_server_dir = os.path.join(self.helper.servers_dir, server_id)
|
||||
@ -752,32 +717,6 @@ class Controller:
|
||||
temp_dir = Helpers.get_os_understandable_path(zip_path)
|
||||
Helpers.ensure_dir_exists(new_server_dir)
|
||||
Helpers.ensure_dir_exists(backup_path)
|
||||
has_properties = False
|
||||
# extracts archive to temp directory
|
||||
for item in os.listdir(temp_dir):
|
||||
if str(item) == "server.properties":
|
||||
has_properties = True
|
||||
try:
|
||||
if not os.path.isdir(os.path.join(temp_dir, item)):
|
||||
FileHelpers.move_file(
|
||||
os.path.join(temp_dir, item), os.path.join(new_server_dir, item)
|
||||
)
|
||||
else:
|
||||
FileHelpers.move_dir(
|
||||
os.path.join(temp_dir, item), os.path.join(new_server_dir, item)
|
||||
)
|
||||
except Exception as ex:
|
||||
logger.error(f"ERROR IN ZIP IMPORT: {ex}")
|
||||
if not has_properties:
|
||||
logger.info(
|
||||
f"No server.properties found on zip file import. "
|
||||
f"Creating one with port selection of {str(port)}"
|
||||
)
|
||||
with open(
|
||||
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
||||
) as file:
|
||||
file.write(f"server-port={port}")
|
||||
file.close()
|
||||
|
||||
full_jar_path = os.path.join(new_server_dir, server_exe)
|
||||
|
||||
@ -799,8 +738,12 @@ class Controller:
|
||||
server_log_file,
|
||||
server_stop,
|
||||
port,
|
||||
user_id,
|
||||
server_type="minecraft-bedrock",
|
||||
)
|
||||
self.import_helper.import_bedrock_zip_server(
|
||||
temp_dir, new_server_dir, full_jar_path, port, new_id
|
||||
)
|
||||
if os.name != "nt":
|
||||
if Helpers.check_file_exists(full_jar_path):
|
||||
os.chmod(full_jar_path, 0o2760)
|
||||
@ -841,6 +784,7 @@ class Controller:
|
||||
server_log_file: str,
|
||||
server_stop: str,
|
||||
server_port: int,
|
||||
created_by: int,
|
||||
server_type: str,
|
||||
server_host: str = "127.0.0.1",
|
||||
):
|
||||
@ -855,6 +799,7 @@ class Controller:
|
||||
server_log_file,
|
||||
server_stop,
|
||||
server_type,
|
||||
created_by,
|
||||
server_port,
|
||||
server_host,
|
||||
)
|
||||
|
@ -26,6 +26,7 @@ class DatabaseBuilder:
|
||||
password=password,
|
||||
email="default@example.com",
|
||||
superuser=True,
|
||||
manager=None,
|
||||
)
|
||||
|
||||
def is_fresh_install(self):
|
||||
|
@ -293,7 +293,7 @@ class ServerInstance:
|
||||
else:
|
||||
user_lang = HelperUsers.get_user_lang_by_id(user_id)
|
||||
|
||||
if self.stats_helper.get_download_status():
|
||||
if self.stats_helper.get_import_status():
|
||||
if user_id:
|
||||
self.helper.websocket_helper.broadcast_user(
|
||||
user_id,
|
||||
@ -612,21 +612,25 @@ class ServerInstance:
|
||||
# caching the name and pid number
|
||||
server_name = self.name
|
||||
server_pid = self.process.pid
|
||||
self.shutdown_timeout = self.settings["shutdown_timeout"]
|
||||
|
||||
while running:
|
||||
i += 1
|
||||
logstr = (
|
||||
f"Server {server_name} is still running "
|
||||
f"- waiting 2s to see if it stops ({int(60-(i*2))} "
|
||||
f"seconds until force close)"
|
||||
)
|
||||
logger.info(logstr)
|
||||
Console.info(logstr)
|
||||
ttk = int(self.shutdown_timeout - (i * 2))
|
||||
if i <= self.shutdown_timeout / 2:
|
||||
logstr = (
|
||||
f"Server {server_name} is still running "
|
||||
"- waiting 2s to see if it stops"
|
||||
f"({ttk} "
|
||||
f"seconds until force close)"
|
||||
)
|
||||
logger.info(logstr)
|
||||
Console.info(logstr)
|
||||
running = self.check_running()
|
||||
time.sleep(2)
|
||||
|
||||
# if we haven't closed in 60 seconds, let's just slam down on the PID
|
||||
if i >= 30:
|
||||
if i >= round(self.shutdown_timeout / 2, 0):
|
||||
logger.info(
|
||||
f"Server {server_name} is still running - Forcing the process down"
|
||||
)
|
||||
@ -1223,6 +1227,7 @@ class ServerInstance:
|
||||
"version": raw_ping_result.get("version"),
|
||||
"icon": raw_ping_result.get("icon"),
|
||||
"crashed": self.is_crashed,
|
||||
"created": datetime.datetime.now().strftime("%Y/%m/%d, %H:%M:%S"),
|
||||
},
|
||||
)
|
||||
total_players += int(raw_ping_result.get("online"))
|
||||
|
@ -394,6 +394,7 @@ class AjaxHandler(BaseHandler):
|
||||
"1",
|
||||
"2",
|
||||
server_data["server_port"],
|
||||
server_data["created_by"],
|
||||
)
|
||||
new_server_id = new_server
|
||||
new_server = self.controller.servers.get_server_data(new_server)
|
||||
@ -416,6 +417,7 @@ class AjaxHandler(BaseHandler):
|
||||
temp_dir,
|
||||
server_data["executable"],
|
||||
server_data["server_port"],
|
||||
server_data["created_by"],
|
||||
)
|
||||
new_server_id = new_server
|
||||
new_server = self.controller.servers.get_server_data(new_server)
|
||||
|
@ -340,10 +340,11 @@ class CreateUser(ApiHandler):
|
||||
|
||||
new_username = self.get_argument("username").lower()
|
||||
new_pass = self.get_argument("password")
|
||||
manager = int(user_obj["user_id"])
|
||||
|
||||
if new_username:
|
||||
self.controller.users.add_user(
|
||||
new_username, new_pass, "default@example.com", True, False
|
||||
new_username, manager, new_pass, "default@example.com", True, False
|
||||
)
|
||||
|
||||
self.return_response(
|
||||
|
@ -453,8 +453,8 @@ class PanelHandler(BaseHandler):
|
||||
for server in un_used_servers[:]:
|
||||
if flag == 0:
|
||||
server["stats"][
|
||||
"downloading"
|
||||
] = self.controller.servers.get_download_status(
|
||||
"importing"
|
||||
] = self.controller.servers.get_import_status(
|
||||
str(server["stats"]["server_id"]["server_id"])
|
||||
)
|
||||
server["stats"]["crashed"] = self.controller.servers.is_crashed(
|
||||
@ -524,6 +524,7 @@ class PanelHandler(BaseHandler):
|
||||
"files",
|
||||
"admin_controls",
|
||||
"schedules",
|
||||
"metrics",
|
||||
]
|
||||
if not self.failed_server:
|
||||
server = self.controller.servers.get_server_instance_by_id(server_id)
|
||||
@ -571,11 +572,11 @@ class PanelHandler(BaseHandler):
|
||||
"started": "False",
|
||||
}
|
||||
if not self.failed_server:
|
||||
page_data["downloading"] = self.controller.servers.get_download_status(
|
||||
page_data["importing"] = self.controller.servers.get_import_status(
|
||||
server_id
|
||||
)
|
||||
else:
|
||||
page_data["downloading"] = False
|
||||
page_data["importing"] = False
|
||||
page_data["server_id"] = server_id
|
||||
try:
|
||||
page_data["waiting_start"] = self.controller.servers.get_waiting_start(
|
||||
@ -754,6 +755,11 @@ class PanelHandler(BaseHandler):
|
||||
page_data["backup_list"] = []
|
||||
page_data["backup_path"] = Helpers.wtol_path(server_info["backup_path"])
|
||||
|
||||
if subpage == "metrics":
|
||||
page_data["history_stats"] = self.controller.servers.get_history_stats(
|
||||
server_id
|
||||
)
|
||||
|
||||
def get_banned_players_html():
|
||||
banned_players = self.controller.servers.get_banned_players(server_id)
|
||||
if banned_players is None:
|
||||
@ -860,6 +866,18 @@ class PanelHandler(BaseHandler):
|
||||
page_data["users"] = self.controller.users.get_all_users()
|
||||
page_data["roles"] = self.controller.roles.get_all_roles()
|
||||
page_data["auth-servers"][user.user_id] = super_auth_servers
|
||||
page_data["managed_users"] = []
|
||||
else:
|
||||
page_data["managed_users"] = self.controller.users.get_managed_users(
|
||||
exec_user["user_id"]
|
||||
)
|
||||
page_data["assigned_roles"] = []
|
||||
for item in page_data["roles"]:
|
||||
page_data["assigned_roles"].append(item.role_id)
|
||||
|
||||
page_data["managed_roles"] = self.controller.users.get_managed_roles(
|
||||
exec_user["user_id"]
|
||||
)
|
||||
|
||||
template = "panel/panel_config.html"
|
||||
|
||||
@ -885,7 +903,7 @@ class PanelHandler(BaseHandler):
|
||||
)
|
||||
return
|
||||
|
||||
page_data["roles_all"] = self.controller.roles.get_all_roles()
|
||||
page_data["roles"] = self.controller.roles.get_all_roles()
|
||||
page_data["servers"] = []
|
||||
page_data["servers_all"] = self.controller.servers.get_all_defined_servers()
|
||||
page_data["role-servers"] = []
|
||||
@ -904,8 +922,16 @@ class PanelHandler(BaseHandler):
|
||||
)
|
||||
if superuser:
|
||||
page_data["super-disabled"] = ""
|
||||
page_data["users"] = self.controller.users.get_all_users()
|
||||
else:
|
||||
page_data["super-disabled"] = "disabled"
|
||||
|
||||
page_data["exec_user"] = exec_user["user_id"]
|
||||
|
||||
page_data["manager"] = {
|
||||
"user_id": -100,
|
||||
"username": "None",
|
||||
}
|
||||
for file in sorted(
|
||||
os.listdir(os.path.join(self.helper.root_dir, "app", "translations"))
|
||||
):
|
||||
@ -1074,9 +1100,21 @@ class PanelHandler(BaseHandler):
|
||||
page_data["user"] = self.controller.users.get_user_by_id(user_id)
|
||||
page_data["servers"] = set()
|
||||
page_data["role-servers"] = page_role_servers
|
||||
page_data["roles_all"] = self.controller.roles.get_all_roles()
|
||||
page_data["roles"] = self.controller.roles.get_all_roles()
|
||||
page_data["exec_user"] = exec_user["user_id"]
|
||||
page_data["servers_all"] = self.controller.servers.get_all_defined_servers()
|
||||
page_data["superuser"] = superuser
|
||||
if page_data["user"]["manager"] is not None:
|
||||
page_data["manager"] = self.controller.users.get_user_by_id(
|
||||
page_data["user"]["manager"]
|
||||
)
|
||||
else:
|
||||
page_data["manager"] = {
|
||||
"user_id": -100,
|
||||
"username": "None",
|
||||
}
|
||||
if exec_user["superuser"]:
|
||||
page_data["users"] = self.controller.users.get_all_users()
|
||||
page_data[
|
||||
"permissions_all"
|
||||
] = self.controller.crafty_perms.list_defined_crafty_permissions()
|
||||
@ -1115,6 +1153,17 @@ class PanelHandler(BaseHandler):
|
||||
"/panel/error?error=Unauthorized access: not a user editor"
|
||||
)
|
||||
return
|
||||
if (
|
||||
(
|
||||
self.controller.users.get_user_by_id(user_id)["manager"]
|
||||
!= exec_user["user_id"]
|
||||
)
|
||||
and not exec_user["superuser"]
|
||||
and str(exec_user["user_id"]) != str(user_id)
|
||||
):
|
||||
self.redirect(
|
||||
"/panel/error?error=Unauthorized access: you cannot edit this user"
|
||||
)
|
||||
|
||||
page_data["servers"] = []
|
||||
page_data["role-servers"] = []
|
||||
@ -1212,6 +1261,11 @@ class PanelHandler(BaseHandler):
|
||||
defined_servers = self.controller.servers.get_authorized_servers(
|
||||
exec_user["user_id"]
|
||||
)
|
||||
|
||||
page_data["role_manager"] = {
|
||||
"user_id": -100,
|
||||
"username": "None",
|
||||
}
|
||||
page_servers = []
|
||||
for server in defined_servers:
|
||||
if server not in page_servers:
|
||||
@ -1229,6 +1283,7 @@ class PanelHandler(BaseHandler):
|
||||
user_roles = self.get_user_roles()
|
||||
page_data["new_role"] = False
|
||||
role_id = self.get_argument("id", None)
|
||||
role = self.controller.roles.get_role(role_id)
|
||||
page_data["role"] = self.controller.roles.get_role_with_servers(role_id)
|
||||
if exec_user["superuser"]:
|
||||
defined_servers = self.controller.servers.list_defined_servers()
|
||||
@ -1252,7 +1307,21 @@ class PanelHandler(BaseHandler):
|
||||
page_data["user-roles"] = user_roles
|
||||
page_data["users"] = self.controller.users.get_all_users()
|
||||
|
||||
if EnumPermissionsCrafty.ROLES_CONFIG not in exec_user_crafty_permissions:
|
||||
if page_data["role"]["manager"] is not None:
|
||||
page_data["role_manager"] = self.controller.users.get_user_by_id(
|
||||
page_data["role"]["manager"]
|
||||
)
|
||||
else:
|
||||
page_data["role_manager"] = {
|
||||
"user_id": -100,
|
||||
"username": "None",
|
||||
}
|
||||
|
||||
if (
|
||||
EnumPermissionsCrafty.ROLES_CONFIG not in exec_user_crafty_permissions
|
||||
or exec_user["user_id"] != role["manager"]
|
||||
and not exec_user["superuser"]
|
||||
):
|
||||
self.redirect(
|
||||
"/panel/error?error=Unauthorized access: not a role editor"
|
||||
)
|
||||
@ -1266,8 +1335,15 @@ class PanelHandler(BaseHandler):
|
||||
elif page == "remove_role":
|
||||
role_id = bleach.clean(self.get_argument("id", None))
|
||||
|
||||
if not superuser:
|
||||
self.redirect("/panel/error?error=Unauthorized access: not superuser")
|
||||
if (
|
||||
not superuser
|
||||
and self.controller.roles.get_role(role_id)["manager"]
|
||||
!= exec_user["user_id"]
|
||||
):
|
||||
self.redirect(
|
||||
"/panel/error?error=Unauthorized access: not superuser not"
|
||||
" role manager"
|
||||
)
|
||||
return
|
||||
if role_id is None:
|
||||
self.redirect("/panel/error?error=Invalid Role ID")
|
||||
@ -1418,6 +1494,7 @@ class PanelHandler(BaseHandler):
|
||||
return
|
||||
server_name = self.get_argument("server_name", None)
|
||||
server_obj = self.controller.servers.get_server_obj(server_id)
|
||||
shutdown_timeout = self.get_argument("shutdown_timeout", 60)
|
||||
if superuser:
|
||||
server_path = self.get_argument("server_path", None)
|
||||
if Helpers.is_os_windows():
|
||||
@ -1498,6 +1575,7 @@ class PanelHandler(BaseHandler):
|
||||
)
|
||||
|
||||
server_obj.server_name = server_name
|
||||
server_obj.shutdown_timeout = shutdown_timeout
|
||||
if superuser:
|
||||
if Helpers.validate_traversal(
|
||||
self.helper.get_servers_root_dir(), server_path
|
||||
@ -1930,6 +2008,7 @@ class PanelHandler(BaseHandler):
|
||||
"system user is not editable"
|
||||
)
|
||||
user_id = bleach.clean(self.get_argument("id", None))
|
||||
user = self.controller.users.get_user_by_id(user_id)
|
||||
username = bleach.clean(self.get_argument("username", None).lower())
|
||||
if (
|
||||
username != self.controller.users.get_user_by_id(user_id)["username"]
|
||||
@ -1962,7 +2041,19 @@ class PanelHandler(BaseHandler):
|
||||
else:
|
||||
superuser = 0
|
||||
|
||||
if not exec_user["superuser"]:
|
||||
if exec_user["superuser"]:
|
||||
manager = self.get_argument("manager")
|
||||
if manager == "":
|
||||
manager = None
|
||||
else:
|
||||
manager = int(manager)
|
||||
else:
|
||||
manager = user["manager"]
|
||||
|
||||
if (
|
||||
not exec_user["superuser"]
|
||||
and int(exec_user["user_id"]) != user["manager"]
|
||||
):
|
||||
if username is None or username == "":
|
||||
self.redirect("/panel/error?error=Invalid username")
|
||||
return
|
||||
@ -2013,6 +2104,7 @@ class PanelHandler(BaseHandler):
|
||||
|
||||
user_data = {
|
||||
"username": username,
|
||||
"manager": manager,
|
||||
"password": password0,
|
||||
"email": email,
|
||||
"enabled": enabled,
|
||||
@ -2029,13 +2121,13 @@ class PanelHandler(BaseHandler):
|
||||
user_id, user_data=user_data, user_crafty_data=user_crafty_data
|
||||
)
|
||||
|
||||
self.controller.management.add_to_audit_log(
|
||||
exec_user["user_id"],
|
||||
f"Edited user {username} (UID:{user_id}) with roles {roles} "
|
||||
f"and permissions {permissions_mask}",
|
||||
server_id=0,
|
||||
source_ip=self.get_remote_ip(),
|
||||
)
|
||||
self.controller.management.add_to_audit_log(
|
||||
exec_user["user_id"],
|
||||
f"Edited user {username} (UID:{user_id}) with roles {roles} "
|
||||
f"and permissions {permissions_mask}",
|
||||
server_id=0,
|
||||
source_ip=self.get_remote_ip(),
|
||||
)
|
||||
self.redirect("/panel/panel_config")
|
||||
|
||||
elif page == "edit_user_apikeys":
|
||||
@ -2158,6 +2250,15 @@ class PanelHandler(BaseHandler):
|
||||
if username is None or username == "":
|
||||
self.redirect("/panel/error?error=Invalid username")
|
||||
return
|
||||
|
||||
if exec_user["superuser"]:
|
||||
manager = self.get_argument("manager")
|
||||
if manager == "":
|
||||
manager = None
|
||||
else:
|
||||
manager = int(manager)
|
||||
else:
|
||||
manager = int(exec_user["user_id"])
|
||||
# does this user id exist?
|
||||
if self.controller.users.get_id_by_name(username) is not None:
|
||||
self.redirect("/panel/error?error=User exists")
|
||||
@ -2172,6 +2273,7 @@ class PanelHandler(BaseHandler):
|
||||
|
||||
user_id = self.controller.users.add_user(
|
||||
username,
|
||||
manager=manager,
|
||||
password=password0,
|
||||
email=email,
|
||||
enabled=enabled,
|
||||
@ -2198,14 +2300,19 @@ class PanelHandler(BaseHandler):
|
||||
server_id=0,
|
||||
source_ip=self.get_remote_ip(),
|
||||
)
|
||||
self.controller.crafty_perms.add_user_creation(exec_user["user_id"])
|
||||
self.redirect("/panel/panel_config")
|
||||
|
||||
elif page == "edit_role":
|
||||
role_id = bleach.clean(self.get_argument("id", None))
|
||||
role_name = bleach.clean(self.get_argument("role_name", None))
|
||||
|
||||
if EnumPermissionsCrafty.ROLES_CONFIG not in exec_user_crafty_permissions:
|
||||
role = self.controller.roles.get_role(role_id)
|
||||
|
||||
if (
|
||||
EnumPermissionsCrafty.ROLES_CONFIG not in exec_user_crafty_permissions
|
||||
and exec_user["user_id"] != role["manager"]
|
||||
and not exec_user["superuser"]
|
||||
):
|
||||
self.redirect(
|
||||
"/panel/error?error=Unauthorized access: not a role editor"
|
||||
)
|
||||
@ -2221,9 +2328,18 @@ class PanelHandler(BaseHandler):
|
||||
self.redirect("/panel/error?error=Invalid Role ID")
|
||||
return
|
||||
|
||||
if exec_user["superuser"]:
|
||||
manager = self.get_argument("manager", None)
|
||||
if manager == "":
|
||||
manager = None
|
||||
else:
|
||||
manager = role["manager"]
|
||||
|
||||
servers = self.get_role_servers()
|
||||
|
||||
self.controller.roles.update_role_advanced(role_id, role_name, servers)
|
||||
self.controller.roles.update_role_advanced(
|
||||
role_id, role_name, servers, manager
|
||||
)
|
||||
|
||||
self.controller.management.add_to_audit_log(
|
||||
exec_user["user_id"],
|
||||
@ -2235,6 +2351,12 @@ class PanelHandler(BaseHandler):
|
||||
|
||||
elif page == "add_role":
|
||||
role_name = bleach.clean(self.get_argument("role_name", None))
|
||||
if exec_user["superuser"]:
|
||||
manager = self.get_argument("manager", None)
|
||||
if manager == "":
|
||||
manager = None
|
||||
else:
|
||||
manager = exec_user["user_id"]
|
||||
|
||||
if EnumPermissionsCrafty.ROLES_CONFIG not in exec_user_crafty_permissions:
|
||||
self.redirect(
|
||||
@ -2259,7 +2381,9 @@ class PanelHandler(BaseHandler):
|
||||
|
||||
servers = self.get_role_servers()
|
||||
|
||||
role_id = self.controller.roles.add_role_advanced(role_name, servers)
|
||||
role_id = self.controller.roles.add_role_advanced(
|
||||
role_name, servers, manager
|
||||
)
|
||||
|
||||
self.controller.management.add_to_audit_log(
|
||||
exec_user["user_id"],
|
||||
@ -2267,7 +2391,6 @@ class PanelHandler(BaseHandler):
|
||||
server_id=0,
|
||||
source_ip=self.get_remote_ip(),
|
||||
)
|
||||
self.controller.crafty_perms.add_role_creation(exec_user["user_id"])
|
||||
self.redirect("/panel/panel_config")
|
||||
|
||||
else:
|
||||
|
@ -116,7 +116,9 @@ class ApiRolesIndexHandler(BaseApiHandler):
|
||||
400, {"status": "error", "error": "ROLE_NAME_ALREADY_EXISTS"}
|
||||
)
|
||||
|
||||
role_id = self.controller.roles.add_role_advanced(role_name, servers)
|
||||
role_id = self.controller.roles.add_role_advanced(
|
||||
role_name, servers, user["user_id"]
|
||||
)
|
||||
|
||||
self.controller.management.add_to_audit_log(
|
||||
user["user_id"],
|
||||
|
@ -665,10 +665,9 @@ class ApiServersIndexHandler(BaseApiHandler):
|
||||
},
|
||||
)
|
||||
|
||||
new_server_id, new_server_uuid = self.controller.create_api_server(data)
|
||||
|
||||
# Increase the server creation counter
|
||||
self.controller.crafty_perms.add_server_creation(user["user_id"])
|
||||
new_server_id, new_server_uuid = self.controller.create_api_server(
|
||||
data, user["user_id"]
|
||||
)
|
||||
|
||||
self.controller.servers.stats.record_stats()
|
||||
|
||||
|
@ -84,6 +84,7 @@ class ApiServersServerActionHandler(BaseApiHandler):
|
||||
new_server_log_file,
|
||||
server_data.get("stop_command"),
|
||||
server_data.get("type"),
|
||||
user_id,
|
||||
server_data.get("server_port"),
|
||||
)
|
||||
|
||||
|
@ -96,6 +96,7 @@ class ApiUsersIndexHandler(BaseApiHandler):
|
||||
|
||||
username = data["username"]
|
||||
username = str(username).lower()
|
||||
manager = int(user["user_id"])
|
||||
password = data["password"]
|
||||
email = data.get("email", "default@example.com")
|
||||
enabled = data.get("enabled", True)
|
||||
@ -149,6 +150,7 @@ class ApiUsersIndexHandler(BaseApiHandler):
|
||||
# TODO: do this in the most efficient way
|
||||
user_id = self.controller.users.add_user(
|
||||
username,
|
||||
manager,
|
||||
password,
|
||||
email,
|
||||
enabled,
|
||||
|
@ -1,6 +1,7 @@
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
import tornado.web
|
||||
import tornado.escape
|
||||
import bleach
|
||||
@ -224,6 +225,23 @@ class ServerHandler(BaseHandler):
|
||||
|
||||
if server_id is not None:
|
||||
if command == "clone_server":
|
||||
if (
|
||||
not superuser
|
||||
and not self.controller.crafty_perms.can_create_server(
|
||||
exec_user["user_id"]
|
||||
)
|
||||
):
|
||||
time.sleep(3)
|
||||
self.helper.websocket_helper.broadcast_user(
|
||||
exec_user["user_id"],
|
||||
"send_start_error",
|
||||
{
|
||||
"error": "<i class='fas fa-exclamation-triangle'"
|
||||
" style='font-size:48px;color:red'>"
|
||||
"</i> Not a server creator or server limit reached."
|
||||
},
|
||||
)
|
||||
return
|
||||
|
||||
def is_name_used(name):
|
||||
for server in self.controller.servers.get_all_defined_servers():
|
||||
@ -231,6 +249,7 @@ class ServerHandler(BaseHandler):
|
||||
return True
|
||||
return
|
||||
|
||||
template = "/panel/dashboard"
|
||||
server_data = self.controller.servers.get_server_data_by_id(
|
||||
server_id
|
||||
)
|
||||
@ -265,6 +284,7 @@ class ServerHandler(BaseHandler):
|
||||
backup_path = os.path.join(self.helper.backup_path, new_server_uuid)
|
||||
server_port = server_data.get("server_port")
|
||||
server_type = server_data.get("type")
|
||||
created_by = exec_user["user_id"]
|
||||
|
||||
new_server_id = self.controller.servers.create_server(
|
||||
new_server_name,
|
||||
@ -276,6 +296,7 @@ class ServerHandler(BaseHandler):
|
||||
new_server_log_file,
|
||||
stop_command,
|
||||
server_type,
|
||||
created_by,
|
||||
server_port,
|
||||
)
|
||||
if not exec_user["superuser"]:
|
||||
@ -283,7 +304,8 @@ class ServerHandler(BaseHandler):
|
||||
new_server_id
|
||||
).get("server_uuid")
|
||||
role_id = self.controller.roles.add_role(
|
||||
f"Creator of Server with uuid={new_server_uuid}"
|
||||
f"Creator of Server with uuid={new_server_uuid}",
|
||||
exec_user["user_id"],
|
||||
)
|
||||
self.controller.server_perms.add_role_server(
|
||||
new_server_id, role_id, "11111111"
|
||||
@ -291,9 +313,6 @@ class ServerHandler(BaseHandler):
|
||||
self.controller.users.add_role_to_user(
|
||||
exec_user["user_id"], role_id
|
||||
)
|
||||
self.controller.crafty_perms.add_server_creation(
|
||||
exec_user["user_id"]
|
||||
)
|
||||
|
||||
self.controller.servers.init_all_servers()
|
||||
|
||||
@ -353,6 +372,7 @@ class ServerHandler(BaseHandler):
|
||||
min_mem,
|
||||
max_mem,
|
||||
port,
|
||||
exec_user["user_id"],
|
||||
)
|
||||
self.controller.management.add_to_audit_log(
|
||||
exec_user["user_id"],
|
||||
@ -369,7 +389,13 @@ class ServerHandler(BaseHandler):
|
||||
return
|
||||
|
||||
new_server_id = self.controller.import_zip_server(
|
||||
server_name, zip_path, import_server_jar, min_mem, max_mem, port
|
||||
server_name,
|
||||
zip_path,
|
||||
import_server_jar,
|
||||
min_mem,
|
||||
max_mem,
|
||||
port,
|
||||
exec_user["user_id"],
|
||||
)
|
||||
if new_server_id == "false":
|
||||
self.redirect(
|
||||
@ -385,8 +411,6 @@ class ServerHandler(BaseHandler):
|
||||
new_server_id,
|
||||
self.get_remote_ip(),
|
||||
)
|
||||
# deletes temp dir
|
||||
FileHelpers.del_dirs(zip_path)
|
||||
else:
|
||||
if len(server_parts) != 3:
|
||||
self.redirect("/panel/error?error=Invalid server data")
|
||||
@ -402,6 +426,7 @@ class ServerHandler(BaseHandler):
|
||||
min_mem,
|
||||
max_mem,
|
||||
port,
|
||||
exec_user["user_id"],
|
||||
)
|
||||
self.controller.management.add_to_audit_log(
|
||||
exec_user["user_id"],
|
||||
@ -420,7 +445,8 @@ class ServerHandler(BaseHandler):
|
||||
new_server_id
|
||||
).get("server_uuid")
|
||||
role_id = self.controller.roles.add_role(
|
||||
f"Creator of Server with uuid={new_server_uuid}"
|
||||
f"Creator of Server with uuid={new_server_uuid}",
|
||||
exec_user["user_id"],
|
||||
)
|
||||
self.controller.server_perms.add_role_server(
|
||||
new_server_id, role_id, "11111111"
|
||||
@ -428,9 +454,6 @@ class ServerHandler(BaseHandler):
|
||||
self.controller.users.add_role_to_user(
|
||||
exec_user["user_id"], role_id
|
||||
)
|
||||
self.controller.crafty_perms.add_server_creation(
|
||||
exec_user["user_id"]
|
||||
)
|
||||
|
||||
else:
|
||||
for role in captured_roles:
|
||||
@ -483,7 +506,11 @@ class ServerHandler(BaseHandler):
|
||||
return
|
||||
|
||||
new_server_id = self.controller.import_bedrock_server(
|
||||
server_name, import_server_path, import_server_exe, port
|
||||
server_name,
|
||||
import_server_path,
|
||||
import_server_exe,
|
||||
port,
|
||||
exec_user["user_id"],
|
||||
)
|
||||
self.controller.management.add_to_audit_log(
|
||||
exec_user["user_id"],
|
||||
@ -500,7 +527,11 @@ class ServerHandler(BaseHandler):
|
||||
return
|
||||
|
||||
new_server_id = self.controller.import_bedrock_zip_server(
|
||||
server_name, zip_path, import_server_exe, port
|
||||
server_name,
|
||||
zip_path,
|
||||
import_server_exe,
|
||||
port,
|
||||
exec_user["user_id"],
|
||||
)
|
||||
if new_server_id == "false":
|
||||
self.redirect(
|
||||
@ -516,8 +547,6 @@ class ServerHandler(BaseHandler):
|
||||
new_server_id,
|
||||
self.get_remote_ip(),
|
||||
)
|
||||
# deletes temp dir
|
||||
FileHelpers.del_dirs(zip_path)
|
||||
else:
|
||||
if len(server_parts) != 2:
|
||||
self.redirect("/panel/error?error=Invalid server data")
|
||||
@ -526,7 +555,13 @@ class ServerHandler(BaseHandler):
|
||||
# TODO: add server type check here and call the correct server
|
||||
# add functions if not a jar
|
||||
new_server_id = self.controller.create_jar_server(
|
||||
server_type, server_version, server_name, min_mem, max_mem, port
|
||||
server_type,
|
||||
server_version,
|
||||
server_name,
|
||||
min_mem,
|
||||
max_mem,
|
||||
port,
|
||||
exec_user["user_id"],
|
||||
)
|
||||
self.controller.management.add_to_audit_log(
|
||||
exec_user["user_id"],
|
||||
@ -545,7 +580,8 @@ class ServerHandler(BaseHandler):
|
||||
new_server_id
|
||||
).get("server_uuid")
|
||||
role_id = self.controller.roles.add_role(
|
||||
f"Creator of Server with uuid={new_server_uuid}"
|
||||
f"Creator of Server with uuid={new_server_uuid}",
|
||||
exec_user["user_id"],
|
||||
)
|
||||
self.controller.server_perms.add_role_server(
|
||||
new_server_id, role_id, "11111111"
|
||||
@ -553,9 +589,6 @@ class ServerHandler(BaseHandler):
|
||||
self.controller.users.add_role_to_user(
|
||||
exec_user["user_id"], role_id
|
||||
)
|
||||
self.controller.crafty_perms.add_server_creation(
|
||||
exec_user["user_id"]
|
||||
)
|
||||
|
||||
else:
|
||||
for role in captured_roles:
|
||||
|
@ -40,6 +40,16 @@
|
||||
<!-- Bootstrap Toggle -->
|
||||
<link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet">
|
||||
<script defer src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"
|
||||
integrity="sha512-ElRFoEQdI5Ht6kZvyzXhYG9NqjtkmlkfYk0wr6wHxU9JEHakS7UJZNeml5ALk+8IKlU6jDgMabC3vkumRokgJA=="
|
||||
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"
|
||||
integrity="sha512-UXumZrZNiOwnTcZSHLOfcTs0aos2MzBWHXOHOuB0J/R44QB0dwY5JgfbvljXcklVf65Gc4El6RjZ+lnwd2az2g=="
|
||||
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/1.2.1/chartjs-plugin-zoom.min.js"
|
||||
integrity="sha512-klQv6lz2YR+MecyFYMFRuU2eAl8IPRo6zHnsc9n142TJuJHS8CG0ix4Oq9na9ceeg1u5EkBfZsFcV3U7J51iew=="
|
||||
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
|
||||
<!-- End Bootstrap Toggle -->
|
||||
|
||||
</head>
|
||||
|
@ -193,9 +193,9 @@
|
||||
<a data-id="{{server['server_data']['server_id']}}" class="" title="{{
|
||||
translate('dashboard', 'delay-explained' , data['lang'])}}">{{ translate('dashboard', 'starting',
|
||||
data['lang']) }}</i></a>
|
||||
{% elif server['stats']['downloading']%}
|
||||
{% elif server['stats']['importing']%}
|
||||
<a data-id="{{server['server_data']['server_id']}}" class=""><i class="fa fa-spinner fa-spin"></i>
|
||||
{{ translate('serverTerm', 'downloading',
|
||||
{{ translate('serverTerm', 'importing',
|
||||
data['lang']) }}</a>
|
||||
{% else %}
|
||||
<a data-id="{{server['server_data']['server_id']}}" class="play_button" data-toggle="tooltip"
|
||||
@ -399,12 +399,12 @@
|
||||
data['lang']) }}</i></a>
|
||||
</div>
|
||||
</div>
|
||||
{% elif server['stats']['downloading']%}
|
||||
{% elif server['stats']['importing']%}
|
||||
<div class="row">
|
||||
<div class="col-12 px-0">
|
||||
<a data-id="{{server['server_data']['server_id']}}" class="btn btn-link"><i
|
||||
class="fa fa-spinner fa-spin"></i>
|
||||
{{ translate('serverTerm', 'downloading', data['lang']) }}</a>
|
||||
{{ translate('serverTerm', 'importing', data['lang']) }}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
@ -893,9 +893,6 @@
|
||||
message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> {% raw translate("dashboard", "bePatientClone", data["lang"]) %} </div>',
|
||||
closeButton: false,
|
||||
});
|
||||
setTimeout(function () {
|
||||
location.reload();
|
||||
}, 5000)
|
||||
}
|
||||
</script>
|
||||
<script src="/static/assets/vendors/js/jquery-ui.js"></script>
|
||||
|
@ -87,6 +87,38 @@
|
||||
<td><a href="/panel/edit_user?id={{user.user_id}}"><i class="fas fa-pencil-alt"></i></a></td>
|
||||
</tr>
|
||||
{% end %}
|
||||
{% for user in data['managed_users'] %}
|
||||
<tr>
|
||||
<td><i class="fas fa-user"></i> {{ user.username }}</td>
|
||||
<td>
|
||||
{% if user.enabled %}
|
||||
<span class="text-success">
|
||||
<i class="fas fa-check-square"></i> Yes
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="text-danger">
|
||||
<i class="far fa-times-square"></i> No
|
||||
</span>
|
||||
|
||||
{% end %}
|
||||
</td>
|
||||
<td id="server_list_{{user.user_id}}">
|
||||
<ul id="{{user.user_id}}">
|
||||
{% for item in data['auth-servers'][user.user_id] %}
|
||||
<li>{{item}}</li>
|
||||
{% end %}
|
||||
</ul>
|
||||
</td>
|
||||
<td id="role_list_{{user.user_id}}">
|
||||
<ul>
|
||||
{% for item in data['user-roles'][user.user_id] %}
|
||||
<li data-toggle="tooltip" title="{{ item }}">{{item}}</li>
|
||||
{% end %}
|
||||
</ul>
|
||||
</td>
|
||||
<td><a href="/panel/edit_user?id={{user.user_id}}"><i class="fas fa-pencil-alt"></i></a></td>
|
||||
</tr>
|
||||
{% end %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@ -146,6 +178,34 @@
|
||||
</tr>
|
||||
{% end %}
|
||||
|
||||
{% if not data['superuser'] %}
|
||||
{% for role in data['managed_roles'] %}
|
||||
{% if role.role_id not in data['assigned_roles'] %}
|
||||
<tr>
|
||||
<td>{{ role.role_name }}</td>
|
||||
<td id="role_list_{{role.role_id}}">
|
||||
<ul id="{{role.role_id}}">
|
||||
{% for item in data['role-servers'][role.role_id] %}
|
||||
<li>{{item}}</li>
|
||||
{% end %}
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<ul>
|
||||
{% for user in data['users'] %}
|
||||
{% for ruser in data['user-roles'][user.user_id] %}
|
||||
{% if ruser == role.role_name %}
|
||||
<li>{{ user.username }}</li>
|
||||
{% end %}
|
||||
{% end %}
|
||||
{% end %}
|
||||
</ul>
|
||||
</td>
|
||||
<td><a href="/panel/edit_role?id={{role.role_id}}"><i class="fas fa-pencil-alt"></i></a></td>
|
||||
</tr>
|
||||
{% end %}
|
||||
{% end %}
|
||||
{% end %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
@ -49,7 +49,7 @@
|
||||
</ul>
|
||||
<div class="">
|
||||
<div class="">
|
||||
<form class="forms-sample" method="post" action="{{ '/panel/add_role' if data['new_role'] else '/panel/edit_role' }}">
|
||||
<form id="role_form" class="forms-sample" method="post" action="{{ '/panel/add_role' if data['new_role'] else '/panel/edit_role' }}">
|
||||
{% raw xsrf_form_html() %}
|
||||
<input type="hidden" name="id" value="{{ data['role']['role_id'] }}">
|
||||
<input type="hidden" name="subpage" value="config">
|
||||
@ -63,6 +63,29 @@
|
||||
<label for="role_name">{{ translate('rolesConfig', 'roleName', data['lang']) }} <small class="text-muted ml-1"> - {{ translate('rolesConfig', 'roleDesc', data['lang']) }}</small> </label>
|
||||
<input type="text" class="form-control" name="role_name" id="role_name" value="{{ data['role']['role_name'] }}" placeholder="Role Name" >
|
||||
</div>
|
||||
|
||||
<br />
|
||||
{% if data['superuser'] %}
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="manager">{{ translate('rolesConfig', 'selectManager',
|
||||
data['lang']) }}
|
||||
</label>
|
||||
<select class="form-select form-control form-control-lg select-css" id="manager" name="manager"
|
||||
form="role_form">
|
||||
{% if data["role_manager"]["username"] != "None" %}
|
||||
<option value='{{data["role_manager"]["user_id"]}}'>{{ data["role_manager"]["username"]
|
||||
}}</option>
|
||||
{% end %}
|
||||
<option value="">None</option>
|
||||
{% for user in data['users'] %}
|
||||
{% if user.user_id != data['role_manager']['user_id']
|
||||
%}
|
||||
<option value="{{user.user_id}}">{{user.username}}</option>
|
||||
{% end %}
|
||||
{% end %}
|
||||
</select>
|
||||
</div>
|
||||
{% end %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -252,6 +275,8 @@
|
||||
<br />
|
||||
{{ translate('rolesConfig', 'configUpdate', data['lang']) }} {{ str(data['role']['last_update']) }}
|
||||
<br />
|
||||
{{ translate('userConfig', 'manager', data['lang']) }}: {{ data['role_manager']['username'] }}
|
||||
<br />
|
||||
</p>
|
||||
</blockquote>
|
||||
<div class="text-center">
|
||||
|
@ -121,6 +121,27 @@ data['lang']) }}{% end %}
|
||||
{% end %}
|
||||
</select>
|
||||
</div>
|
||||
{% if data['superuser'] %}
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="manager">{{ translate('userConfig', 'selectManager',
|
||||
data['lang']) }}
|
||||
</label>
|
||||
<select class="form-select form-control form-control-lg select-css" id="manager" name="manager"
|
||||
form="user_form">
|
||||
{% if data["manager"]["username"] != "None" %}
|
||||
<option value='{{data["manager"]["user_id"]}}'>{{ data["manager"]["username"]
|
||||
}}</option>
|
||||
{% end %}
|
||||
<option value="">None</option>
|
||||
{% for user in data['users'] %}
|
||||
{% if user.username != data['user']['username'] and user.user_id != data['manager']['user_id']
|
||||
%}
|
||||
<option value="{{user.user_id}}">{{user.username}}</option>
|
||||
{% end %}
|
||||
{% end %}
|
||||
</select>
|
||||
</div>
|
||||
{% end %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -141,21 +162,29 @@ data['lang']) }}{% end %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for role in data['roles_all'] %}
|
||||
{% for role in data['roles'] %}
|
||||
<tr>
|
||||
{% if data['superuser'] or role.role_id in data['user']['roles'] or role.manager == data['exec_user'] %}
|
||||
<td>{{ role.role_name }}</td>
|
||||
<td>
|
||||
{% if role.role_id in data['user']['roles'] %}
|
||||
{% if role.manager == data['exec_user'] or data['superuser'] %}
|
||||
<input type="checkbox" class="form-check-input"
|
||||
id="role_{{ role.role_id }}_membership" name="role_{{ role.role_id }}_membership"
|
||||
checked="" value="1">
|
||||
{% else %}
|
||||
<input type="checkbox" class="form-check-input"
|
||||
id="role_{{ role.role_id }}_membership" name="role_{{ role.role_id }}_membership"
|
||||
checked="" value="1" disabled>
|
||||
{% end %}
|
||||
{% elif data['superuser'] or role.manager == data['exec_user'] %}
|
||||
<input type="checkbox" class="form-check-input"
|
||||
id="role_{{ role.role_id }}_membership" name="role_{{ role.role_id }}_membership"
|
||||
value="1">
|
||||
{% end %}
|
||||
|
||||
</td>
|
||||
{% end %}
|
||||
</tr>
|
||||
{% end %}
|
||||
</tbody>
|
||||
@ -268,6 +297,8 @@ data['lang']) }}{% end %}
|
||||
<br />
|
||||
{{ translate('userConfig', 'lastIP', data['lang']) }} {{ data['user']['last_ip'] }}
|
||||
<br />
|
||||
{{ translate('userConfig', 'manager', data['lang'])}}: {{data['manager']['username'] }}
|
||||
<br />
|
||||
</p>
|
||||
</blockquote>
|
||||
</div>
|
||||
@ -284,7 +315,7 @@ data['lang']) }}{% end %}
|
||||
{% else %}
|
||||
<button class="btn btn-sm btn-danger delete-user"><i class="fas fa-trash"></i> {{
|
||||
translate('userConfig', 'deleteUserB', data['lang']) }}</a>
|
||||
{% end %}
|
||||
{% end %}</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@ -30,6 +30,7 @@
|
||||
{% if data['permissions']['Players'] in data['user_permissions'] and data['server_data']['type'] != 'minecraft-bedrock' %}
|
||||
<a class="dropdown-item {% if data['active_link'] == 'admin_controls' %}active{% end %}" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=admin_controls" role="tab" aria-selected="true"><i class="fas fa-users"></i> {{ translate('serverDetails', 'playerControls', data['lang']) }}</a>
|
||||
{% end %}
|
||||
<a class="dropdown-item {% if data['active_link'] == 'metrics' %}active{% end %}" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=metrics" role="tab" aria-selected="true"><i class='fas fa-chart-area'></i>{{ translate('serverDetails', 'metrics', data['lang']) }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -49,4 +49,8 @@
|
||||
<i class="fas fa-users"></i>{{ translate('serverDetails', 'playerControls', data['lang']) }}</a>
|
||||
</li>
|
||||
{% end %}
|
||||
<li class="nav-item term-nav-item">
|
||||
<a class="nav-link {% if data['active_link'] == 'metrics' %}active{% end %}" href="/panel/server_detail?id={{ data['server_stats']['server_id']['server_id'] }}&subpage=metrics" role="tab" aria-selected="true">
|
||||
<i class='fas fa-chart-area'></i>{{ translate('serverDetails', 'metrics', data['lang']) }}</a>
|
||||
</li>
|
||||
</ul>
|
@ -165,6 +165,18 @@
|
||||
</div>
|
||||
{% end %}
|
||||
|
||||
<div class="form-group">
|
||||
<label for="shutdown_timeout">{{ translate('serverConfig', 'shutdownTimeout', data['lang']) }}
|
||||
<small class="text-muted ml-1"> - {{ translate('serverConfig', 'timeoutExplain1', data['lang'])
|
||||
}}
|
||||
{{ data['server_stats']['server_id']['stop_command'] }} {{ translate('serverConfig',
|
||||
'timeoutExplain2', data['lang']) }}
|
||||
</small> </label>
|
||||
<input type="number" class="form-control" name="shutdown_timeout" id="shutdown_timeout"
|
||||
value="{{ data['server_stats']['server_id']['shutdown_timeout'] }}" step="2" max="300" min="60"
|
||||
required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="logs_delete_after">{{ translate('serverConfig', 'removeOldLogsAfter', data['lang']) }}
|
||||
<small class="text-muted ml-1"> - {{ translate('serverConfig', 'removeOldLogsAfterDesc',
|
||||
|
225
app/frontend/templates/panel/server_metrics.html
Normal file
225
app/frontend/templates/panel/server_metrics.html
Normal file
@ -0,0 +1,225 @@
|
||||
{% extends ../base.html %}
|
||||
|
||||
{% block meta %}
|
||||
{% end %}
|
||||
|
||||
{% block title %}Crafty Controller - {{ translate('serverDetails', 'serverDetails', data['lang']) }}{% end %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- 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>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- Page Title Header Ends-->
|
||||
|
||||
{% include "parts/details_stats.html %}
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-12 grid-margin">
|
||||
<div class="card">
|
||||
<div class="card-body pt-0">
|
||||
<span class="d-none d-sm-block">
|
||||
{% include "parts/server_controls_list.html %}
|
||||
</span>
|
||||
<span class="d-block d-sm-none">
|
||||
{% include "parts/m_server_controls_list.html %}
|
||||
</span>
|
||||
<button style="float: right; visibility: hidden;" class="btn btn-outline-success reset-button"
|
||||
id="reset-button"><i class="fas fa-undo"></i> {{ translate('serverMetrics', 'resetZoom', data['lang'])
|
||||
}}</button>
|
||||
{% if data['user_data']['hints'] %}
|
||||
<span data-html="true" class="hints text-center" title="<i class='fa fa-info-circle'></i> " ,
|
||||
data-content="{{
|
||||
translate('serverMetrics', 'zoomHint1' , data['lang'])}} <br> <br> {{ translate('serverMetrics', 'zoomHint2', data['lang'])}}" , data-placement="top"></span>
|
||||
{% end %}
|
||||
<div class="chart-wrapper">
|
||||
<canvas id="lineChart"></canvas>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<style>
|
||||
.chart-wrapper {
|
||||
height: 65vh;
|
||||
}
|
||||
|
||||
.popover-body {
|
||||
color: white !important;
|
||||
;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
var zoomed = false;
|
||||
//line
|
||||
var ctxL = document.getElementById("lineChart").getContext('2d');
|
||||
const players = []
|
||||
const dates = []
|
||||
const ram = []
|
||||
const cpu = []
|
||||
{% for item in data['history_stats'] %}
|
||||
{% if 'minecraft-java' in data['server_stats']['server_type'] %}
|
||||
players.push("{{ item.online }}");
|
||||
{% end %}
|
||||
dates.push("{{ item.created.strftime('%Y/%m/%d, %H:%M:%S') }}");
|
||||
ram.push("{{ item.mem_percent }}")
|
||||
cpu.push("{{ item.cpu }}")
|
||||
{% end %}
|
||||
var hist_chart = new Chart(ctxL, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: dates,
|
||||
datasets: [{
|
||||
label: "Players",
|
||||
data: players,
|
||||
borderColor: [
|
||||
'rgba(136, 98, 224, .5)',
|
||||
],
|
||||
borderWidth: 2,
|
||||
lineTension: 0,
|
||||
},
|
||||
{
|
||||
label: "MEM",
|
||||
data: ram,
|
||||
borderColor: [
|
||||
'rgba(33, 150, 243, .5)',
|
||||
],
|
||||
borderWidth: 2,
|
||||
lineTension: 0,
|
||||
},
|
||||
{
|
||||
label: "CPU",
|
||||
data: cpu,
|
||||
borderColor: [
|
||||
'rgba(255, 175, 0, .5)',
|
||||
],
|
||||
borderWidth: 2,
|
||||
lineTension: 0,
|
||||
},
|
||||
]
|
||||
},
|
||||
options: {
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
zoom: {
|
||||
zoom: {
|
||||
onZoom({ hist_chart }) {
|
||||
console.log("zooming");
|
||||
document.getElementById("reset-button").style.visibility = "visible";
|
||||
zoomed = true;
|
||||
},
|
||||
wheel: {
|
||||
enabled: true,
|
||||
modifierKey: 'shift',
|
||||
},
|
||||
drag: {
|
||||
enabled: true,
|
||||
modifierKey: "shift"
|
||||
},
|
||||
pinch: {
|
||||
enabled: true
|
||||
},
|
||||
mode: 'x',
|
||||
},
|
||||
pan: {
|
||||
enabled: true,
|
||||
mode: "x",
|
||||
threshhold: 1,
|
||||
}
|
||||
},
|
||||
},
|
||||
fill: false,
|
||||
lineTension: 5,
|
||||
responsive: true,
|
||||
scales: {
|
||||
y: {
|
||||
min: 0,
|
||||
},
|
||||
x: {
|
||||
position: 'right',
|
||||
min: dates.length - 200,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
$(window).ready(function () {
|
||||
$('body').click(function () {
|
||||
$('.hints').popover("hide");
|
||||
});
|
||||
});
|
||||
$(document).ready(function () {
|
||||
if ($(window).width() > 1000) {
|
||||
$('[data-toggle="popover"]').popover();
|
||||
$('.hints').popover("show");
|
||||
}
|
||||
webSocket.on('update_server_details', function (data) {
|
||||
dates.push(data.created);
|
||||
players.push(data.online);
|
||||
cpu.push(data.cpu)
|
||||
ram.push(data.mem_percent)
|
||||
data = {
|
||||
labels: dates,
|
||||
datasets: [{
|
||||
label: "Players",
|
||||
data: players,
|
||||
borderColor: [
|
||||
'rgba(136, 98, 224, .5)',
|
||||
],
|
||||
borderWidth: 2,
|
||||
lineTension: 0,
|
||||
},
|
||||
{
|
||||
label: "MEM",
|
||||
data: ram,
|
||||
borderColor: [
|
||||
'rgba(33, 150, 243, .5)',
|
||||
],
|
||||
borderWidth: 2,
|
||||
lineTension: 0,
|
||||
},
|
||||
{
|
||||
label: "CPU",
|
||||
data: cpu,
|
||||
borderColor: [
|
||||
'rgba(255, 175, 0, .5)',
|
||||
],
|
||||
borderWidth: 2,
|
||||
lineTension: 0,
|
||||
},
|
||||
]
|
||||
}
|
||||
if (!zoomed) {
|
||||
hist_chart.options.scales.x.min = dates.length - 200;
|
||||
}
|
||||
hist_chart.update(data)
|
||||
});
|
||||
|
||||
$(".reset-button").click(function () {
|
||||
console.log("resetting zoom");
|
||||
zoomed = false;
|
||||
hist_chart.resetZoom();
|
||||
document.getElementById("reset-button").style.visibility = "hidden";
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
{% end %}
|
@ -65,9 +65,9 @@
|
||||
<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['downloading'] %}
|
||||
{% elif data['importing'] %}
|
||||
<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: 12rem; white-space: nowrap;" class="btn btn-secondary m-1 flex-grow-1 disabled"><i class="fa fa-spinner fa-spin"></i> {{ translate('serverTerm', 'downloading',
|
||||
<button onclick="" id="start-btn" style="max-width: 12rem; white-space: nowrap;" class="btn btn-secondary m-1 flex-grow-1 disabled"><i class="fa fa-spinner fa-spin"></i> {{ translate('serverTerm', 'importing',
|
||||
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>
|
||||
|
16
app/migrations/20220819_role_manager.py
Normal file
16
app/migrations/20220819_role_manager.py
Normal file
@ -0,0 +1,16 @@
|
||||
# Generated by database migrator
|
||||
import peewee
|
||||
|
||||
|
||||
def migrate(migrator, database, **kwargs):
|
||||
migrator.add_columns("roles", manager=peewee.IntegerField(null=True))
|
||||
"""
|
||||
Write your migrations here.
|
||||
"""
|
||||
|
||||
|
||||
def rollback(migrator, database, **kwargs):
|
||||
migrator.drop_columns("roles", ["manager"])
|
||||
"""
|
||||
Write your rollback migrations here.
|
||||
"""
|
16
app/migrations/20220819_user_manager.py
Normal file
16
app/migrations/20220819_user_manager.py
Normal file
@ -0,0 +1,16 @@
|
||||
# Generated by database migrator
|
||||
import peewee
|
||||
|
||||
|
||||
def migrate(migrator, database, **kwargs):
|
||||
migrator.add_columns("users", manager=peewee.IntegerField(null=True))
|
||||
"""
|
||||
Write your migrations here.
|
||||
"""
|
||||
|
||||
|
||||
def rollback(migrator, database, **kwargs):
|
||||
migrator.drop_columns("users", ["manager"])
|
||||
"""
|
||||
Write your rollback migrations here.
|
||||
"""
|
16
app/migrations/20220820_quota.py
Normal file
16
app/migrations/20220820_quota.py
Normal file
@ -0,0 +1,16 @@
|
||||
# Generated by database migrator
|
||||
import peewee
|
||||
|
||||
|
||||
def migrate(migrator, database, **kwargs):
|
||||
migrator.add_columns("servers", created_by=peewee.IntegerField(default=-100))
|
||||
"""
|
||||
Write your migrations here.
|
||||
"""
|
||||
|
||||
|
||||
def rollback(migrator, database, **kwargs):
|
||||
migrator.drop_columns("servers", ["created_by"])
|
||||
"""
|
||||
Write your rollback migrations here.
|
||||
"""
|
20
app/migrations/20220820_user_crafty.py
Normal file
20
app/migrations/20220820_user_crafty.py
Normal file
@ -0,0 +1,20 @@
|
||||
# Generated by database migrator
|
||||
import peewee
|
||||
|
||||
|
||||
def migrate(migrator, database, **kwargs):
|
||||
migrator.drop_columns("user_crafty", ["created_server"])
|
||||
migrator.drop_columns("user_crafty", ["created_user"])
|
||||
migrator.drop_columns("user_crafty", ["created_role"])
|
||||
"""
|
||||
Write your migrations here.
|
||||
"""
|
||||
|
||||
|
||||
def rollback(migrator, database, **kwargs):
|
||||
migrator.add_columns("user_crafty", created_server=peewee.IntegerField(default=0))
|
||||
migrator.add_columns("user_crafty", created_user=peewee.IntegerField(default=0))
|
||||
migrator.add_columns("user_crafty", created_role=peewee.IntegerField(default=0))
|
||||
"""
|
||||
Write your rollback migrations here.
|
||||
"""
|
16
app/migrations/20220821_shutdown_timeout.py
Normal file
16
app/migrations/20220821_shutdown_timeout.py
Normal file
@ -0,0 +1,16 @@
|
||||
# Generated by database migrator
|
||||
import peewee
|
||||
|
||||
|
||||
def migrate(migrator, database, **kwargs):
|
||||
migrator.add_columns("servers", shutdown_timeout=peewee.IntegerField(default=60))
|
||||
"""
|
||||
Write your migrations here.
|
||||
"""
|
||||
|
||||
|
||||
def rollback(migrator, database, **kwargs):
|
||||
migrator.drop_columns("servers", ["shutdown_timeout"])
|
||||
"""
|
||||
Write your rollback migrations here.
|
||||
"""
|
17
app/migrations/stats/20220817_schedule_rename_downloading.py
Normal file
17
app/migrations/stats/20220817_schedule_rename_downloading.py
Normal file
@ -0,0 +1,17 @@
|
||||
# Generated by database migrator
|
||||
import peewee
|
||||
|
||||
|
||||
def migrate(migrator, database, **kwargs):
|
||||
migrator.rename_column("server_stats", "downloading", "importing")
|
||||
|
||||
"""
|
||||
Write your migrations here.
|
||||
"""
|
||||
|
||||
|
||||
def rollback(migrator, database, **kwargs):
|
||||
migrator.rename_column("server_stats", "importing", "downloading")
|
||||
"""
|
||||
Write your rollback migrations here.
|
||||
"""
|
@ -245,7 +245,8 @@
|
||||
"roleUsers": "Role Users: ",
|
||||
"serverAccess": "Access?",
|
||||
"serverName": "Server Name",
|
||||
"serversDesc": "servers this role is allowed to access"
|
||||
"serversDesc": "servers this role is allowed to access",
|
||||
"selectManager": "Select a manager for this Role"
|
||||
},
|
||||
"serverBackups": {
|
||||
"backupAtMidnight": "Auto-backup at midnight?",
|
||||
@ -324,7 +325,10 @@
|
||||
"stopBeforeDeleting": "Please stop the server before deleting it",
|
||||
"update": "Update Executable",
|
||||
"yesDelete": "Yes, delete",
|
||||
"yesDeleteFiles": "Yes, delete files"
|
||||
"yesDeleteFiles": "Yes, delete files",
|
||||
"shutdownTimeout": "Shutdown Timeout",
|
||||
"timeoutExplain1": "How long Crafty will wait for your server to shutdown after executing the",
|
||||
"timeoutExplain2": "command before it forces the process down."
|
||||
},
|
||||
"serverConfigHelp": {
|
||||
"desc": "Here is where you can change the configuration of your server",
|
||||
@ -351,7 +355,8 @@
|
||||
"playerControls": "Player Management",
|
||||
"schedule": "Schedule",
|
||||
"serverDetails": "Server Details",
|
||||
"terminal": "Terminal"
|
||||
"terminal": "Terminal",
|
||||
"metrics": "Metrics"
|
||||
},
|
||||
"serverFiles": {
|
||||
"clickUpload": "Click here to select your files",
|
||||
@ -463,7 +468,7 @@
|
||||
"serverTerm": {
|
||||
"commandInput": "Enter your command",
|
||||
"delay-explained": "The service/agent has recently started and is delaying the start of the minecraft server instance",
|
||||
"downloading": "Downloading...",
|
||||
"importing": "Importing...",
|
||||
"restart": "Restart",
|
||||
"sendCommand": "Send command",
|
||||
"start": "Start",
|
||||
@ -472,6 +477,11 @@
|
||||
"stopScroll": "Stop Auto Scrolling",
|
||||
"updating": "Updating..."
|
||||
},
|
||||
"serverMetrics": {
|
||||
"resetZoom": "Reset Zoom",
|
||||
"zoomHint1": "To zoom on the graph hold your shift key then use your scroll wheel.",
|
||||
"zoomHint2": "Alternatively hold the shift key then click and drag the area you'd like to zoom in on."
|
||||
},
|
||||
"serverWizard": {
|
||||
"absoluteServerPath": "Absolute path to your server",
|
||||
"absoluteZipPath": "Absolute path to your server",
|
||||
@ -556,6 +566,8 @@
|
||||
"userRoles": "User Roles",
|
||||
"userRolesDesc": "Roles this user is a member of.",
|
||||
"userSettings": "User Settings",
|
||||
"uses": "Number of uses allowed (-1==No Limit)"
|
||||
"uses": "Number of uses allowed (-1==No Limit)",
|
||||
"manager": "Manager",
|
||||
"selectManager": "Select Manager for User"
|
||||
}
|
||||
}
|
||||
}
|
4
main.py
4
main.py
@ -14,6 +14,7 @@ from app.classes.shared.import3 import Import3
|
||||
from app.classes.shared.console import Console
|
||||
from app.classes.shared.helpers import Helpers
|
||||
from app.classes.models.users import HelperUsers
|
||||
from app.classes.shared.import_helper import ImportHelpers
|
||||
|
||||
console = Console()
|
||||
helper = Helpers()
|
||||
@ -135,8 +136,9 @@ if __name__ == "__main__":
|
||||
else:
|
||||
Console.debug("Existing install detected")
|
||||
file_helper = FileHelpers(helper)
|
||||
import_helper = ImportHelpers(helper, file_helper)
|
||||
# now the tables are created, we can load the tasks_manager and server controller
|
||||
controller = Controller(database, helper, file_helper)
|
||||
controller = Controller(database, helper, file_helper, import_helper)
|
||||
import3 = Import3(helper, controller)
|
||||
tasks_manager = TasksManager(helper, controller)
|
||||
tasks_manager.start_webserver()
|
||||
|
Loading…
Reference in New Issue
Block a user