Plugin Version
0.11.1
Operating System
Linux (Debian/Ubuntu)
Bug Description
Water disappears immediately after being placed in a player's own faction claim. Reported by Discord user bonito: "Cant place water on own claim — Water just disappear when placed in claim."
The player is a member of the faction that owns the claim, so they should have full BUILD permission. The water block appears briefly then vanishes.
Code Analysis
There are two separate protection paths for fluid in claimed territory:
1. Placement path (HyperFactionsPlaceFluidInteraction.interactWithBlock())
- Checks
canInteract(playerUuid, world, x, z, InteractionType.BUILD) - For faction members in their own claim, this returns
ALLOWED_OWN_CLAIM — placement is permitted - This path appears to work correctly (the water briefly appears)
2. Spread path (HyperProtect-Mixin FlameTickInterceptor.onSpread())
- Intercepts
FluidTicker.spread() via mixin redirect - Calls
queryFluidVerdict() → FluidSpreadHook.evaluateFluidSpread() (slot 25) → ProtectionChecker.shouldBlockFluidSpread() shouldBlockFluidSpread() (line 1237-1239) blindly delegates to shouldBlockFireSpread()- For faction claims,
shouldBlockFireSpread() (lines 1218-1222) returns !ConfigManager.get().isFireSpreadAllowed() - If
fireSpreadAllowed is false in config, ALL fluid spread in claims is blocked — including water placed by the claim owner
Root cause:shouldBlockFluidSpread() reuses shouldBlockFireSpread() logic, which has no concept of WHO placed the fluid. When fireSpreadAllowed: false is set in factions.json, the mixin removes ALL spreading fluid in claims indiscriminately — even water the owner just placed. The fluid placement succeeds (source block appears), but the mixin immediately prevents it from spreading, causing the water to appear to "disappear."
Key files:
ProtectionChecker.java:1237-1239 — shouldBlockFluidSpread() delegates to shouldBlockFireSpread()ProtectionChecker.java:1218-1222 — claim-level fire spread check uses global config toggleFlameTickInterceptor.java:139-143 — mixin removes fluid when verdict is DENYHyperProtectIntegration.java:1172-1187 — FluidSpreadHook at slot 25FactionsConfig.java:102 — fireSpreadAllowed defaults to true
Steps to Reproduce
- Create a faction and claim territory
- Set
fireSpreadAllowed: false in config/factions.json (or verify current config) - Place a water bucket in your own faction claim
- Water source block appears briefly, then disappears as spread is blocked
Expected Behavior
Water placed by a faction member in their own claim should persist and spread normally. The fireSpreadAllowed config should only affect fire spread (and possibly fluid from OUTSIDE the claim spreading IN), not fluid placed by authorized members within their own territory.
Logs
No response
Code Snippets
// ProtectionChecker.java:1237-1239 — the problematic delegationpublicbooleanshouldBlockFluidSpread(@NotNullWorldworld, intx, inty, intz) {
returnshouldBlockFireSpread(world, x, y, z);
}
// ProtectionChecker.java:1218-1222 — claim-level check (no player context)FactionclaimOwner = chunkManager.getFactionAt(world, chunkX, chunkZ);
if (claimOwner != null) {
return !ConfigManager.get().isFireSpreadAllowed();
}Media
No response
Additional information
Reported by: Discord user "bonito"
Possible fix approaches:
- Separate fluid spread from fire spread — give
shouldBlockFluidSpread() its own logic that always allows fluid spread in claims (fire and fluid are fundamentally different concerns) - Add a dedicated
fluidSpreadAllowed config option — separate from fireSpreadAllowed, defaulting to true - Track player-placed fluid sources — allow spread from player-placed source blocks while still blocking natural/external fluid spread (more complex, may not be necessary)
Option 1 or 2 is the simplest fix. The core issue is that fluid spread should not be governed by the fire spread config toggle.
Confirmation Checklist
Plugin Version
0.11.1
Operating System
Linux (Debian/Ubuntu)
Bug Description
Water disappears immediately after being placed in a player's own faction claim. Reported by Discord user bonito: "Cant place water on own claim — Water just disappear when placed in claim."
The player is a member of the faction that owns the claim, so they should have full BUILD permission. The water block appears briefly then vanishes.
Code Analysis
There are two separate protection paths for fluid in claimed territory:
1. Placement path (
HyperFactionsPlaceFluidInteraction.interactWithBlock())canInteract(playerUuid, world, x, z, InteractionType.BUILD)ALLOWED_OWN_CLAIM— placement is permitted2. Spread path (HyperProtect-Mixin
FlameTickInterceptor.onSpread())FluidTicker.spread()via mixin redirectqueryFluidVerdict()→FluidSpreadHook.evaluateFluidSpread()(slot 25) →ProtectionChecker.shouldBlockFluidSpread()shouldBlockFluidSpread()(line 1237-1239) blindly delegates toshouldBlockFireSpread()shouldBlockFireSpread()(lines 1218-1222) returns!ConfigManager.get().isFireSpreadAllowed()fireSpreadAllowedisfalsein config, ALL fluid spread in claims is blocked — including water placed by the claim ownerRoot cause:
shouldBlockFluidSpread()reusesshouldBlockFireSpread()logic, which has no concept of WHO placed the fluid. WhenfireSpreadAllowed: falseis set infactions.json, the mixin removes ALL spreading fluid in claims indiscriminately — even water the owner just placed. The fluid placement succeeds (source block appears), but the mixin immediately prevents it from spreading, causing the water to appear to "disappear."Key files:
ProtectionChecker.java:1237-1239—shouldBlockFluidSpread()delegates toshouldBlockFireSpread()ProtectionChecker.java:1218-1222— claim-level fire spread check uses global config toggleFlameTickInterceptor.java:139-143— mixin removes fluid when verdict is DENYHyperProtectIntegration.java:1172-1187—FluidSpreadHookat slot 25FactionsConfig.java:102—fireSpreadAlloweddefaults totrueSteps to Reproduce
fireSpreadAllowed: falseinconfig/factions.json(or verify current config)Expected Behavior
Water placed by a faction member in their own claim should persist and spread normally. The
fireSpreadAllowedconfig should only affect fire spread (and possibly fluid from OUTSIDE the claim spreading IN), not fluid placed by authorized members within their own territory.Logs
No response
Code Snippets
Media
No response
Additional information
Reported by: Discord user "bonito"
Possible fix approaches:
shouldBlockFluidSpread()its own logic that always allows fluid spread in claims (fire and fluid are fundamentally different concerns)fluidSpreadAllowedconfig option — separate fromfireSpreadAllowed, defaulting totrueOption 1 or 2 is the simplest fix. The core issue is that fluid spread should not be governed by the fire spread config toggle.
Confirmation Checklist