Started embedding new techhider into fight system

This commit is contained in:
D4rkr34lm
2026-05-20 21:30:44 +02:00
parent ba29e5cf23
commit 5da3767378
4 changed files with 55 additions and 135 deletions
@@ -100,8 +100,9 @@ public class FightSystem extends JavaPlugin {
new OneShotStateDependent(ArenaMode.Test, FightState.All, WorldEditRendererCUIEditor::new);
Config.world.setGameRule(GameRule.REDUCED_DEBUG_INFO, ArenaMode.AntiTest.contains(Config.mode));
techHider = new TechHiderWrapper();
hullHider = new HullHider();
techHider = new TechHiderWrapper(hullHider);
FileSource.startReplay();
@@ -62,9 +62,6 @@ public class HullHider implements Listener {
@Getter
private final Map<FightTeam, Hull> hullMap = new HashMap<>();
private final Hull[] hulls;
private final Map<Class<?>, BiFunction<Player, Object, Object>> packetHiders = new HashMap<>();
private static final Class<?> packetPlayOutExplosion = ClientboundExplodePacket.class;
public HullHider() {
if (!TechHiderWrapper.ENABLED) {
@@ -75,25 +72,8 @@ public class HullHider implements Listener {
Fight.teams().forEach(team -> hullMap.put(team, new Hull(team)));
hulls = hullMap.values().toArray(new Hull[0]);
packetHiders.put(packetPlayOutWorldEvent, this::worldEventHider);
packetHiders.put(packetPlayOutExplosion, this::explosionHider);
posHiderGenerator(ClientboundLevelParticlesPacket.class, double.class, 1.0);
posHiderGenerator(ClientboundSoundPacket.class, int.class, 8.0);
new StateDependentListener(TechHiderWrapper.ENABLED, FightState.Schem, this);
new StateDependent(TechHiderWrapper.ENABLED, FightState.Schem) {
@Override
public void enable() {
packetHiders.forEach(TinyProtocol.instance::addFilter);
Bukkit.getOnlinePlayers().forEach(HullHider.this::updatePlayer);
}
@Override
public void disable() {
Bukkit.getOnlinePlayers().forEach(player -> removePlayer(player, true));
packetHiders.forEach(TinyProtocol.instance::removeFilter);
}
}.register();
new StateDependentTask(TechHiderWrapper.ENABLED, FightState.Schem, this::onTick, 0, 1);
}
@@ -209,39 +189,4 @@ public class HullHider implements Listener {
hull.removeREntity(e);
}
}
private static final Class<?> packetPlayOutWorldEvent = ClientboundLevelEventPacket.class;
private static final Reflection.Field<?> worldEventPosition = Reflection.getField(packetPlayOutWorldEvent, TechHider.blockPosition, 0);
public static final Reflection.Field<Integer> blockPositionY = Reflection.getField(Vec3i.class, int.class, 1);
private Object worldEventHider(Player player, Object packet) {
Object baseBlock = worldEventPosition.get(packet);
return packetHider(player, packet, new Location(Config.world, TechHider.blockPositionX.get(baseBlock), blockPositionY.get(baseBlock), TechHider.blockPositionZ.get(baseBlock)));
}
private Object explosionHider(Player player, Object packet) {
return ReflectionWrapper.impl.explosionHider(player, packet, this::packetHider);
}
private void posHiderGenerator(Class<?> type, Class<? extends Number> posType, double factor) {
Function<Object, Location> location = posPacketToLocation(type, posType, factor);
packetHiders.put(type, (player, packet) -> packetHider(player, packet, location.apply(packet)));
}
public static Function<Object, Location> posPacketToLocation(Class<?> type, Class<? extends Number> posType, double factor) {
Reflection.Field<? extends Number> x = Reflection.getField(type, posType, 0);
Reflection.Field<? extends Number> y = Reflection.getField(type, posType, 1);
Reflection.Field<? extends Number> z = Reflection.getField(type, posType, 2);
return packet -> new Location(Config.world, x.get(packet).doubleValue() / factor, y.get(packet).doubleValue() / factor, z.get(packet).doubleValue() / factor);
}
private Object packetHider(Player player, Object packet, Location location) {
for (Hull hull : hulls) {
if (hull.isLocationHidden(player, location)) return null;
}
return packet;
}
}
@@ -31,8 +31,14 @@ import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependent;
import de.steamwar.fightsystem.states.StateDependentListener;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.techhider.TechHider;
import lombok.Getter;
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 org.bukkit.GameMode;
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -45,27 +51,62 @@ import java.io.IOException;
import java.nio.file.Files;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
public class TechHiderWrapper extends StateDependent implements TechHider.LocationEvaluator, Listener {
public class TechHiderWrapper extends StateDependent implements Listener {
public static final boolean ENABLED = !Config.OnlyPublicSchematics && !Config.test() && Config.GameModeConfig.Techhider.Active;
@Getter
private final ConcurrentHashMap<Player, Region> hiddenRegion = new ConcurrentHashMap<>();
private final ConcurrentHashMap<Player, Long> patterns = new ConcurrentHashMap<>();
private final TechHider techHider;
private final SecretKey key;
public TechHiderWrapper() {
public TechHiderWrapper(HullHider hullHider) {
super(ENABLED, FightState.Schem);
techHider = new TechHider(this, Config.GameModeConfig.Techhider.ObfuscateWith, Config.GameModeConfig.Techhider.HiddenBlocks, Config.GameModeConfig.Techhider.HiddenBlockEntities);
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 parsedId = ResourceLocation.parse(id);
return BuiltInRegistries.BLOCK_ENTITY_TYPE.get(parsedId).get().value();
})
.collect(Collectors.toUnmodifiableSet());
techHider = new TechHider(CraftMagicNumbers.getBlock(Config.GameModeConfig.Techhider.ObfuscateWith)) {
@Override
public boolean isPlayerPrivilegedToAccessPosition(Player p, int blockX, int blockY, int blockZ) {
return !hullHider.isBlockHidden(p, blockX, blockY, blockZ);
}
try {
key = new SecretKeySpec(Files.readAllBytes(new File(System.getProperty("user.home"), "hullhider.key").toPath()), "AES");
} catch (IOException e) {
throw new SecurityException(e);
}
@Override
public boolean isPlayerPrivilegedToAccessBlock(Player p, int blockX, int blockY, int blockZ, Block block) {
Region hiddenRegion = getHiddenRegion(p);
return !hiddenRegion.inRegion(blockX, blockY, blockZ) || !blocksToObfuscate.contains(block) ;
}
@Override
public boolean isPlayerPrivilegedToAccessEntity(Player p, int entityId) {
return false;
}
@Override
public boolean isPlayerPrivilegedToAccessBlocEntity(Player p, int blockX, int blockY, int blockZ, BlockEntityType<?> type) {
Region hiddenRegion = getHiddenRegion(p);
return !hiddenRegion.inRegion(blockX, blockY, blockZ) || !blockEntityTypeToObfuscate.contains(type);
}
@Override
public boolean isPlayerPrivilegedToAccessContainer(Player p, int containerId) {
return false;
}
@Override
public boolean isPlayerPrivilegedToAccessSound(Player p, ResourceLocation soundId) {
return false;
}
};
new StateDependentListener(ENABLED, FightState.Schem, this);
register();
@@ -73,12 +114,11 @@ public class TechHiderWrapper extends StateDependent implements TechHider.Locati
@Override
public void enable() {
techHider.enable();
}
@Override
public void disable() {
techHider.disable();
hiddenRegion.clear();
}
@@ -117,72 +157,6 @@ public class TechHiderWrapper extends StateDependent implements TechHider.Locati
});
}
@Override
public boolean suppressInteractions(Player player) {
return player.getGameMode() == GameMode.SPECTATOR;
}
@Override
public boolean skipChunk(Player player, int chunkX, int chunkZ) {
return getHiddenRegion(player).chunkOutside(chunkX, chunkZ);
}
@Override
public boolean skipChunkSection(Player player, int chunkX, int chunkY, int chunkZ) {
return getHiddenRegion(player).chunkSectionOutside(chunkX, chunkY, chunkZ);
}
@Override
public TechHider.State check(Player player, int x, int y, int z) {
if (hiddenRegion.computeIfAbsent(player, this::getHiddenRegion).inRegion(x, y, z)) {
if (FightSystem.getHullHider().isBlockHidden(player, x, y, z)) {
int id = ((y & 3) << 4) + ((z & 3) << 2) + (x & 3);
return (patterns.computeIfAbsent(player, this::getPattern) & (1L << id)) == 0 ? TechHider.State.HIDE_AIR : TechHider.State.HIDE;
} else {
return TechHider.State.CHECK;
}
} else {
return TechHider.State.SKIP;
}
}
public long getPattern(Player player) {
long pattern = SteamwarUser.get(player.getUniqueId()).getId();
byte[] bytes = new byte[]{
(byte) (pattern & 0xFF),
(byte) ((pattern >>> 8) & 0xFF),
(byte) ((pattern >>> 16) & 0xFF),
(byte) ((pattern >>> 24) & 0xFF)
};
try {
Cipher cipher = Cipher.getInstance("AES_256/CFB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key);
bytes = cipher.doFinal(bytes);
} catch (IllegalBlockSizeException | BadPaddingException | NoSuchAlgorithmException | NoSuchPaddingException |
InvalidKeyException e) {
throw new SecurityException(e);
}
pattern = bytes[0] & 0xFFL |
((bytes[1] & 0xFFL) << 8) |
((bytes[2] & 0xFFL) << 16) |
((bytes[3] & 0xFFL) << 24);
/* XXXO OOOX
* XXXO OOOX
* XXOX OOXO
* OOXX XXOO */
pattern |= 0b1110_1110_1101_0011___0001_0001_0010_1100___0000_0000_0000_0000___0000_0000_0000_0000L;
return pattern;
}
@Override
public boolean blockPrecise(Player player, int chunkX, int chunkY, int chunkZ) {
return FightSystem.getHullHider().blockPrecise(player, chunkX, chunkY, chunkZ);
}
private Region getHiddenRegion(Player player) {
if (Config.isReferee(player)) return Region.EMPTY;
@@ -189,7 +189,7 @@ public abstract class TechHider {
private ChunkHider chunkHider;
// TODO handle packet bundle
public TechHider(Plugin plugin, Block blockUsedForObfuscation) {
public TechHider(Block blockUsedForObfuscation) {
this.blockUsedForObfuscation = blockUsedForObfuscation;
this.blockStateUsedForObfuscation = blockUsedForObfuscation.defaultBlockState();