Extract obfuscation config into HiderCore

ObfuscationConfig resolves the hidden blocks, block states (including all
waterlogged states when water is hidden) and block entity types plus the
obfuscation block, either from a gamemode's techhider config or from plain
materials. TechHiderWrapper now only contains the fight specific access rules.
This commit is contained in:
2026-10-31 14:50:32 +01:00
parent da4b684a4b
commit 7d4252325a
3 changed files with 125 additions and 63 deletions
@@ -32,32 +32,21 @@ import de.steamwar.fightsystem.states.StateDependent;
import de.steamwar.fightsystem.states.StateDependentListener;
import de.steamwar.techhider.AccessPrivilegeProvider;
import de.steamwar.techhider.AccessPrivilegeProvider.ForPlayer;
import de.steamwar.techhider.ObfuscationConfig;
import de.steamwar.techhider.TechHider;
import lombok.Getter;
import net.minecraft.core.Holder;
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;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.Arrays;
import java.util.Collection;
import java.util.Objects;
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 {
@@ -80,29 +69,15 @@ public class TechHiderWrapper extends StateDependent implements Listener {
@Override
public void enable() {
Set<BlockState> blockStatesToObfuscate = getBlockStatesToHideFromMaterials(Config.GameModeConfig.Techhider.HiddenBlocks);
Set<Block> blocksToObfuscate = Config.GameModeConfig.Techhider.HiddenBlocks.stream()
.map(CraftMagicNumbers::getBlock)
.collect(Collectors.toUnmodifiableSet());
Set<BlockEntityType<?>> blockEntityTypeToObfuscate = Config.GameModeConfig.Techhider.HiddenBlockEntities.stream()
.map(id -> {
ResourceLocation loc = ResourceLocation.parse(id);
return BuiltInRegistries.BLOCK_ENTITY_TYPE.get(loc).orElse(null);
})
.filter(Objects::nonNull)
.map(Holder.Reference::value)
.collect(Collectors.toUnmodifiableSet());
new TechHider(CraftMagicNumbers.getBlock(Config.GameModeConfig.Techhider.ObfuscateWith), newProvider(blockStatesToObfuscate, blocksToObfuscate, blockEntityTypeToObfuscate));
ObfuscationConfig obfuscation = ObfuscationConfig.of(Config.GameModeConfig.Techhider);
new TechHider(obfuscation.getObfuscateWith(), newProvider(obfuscation));
}
private AccessPrivilegeProvider newProvider(Set<BlockState> blockStatesToObfuscate, Set<Block> blocksToObfuscate, Set<BlockEntityType<?>> blockEntityTypeToObfuscate) {
private AccessPrivilegeProvider newProvider(ObfuscationConfig obfuscation) {
return new AccessPrivilegeProvider() {
@Override
public ForPlayer forPlayer(Player p) {
return new FightPlayerAccess(p, getHiddenRegions(p), blockStatesToObfuscate, blocksToObfuscate, blockEntityTypeToObfuscate);
return new FightPlayerAccess(p, getHiddenRegions(p), obfuscation);
}
@Override
@@ -118,16 +93,12 @@ public class TechHiderWrapper extends StateDependent implements Listener {
private class FightPlayerAccess implements ForPlayer {
private final Player player;
private final Region[] hiddenRegions;
private final Set<BlockState> blockStatesToObfuscate;
private final Set<Block> blocksToObfuscate;
private final Set<BlockEntityType<?>> blockEntityTypeToObfuscate;
private final ObfuscationConfig obfuscation;
private FightPlayerAccess(Player player, Region[] hiddenRegions, Set<BlockState> blockStatesToObfuscate, Set<Block> blocksToObfuscate, Set<BlockEntityType<?>> blockEntityTypeToObfuscate) {
private FightPlayerAccess(Player player, Region[] hiddenRegions, ObfuscationConfig obfuscation) {
this.player = player;
this.hiddenRegions = hiddenRegions;
this.blockStatesToObfuscate = blockStatesToObfuscate;
this.blocksToObfuscate = blocksToObfuscate;
this.blockEntityTypeToObfuscate = blockEntityTypeToObfuscate;
this.obfuscation = obfuscation;
}
private boolean isHidden(int blockX, int blockY, int blockZ) {
@@ -155,12 +126,12 @@ public class TechHiderWrapper extends StateDependent implements Listener {
@Override
public boolean canAccessBlock(int blockX, int blockY, int blockZ, Block block) {
return !isHidden(blockX, blockY, blockZ) || !blocksToObfuscate.contains(block);
return !isHidden(blockX, blockY, blockZ) || !obfuscation.hidesBlock(block);
}
@Override
public boolean canAccessBlockState(int blockX, int blockY, int blockZ, BlockState blockState) {
return !isHidden(blockX, blockY, blockZ) || !blockStatesToObfuscate.contains(blockState);
return !isHidden(blockX, blockY, blockZ) || !obfuscation.hidesBlockState(blockState);
}
// TODO will require entity tracking on the netty thread to prevent future race conditions
@@ -177,7 +148,7 @@ public class TechHiderWrapper extends StateDependent implements Listener {
@Override
public boolean canAccessBlockEntity(int blockX, int blockY, int blockZ, BlockEntityType<?> type) {
return !isHidden(blockX, blockY, blockZ) || !blockEntityTypeToObfuscate.contains(type);
return !isHidden(blockX, blockY, blockZ) || !obfuscation.hidesBlockEntity(type);
}
}
@@ -235,27 +206,4 @@ public class TechHiderWrapper extends StateDependent implements Listener {
return new Region[]{Fight.getOpposite(fightPlayer.getTeam()).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());
}
}
}