From 74d2ada067bd2fd9436710ab7ac260e0eddf1314 Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 29 Jul 2026 01:03:24 +0200 Subject: Add per-instance mod management with client-side detection - New mod validation engine (src/mods.rs) with constant-pool class-file scanning: detects server-side content (block, tileentity, command, worldgen) vs client-only API (gui, renderer, forge/client) - 7 client-only mods correctly detected (AppleSkin, CraftingTweaks, Durability101, EnchantmentDescriptions, InventoryHUD, MouseTweaks, TrashSlot); 51 server-capable; 1 unknown - Routes + templating for mod upload (jar/zip), listing, delete, rescan - Multipart upload with 500MB limit (bypasses axum's default 2MB) - Per-instance mod summary card on edit page - Whitelist toggle checkbox on edit page (persisted, drives ENABLE_WHITELIST) - Dynamic Java image tag (java8/java17/java21) based on MC version - Class scan is informational-only; rejection based on metadata side=CLIENT - has_modpack flag cleanup on mod delete - Remove hx-boost from (was corrupting multipart uploads) --- templates/mods/list.html | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 templates/mods/list.html (limited to 'templates/mods/list.html') diff --git a/templates/mods/list.html b/templates/mods/list.html new file mode 100644 index 0000000..b8aff1f --- /dev/null +++ b/templates/mods/list.html @@ -0,0 +1,88 @@ +{% extends "base.html" %} +{% block content %} + + +{% if let Some(msg) = flash %} +
{{ msg.text }}
+{% endif %} + +
+
+ + +
+

+ Upload .jar files directly or a .zip containing multiple .jar files. + Mods containing only client-side classes will be rejected. +

+
+ +{% if mods.is_empty() %} +
+

No mods installed. Upload a mod to get started.

+
+{% else %} + + + + + + + + + + + + + {% for m in mods %} + + + + + + + + + {% endfor %} + +
NameFilenameSideStatusAdded
+ {% if let Some(name) = m.display_name %} + {{ name }} + {% else %} + {{ m.filename }} + {% endif %} + {{ m.filename }} + {{ m.side }} + + {% if !m.accepted %} + Rejected + {% else if m.side == "CLIENT" %} + Warning + {% else %} + Accepted + {% endif %} + {% if let Some(reason) = m.rejection_reason %} +
{{ reason }}
+ {% endif %} +
{{ m.created_at }} +
+ +
+
+{% endif %} + +
+
+ +
+
+{% endblock %} -- cgit v1.2.3