From 5d70f75ac98d086b8bb6afc0acc4ce4fac351224 Mon Sep 17 00:00:00 2001 From: D4rkr34lm Date: Fri, 22 May 2026 23:12:39 +0200 Subject: [PATCH 1/7] Move techhider init into enable to prevent always active even in check and test state --- .../fightsystem/utils/TechHiderWrapper.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java index 091d5717..1a6b445e 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java @@ -57,9 +57,19 @@ public class TechHiderWrapper extends StateDependent implements Listener { @Getter private final ConcurrentHashMap hiddenRegion = new ConcurrentHashMap<>(); + private final HullHider hullHider; public TechHiderWrapper(HullHider hullHider) { super(ENABLED, FightState.All); + + this.hullHider = hullHider; + + new StateDependentListener(ENABLED, FightState.All, this); + register(); + } + + @Override + public void enable() { Set blocksToObfuscate = Config.GameModeConfig.Techhider.HiddenBlocks.stream() .map(CraftMagicNumbers::getBlock) .collect(Collectors.toUnmodifiableSet()); @@ -116,13 +126,6 @@ public class TechHiderWrapper extends StateDependent implements Listener { return p.getGameMode() != GameMode.SPECTATOR; } }); - - new StateDependentListener(ENABLED, FightState.All, this); - register(); - } - - @Override - public void enable() { } @Override From 69b924ded6d7d8da34716380730090d27fc5df61 Mon Sep 17 00:00:00 2001 From: D4rkr34lm Date: Sat, 23 May 2026 12:29:19 +0200 Subject: [PATCH 2/7] fix techhider not hiding waterlogged blocks if neccecary --- .../fightsystem/utils/TechHiderWrapper.java | 36 +++++++++++++++++++ .../techhider/AccessPrivilegeProvider.java | 3 ++ .../src/de/steamwar/techhider/ChunkHider.java | 2 +- .../src/de/steamwar/techhider/TechHider.java | 13 +++---- 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java index 1a6b445e..3fc4a364 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java @@ -38,7 +38,11 @@ import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; import org.bukkit.GameMode; +import org.bukkit.Material; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.entity.Player; @@ -46,10 +50,12 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerQuitEvent; +import java.util.Collection; import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; +import java.util.stream.Stream; public class TechHiderWrapper extends StateDependent implements Listener { @@ -70,6 +76,8 @@ public class TechHiderWrapper extends StateDependent implements Listener { @Override public void enable() { + Set blockStatesToObfuscate = getBlockStatesToHideFromMaterials(Config.GameModeConfig.Techhider.HiddenBlocks); + Set blocksToObfuscate = Config.GameModeConfig.Techhider.HiddenBlocks.stream() .map(CraftMagicNumbers::getBlock) .collect(Collectors.toUnmodifiableSet()); @@ -104,6 +112,11 @@ public class TechHiderWrapper extends StateDependent implements Listener { return !getHiddenRegion(p).inRegion(blockX, blockY, blockZ) || !blocksToObfuscate.contains(block); } + @Override + public boolean isPlayerPrivilegedToAccessBlockState(Player p, int blockX, int blockY, int blockZ, BlockState blockState) { + return !getHiddenRegion(p).inRegion(blockX, blockY, blockZ) || !blockStatesToObfuscate.contains(blockState); + } + // TODO will require entity tracking on the netty thread to prevent future race conditions @Override public boolean isPlayerPrivilegedToAccessEntity(Player p, int entityId) { @@ -178,4 +191,27 @@ public class TechHiderWrapper extends StateDependent implements Listener { return Fight.getOpposite(team).getExtendRegion(); } + + private Stream getWaterloggedBlockStates() { + FluidState waterFluidState = Fluids.WATER.getSource(false); + + return BuiltInRegistries.BLOCK.stream() + .map((block) -> block.getStateDefinition().getPossibleStates()) + .flatMap(Collection::stream) + .filter((blockState -> blockState.getFluidState() == waterFluidState)); + } + + private Set getBlockStatesToHideFromMaterials(Set materials) { + Stream allStatesFromMaterials = materials.stream() + .map(CraftMagicNumbers::getBlock) + .map((block) -> block.getStateDefinition().getPossibleStates()) + .flatMap(Collection::stream); + + if(materials.contains(Material.WATER)) { + return Stream.concat(allStatesFromMaterials, getWaterloggedBlockStates()).collect(Collectors.toUnmodifiableSet()); + } + else { + return allStatesFromMaterials.collect(Collectors.toUnmodifiableSet()); + } + } } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/AccessPrivilegeProvider.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/AccessPrivilegeProvider.java index 16df8ab0..b04748c6 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/AccessPrivilegeProvider.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/AccessPrivilegeProvider.java @@ -21,6 +21,7 @@ package de.steamwar.techhider; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; import org.bukkit.entity.Player; public interface AccessPrivilegeProvider { @@ -30,6 +31,8 @@ public interface AccessPrivilegeProvider { boolean isPlayerPrivilegedToAccessBlock(Player p, int blockX, int blockY, int blockZ, Block block); + boolean isPlayerPrivilegedToAccessBlockState(Player p, int blockX, int blockY, int blockZ, BlockState blockState); + boolean isPlayerPrivilegedToAccessEntity(Player p, int entityId); boolean isPlayerPrivilegedToAccessBlockEntity(Player p, int blockX, int blockY, int blockZ, BlockEntityType type); diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java index 0a280bee..b0bd2658 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java @@ -201,7 +201,7 @@ public class ChunkHider { Block block = blockState.getBlock(); - if (accessPrivilegeProvider.isPlayerPrivilegedToAccessPosition(player, worldX, worldY, worldZ) && accessPrivilegeProvider.isPlayerPrivilegedToAccessBlock(player, worldX, worldY, worldZ, block)) { + if (accessPrivilegeProvider.isPlayerPrivilegedToAccessPosition(player, worldX, worldY, worldZ) && accessPrivilegeProvider.isPlayerPrivilegedToAccessBlock(player, worldX, worldY, worldZ, block) && accessPrivilegeProvider.isPlayerPrivilegedToAccessBlockState(player, worldX, worldY, worldZ, blockState)) { obfuscatedData[blockDataIndex] = blockId; } else { obfuscatedData[blockDataIndex] = blockIdUsedForHiding; diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java index ed18f556..f9764bfa 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java @@ -423,12 +423,13 @@ public class TechHider { private Packet processBlockUpdatePacket(Player player, ClientboundBlockUpdatePacket packet) { BlockPos blockPos = packet.getPos(); - Block block = packet.getBlockState().getBlock(); + BlockState blockState = packet.getBlockState(); + Block block = blockState.getBlock(); int blockX = blockPos.getX(); int blockY = blockPos.getY(); int blockZ = blockPos.getZ(); - if (privilegeProvider.isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ) && privilegeProvider.isPlayerPrivilegedToAccessBlock(player, blockX, blockY, blockZ, block)) { + if (privilegeProvider.isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ) && privilegeProvider.isPlayerPrivilegedToAccessBlock(player, blockX, blockY, blockZ, block) && privilegeProvider.isPlayerPrivilegedToAccessBlockState(player, blockX, blockY, blockZ, blockState)) { return packet; } else if (privilegeProvider.isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ)) { return new ClientboundBlockUpdatePacket(blockPos, blockStateUsedForObfuscation); @@ -471,7 +472,6 @@ public class TechHider { short[] oldPos = oldPosField.get(packet); BlockState[] oldStates = oldStatesField.get(packet); - boolean modified = false; List filteredPos = new ArrayList<>(oldPos.length); List filteredStates = new ArrayList<>(oldStates.length); @@ -484,12 +484,10 @@ public class TechHider { int worldY = sectionPos.relativeToBlockY(posShort); int worldZ = sectionPos.relativeToBlockZ(posShort); - if (privilegeProvider.isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ) && privilegeProvider.isPlayerPrivilegedToAccessBlock(p, worldX, worldY, worldZ, block)) { - // TODO statefull !!! + if (privilegeProvider.isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ) && privilegeProvider.isPlayerPrivilegedToAccessBlock(p, worldX, worldY, worldZ, block) && privilegeProvider.isPlayerPrivilegedToAccessBlockState(p, worldX, worldY, worldZ, state)) { filteredPos.add(posShort); filteredStates.add(state); } else if (privilegeProvider.isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ)) { - modified = true; filteredPos.add(posShort); filteredStates.add(blockStateUsedForObfuscation); } @@ -498,9 +496,6 @@ public class TechHider { if (filteredStates.isEmpty()) { return null; } - if (!modified) { - return packet; - } short[] newPos = new short[filteredPos.size()]; for (int i = 0; i < newPos.length; i++) { From 78617d5a986cb1bd7e9b2658ea644b6a916735e4 Mon Sep 17 00:00:00 2001 From: D4rkr34lm Date: Sat, 23 May 2026 16:15:31 +0200 Subject: [PATCH 3/7] another fix --- .../src/de/steamwar/techhider/ChunkHider.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java index b0bd2658..3d7fa97c 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java @@ -179,7 +179,7 @@ public class ChunkHider { out.readBytes(data); List blockEntities = chunkBlockEntitiesDataField.get(chunkData); - List filteredBlockEntities = filterBlockEntities(player, blockEntities); + List filteredBlockEntities = filterBlockEntities(player, blockEntities, chunkX, chunkZ); return buildNewChunkPacket(packet, data, filteredBlockEntities); @@ -256,18 +256,24 @@ public class ChunkHider { private static final Reflection.Field packedXZField = Reflection.getField(blockEntitiyInfoClass, int.class, 0); private static final Reflection.Field yField = Reflection.getField(blockEntitiyInfoClass, int.class, 1); - private List filterBlockEntities(Player player, List blockEntities) { + private List filterBlockEntities(Player player, List blockEntities, int chunkX, int chunkZ) { + int fourBitBitmask = 0b0000_1111; + return blockEntities.stream() .filter((blockEntityInfo) -> { BlockEntityType type = blockEntityInfoTypeField.get(blockEntityInfo); int packedXZ = packedXZField.get(blockEntityInfo); - int y = yField.get(blockEntityInfo); - int x = SectionPos.sectionRelativeX((short) packedXZ); - int z = SectionPos.sectionRelativeZ((short) packedXZ); + int localX = (packedXZ >> 4) & fourBitBitmask; + int localZ = packedXZ & fourBitBitmask; - return accessPrivilegeProvider.isPlayerPrivilegedToAccessPosition(player, x, y, z) && accessPrivilegeProvider.isPlayerPrivilegedToAccessBlockEntity(player, x, y, z, type); + int worldX = (chunkX * SECTION_SPAN_SIZE) + localX; + int worldZ = (chunkZ * SECTION_SPAN_SIZE) + localZ; + + int worldY = yField.get(blockEntityInfo); + + return accessPrivilegeProvider.isPlayerPrivilegedToAccessPosition(player, worldX, worldY, worldZ) && accessPrivilegeProvider.isPlayerPrivilegedToAccessBlockEntity(player, worldX, worldY, worldZ, type); }).toList(); } From 628001e69362ab398fff21912d334524a05e02cc Mon Sep 17 00:00:00 2001 From: D4rkr34lm Date: Sun, 24 May 2026 13:42:08 +0200 Subject: [PATCH 4/7] Disable Replays --- .../de/steamwar/velocitycore/commands/ReplayCommand.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/ReplayCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/ReplayCommand.java index 26b55da0..99d69d30 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/ReplayCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/ReplayCommand.java @@ -42,6 +42,12 @@ public class ReplayCommand extends SWCommand { super("replay"); } + public void genericCommand(PlayerChatter sender) { + sender.system("REPLAY_UNAVAILABLE"); + return; + } + + /* @Register public void genericCommand(PlayerChatter sender, int replayId, @StaticValue(value = {"", "-a"}, allowISE = true) @OptionalValue("") boolean isAdmin, @OptionalValue("") String optionalMap) { Fight fight = Fight.getById(replayId); @@ -109,4 +115,5 @@ public class ReplayCommand extends SWCommand { private Message parseLeader(SteamwarUser leader, int players, boolean winner) { return new Message("REPLAY_" + (players > 1 ? "" : "SOLO_") + (winner ? "WINNER" : "LOSER"), leader.getUserName(), players - 1); } + */ } From de6ac2cf207b61681aefc6450d215efa313094cd Mon Sep 17 00:00:00 2001 From: D4rkr34lm Date: Sun, 24 May 2026 13:44:57 +0200 Subject: [PATCH 5/7] fix --- .../src/de/steamwar/velocitycore/commands/ReplayCommand.java | 1 + 1 file changed, 1 insertion(+) diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/ReplayCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/ReplayCommand.java index 99d69d30..b6bdd7ec 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/ReplayCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/ReplayCommand.java @@ -42,6 +42,7 @@ public class ReplayCommand extends SWCommand { super("replay"); } + @Register public void genericCommand(PlayerChatter sender) { sender.system("REPLAY_UNAVAILABLE"); return; From 71258318db54fb4333790b60d2cf6e3a5ca19685 Mon Sep 17 00:00:00 2001 From: D4rkr34lm Date: Sun, 24 May 2026 23:39:50 +0200 Subject: [PATCH 6/7] Replace trace rendering by fallingblockentity with display entity for better accuracy --- .../tracer/rendering/TraceEntity.java | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/TraceEntity.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/TraceEntity.java index c00d976d..ff3cbcea 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/TraceEntity.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/TraceEntity.java @@ -24,13 +24,16 @@ import de.steamwar.bausystem.configplayer.Config; import de.steamwar.bausystem.features.tracer.TNTPoint; import de.steamwar.bausystem.features.tracer.Trace; import de.steamwar.bausystem.features.tracer.TraceManager; +import de.steamwar.entity.RBlockDisplay; import de.steamwar.entity.REntityServer; -import de.steamwar.entity.RFallingBlockEntity; import lombok.Getter; import net.md_5.bungee.api.chat.ClickEvent; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Player; +import org.bukkit.util.Transformation; +import org.joml.Quaternionf; +import org.joml.Vector3f; import yapion.hierarchy.types.YAPIONValue; import java.util.List; @@ -41,7 +44,16 @@ import static de.steamwar.bausystem.features.util.TNTClickListener.TNT_CLICK_DET /** * Wrapper for the rendering of a record bundle */ -public class TraceEntity extends RFallingBlockEntity { +public class TraceEntity extends RBlockDisplay { + + private static final float TNT_VISUAL_SCALE = 0.98F; + private static final float TNT_VISUAL_OFFSET = -TNT_VISUAL_SCALE / 2.0F; + private static final Transformation TNT_VISUAL_TRANSFORM = new Transformation( + new Vector3f(TNT_VISUAL_OFFSET, 0.0F, TNT_VISUAL_OFFSET), + new Quaternionf(0, 0, 0, 1), + new Vector3f(TNT_VISUAL_SCALE, TNT_VISUAL_SCALE, TNT_VISUAL_SCALE), + new Quaternionf(0, 0, 0, 1) + ); /** * The records represented by this REntity @@ -57,11 +69,13 @@ public class TraceEntity extends RFallingBlockEntity { private final Trace trace; public TraceEntity(REntityServer server, Location location, boolean isExplosion, List records, Trace trace) { - super(server, location, isExplosion ? Material.RED_STAINED_GLASS : Material.TNT); + super(server, location); + Material material = isExplosion ? Material.RED_STAINED_GLASS : Material.TNT; this.records = records; this.trace = trace; uniqueTntIdsString = records.stream().map(TNTPoint::getTntId).distinct().map(Object::toString).collect(Collectors.joining(" ")); - setNoGravity(true); + setTransform(TNT_VISUAL_TRANSFORM); + setBlock(material.createBlockData()); } /** From 9934b8bbb2c8e23628602b70da9166a05b1826a6 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Mon, 25 May 2026 01:55:20 +0200 Subject: [PATCH 7/7] Fix TNTLeague InviteCommand.kt Signed-off-by: Chaoscaot --- TNTLeague/src/de/steamwar/tntleague/command/InviteCommand.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TNTLeague/src/de/steamwar/tntleague/command/InviteCommand.kt b/TNTLeague/src/de/steamwar/tntleague/command/InviteCommand.kt index d8317219..4e95c38f 100644 --- a/TNTLeague/src/de/steamwar/tntleague/command/InviteCommand.kt +++ b/TNTLeague/src/de/steamwar/tntleague/command/InviteCommand.kt @@ -28,6 +28,9 @@ import net.md_5.bungee.api.chat.ClickEvent import org.bukkit.entity.Player object InviteCommand : SWCommand("invite") { + init { + message = de.steamwar.tntleague.message + } @Register fun invitePlayer(@Validator("isLeader") sender: Player, target: Player) {