mcmanager 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcmanager-0.1.0/MANIFEST.in +5 -0
- mcmanager-0.1.0/PKG-INFO +106 -0
- mcmanager-0.1.0/README.md +90 -0
- mcmanager-0.1.0/mcmanager/__init__.py +0 -0
- mcmanager-0.1.0/mcmanager/asgi.py +16 -0
- mcmanager-0.1.0/mcmanager/cli.py +115 -0
- mcmanager-0.1.0/mcmanager/configs/server.properties +33 -0
- mcmanager-0.1.0/mcmanager/console/__init__.py +0 -0
- mcmanager-0.1.0/mcmanager/console/admin.py +29 -0
- mcmanager-0.1.0/mcmanager/console/apps.py +22 -0
- mcmanager-0.1.0/mcmanager/console/models.py +112 -0
- mcmanager-0.1.0/mcmanager/console/static/css/font-awesome.css +2337 -0
- mcmanager-0.1.0/mcmanager/console/static/css/font-awesome.min.css +4 -0
- mcmanager-0.1.0/mcmanager/console/static/css/styles.css +3 -0
- mcmanager-0.1.0/mcmanager/console/static/css/tailwind.css +743 -0
- mcmanager-0.1.0/mcmanager/console/static/css/toastify.min.css +15 -0
- mcmanager-0.1.0/mcmanager/console/static/fonts/fontawesome-webfont.ttf +0 -0
- mcmanager-0.1.0/mcmanager/console/static/fonts/fontawesome-webfont.woff +0 -0
- mcmanager-0.1.0/mcmanager/console/static/fonts/fontawesome-webfont.woff2 +0 -0
- mcmanager-0.1.0/mcmanager/console/static/img/favicon.ico +0 -0
- mcmanager-0.1.0/mcmanager/console/static/js/toastify-js.js +15 -0
- mcmanager-0.1.0/mcmanager/console/templates/console/index.html +223 -0
- mcmanager-0.1.0/mcmanager/console/templates/index.html +42 -0
- mcmanager-0.1.0/mcmanager/console/tests.py +3 -0
- mcmanager-0.1.0/mcmanager/console/urls.py +14 -0
- mcmanager-0.1.0/mcmanager/console/views.py +175 -0
- mcmanager-0.1.0/mcmanager/settings.py +158 -0
- mcmanager-0.1.0/mcmanager/urls.py +11 -0
- mcmanager-0.1.0/mcmanager/wsgi.py +16 -0
- mcmanager-0.1.0/mcmanager.egg-info/PKG-INFO +106 -0
- mcmanager-0.1.0/mcmanager.egg-info/SOURCES.txt +36 -0
- mcmanager-0.1.0/mcmanager.egg-info/dependency_links.txt +1 -0
- mcmanager-0.1.0/mcmanager.egg-info/entry_points.txt +2 -0
- mcmanager-0.1.0/mcmanager.egg-info/requires.txt +3 -0
- mcmanager-0.1.0/mcmanager.egg-info/top_level.txt +1 -0
- mcmanager-0.1.0/pyproject.toml +36 -0
- mcmanager-0.1.0/requirements.txt +7 -0
- mcmanager-0.1.0/setup.cfg +4 -0
mcmanager-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mcmanager
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Django-based web interface to manage Minecraft servers on a VPS
|
|
5
|
+
License: MIT
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: Framework :: Django
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
10
|
+
Classifier: Topic :: Games/Entertainment
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: Django<5.2.0,>=4.2.0
|
|
14
|
+
Requires-Dist: psutil>=5.8.0
|
|
15
|
+
Requires-Dist: whitenoise>=6.0.0
|
|
16
|
+
|
|
17
|
+
# mcmanager (BETA)
|
|
18
|
+
|
|
19
|
+
Um painel web simples baseado em Django para gerenciar servidores Minecraft diretamente na sua VPS Linux.
|
|
20
|
+
|
|
21
|
+
## Instalação
|
|
22
|
+
|
|
23
|
+
### 1. Instalar o Java 8 (Necessário para o Minecraft)
|
|
24
|
+
|
|
25
|
+
```console
|
|
26
|
+
sudo apt-get update
|
|
27
|
+
sudo apt-get install openjdk-8-jre-headless
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 2. Instalar o mcmanager do PyPI
|
|
31
|
+
|
|
32
|
+
```console
|
|
33
|
+
pip install mcmanager
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 3. Inicializar e rodar o painel
|
|
37
|
+
|
|
38
|
+
```console
|
|
39
|
+
# Inicializa o banco de dados e cria os diretórios na pasta ~/.mcmanager
|
|
40
|
+
mcmanager init
|
|
41
|
+
|
|
42
|
+
# Cria um usuário administrador
|
|
43
|
+
mcmanager createsuperuser
|
|
44
|
+
|
|
45
|
+
# Inicia o painel
|
|
46
|
+
mcmanager run
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Pronto! Acesse `http://sua-vps-ip:8000/admin/` para logar com o superusuário criado e começar a gerenciar seus servidores.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Estrutura de Diretórios e Dados
|
|
54
|
+
|
|
55
|
+
Por padrão, todos os dados do painel ficam armazenados de forma isolada na home do usuário:
|
|
56
|
+
- `~/.mcmanager/db.sqlite3` (Banco de dados do painel)
|
|
57
|
+
- `~/.mcmanager/jar/` (Coloque seus arquivos `.jar` de servidor aqui, ex: `spigot.jar`, `vanilla.jar`)
|
|
58
|
+
- `~/.mcmanager/servers/` (Diretório onde cada servidor criado será executado)
|
|
59
|
+
- `~/.mcmanager/configs/` (Onde fica o `server.properties` padrão)
|
|
60
|
+
- `~/.mcmanager/staticfiles/` (Arquivos estáticos compilados do painel)
|
|
61
|
+
|
|
62
|
+
### Customizações por Variáveis de Ambiente
|
|
63
|
+
|
|
64
|
+
Você pode ajustar o comportamento do painel definindo variáveis de ambiente antes de executar o comando `mcmanager`:
|
|
65
|
+
|
|
66
|
+
* **`MCMANAGER_DATA_DIR`**: Altera a pasta padrão onde os servidores e banco de dados são salvos (padrão: `~/.mcmanager`).
|
|
67
|
+
* **`MCMANAGER_JAVA_BIN`**: Especifica o caminho binário do Java (padrão: `/usr/lib/jvm/java-8-openjdk-amd64/bin/java`). Use `whereis java` para encontrar o caminho correto na sua VPS.
|
|
68
|
+
* **`MCMANAGER_ALLOWED_HOSTS`**: Lista de hosts permitidos separados por vírgula (padrão: `*`).
|
|
69
|
+
* **`MCMANAGER_DEBUG`**: Define se o painel roda em modo debug (`True` ou `False`).
|
|
70
|
+
|
|
71
|
+
Exemplo definindo um caminho diferente de Java e iniciando:
|
|
72
|
+
```console
|
|
73
|
+
export MCMANAGER_JAVA_BIN="/usr/bin/java"
|
|
74
|
+
mcmanager run
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Desenvolvimento Local
|
|
80
|
+
|
|
81
|
+
Se você deseja contribuir ou modificar o código localmente:
|
|
82
|
+
|
|
83
|
+
1. Clone o repositório.
|
|
84
|
+
2. Crie e ative um ambiente virtual.
|
|
85
|
+
3. Instale as dependências e o pacote local no modo editável:
|
|
86
|
+
```console
|
|
87
|
+
pip install -r requirements.txt
|
|
88
|
+
pip install -e .
|
|
89
|
+
```
|
|
90
|
+
4. Ao rodar `python manage.py runserver`, o painel rodará em modo debug local e usará a própria pasta do projeto para salvar os arquivos de desenvolvimento.
|
|
91
|
+
|
|
92
|
+
### Comandos de Desenvolvimento Úteis
|
|
93
|
+
|
|
94
|
+
* **Formatar código:**
|
|
95
|
+
```console
|
|
96
|
+
python manage.py format_code
|
|
97
|
+
```
|
|
98
|
+
* **Gerar nova Secret Key de desenvolvimento:**
|
|
99
|
+
```console
|
|
100
|
+
python manage.py generate_secret_key
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Capturas de Tela
|
|
104
|
+
|
|
105
|
+

