forked from SteamWar/SteamWar
Make Techhider more robust
This commit is contained in:
+12
-6
@@ -108,7 +108,7 @@ public class SpectatorListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addHidingRules(Player player, List<HidingRule> rules) {
|
public void addHidingRules(Player player, List<HidingRule> rules) {
|
||||||
if (!(Permission.BUILD.hasPermission(player) || NO_TECHHIDER.contains(player))) {
|
if (!NO_TECHHIDER.contains(player)) {
|
||||||
rules.add(SPECTATOR_RULE);
|
rules.add(SPECTATOR_RULE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,6 +138,9 @@ public class SpectatorListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
|
if (Permission.BUILD.hasPermission(event.getPlayer())) {
|
||||||
|
NO_TECHHIDER.add(event.getPlayer());
|
||||||
|
}
|
||||||
if (BauSystem.DEV_SERVER) return;
|
if (BauSystem.DEV_SERVER) return;
|
||||||
if (event.getPlayer().getUniqueId().equals(BauServer.getInstance().getOwner())) {
|
if (event.getPlayer().getUniqueId().equals(BauServer.getInstance().getOwner())) {
|
||||||
return;
|
return;
|
||||||
@@ -159,17 +162,20 @@ public class SpectatorListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onBauMemberUpdate(BauMemberUpdateEvent event) {
|
public void onBauMemberUpdate(BauMemberUpdateEvent event) {
|
||||||
|
event.getChanged().forEach(player -> {
|
||||||
|
if (Permission.BUILD.hasPermission(player)) {
|
||||||
|
NO_TECHHIDER.add(player);
|
||||||
|
} else {
|
||||||
|
NO_TECHHIDER.remove(player);
|
||||||
|
}
|
||||||
|
resendChunks(player);
|
||||||
|
});
|
||||||
if (!anySupervisorOnline(null) && !BauSystem.DEV_SERVER) {
|
if (!anySupervisorOnline(null) && !BauSystem.DEV_SERVER) {
|
||||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||||
player.kickPlayer("");
|
player.kickPlayer("");
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.getChanged().forEach(player -> {
|
|
||||||
NO_TECHHIDER.remove(player);
|
|
||||||
resendChunks(player);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.features.xray;
|
package de.steamwar.bausystem.features.xray;
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.features.hullhider.HullHiderCommand;
|
import de.steamwar.bausystem.features.hullhider.HullHiderCommand;
|
||||||
import de.steamwar.bausystem.features.techhider.HidingRule;
|
import de.steamwar.bausystem.features.techhider.HidingRule;
|
||||||
@@ -30,12 +29,10 @@ import de.steamwar.core.CraftbukkitWrapper;
|
|||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import de.steamwar.linkage.LinkedInstance;
|
import de.steamwar.linkage.LinkedInstance;
|
||||||
import de.steamwar.techhider.ObfuscationConfig;
|
import de.steamwar.techhider.ObfuscationConfig;
|
||||||
|
import io.papermc.paper.event.player.PlayerFailMoveEvent;
|
||||||
|
import io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason;
|
||||||
import net.md_5.bungee.api.ChatMessageType;
|
import net.md_5.bungee.api.ChatMessageType;
|
||||||
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
@@ -45,7 +42,6 @@ import org.bukkit.event.player.PlayerQuitEvent;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.function.BiFunction;
|
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
public class XrayCommand extends SWCommand implements Listener {
|
public class XrayCommand extends SWCommand implements Listener {
|
||||||
@@ -103,27 +99,12 @@ public class XrayCommand extends SWCommand implements Listener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
@EventHandler
|
||||||
BiFunction<Player, ServerboundMovePlayerPacket, Object> positionSetter = (player, packet) -> {
|
public void onFailMove(PlayerFailMoveEvent event) {
|
||||||
Region region = Region.getRegion(player.getLocation());
|
if (event.getFailReason() != FailReason.CLIPPED_INTO_BLOCK) return;
|
||||||
if (hidden.containsKey(region) && hidden.get(region).contains(player)) {
|
Region region = Region.getRegion(event.getTo());
|
||||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
if (!hidden.containsKey(region) || !hidden.get(region).contains(event.getPlayer())) return;
|
||||||
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
event.setAllowed(true);
|
||||||
if (packet.hasPos) {
|
|
||||||
serverPlayer.setPosRaw(packet.x, packet.y, packet.z);
|
|
||||||
}
|
|
||||||
if (packet.hasRot) {
|
|
||||||
serverPlayer.setXRot(packet.xRot);
|
|
||||||
serverPlayer.setYRot(packet.yRot);
|
|
||||||
}
|
|
||||||
}, 0);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return packet;
|
|
||||||
};
|
|
||||||
|
|
||||||
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.Pos.class, positionSetter);
|
|
||||||
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.PosRot.class, positionSetter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
|
|||||||
@@ -132,6 +132,10 @@ public class FightHullHider {
|
|||||||
return hullHider.isBlockHidden(player, x, y, z);
|
return hullHider.isBlockHidden(player, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isEntityHidden(Player player, int entityId) {
|
||||||
|
return hullHider.isEntityHidden(player, entityId);
|
||||||
|
}
|
||||||
|
|
||||||
private void onTick() {
|
private void onTick() {
|
||||||
Recording.iterateOverEntities(Objects::nonNull, hullHider::checkEntity);
|
Recording.iterateOverEntities(Objects::nonNull, hullHider::checkEntity);
|
||||||
hullHider.sendUncoveredBlocks();
|
hullHider.sendUncoveredBlocks();
|
||||||
|
|||||||
+1
-9
@@ -39,7 +39,6 @@ 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.block.state.BlockState;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.craftbukkit.CraftWorld;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
@@ -133,16 +132,9 @@ public class TechHiderWrapper extends StateDependent implements Listener {
|
|||||||
return !isHidden(blockX, blockY, blockZ) || !obfuscation.hidesBlockState(blockState);
|
return !isHidden(blockX, blockY, blockZ) || !obfuscation.hidesBlockState(blockState);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO will require entity tracking on the netty thread to prevent future race conditions
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canAccessEntity(int entityId) {
|
public boolean canAccessEntity(int entityId) {
|
||||||
net.minecraft.world.entity.Entity nmsEntity = ((CraftWorld) player.getWorld()).getHandle().moonrise$getEntityLookup().get(entityId);
|
return !hullHider.isEntityHidden(player, entityId);
|
||||||
|
|
||||||
if (nmsEntity != null) {
|
|
||||||
return !hullHider.isBlockHidden(player, nmsEntity.getBlockX(), nmsEntity.getBlockY(), nmsEntity.getBlockZ());
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import org.bukkit.entity.Player;
|
|||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@@ -81,8 +82,9 @@ public class Hull {
|
|||||||
private final HashSet<IntVector> uncoveredSurface = new HashSet<>();
|
private final HashSet<IntVector> uncoveredSurface = new HashSet<>();
|
||||||
|
|
||||||
private final Viewers viewers;
|
private final Viewers viewers;
|
||||||
private final HashSet<Entity> entities = new HashSet<>();
|
// Concurrent as it is read on netty threads, keyed by entity id
|
||||||
private final HashSet<REntity> rentities = new HashSet<>();
|
private final Map<Integer, Entity> entities = new ConcurrentHashMap<>();
|
||||||
|
private final Set<REntity> rentities = ConcurrentHashMap.newKeySet();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param groundVisible whether the bottom layer of the region is uncovered (if the region does not reach the ground)
|
* @param groundVisible whether the bottom layer of the region is uncovered (if the region does not reach the ground)
|
||||||
@@ -162,6 +164,10 @@ public class Hull {
|
|||||||
return region.contains(x, y, z) && !isViewer(player) && !visibility.get(region.toIndex(x, y, z));
|
return region.contains(x, y, z) && !isViewer(player) && !visibility.get(region.toIndex(x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isEntityHidden(Player player, int entityId) {
|
||||||
|
return player.getEntityId() != entityId && entities.containsKey(entityId) && !isViewer(player);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isViewer(Player player) {
|
public boolean isViewer(Player player) {
|
||||||
return player != null && viewers.isViewer(player);
|
return player != null && viewers.isViewer(player);
|
||||||
}
|
}
|
||||||
@@ -187,13 +193,13 @@ public class Hull {
|
|||||||
private void updateEntities(Player player, boolean wasViewer) {
|
private void updateEntities(Player player, boolean wasViewer) {
|
||||||
if (isViewer(player)) {
|
if (isViewer(player)) {
|
||||||
if (!wasViewer) {
|
if (!wasViewer) {
|
||||||
for (Entity entity : entities) {
|
for (Entity entity : entities.values()) {
|
||||||
trackEntity(player, entity);
|
trackEntity(player, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Also hides the entities from players that joined after they were hidden
|
// Also hides the entities from players that joined after they were hidden
|
||||||
for (Entity entity : entities) {
|
for (Entity entity : entities.values()) {
|
||||||
if (!player.equals(entity)) untrackEntity(player, entity);
|
if (!player.equals(entity)) untrackEntity(player, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,13 +216,13 @@ public class Hull {
|
|||||||
public void checkEntity(Entity entity) {
|
public void checkEntity(Entity entity) {
|
||||||
Location location = entity.getLocation();
|
Location location = entity.getLocation();
|
||||||
if (region.contains(location) && !visibility.get(new IntVector(location).toId(region))) {
|
if (region.contains(location) && !visibility.get(new IntVector(location).toId(region))) {
|
||||||
if (entities.add(entity)) {
|
if (entities.put(entity.getEntityId(), entity) == null) {
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
if (!isViewer(player) && !player.equals(entity)) untrackEntity(player, entity);
|
if (!isViewer(player) && !player.equals(entity)) untrackEntity(player, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (entities.remove(entity)) {
|
if (entities.remove(entity.getEntityId()) != null) {
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
if (!isViewer(player) && !player.equals(entity)) trackEntity(player, entity);
|
if (!isViewer(player) && !player.equals(entity)) trackEntity(player, entity);
|
||||||
}
|
}
|
||||||
@@ -241,7 +247,7 @@ public class Hull {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void removeEntity(Entity entity) {
|
public void removeEntity(Entity entity) {
|
||||||
entities.remove(entity);
|
entities.remove(entity.getEntityId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkREntity(REntity entity) {
|
public void checkREntity(REntity entity) {
|
||||||
@@ -264,7 +270,7 @@ public class Hull {
|
|||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
if (isViewer(player)) continue;
|
if (isViewer(player)) continue;
|
||||||
|
|
||||||
for (Entity entity : entities) {
|
for (Entity entity : entities.values()) {
|
||||||
if (!player.equals(entity)) trackEntity(player, entity);
|
if (!player.equals(entity)) trackEntity(player, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,6 +146,16 @@ public class HullHider<K> implements Listener {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isEntityHidden(Player player, int entityId) {
|
||||||
|
for (Hull hull : hulls) {
|
||||||
|
if (hull.isEntityHidden(player, entityId)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onBlockPhysic(BlockPhysicsEvent e) {
|
public void onBlockPhysic(BlockPhysicsEvent e) {
|
||||||
if (e.getBlock() == e.getSourceBlock() || e.getChangedType() == Material.AIR) {
|
if (e.getBlock() == e.getSourceBlock() || e.getChangedType() == Material.AIR) {
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ import net.minecraft.util.SimpleBitStorage;
|
|||||||
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.block.state.BlockState;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.World;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -48,6 +49,15 @@ public class ChunkHider {
|
|||||||
private final int BLOCKS_PER_SECTION = 4096;
|
private final int BLOCKS_PER_SECTION = 4096;
|
||||||
private final int BIOMES_PER_SECTION = 64;
|
private final int BIOMES_PER_SECTION = 64;
|
||||||
|
|
||||||
|
private final int worldMinHeight;
|
||||||
|
private final int worldMaxHeight;
|
||||||
|
|
||||||
|
public ChunkHider() {
|
||||||
|
World world = Bukkit.getWorlds().getFirst();
|
||||||
|
worldMinHeight = world.getMinHeight();
|
||||||
|
worldMaxHeight = world.getMaxHeight();
|
||||||
|
}
|
||||||
|
|
||||||
private int getLongsRequiredToEncodeEntries(int bitsPerEntry, int entryCount) {
|
private int getLongsRequiredToEncodeEntries(int bitsPerEntry, int entryCount) {
|
||||||
int entriesPerLong = Long.SIZE / bitsPerEntry;
|
int entriesPerLong = Long.SIZE / bitsPerEntry;
|
||||||
int dataLengthAsLongCount = (entryCount + entriesPerLong - 1) / entriesPerLong;
|
int dataLengthAsLongCount = (entryCount + entriesPerLong - 1) / entriesPerLong;
|
||||||
@@ -67,7 +77,6 @@ public class ChunkHider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ClientboundLevelChunkWithLightPacket processLevelChunkWithLightPacket(ForPlayer access, ClientboundLevelChunkWithLightPacket packet) {
|
public ClientboundLevelChunkWithLightPacket processLevelChunkWithLightPacket(ForPlayer access, ClientboundLevelChunkWithLightPacket packet) {
|
||||||
Player player = access.getPlayer();
|
|
||||||
int chunkX = packet.getX();
|
int chunkX = packet.getX();
|
||||||
int chunkZ = packet.getZ();
|
int chunkZ = packet.getZ();
|
||||||
ClientboundLevelChunkPacketData chunkData = packet.getChunkData();
|
ClientboundLevelChunkPacketData chunkData = packet.getChunkData();
|
||||||
@@ -75,9 +84,6 @@ public class ChunkHider {
|
|||||||
ByteBuf in = Unpooled.wrappedBuffer(chunkData.getReadBuffer());
|
ByteBuf in = Unpooled.wrappedBuffer(chunkData.getReadBuffer());
|
||||||
ByteBuf out = Unpooled.buffer(in.readableBytes() + 64);
|
ByteBuf out = Unpooled.buffer(in.readableBytes() + 64);
|
||||||
|
|
||||||
int worldMinHeight = player.getWorld().getMinHeight();
|
|
||||||
int worldMaxHeight = player.getWorld().getMaxHeight();
|
|
||||||
|
|
||||||
for (int yOffset = worldMinHeight; yOffset < worldMaxHeight; yOffset += SECTION_SPAN_SIZE) {
|
for (int yOffset = worldMinHeight; yOffset < worldMaxHeight; yOffset += SECTION_SPAN_SIZE) {
|
||||||
short blockCount = in.readShort();
|
short blockCount = in.readShort();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user