From 6d641856fe819732fb45e517efc255c62cd78a0f Mon Sep 17 00:00:00 2001 From: Lixfel Date: Thu, 18 Jan 2024 01:16:56 +0100 Subject: [PATCH] (Untested) Explosion, Particle and Sound Hider Signed-off-by: Lixfel --- .../de/steamwar/fightsystem/utils/Hull.java | 4 ++ .../steamwar/fightsystem/utils/HullHider.java | 60 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java index ab7cb7f..838bc2f 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java @@ -90,6 +90,10 @@ public class Hull { } } + public boolean isLocationHidden(Player player, Location location) { + return players.contains(player) && !visibility.get(new IntVector(location).toId(region)); + } + @SuppressWarnings("deprecation") public void addPlayer(Player player) { if(players.add(player)) { diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHider.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHider.java index 1d95eef..465204f 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHider.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHider.java @@ -19,8 +19,11 @@ package de.steamwar.fightsystem.utils; +import com.comphenix.tinyprotocol.Reflection; +import com.comphenix.tinyprotocol.TinyProtocol; import de.steamwar.core.Core; import de.steamwar.entity.REntity; +import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.fight.Fight; import de.steamwar.fightsystem.fight.FightPlayer; import de.steamwar.fightsystem.fight.FightTeam; @@ -29,7 +32,9 @@ import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.StateDependent; import de.steamwar.fightsystem.states.StateDependentListener; import de.steamwar.fightsystem.states.StateDependentTask; +import de.steamwar.techhider.TechHider; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -43,28 +48,41 @@ import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.function.BiFunction; +import java.util.function.Function; public class HullHider implements Listener { private static final boolean ENABLED = TechHiderWrapper.ENABLED && Core.getVersion() >= 18; private final Map hulls = new HashMap<>(); + private final Map, BiFunction> packetHiders = new HashMap<>(); public HullHider() { if(ENABLED) Fight.teams().forEach(team -> hulls.put(team, new Hull(team))); + packetHiders.put(packetPlayOutWorldEvent, this::worldEventHider); + packetHiders.put(packetPlayOutExplosion, this::explosionHider); + posHiderGenerator("{nms.network.protocol.game}.PacketPlayOutWorldParticles", Core.getVersion() >= 18 ? double.class : float.class, 1.0); + posHiderGenerator("{nms.network.protocol.game}.PacketPlayOutNamedSoundEffect", int.class, 8.0); + if(Core.getVersion() >= 9 && Core.getVersion() < 18) + posHiderGenerator("{nms.network.protocol.game}.PacketPlayOutCustomSoundEffect", int.class, 8.0); + new StateDependentListener(ENABLED, FightState.Schem, this); new StateDependent(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(ENABLED, FightState.Schem, this::onTick, 0, 1); @@ -144,4 +162,46 @@ public class HullHider implements Listener { public void despawnREntity(REntity e) { hulls.values().forEach(hull -> hull.removeREntity(e)); } + + + private static final Class packetPlayOutWorldEvent = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutWorldEvent"); + private static final Reflection.FieldAccessor worldEventPosition = Reflection.getField(packetPlayOutWorldEvent, TechHider.blockPosition, 0); + public static final Reflection.FieldAccessor blockPositionY = Reflection.getField("{nms.core}.BaseBlockPosition", 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 static final Class packetPlayOutExplosion = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutExplosion"); + private static final Reflection.FieldAccessor explosionBlocks = Reflection.getField(packetPlayOutExplosion, List.class, 0); + private static final Function explosionLocation = posPacketToLocation(packetPlayOutExplosion, double.class, 1.0); + private Object explosionHider(Player player, Object packet) { + if(explosionBlocks.get(packet).isEmpty()) + return packetHider(player, packet, explosionLocation.apply(packet)); + + return packet; + } + + private void posHiderGenerator(String typeName, Class posType, double factor) { + Class type = Reflection.getClass(typeName); + Function location = posPacketToLocation(type, posType, factor); + packetHiders.put(type, (player, packet) -> packetHider(player, packet, location.apply(packet))); + } + + private static Function posPacketToLocation(Class type, Class posType, double factor) { + Reflection.FieldAccessor x = Reflection.getField(type, posType, 0); + Reflection.FieldAccessor y = Reflection.getField(type, posType, 1); + Reflection.FieldAccessor z = Reflection.getField(type, posType, 2); + + return packet -> new Location(Config.world, (double)x.get(packet)/factor, (double)y.get(packet)/factor, (double)z.get(packet)/factor); + } + + private Object packetHider(Player player, Object packet, Location location) { + for(Hull hull : hulls.values()) { + if(hull.isLocationHidden(player, location)) + return null; + } + + return packet; + } }