|
|
106
|
+

|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# mcmanager (BETA)
|
|
2
|
+
|
|
3
|
+
Um painel web simples baseado em Django para gerenciar servidores Minecraft diretamente na sua VPS Linux.
|
|
4
|
+
|
|
5
|
+
## Instalação
|
|
6
|
+
|
|
7
|
+
### 1. Instalar o Java 8 (Necessário para o Minecraft)
|
|
8
|
+
|
|
9
|
+
```console
|
|
10
|
+
sudo apt-get update
|
|
11
|
+
sudo apt-get install openjdk-8-jre-headless
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### 2. Instalar o mcmanager do PyPI
|
|
15
|
+
|
|
16
|
+
```console
|
|
17
|
+
pip install mcmanager
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### 3. Inicializar e rodar o painel
|
|
21
|
+
|
|
22
|
+
```console
|
|
23
|
+
# Inicializa o banco de dados e cria os diretórios na pasta ~/.mcmanager
|
|
24
|
+
mcmanager init
|
|
25
|
+
|
|
26
|
+
# Cria um usuário administrador
|
|
27
|
+
mcmanager createsuperuser
|
|
28
|
+
|
|
29
|
+
# Inicia o painel
|
|
30
|
+
mcmanager run
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Pronto! Acesse `http://sua-vps-ip:8000/admin/` para logar com o superusuário criado e começar a gerenciar seus servidores.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Estrutura de Diretórios e Dados
|
|
38
|
+
|
|
39
|
+
Por padrão, todos os dados do painel ficam armazenados de forma isolada na home do usuário:
|
|
40
|
+
- `~/.mcmanager/db.sqlite3` (Banco de dados do painel)
|
|
41
|
+
- `~/.mcmanager/jar/` (Coloque seus arquivos `.jar` de servidor aqui, ex: `spigot.jar`, `vanilla.jar`)
|
|
42
|
+
- `~/.mcmanager/servers/` (Diretório onde cada servidor criado será executado)
|
|
43
|
+
- `~/.mcmanager/configs/` (Onde fica o `server.properties` padrão)
|
|
44
|
+
- `~/.mcmanager/staticfiles/` (Arquivos estáticos compilados do painel)
|
|
45
|
+
|
|
46
|
+
### Customizações por Variáveis de Ambiente
|
|
47
|
+
|
|
48
|
+
Você pode ajustar o comportamento do painel definindo variáveis de ambiente antes de executar o comando `mcmanager`:
|
|
49
|
+
|
|
50
|
+
* **`MCMANAGER_DATA_DIR`**: Altera a pasta padrão onde os servidores e banco de dados são salvos (padrão: `~/.mcmanager`).
|
|
51
|
+
* **`MCMANAGER_JAVA_BIN`**: Especifica o caminho binário do Java (padrão: `/usr/lib/jvm/java-8-openjdk-amd64/bin/java`). Use `whereis java` para encontrar o caminho correto na sua VPS.
|
|
52
|
+
* **`MCMANAGER_ALLOWED_HOSTS`**: Lista de hosts permitidos separados por vírgula (padrão: `*`).
|
|
53
|
+
* **`MCMANAGER_DEBUG`**: Define se o painel roda em modo debug (`True` ou `False`).
|
|
54
|
+
|
|
55
|
+
Exemplo definindo um caminho diferente de Java e iniciando:
|
|
56
|
+
```console
|
|
57
|
+
export MCMANAGER_JAVA_BIN="/usr/bin/java"
|
|
58
|
+
mcmanager run
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Desenvolvimento Local
|
|
64
|
+
|
|
65
|
+
Se você deseja contribuir ou modificar o código localmente:
|
|
66
|
+
|
|
67
|
+
1. Clone o repositório.
|
|
68
|
+
2. Crie e ative um ambiente virtual.
|
|
69
|
+
3. Instale as dependências e o pacote local no modo editável:
|
|
70
|
+
```console
|
|
71
|
+
pip install -r requirements.txt
|
|
72
|
+
pip install -e .
|
|
73
|
+
```
|
|
74
|
+
4. Ao rodar `python manage.py runserver`, o painel rodará em modo debug local e usará a própria pasta do projeto para salvar os arquivos de desenvolvimento.
|
|
75
|
+
|
|
76
|
+
### Comandos de Desenvolvimento Úteis
|
|
77
|
+
|
|
78
|
+
* **Formatar código:**
|
|
79
|
+
```console
|
|
80
|
+
python manage.py format_code
|
|
81
|
+
```
|
|
82
|
+
* **Gerar nova Secret Key de desenvolvimento:**
|
|
83
|
+
```console
|
|
84
|
+
python manage.py generate_secret_key
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Capturas de Tela
|
|
88
|
+
|
|
89
|
+

