From ea1bc7db954030ad5e4b40391e8e0d655b9d7e9a Mon Sep 17 00:00:00 2001 From: salmonik Date: Tue, 4 Aug 2026 14:05:15 +0200 Subject: small changes --- src/docker.rs | 8 +++++--- src/main.rs | 2 +- src/mods.rs | 30 ++++++++++++++---------------- 3 files changed, 20 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/docker.rs b/src/docker.rs index f171d43..fe2232f 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -125,6 +125,7 @@ impl DockerManager { "ENABLE_RCON=true".into(), format!("RCON_PASSWORD={}", instance.rcon_password), "RCON_PORT=25575".into(), + "JVM_OPTS=-Dfml.queryResult=confirm".into(), format!("MOTD={}", instance.motd), format!("GAMEMODE={}", instance.gamemode), format!("LEVEL_TYPE={}", instance.level_type), @@ -137,9 +138,10 @@ impl DockerManager { } if let Some(ref seed) = instance.world_seed - && !seed.is_empty() { - env_strings.push(format!("LEVEL_SEED={seed}")); - } + && !seed.is_empty() + { + env_strings.push(format!("LEVEL_SEED={seed}")); + } let mut exposed_ports: HashMap> = HashMap::new(); exposed_ports.insert("25565/tcp".into(), HashMap::new()); diff --git a/src/main.rs b/src/main.rs index 666b2d1..28579f3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -64,7 +64,7 @@ async fn main() { let router = routes::build_router(state); - let addr = format!("127.0.0.1:{}", config.webui_port); + let addr = format!("0.0.0.0:{}", config.webui_port); tracing::info!("Starting Minecraft UI on http://{addr}"); let listener = tokio::net::TcpListener::bind(&addr) diff --git a/src/mods.rs b/src/mods.rs index 10799f0..e165f20 100644 --- a/src/mods.rs +++ b/src/mods.rs @@ -4,12 +4,10 @@ //! 2. Class scan — walks `.class` entries looking for `net/minecraft/server` //! vs `net/minecraft/client` references. //! -//! **Rejection policy:** only mods that explicitly declare themselves client-only -//! in their metadata (`mods.toml` side=CLIENT, `fabric.mod.json` environment=client) -//! are rejected. The class scan is purely informational — many Forge mods that -//! work on servers reference `net/minecraft/client/…` for rendering/GUI but do -//! their server work through common API classes (`net/minecraft/block/Block`, etc.) -//! without ever referencing `net/minecraft/server/…` directly. +//! **Rejection policy:** only structurally invalid mods (oversized, unreadable +//! archive) are rejected. Client-only and ambiguous mods are accepted — Forge +//! ignores client-only mods on the server, but they may still be needed for +//! client-server handshake compatibility (e.g. AppleSkin, TrashSlot). use std::io::{Cursor, Read}; use zip::ZipArchive; @@ -51,13 +49,10 @@ const MAX_MOD_SIZE_BYTES: usize = 500 * 1024 * 1024; /// Returns a `ValidationResult` indicating whether the mod is safe to install. /// /// **Rejection policy:** -/// - Only mods that explicitly declare themselves client-only **in their metadata** -/// (`mods.toml` side=CLIENT, `fabric.mod.json` environment=client) are rejected -/// outright. The class-file scan is purely informational — many Forge mods that -/// work perfectly on a server reference `net/minecraft/client/…` classes for -/// rendering/GUI while doing their server logic through common API classes -/// (`net/minecraft/block/Block`, `net/minecraft/item/Item`, …) without ever -/// referencing `net/minecraft/server/…` directly. +/// - Only mods that fail structural checks (oversized, unreadable archive) are +/// rejected outright. Client-only and ambiguous mods are accepted — Forge +/// ignores client-only mods on the server, but they may still be needed for +/// client-server handshake compatibility (e.g. AppleSkin, TrashSlot). pub fn validate_mod(data: &[u8], filename: &str) -> ValidationResult { // Reject oversized files early to prevent DoS if data.len() > MAX_MOD_SIZE_BYTES { @@ -75,13 +70,16 @@ pub fn validate_mod(data: &[u8], filename: &str) -> ValidationResult { // Phase 1: metadata check let (meta_side, meta_display_name) = read_metadata(data); - // Only reject based on metadata — the mod author's explicit declaration. + // Client-only mods are accepted — Forge simply ignores them on the + // server side, and they may still be required in the mods folder for + // client-server compatibility handshake or anti-cheat measures. if meta_side == Some(ModSide::Client) { return ValidationResult { - accepted: false, + accepted: true, rejection_reason: Some(format!( "Mod '{}' declares itself as client-only in its metadata. \ - It would crash the server.", + It is accepted — Forge ignores client-only mods on the server, \ + but they may be needed for client-server compatibility.", meta_display_name.as_deref().unwrap_or(filename) )), display_name: meta_display_name, -- cgit v1.2.3