From b43dc289a072034e69834b80fb095fd041e5f812 Mon Sep 17 00:00:00 2001 From: ehko Date: Wed, 27 May 2026 09:06:37 -0400 Subject: [PATCH] added in bypass for hub protection --- .../net/kewwbec/hub/HubPermissionsNodes.java | 10 +++++ src/main/java/net/kewwbec/hub/HubPlugin.java | 23 +++++++--- .../net/kewwbec/hub/command/BuildCommand.java | 43 +++++++++++++++++++ .../protection/CancelBreakBlockSystem.java | 15 +++---- .../protection/CancelDamageBlockSystem.java | 8 +++- .../protection/CancelPlaceBlockSystem.java | 8 +++- .../kewwbec/hub/service/BuildModeService.java | 28 ++++++++++++ 7 files changed, 120 insertions(+), 15 deletions(-) create mode 100644 src/main/java/net/kewwbec/hub/HubPermissionsNodes.java create mode 100644 src/main/java/net/kewwbec/hub/command/BuildCommand.java create mode 100644 src/main/java/net/kewwbec/hub/service/BuildModeService.java diff --git a/src/main/java/net/kewwbec/hub/HubPermissionsNodes.java b/src/main/java/net/kewwbec/hub/HubPermissionsNodes.java new file mode 100644 index 0000000..6659204 --- /dev/null +++ b/src/main/java/net/kewwbec/hub/HubPermissionsNodes.java @@ -0,0 +1,10 @@ +package net.kewwbec.hub; + +public final class HubPermissionsNodes { + + public static final String ROOT = "networkhub"; + public static final String BUILD = ROOT + ".build"; + + private HubPermissionsNodes() { + } +} diff --git a/src/main/java/net/kewwbec/hub/HubPlugin.java b/src/main/java/net/kewwbec/hub/HubPlugin.java index 3f3edbc..ee6add8 100644 --- a/src/main/java/net/kewwbec/hub/HubPlugin.java +++ b/src/main/java/net/kewwbec/hub/HubPlugin.java @@ -2,20 +2,23 @@ package net.kewwbec.hub; import com.hypixel.hytale.logger.HytaleLogger; import com.hypixel.hytale.server.core.event.events.player.AddPlayerToWorldEvent; +import com.hypixel.hytale.server.core.event.events.player.PlayerDisconnectEvent; import com.hypixel.hytale.server.core.event.events.player.PlayerReadyEvent; import com.hypixel.hytale.server.core.event.events.player.RemovedPlayerFromWorldEvent; import com.hypixel.hytale.server.core.plugin.JavaPlugin; import com.hypixel.hytale.server.core.plugin.JavaPluginInit; +import com.hypixel.hytale.server.core.universe.PlayerRef; import com.hypixel.hytale.server.core.universe.world.events.AllWorldsLoadedEvent; -import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; +import net.kewwbec.hub.command.BuildCommand; import net.kewwbec.hub.config.HubConfig; import net.kewwbec.hub.config.HubConfigLoader; import net.kewwbec.hub.listener.HubJoinListener; import net.kewwbec.hub.listener.HubMessageListener; +import net.kewwbec.hub.protection.CancelBreakBlockSystem; import net.kewwbec.hub.protection.CancelDamageBlockSystem; import net.kewwbec.hub.protection.CancelPlaceBlockSystem; -import net.kewwbec.hub.protection.CancelBreakBlockSystem; import net.kewwbec.hub.protection.HubWorldFilter; +import net.kewwbec.hub.service.BuildModeService; import net.kewwbec.hub.service.HubWorldService; import javax.annotation.Nonnull; @@ -28,6 +31,7 @@ public final class HubPlugin extends JavaPlugin { private HubConfig config; private HubWorldFilter filter; + private BuildModeService buildMode; private HubWorldService worldService; public HubPlugin(@Nonnull JavaPluginInit init) { @@ -43,6 +47,7 @@ public final class HubPlugin extends JavaPlugin { this.config = new HubConfig(); } this.filter = new HubWorldFilter(config); + this.buildMode = new BuildModeService(); LOGGER.at(Level.INFO).log("Hub setup complete"); } @@ -58,20 +63,28 @@ public final class HubPlugin extends JavaPlugin { getEventRegistry().registerGlobal(PlayerReadyEvent.class, joinListener::onReady); getEventRegistry().registerGlobal(AddPlayerToWorldEvent.class, messageListener::onAdd); getEventRegistry().registerGlobal(RemovedPlayerFromWorldEvent.class, messageListener::onRemove); + getEventRegistry().registerGlobal(PlayerDisconnectEvent.class, this::onDisconnect); if (config.protection.disable_block_break) { - getEntityStoreRegistry().registerSystem(new CancelBreakBlockSystem(filter)); + getEntityStoreRegistry().registerSystem(new CancelBreakBlockSystem(filter, buildMode)); } if (config.protection.disable_block_place) { - getEntityStoreRegistry().registerSystem(new CancelPlaceBlockSystem(filter)); + getEntityStoreRegistry().registerSystem(new CancelPlaceBlockSystem(filter, buildMode)); } if (config.protection.disable_block_damage) { - getEntityStoreRegistry().registerSystem(new CancelDamageBlockSystem(filter)); + getEntityStoreRegistry().registerSystem(new CancelDamageBlockSystem(filter, buildMode)); } + getCommandRegistry().registerCommand(new BuildCommand(buildMode)); + LOGGER.at(Level.INFO).log("Hub started"); } + private void onDisconnect(@Nonnull PlayerDisconnectEvent event) { + PlayerRef ref = event.getPlayerRef(); + if (ref != null) buildMode.clear(ref.getUuid()); + } + @Override protected void shutdown() { LOGGER.at(Level.INFO).log("Hub shutdown complete"); diff --git a/src/main/java/net/kewwbec/hub/command/BuildCommand.java b/src/main/java/net/kewwbec/hub/command/BuildCommand.java new file mode 100644 index 0000000..7e5e026 --- /dev/null +++ b/src/main/java/net/kewwbec/hub/command/BuildCommand.java @@ -0,0 +1,43 @@ +package net.kewwbec.hub.command; + +import com.hypixel.hytale.component.Ref; +import com.hypixel.hytale.component.Store; +import com.hypixel.hytale.server.core.Message; +import com.hypixel.hytale.server.core.command.system.CommandContext; +import com.hypixel.hytale.server.core.command.system.basecommands.AbstractPlayerCommand; +import com.hypixel.hytale.server.core.universe.PlayerRef; +import com.hypixel.hytale.server.core.universe.world.World; +import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; +import net.kewwbec.hub.HubPermissionsNodes; +import net.kewwbec.hub.service.BuildModeService; + +import javax.annotation.Nonnull; +import java.awt.Color; + +/** + * /build - toggle build mode for the caller. Bypasses hub block break/place/damage protection + * while ON. World-level flags (PvP, fall damage) are not affected; those are server-wide and not + * per-player. Cleared on disconnect. + */ +public final class BuildCommand extends AbstractPlayerCommand { + + private final BuildModeService buildMode; + + public BuildCommand(@Nonnull BuildModeService buildMode) { + super("build", "Toggle build mode - bypass hub block protection for yourself"); + this.buildMode = buildMode; + requirePermission(HubPermissionsNodes.BUILD); + } + + @Override protected boolean canGeneratePermission() { return false; } + + @Override + protected void execute(@Nonnull CommandContext ctx, @Nonnull Store store, @Nonnull Ref ref, @Nonnull PlayerRef sender, @Nonnull World world) { + boolean nowOn = buildMode.toggle(sender.getUuid()); + if (nowOn) { + ctx.sendMessage(Message.raw("Build mode ON. You can break, place, and damage blocks in hub worlds. Run /build again to turn off.").color(Color.GREEN)); + } else { + ctx.sendMessage(Message.raw("Build mode OFF. Hub protection is back to normal for you.").color(Color.YELLOW)); + } + } +} diff --git a/src/main/java/net/kewwbec/hub/protection/CancelBreakBlockSystem.java b/src/main/java/net/kewwbec/hub/protection/CancelBreakBlockSystem.java index 5b8f57c..651d6c8 100644 --- a/src/main/java/net/kewwbec/hub/protection/CancelBreakBlockSystem.java +++ b/src/main/java/net/kewwbec/hub/protection/CancelBreakBlockSystem.java @@ -6,25 +6,22 @@ import com.hypixel.hytale.component.Store; import com.hypixel.hytale.component.query.Query; import com.hypixel.hytale.component.system.EntityEventSystem; import com.hypixel.hytale.server.core.event.events.ecs.BreakBlockEvent; +import com.hypixel.hytale.server.core.universe.PlayerRef; import com.hypixel.hytale.server.core.universe.world.World; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; +import net.kewwbec.hub.service.BuildModeService; import javax.annotation.Nonnull; -/** - * ECS system that cancels BreakBlockEvent inside hub worlds. - * - * BreakBlockEvent extends CancellableEcsEvent and is dispatched per-entity - * (the breaker) via entityStore.invoke(ref, event). Hytale's BlockHarvestUtils - * checks event.isCancelled() and aborts the actual break if true. - */ public final class CancelBreakBlockSystem extends EntityEventSystem { private final HubWorldFilter filter; + private final BuildModeService buildMode; - public CancelBreakBlockSystem(@Nonnull HubWorldFilter filter) { + public CancelBreakBlockSystem(@Nonnull HubWorldFilter filter, @Nonnull BuildModeService buildMode) { super(BreakBlockEvent.class); this.filter = filter; + this.buildMode = buildMode; } @Override @@ -42,6 +39,8 @@ public final class CancelBreakBlockSystem extends EntityEventSystem { private final HubWorldFilter filter; + private final BuildModeService buildMode; - public CancelDamageBlockSystem(@Nonnull HubWorldFilter filter) { + public CancelDamageBlockSystem(@Nonnull HubWorldFilter filter, @Nonnull BuildModeService buildMode) { super(DamageBlockEvent.class); this.filter = filter; + this.buildMode = buildMode; } @Override @@ -35,6 +39,8 @@ public final class CancelDamageBlockSystem extends EntityEventSystem { private final HubWorldFilter filter; + private final BuildModeService buildMode; - public CancelPlaceBlockSystem(@Nonnull HubWorldFilter filter) { + public CancelPlaceBlockSystem(@Nonnull HubWorldFilter filter, @Nonnull BuildModeService buildMode) { super(PlaceBlockEvent.class); this.filter = filter; + this.buildMode = buildMode; } @Override @@ -35,6 +39,8 @@ public final class CancelPlaceBlockSystem extends EntityEventSystem on = ConcurrentHashMap.newKeySet(); + + public boolean isOn(@Nonnull UUID uuid) { + return on.contains(uuid); + } + + public boolean toggle(@Nonnull UUID uuid) { + if (on.add(uuid)) return true; + on.remove(uuid); + return false; + } + + public void clear(@Nonnull UUID uuid) { + on.remove(uuid); + } +}