|
|
90
|
+

|
|
File without changes
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ASGI config for mcmanager project.
|
|
3
|
+
|
|
4
|
+
It exposes the ASGI callable as a module-level variable named ``application``.
|
|
5
|
+
|
|
6
|
+
For more information on this file, see
|
|
7
|
+
https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
|
|
12
|
+
from django.core.asgi import get_asgi_application
|
|
13
|
+
|
|
14
|
+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mcmanager.settings')
|
|
15
|
+
|
|
16
|
+
application = get_asgi_application()
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
import argparse
|
|
4
|
+
import shutil
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
def get_data_dir():
|
|
8
|
+
"""Determina o diretório de dados com base na variável de ambiente ou home"""
|
|
9
|
+
if os.environ.get("MCMANAGER_DATA_DIR"):
|
|
10
|
+
return Path(os.environ["MCMANAGER_DATA_DIR"]).resolve()
|
|
11
|
+
|
|
12
|
+
debug_mode = os.environ.get("MCMANAGER_DEBUG", "False").lower() in ("true", "1", "yes")
|
|
13
|
+
if debug_mode:
|
|
14
|
+
# Se estiver em modo debug local, usa a pasta do próprio projeto
|
|
15
|
+
return Path(__file__).resolve().parent.parent
|
|
16
|
+
else:
|
|
17
|
+
return Path.home() / ".mcmanager"
|
|
18
|
+
|
|
19
|
+
def main():
|
|
20
|
+
parser = argparse.ArgumentParser(
|
|
21
|
+
description="mcmanager - Painel de Controle de Servidores Minecraft"
|
|
22
|
+
)
|
|
23
|
+
subparsers = parser.add_subparsers(dest="command", required=True, help="Subcomando a executar")
|
|
24
|
+
|
|
25
|
+
# Comando init
|
|
26
|
+
init_parser = subparsers.add_parser("init", help="Inicializa o diretório de dados, banco e arquivos padrões")
|
|
27
|
+
|
|
28
|
+
# Comando run
|
|
29
|
+
run_parser = subparsers.add_parser("run", help="Inicia o servidor web do painel")
|
|
30
|
+
run_parser.add_argument("--host", default="0.0.0.0", help="Endereço IP para escutar (padrão: 0.0.0.0)")
|
|
31
|
+
run_parser.add_argument("--port", type=int, default=8000, help="Porta para escutar (padrão: 8000)")
|
|
32
|
+
|
|
33
|
+
# Comando createsuperuser
|
|
34
|
+
createsuperuser_parser = subparsers.add_parser(
|
|
35
|
+
"createsuperuser", help="Cria um usuário administrador para o painel"
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# Comando shell
|
|
39
|
+
shell_parser = subparsers.add_parser("shell", help="Inicia o console interativo do Django")
|
|
40
|
+
|
|
41
|
+
args = parser.parse_args()
|
|
42
|
+
|
|
43
|
+
# 1. Obter e criar estrutura de dados do usuário
|
|
44
|
+
data_dir = get_data_dir()
|
|
45
|
+
data_dir.mkdir(parents=True, exist_ok=True)
|
|
46
|
+
(data_dir / "servers").mkdir(exist_ok=True)
|
|
47
|
+
(data_dir / "jar").mkdir(exist_ok=True)
|
|
48
|
+
(data_dir / "configs").mkdir(exist_ok=True)
|
|
49
|
+
|
|
50
|
+
# 2. Copiar server.properties padrão se não existir
|
|
51
|
+
properties_dest = data_dir / "configs" / "server.properties"
|
|
52
|
+
if not properties_dest.exists():
|
|
53
|
+
# Tenta carregar usando importlib.resources (PEP 517)
|
|
54
|
+
copied = False
|
|
55
|
+
try:
|
|
56
|
+
from importlib import resources
|
|
57
|
+
# Python 3.9+
|
|
58
|
+
source_path = resources.files("mcmanager").joinpath("configs/server.properties")
|
|
59
|
+
with source_path.open("rb") as fsrc:
|
|
60
|
+
with open(properties_dest, "wb") as fdst:
|
|
61
|
+
shutil.copyfileobj(fsrc, fdst)
|
|
62
|
+
copied = True
|
|
63
|
+
except Exception:
|
|
64
|
+
pass
|
|
65
|
+
|
|
66
|
+
if not copied:
|
|
67
|
+
# Fallback para caminho relativo
|
|
68
|
+
source_path = Path(__file__).resolve().parent / "configs" / "server.properties"
|
|
69
|
+
if source_path.exists():
|
|
70
|
+
shutil.copy(source_path, properties_dest)
|
|
71
|
+
copied = True
|
|
72
|
+
|
|
73
|
+
if copied:
|
|
74
|
+
print(f"[*] Arquivo server.properties padrão copiado para: {properties_dest}")
|
|
75
|
+
else:
|
|
76
|
+
print("[!] Aviso: Não foi possível copiar o arquivo server.properties padrão.")
|
|
77
|
+
|
|
78
|
+
# 3. Configurar variáveis de ambiente do Django
|
|
79
|
+
os.environ.setdefault("MCMANAGER_DATA_DIR", str(data_dir))
|
|
80
|
+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mcmanager.settings")
|
|
81
|
+
|
|
82
|
+
# 4. Inicializar Django
|
|
83
|
+
import django
|
|
84
|
+
django.setup()
|
|
85
|
+
|
|
86
|
+
from django.core.management import call_command
|
|
87
|
+
|
|
88
|
+
# 5. Executar os subcomandos
|
|
89
|
+
if args.command == "init":
|
|
90
|
+
print("[*] Executando migrações do banco de dados...")
|
|
91
|
+
call_command("migrate", interactive=False)
|
|
92
|
+
print("[*] Coletando arquivos estáticos...")
|
|
93
|
+
call_command("collectstatic", "--noinput", "--clear")
|
|
94
|
+
print("\n[+] Inicialização concluída com sucesso!")
|
|
95
|
+
print(f"[+] Seus dados estão em: {data_dir}")
|
|
96
|
+
print("[+] Agora você pode rodar: mcmanager createsuperuser")
|
|
97
|
+
|
|
98
|
+
elif args.command == "run":
|
|
99
|
+
bind_address = f"{args.host}:{args.port}"
|
|
100
|
+
print(f"[*] Iniciando servidor mcmanager em http://{bind_address}/")
|
|
101
|
+
print("[*] Pressione CTRL+C para encerrar.")
|
|
102
|
+
# Em produção, rodamos sem autoreload
|
|
103
|
+
call_command("runserver", "--noreload", "--nostatic", bind_address)
|
|
104
|
+
|
|
105
|
+
elif args.command == "createsuperuser":
|
|
106
|
+
try:
|
|
107
|
+
call_command("createsuperuser")
|
|
108
|
+
except KeyboardInterrupt:
|
|
109
|
+
print("\n[!] Operação cancelada.")
|
|
110
|
+
|
|
111
|
+
elif args.command == "shell":
|
|
112
|
+
call_command("shell")
|
|
113
|
+
|
|
114
|
+
if __name__ == "__main__":
|
|
115
|
+
main()
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#Minecraft server properties
|
|
2
|
+
#Wed Jul 10 19:30:06 UTC 2024
|
|
3
|
+
generator-settings=
|
|
4
|
+
op-permission-level=4
|
|
5
|
+
allow-nether=true
|
|
6
|
+
level-name=world
|
|
7
|
+
enable-query=false
|
|
8
|
+
allow-flight=true
|
|
9
|
+
announce-player-achievements=true
|
|
10
|
+
server-port=25566
|
|
11
|
+
level-type=DEFAULT
|
|
12
|
+
enable-rcon=false
|
|
13
|
+
force-gamemode=false
|
|
14
|
+
level-seed=
|
|
15
|
+
server-ip=
|
|
16
|
+
max-build-height=256
|
|
17
|
+
spawn-npcs=true
|
|
18
|
+
white-list=false
|
|
19
|
+
spawn-animals=true
|
|
20
|
+
hardcore=false
|
|
21
|
+
snooper-enabled=true
|
|
22
|
+
online-mode=false
|
|
23
|
+
resource-pack=
|
|
24
|
+
pvp=true
|
|
25
|
+
difficulty=1
|
|
26
|
+
enable-command-block=false
|
|
27
|
+
gamemode=0
|
|
28
|
+
player-idle-timeout=0
|
|
29
|
+
max-players=5
|
|
30
|
+
spawn-monsters=true
|
|
31
|
+
generate-structures=true
|
|
32
|
+
view-distance=10
|
|
33
|
+
motd=A Minecraft Server
|
|
File without changes
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
from django.contrib import admin
|
|
3
|
+
from django.http import HttpRequest
|
|
4
|
+
from django.http.response import HttpResponse
|
|
5
|
+
from .models import Server, Type
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@admin.register(Server)
|
|
9
|
+
class ServerAdmin(admin.ModelAdmin):
|
|
10
|
+
list_display = ('name', 'port', 'type', 'status')
|
|
11
|
+
exclude = ('jar', 'server_properties')
|
|
12
|
+
search_fields = ('name', 'port', 'type')
|
|
13
|
+
list_filter = ('type', 'status')
|
|
14
|
+
readonly_fields = ('status',)
|
|
15
|
+
|
|
16
|
+
def get_form(self, request, obj=..., change=..., **kwargs) -> Any:
|
|
17
|
+
if obj is None:
|
|
18
|
+
self.exclude = ('jar', 'server_properties')
|
|
19
|
+
self.readonly_fields = ('status',)
|
|
20
|
+
else:
|
|
21
|
+
self.exclude = None
|
|
22
|
+
self.readonly_fields = ('status', 'jar')
|
|
23
|
+
return super().get_form(request, obj, change, **kwargs)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@admin.register(Type)
|
|
27
|
+
class TypeAdmin(admin.ModelAdmin):
|
|
28
|
+
list_display = ('name',)
|
|
29
|
+
search_fields = ('name',)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from django.apps import AppConfig
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ConsoleConfig(AppConfig):
|
|
5
|
+
default_auto_field = 'django.db.models.BigAutoField'
|
|
6
|
+
name = 'mcmanager.console'
|
|
7
|
+
|
|
8
|
+
def ready(self) -> None:
|
|
9
|
+
try:
|
|
10
|
+
print('Checking server status...')
|
|
11
|
+
from .views import is_server_running
|
|
12
|
+
from .models import Server
|
|
13
|
+
for server in Server.objects.all():
|
|
14
|
+
if is_server_running(server.id):
|
|
15
|
+
server.status = True
|
|
16
|
+
server.save()
|
|
17
|
+
else:
|
|
18
|
+
server.status = False
|
|
19
|
+
server.save()
|
|
20
|
+
print('Server status checked!')
|
|
21
|
+
except Exception as e:
|
|
22
|
+
print(e)
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
import os
|
|
3
|
+
import shutil
|
|
4
|
+
from django.db import models
|
|
5
|
+
from django.conf import settings
|
|
6
|
+
from django.dispatch import receiver
|
|
7
|
+
from django.db.models.signals import post_save, pre_save, pre_delete
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_jar_files():
|
|
11
|
+
jar_dir = getattr(settings, 'JAR_DIR', os.path.join(settings.BASE_DIR, 'jar'))
|
|
12
|
+
if not os.path.exists(jar_dir):
|
|
13
|
+
os.makedirs(jar_dir)
|
|
14
|
+
return [(x, x) for x in os.listdir(jar_dir) if x.endswith('.jar')]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def get_default_server_prop():
|
|
18
|
+
configs_dir = getattr(settings, 'CONFIGS_DIR', os.path.join(settings.BASE_DIR, 'configs'))
|
|
19
|
+
with open(os.path.join(configs_dir, 'server.properties'), 'r', encoding='utf-8') as arq:
|
|
20
|
+
text = arq.read()
|
|
21
|
+
return text
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Type(models.Model):
|
|
25
|
+
name = models.CharField(max_length=100)
|
|
26
|
+
dependencies = models.JSONField(blank=True, null=True)
|
|
27
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
|
28
|
+
updated_at = models.DateTimeField(auto_now=True)
|
|
29
|
+
|
|
30
|
+
def __str__(self):
|
|
31
|
+
return self.name
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Server(models.Model):
|
|
35
|
+
name = models.CharField(max_length=100)
|
|
36
|
+
jar_template = models.CharField(max_length=100, choices=get_jar_files())
|
|
37
|
+
jar = models.CharField(max_length=100, blank=True, null=True)
|
|
38
|
+
# ip = models.GenericIPAddressField(blank=True, null=True)
|
|
39
|
+
port = models.IntegerField(default=25565)
|
|
40
|
+
memory_limit = models.IntegerField("Memory Limit (MB)", default=1024)
|
|
41
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
|
42
|
+
updated_at = models.DateTimeField(auto_now=True)
|
|
43
|
+
type = models.ForeignKey(
|
|
44
|
+
Type, on_delete=models.CASCADE, related_name='servers')
|
|
45
|
+
status = models.BooleanField(default=False)
|
|
46
|
+
server_properties = models.TextField(blank=True, null=True)
|
|
47
|
+
|
|
48
|
+
def __str__(self):
|
|
49
|
+
return self.name
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@receiver(pre_delete, sender=Server)
|
|
53
|
+
def pre_delete_server(sender, instance, **kwargs):
|
|
54
|
+
servers_dir = getattr(settings, 'SERVERS_DIR', os.path.join(settings.BASE_DIR, 'servers'))
|
|
55
|
+
server_path = os.path.join(servers_dir, f'server_{instance.id}')
|
|
56
|
+
if os.path.exists(server_path):
|
|
57
|
+
shutil.rmtree(server_path)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
pre_delete.connect(pre_delete_server, sender=Server)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@receiver(post_save, sender=Server)
|
|
64
|
+
def post_save_server(sender, instance, **kwargs):
|
|
65
|
+
servers_dir = getattr(settings, 'SERVERS_DIR', os.path.join(settings.BASE_DIR, 'servers'))
|
|
66
|
+
jar_dir = getattr(settings, 'JAR_DIR', os.path.join(settings.BASE_DIR, 'jar'))
|
|
67
|
+
configs_dir = getattr(settings, 'CONFIGS_DIR', os.path.join(settings.BASE_DIR, 'configs'))
|
|
68
|
+
|
|
69
|
+
server_path = os.path.join(servers_dir, f'server_{instance.id}')
|
|
70
|
+
properties_path = os.path.join(server_path, 'server.properties')
|
|
71
|
+
|
|
72
|
+
if not instance.jar:
|
|
73
|
+
instance.jar = str(instance.id) + "_" + instance.jar_template
|
|
74
|
+
os.makedirs(server_path, exist_ok=True)
|
|
75
|
+
shutil.copy(os.path.join(jar_dir, instance.jar_template), os.path.join(server_path, instance.jar))
|
|
76
|
+
shutil.copy(os.path.join(configs_dir, 'server.properties'), properties_path)
|
|
77
|
+
|
|
78
|
+
if instance.type.dependencies:
|
|
79
|
+
for dependency in instance.type.dependencies:
|
|
80
|
+
dep_source = os.path.join(jar_dir, dependency)
|
|
81
|
+
dep_dest = os.path.join(server_path, dependency)
|
|
82
|
+
if os.path.isdir(dep_source):
|
|
83
|
+
shutil.copytree(dep_source, dep_dest)
|
|
84
|
+
else:
|
|
85
|
+
shutil.copy(dep_source, dep_dest)
|
|
86
|
+
|
|
87
|
+
with open(os.path.join(server_path, 'eula.txt'), 'w', encoding='utf-8') as f:
|
|
88
|
+
f.write('eula=true')
|
|
89
|
+
|
|
90
|
+
new_server_properties = []
|
|
91
|
+
with open(properties_path, 'r', encoding='utf-8', errors='ignore') as f:
|
|
92
|
+
for line in f:
|
|
93
|
+
if line.startswith('server-port='):
|
|
94
|
+
new_server_properties.append(f'server-port={instance.port}\n')
|
|
95
|
+
else:
|
|
96
|
+
new_server_properties.append(line)
|
|
97
|
+
|
|
98
|
+
with open(properties_path, 'w', encoding='utf-8') as f:
|
|
99
|
+
f.write(''.join(new_server_properties))
|
|
100
|
+
|
|
101
|
+
with open(properties_path, 'r', encoding='utf-8', errors='ignore') as f:
|
|
102
|
+
text = f.read()
|
|
103
|
+
|
|
104
|
+
instance.server_properties = text
|
|
105
|
+
instance.save()
|
|
106
|
+
else:
|
|
107
|
+
with open(properties_path, 'w', encoding='utf-8') as f:
|
|
108
|
+
f.write(instance.server_properties)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
post_save.connect(post_save_server, sender=Server)
|
|
112
|
+
|