fix techhider not hiding waterlogged blocks if neccecary

This commit is contained in:
D4rkr34lm
2026-05-23 12:29:19 +02:00
parent 002f7e5542
commit 69b924ded6
4 changed files with 44 additions and 10 deletions
@@ -38,7 +38,11 @@ import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType; 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.GameMode;
import org.bukkit.Material;
import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.craftbukkit.util.CraftMagicNumbers;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -46,10 +50,12 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import java.util.Collection;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
public class TechHiderWrapper extends StateDependent implements Listener { public class TechHiderWrapper extends StateDependent implements Listener {
@@ -70,6 +76,8 @@ public class TechHiderWrapper extends StateDependent implements Listener {
@Override @Override
public void enable() { public void enable() {
Set<BlockState> blockStatesToObfuscate = getBlockStatesToHideFromMaterials(Config.GameModeConfig.Techhider.HiddenBlocks);
Set<Block> blocksToObfuscate = Config.GameModeConfig.Techhider.HiddenBlocks.stream() Set<Block> blocksToObfuscate = Config.GameModeConfig.Techhider.HiddenBlocks.stream()
.map(CraftMagicNumbers::getBlock) .map(CraftMagicNumbers::getBlock)
.collect(Collectors.toUnmodifiableSet()); .collect(Collectors.toUnmodifiableSet());
@@ -104,6 +112,11 @@ public class TechHiderWrapper extends StateDependent implements Listener {
return !getHiddenRegion(p).inRegion(blockX, blockY, blockZ) || !blocksToObfuscate.contains(block); 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 // TODO will require entity tracking on the netty thread to prevent future race conditions
@Override @Override
public boolean isPlayerPrivilegedToAccessEntity(Player p, int entityId) { public boolean isPlayerPrivilegedToAccessEntity(Player p, int entityId) {
@@ -178,4 +191,27 @@ public class TechHiderWrapper extends StateDependent implements Listener {
return Fight.getOpposite(team).getExtendRegion(); return Fight.getOpposite(team).getExtendRegion();
} }
private Stream<BlockState> 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<BlockState> getBlockStatesToHideFromMaterials(Set<Material> materials) {
Stream<BlockState> 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());
}
}
} }
@@ -21,6 +21,7 @@ package de.steamwar.techhider;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public interface AccessPrivilegeProvider { public interface AccessPrivilegeProvider {
@@ -30,6 +31,8 @@ public interface AccessPrivilegeProvider {
boolean isPlayerPrivilegedToAccessBlock(Player p, int blockX, int blockY, int blockZ, Block block); 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 isPlayerPrivilegedToAccessEntity(Player p, int entityId);
boolean isPlayerPrivilegedToAccessBlockEntity(Player p, int blockX, int blockY, int blockZ, BlockEntityType<?> type); boolean isPlayerPrivilegedToAccessBlockEntity(Player p, int blockX, int blockY, int blockZ, BlockEntityType<?> type);
@@ -201,7 +201,7 @@ public class ChunkHider {
Block block = blockState.getBlock(); 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; obfuscatedData[blockDataIndex] = blockId;
} else { } else {
obfuscatedData[blockDataIndex] = blockIdUsedForHiding; obfuscatedData[blockDataIndex] = blockIdUsedForHiding;
@@ -423,12 +423,13 @@ public class TechHider {
private Packet<?> processBlockUpdatePacket(Player player, ClientboundBlockUpdatePacket packet) { private Packet<?> processBlockUpdatePacket(Player player, ClientboundBlockUpdatePacket packet) {
BlockPos blockPos = packet.getPos(); BlockPos blockPos = packet.getPos();
Block block = packet.getBlockState().getBlock(); BlockState blockState = packet.getBlockState();
Block block = blockState.getBlock();
int blockX = blockPos.getX(); int blockX = blockPos.getX();
int blockY = blockPos.getY(); int blockY = blockPos.getY();
int blockZ = blockPos.getZ(); 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; return packet;
} else if (privilegeProvider.isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ)) { } else if (privilegeProvider.isPlayerPrivilegedToAccessPosition(player, blockX, blockY, blockZ)) {
return new ClientboundBlockUpdatePacket(blockPos, blockStateUsedForObfuscation); return new ClientboundBlockUpdatePacket(blockPos, blockStateUsedForObfuscation);
@@ -471,7 +472,6 @@ public class TechHider {
short[] oldPos = oldPosField.get(packet); short[] oldPos = oldPosField.get(packet);
BlockState[] oldStates = oldStatesField.get(packet); BlockState[] oldStates = oldStatesField.get(packet);
boolean modified = false;
List<Short> filteredPos = new ArrayList<>(oldPos.length); List<Short> filteredPos = new ArrayList<>(oldPos.length);
List<BlockState> filteredStates = new ArrayList<>(oldStates.length); List<BlockState> filteredStates = new ArrayList<>(oldStates.length);
@@ -484,12 +484,10 @@ public class TechHider {
int worldY = sectionPos.relativeToBlockY(posShort); int worldY = sectionPos.relativeToBlockY(posShort);
int worldZ = sectionPos.relativeToBlockZ(posShort); int worldZ = sectionPos.relativeToBlockZ(posShort);
if (privilegeProvider.isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ) && privilegeProvider.isPlayerPrivilegedToAccessBlock(p, worldX, worldY, worldZ, block)) { if (privilegeProvider.isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ) && privilegeProvider.isPlayerPrivilegedToAccessBlock(p, worldX, worldY, worldZ, block) && privilegeProvider.isPlayerPrivilegedToAccessBlockState(p, worldX, worldY, worldZ, state)) {
// TODO statefull !!!
filteredPos.add(posShort); filteredPos.add(posShort);
filteredStates.add(state); filteredStates.add(state);
} else if (privilegeProvider.isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ)) { } else if (privilegeProvider.isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ)) {
modified = true;
filteredPos.add(posShort); filteredPos.add(posShort);
filteredStates.add(blockStateUsedForObfuscation); filteredStates.add(blockStateUsedForObfuscation);
} }
@@ -498,9 +496,6 @@ public class TechHider {
if (filteredStates.isEmpty()) { if (filteredStates.isEmpty()) {
return null; return null;
} }
if (!modified) {
return packet;
}
short[] newPos = new short[filteredPos.size()]; short[] newPos = new short[filteredPos.size()];
for (int i = 0; i < newPos.length; i++) { for (int i = 0; i < newPos.length; i++) {