ForgeFix и новые фичи в интерфейсе
This commit is contained in:
+49
-10
@@ -19,7 +19,7 @@ from uvicorn.protocols.http.httptools_impl import HttpToolsProtocol
|
||||
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||
logging.getLogger("httpcore").setLevel(logging.WARNING)
|
||||
|
||||
from pack_manager import DATA_DIR, scan_pack, get_cached_manifest, PACKS_DIR
|
||||
from pack_manager import DATA_DIR, scan_pack, get_cached_manifest, PACKS_DIR, is_pack_disabled, get_pack_presets, get_merged_manifest
|
||||
from models import PackMeta
|
||||
from middleware import LoggingMiddleware
|
||||
from cli import parse_args, run_test_mode, run_production_mode, run_development_mode, run_sync_mode
|
||||
@@ -1026,7 +1026,9 @@ async def list_packs(
|
||||
"loader_type": meta.get("loader_type", "vanilla"),
|
||||
"loader_version": meta.get("loader_version"),
|
||||
"asset_index": meta.get("asset_index"),
|
||||
"description": description
|
||||
"description": description,
|
||||
"disabled": is_pack_disabled(pack_dir.name),
|
||||
"presets": get_pack_presets(pack_dir.name)
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to load pack meta for {pack_dir.name}: {e}")
|
||||
@@ -1047,7 +1049,8 @@ async def list_packs(
|
||||
async def get_pack_diff(
|
||||
pack_name: str,
|
||||
request: Request,
|
||||
current_user: dict = Depends(get_current_user) # Добавляем зависимость
|
||||
current_user: dict = Depends(get_current_user),
|
||||
preset: Optional[str] = None
|
||||
):
|
||||
"""Client sends: { "mods/jei.jar": "sha256_hash", ... }
|
||||
Server returns diff information
|
||||
@@ -1060,6 +1063,10 @@ async def get_pack_diff(
|
||||
detail="Для скачивания сборок требуется активная проходка. Обратитесь к администратору."
|
||||
)
|
||||
|
||||
# Check if pack is disabled
|
||||
if is_pack_disabled(pack_name):
|
||||
raise HTTPException(403, "Pack is disabled by administrator")
|
||||
|
||||
client_ip = request.client.host if request.client else "unknown"
|
||||
|
||||
# Читаем тело запроса
|
||||
@@ -1071,13 +1078,17 @@ async def get_pack_diff(
|
||||
|
||||
logger.info("Received diff request",
|
||||
pack=pack_name,
|
||||
preset=preset,
|
||||
client_files_count=len(body),
|
||||
client_ip=client_ip)
|
||||
|
||||
try:
|
||||
meta = get_cached_manifest(pack_name)
|
||||
if not meta:
|
||||
meta = await scan_pack(pack_name)
|
||||
if preset:
|
||||
meta = get_merged_manifest(pack_name, preset)
|
||||
else:
|
||||
meta = get_cached_manifest(pack_name)
|
||||
if not meta:
|
||||
meta = await scan_pack(pack_name)
|
||||
except FileNotFoundError:
|
||||
logger.warning("Pack not found", pack=pack_name, client_ip=client_ip)
|
||||
raise HTTPException(404, "Pack not found")
|
||||
@@ -1095,6 +1106,8 @@ async def get_pack_diff(
|
||||
client_hash = body.get(path)
|
||||
if client_hash is None or client_hash != entry.hash:
|
||||
url = f"/pack/{pack_name}/file/{path}"
|
||||
if preset:
|
||||
url += f"?preset={preset}"
|
||||
to_download.append({
|
||||
"path": path,
|
||||
"url": url,
|
||||
@@ -1127,6 +1140,9 @@ async def get_pack_diff(
|
||||
@app.get("/pack/{pack_name}")
|
||||
async def get_pack_manifest(pack_name: str, request: Request, current_user: dict = Depends(get_current_user)):
|
||||
"""Get pack manifest with caching"""
|
||||
if is_pack_disabled(pack_name):
|
||||
raise HTTPException(403, "Pack is disabled by administrator")
|
||||
|
||||
client_ip = request.client.host if request.client else "unknown"
|
||||
|
||||
cached_meta = get_cached_manifest(pack_name)
|
||||
@@ -1166,13 +1182,34 @@ async def get_pack_manifest(pack_name: str, request: Request, current_user: dict
|
||||
|
||||
|
||||
@app.get("/pack/{pack_name}/file/{file_path:path}")
|
||||
async def get_pack_file(pack_name: str, file_path: str, request: Request, current_user: dict = Depends(get_current_user)):
|
||||
"""Get a file from a pack"""
|
||||
async def get_pack_file(pack_name: str, file_path: str, request: Request, current_user: dict = Depends(get_current_user), preset: Optional[str] = None):
|
||||
"""Get a file from a pack. If preset is specified, try preset dir first, fall back to base."""
|
||||
if not has_permission(current_user["role"], Permissions.DOWNLOAD_PACK):
|
||||
raise HTTPException(403, "Requires active pass")
|
||||
full_path = PACKS_DIR / pack_name / file_path
|
||||
if is_pack_disabled(pack_name):
|
||||
raise HTTPException(403, "Pack is disabled by administrator")
|
||||
|
||||
client_ip = request.client.host if request.client else None
|
||||
|
||||
# If preset specified, try preset path first
|
||||
if preset:
|
||||
preset_path = PACKS_DIR / pack_name / "presets" / preset / file_path
|
||||
preset_resolved = preset_path.resolve()
|
||||
preset_root = (PACKS_DIR / pack_name).resolve()
|
||||
try:
|
||||
if str(preset_resolved).startswith(str(preset_root)) and preset_resolved.is_file():
|
||||
full_path = preset_resolved
|
||||
else:
|
||||
full_path = None
|
||||
except (ValueError, OSError):
|
||||
full_path = None
|
||||
else:
|
||||
full_path = None
|
||||
|
||||
# Fall back to base path
|
||||
if full_path is None:
|
||||
full_path = PACKS_DIR / pack_name / file_path
|
||||
|
||||
# Security: prevent path traversal
|
||||
try:
|
||||
full_path = full_path.resolve()
|
||||
@@ -2245,7 +2282,9 @@ async def proxy_download(request: Request):
|
||||
"resources.download.minecraft.net",
|
||||
"maven.minecraftforge.net",
|
||||
"files.minecraftforge.net",
|
||||
"maven.neoforged.net"
|
||||
"maven.neoforged.net",
|
||||
"api.zernmc.ru",
|
||||
"api.zernmc.online"
|
||||
]
|
||||
|
||||
# Проверяем, что URL ведет на разрешенный домен
|
||||
|
||||
Reference in New Issue
Block a user