This commit is contained in:
2025-01-14 15:16:03 +03:00
parent 6a3fe2d4f2
commit f9ce231443
11 changed files with 178 additions and 1 deletions

4
.gitignore vendored
View File

@@ -1,3 +1,7 @@
server/content
server/token.txt
updater/mods
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2025 depish
Copyright (c) 2025 Leonov Artur <depish.eskry@yandex.ru>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

3
server/config.json Normal file
View File

@@ -0,0 +1,3 @@
{
"content": "./content"
}

2
server/requirments.txt Normal file
View File

@@ -0,0 +1,2 @@
fastapi
uvicorn

54
server/server.py Normal file
View File

@@ -0,0 +1,54 @@
from fastapi import FastAPI, Request, Header, Depends, Response, HTTPException
from fastapi.responses import FileResponse
import os
import json
from pathlib import Path
config_path: Path = Path("./config.json")
config: dict = {}
with open(config_path, "r") as f:
config = json.load(f)
CONTENT_PATH: Path = Path(config["content"]).resolve()
MODS_PATH: Path = CONTENT_PATH / "mods"
RESOURCEPACKS_PATH: Path = CONTENT_PATH / "resourcepacks"
if not CONTENT_PATH.exists():
CONTENT_PATH.mkdir(parents=True)
MODS_PATH.mkdir()
RESOURCEPACKS_PATH.mkdir()
# Токен для доступа к сервису
TOKEN: str = None
TOKENFILE = Path(__file__).parent / "token.txt"
if not TOKENFILE.exists():
TOKEN = os.urandom(48).hex()
with open(TOKENFILE, "w") as f:
f.write(TOKEN)
else:
with open(TOKENFILE, "r") as f:
TOKEN = f.read()
# Функция для проверки токена
def check_token(authorization: str = Header(...)):
if authorization != TOKEN:
raise HTTPException(status_code=401, detail="Неверный токен")
app = FastAPI()
@app.get("/mods/files")
async def get_files():
# Получаем список всех файлов в указанной директории
files = os.listdir(str(MODS_PATH))
return {"files": files}
@app.get("/mods/download/{filename}")
async def download_file(filename: str):
file_path: Path = MODS_PATH / filename
if not file_path.exists():
return {"error": f"Файл {filename} не найден"}
return FileResponse(path=file_path, filename=str(filename), media_type="application/octet-stream")

4
server/start-server.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/bash
source .venv/bin/activate
uvicorn main:app --host 0.0.0.0 --port 7779

5
updater/config.json Normal file
View File

@@ -0,0 +1,5 @@
{
"minecraft": "./",
"server.url": "http://localhost:7779",
"token": ""
}

1
updater/requirments.txt Normal file
View File

@@ -0,0 +1 @@
requests

21
updater/update.bat Normal file
View File

@@ -0,0 +1,21 @@
@echo off
:: Если это git репозиторий то автоматически обновляемся
IF EXIST .git (
git pull
)
:: Проверяем существование виртуального окружения
IF EXIST .\venv (
:: Активируем виртуальное окружение
call .venv\Scripts\activate.bat
) ELSE (
:: Создаем новое виртуальное окружение
python -m venv .venv
call .venv\Scripts\activate.bat
pip3 install -r requirements.txt
)
:: Запускаем скрипт updater.py
python .\updater.py

15
updater/update.sh Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/bash
if [ -d ".git" ]; then
git pull
fi
if [ ! -d ".venv" ]; then
python3 -m venv .venv
source .venv/bin/activate
pip3 install -r ./requirments.txt
else
source .venv/bin/activate
fi
python3 ./updater.py

68
updater/updater.py Normal file
View File

@@ -0,0 +1,68 @@
from pathlib import Path
import json
import os
import requests
CONFIG_FILE: Path = Path(__file__).parent / "config.json"
CONFIG: dict = {}
with CONFIG_FILE.open() as f:
CONFIG = json.load(f)
TOKEN: str = CONFIG["token"]
MINECRAFT_FOLDER: Path = Path(CONFIG["minecraft"]).resolve()
MODS_FOLDER: Path = MINECRAFT_FOLDER / "mods"
# Создаем папку модов если ее нет
if not MODS_FOLDER.exists():
MODS_FOLDER.mkdir(parents=True)
CURRENT_MODS: list["Path"] = [Path(p).name for p in os.listdir(MODS_FOLDER)]
def get_mod_list():
headers = {'Authorization': TOKEN}
response = requests.get(f'{CONFIG["server.url"]}/mods/files', headers=headers)
if response.status_code == 200:
return response.json().get('files', [])
else:
print(f'Ошибка при получении списка файлов: {response.text}')
return []
def download_file(filename: str, dest: Path):
headers = {'Authorization': TOKEN}
url = f'{CONFIG["server.url"]}/mods/download/{filename}'
response = requests.get(url, headers=headers)
if response.status_code == 200:
with open(dest, 'wb') as f:
f.write(response.content)
print(f'Файл {filename} успешно загружен.')
else:
print(f'Не удалось загрузить файл {filename}: {response.text}')
ACTUAL_MODS: list["str"] = get_mod_list()
TO_DELETE: list["Path"] = []
TO_DOWNLOAD: list["str"] = []
# Проверяем лишние или старые моды
for cur_mod in CURRENT_MODS:
# Проверяем лишние или старые моды
if cur_mod not in ACTUAL_MODS:
TO_DELETE.append(MODS_FOLDER / cur_mod)
for amod in ACTUAL_MODS:
if amod not in CURRENT_MODS:
TO_DOWNLOAD.append(amod)
# Применение действий
# Удаление лишнего
for file in TO_DELETE:
print(f"Удаление {amod}")
os.remove(str(file))
# Скачивание нужного
for filename in TO_DOWNLOAD:
download_file(filename, MODS_FOLDER / filename)