Welcome to the Hangar Open Beta. Please report any issue you encounter on GitHub!
Avatar for castledking

A modern, secure Essentials solution

Report Allium?

Release
0.2.5a

castledking released Allium version 0.2.5a on July 6, 2026

Allium v0.2.5a

Wiki: https://github.com/castledking/Allium/wiki

Highlights

  • Translation probe config corruption fixedapplyBundledDefaults no longer calls config.save(), preventing the old JAR's defaults from being written to disk on every restart. A new seedMissingProbeConfig() method writes the translation-probe section to disk only when the file actually lacks it (using contains(path, true) to ignore in-memory defaults).
  • Hardcoded probe check fallbackloadChecks() now cascades: disk config → bundled resource → createDefaultChecks() with 16 hardcoded checks (meteor + 14 IPN + 2 libIPN). This ensures the probe always has checks even when both the disk config and old JAR resource lack the section.
  • Probe enabled fallbackisEnabled() now falls back to root enabled, so the probe registers even when the translation-probe section is entirely absent from the config file.
  • Stealthier probeCloseWindow is sent immediately (no 2-tick delay, sign GUI never renders), and the sign position is Y - 30 below the player (out of view). Zero visual flicker.
  • /allium modguard reload — New command unregisters the probe, reloads the config from disk, and re-registers. Requires allium.admin.

Bug Fixes

Bug Root Cause Fix
Config file overwritten on every restart applyBundledDefaults called config.save() with copyDefaults(true), writing old JAR defaults back to disk Removed config.save() and copyDefaults(true) from applyBundledDefaults
translation-probe section never persisted to disk seedMissingProbeConfig used config.contains("translation-probe") which returned true from defaults set by applyBundledDefaults — even though the file lacked the section Changed to config.contains("translation-probe", true) to ignore defaults and check only the file
Probe has no checks after config corruption loadChecks() had no fallback when both disk config and bundled resource lacked the checks section Added createDefaultChecks() with 16 hardcoded checks as final fallback
Probe doesn't fire when translation-probe section is missing registerTranslationProbe() and isEnabled() returned false for config.getBoolean("translation-probe.enabled", false) when the section was absent Changed fallback to config.getBoolean("translation-probe.enabled", config.getBoolean("enabled", false))
Probe delay too slow (3s) and timeout too long (4s) Config defaults for delay-ticks (60) and timeout-ticks (80) were unnecessarily conservative Changed to 10 ticks (0.5s) and 30 ticks (1.5s)
Sign GUI visible to player on join CloseWindow was sent after a 2-tick delay, giving the client time to render the sign CloseWindow sent immediately in the same packet batch; sign placed 30 blocks below player
No reload command — required full restart for config changes No implementation Added /allium modguard reload which calls ModGuardManager.reload()

Files Changed (4)

File Change
managers/security/ModGuardManager.java applyBundledDefaults no longer saves to disk; added seedMissingProbeConfig() with contains(path, true) guard; added reload() static method; added /allium modguard reload dispatcher
managers/security/ModGuardTranslationProbe.java Added createDefaultChecks() (16 hardcoded checks); loadChecks() now cascades config → bundled → hardcoded; isEnabled() falls back to root enabled; CloseWindow immediate; sign Y -30; delay-ticks 10, timeout-ticks 30
modguard/config.yml Cleaned up: removed debug, regex-matching, case-sensitive, banned-mods, allowed-mods; added translation-probe section with all 16 checks with require-corroboration-for-kick: false
commands/Core.java Added handleModGuardCommand() for /allium modguard reload

Technical Details

Config Persistence Chain

The old code had two bugs forming a corruption loop:

  1. applyBundledDefaults called config.save() with the old JAR's bundled config (no translation-probe section), overwriting user changes on every restart
  2. Even after removing config.save(), seedMissingProbeConfig checked config.contains("translation-probe") — but applyBundledDefaults had already set the NEW bundled resource as defaults, which DO contain the section. So contains() returned true from defaults and seedMissingProbeConfig returned early without persisting

Fix: seedMissingProbeConfig now uses config.contains("translation-probe", true) to skip default-only matches. It also writes the full 16-check section to disk when absent, so subsequent restarts load it directly from the file.

Probe Check Fallback Chain

loadChecks() now follows this order:

  1. config().getConfigurationSection("translation-probe.checks") — reads from the in-memory config (loaded from disk or defaults)
  2. loadBundledChecks() — reads from the JAR resource (modguard/config.yml) and copies checks into the in-memory config
  3. createDefaultChecks() — 16 hardcoded checks: meteor + 14 IPN (key.inventoryprofiles.*) + 2 libIPN

This ensures the probe always has checks regardless of which JAR version is deployed or whether the config file contains the section.

Support and Feedback

Issues: https://github.com/castledking/Allium/issues Wiki: https://github.com/castledking/Allium/wiki Discord: https://discord.com/invite/pCKdCX6nYr Website: https://castled.codes/

Information

Published onJuly 6, 2026
Downloads1

Platforms

Paper Paper (1.20-1.21.8, 26.1-26.2)