summaryrefslogtreecommitdiffstats
path: root/src/routes/players.rs
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-07-29 01:03:24 +0200
committersalmonik <salmonik@tuta.io>2026-07-29 01:03:24 +0200
commit74d2ada067bd2fd9436710ab7ac260e0eddf1314 (patch)
tree1f791bb895a611d8e729a735ba098a647808a157 /src/routes/players.rs
parentcreate example config on startup (diff)
downloadminecraft-ui-74d2ada067bd2fd9436710ab7ac260e0eddf1314.tar.gz
minecraft-ui-74d2ada067bd2fd9436710ab7ac260e0eddf1314.zip
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 <body> (was corrupting multipart uploads)
Diffstat (limited to '')
-rw-r--r--src/routes/players.rs5
1 files changed, 2 insertions, 3 deletions
diff --git a/src/routes/players.rs b/src/routes/players.rs
index 5c90efb..7cfb722 100644
--- a/src/routes/players.rs
+++ b/src/routes/players.rs
@@ -75,14 +75,13 @@ async fn manage_players(
75} 75}
76 76
77fn read_json_list(path: &std::path::Path) -> Vec<String> { 77fn read_json_list(path: &std::path::Path) -> Vec<String> {
78 if let Ok(contents) = std::fs::read_to_string(path) { 78 if let Ok(contents) = std::fs::read_to_string(path)
79 if let Ok(entries) = serde_json::from_str::<Vec<serde_json::Value>>(&contents) { 79 && let Ok(entries) = serde_json::from_str::<Vec<serde_json::Value>>(&contents) {
80 return entries 80 return entries
81 .iter() 81 .iter()
82 .filter_map(|e| e["name"].as_str().map(String::from)) 82 .filter_map(|e| e["name"].as_str().map(String::from))
83 .collect(); 83 .collect();
84 } 84 }
85 }
86 vec![] 85 vec![]
87} 86}
88 87