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) {
|
||||
if (!(Permission.BUILD.hasPermission(player) || NO_TECHHIDER.contains(player))) {
|
||||
if (!NO_TECHHIDER.contains(player)) {
|
||||
rules.add(SPECTATOR_RULE);
|
||||
}
|
||||
}
|
||||
@@ -138,6 +138,9 @@ public class SpectatorListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
if (Permission.BUILD.hasPermission(event.getPlayer())) {
|
||||
NO_TECHHIDER.add(event.getPlayer());
|
||||
}
|
||||
if (BauSystem.DEV_SERVER) return;
|
||||
if (event.getPlayer().getUniqueId().equals(BauServer.getInstance().getOwner())) {
|
||||
return;
|
||||
@@ -159,17 +162,20 @@ public class SpectatorListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
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) {
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
player.kickPlayer("");
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
event.getChanged().forEach(player -> {
|
||||
NO_TECHHIDER.remove(player);
|
||||
resendChunks(player);
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
package de.steamwar.bausystem.features.xray;
|
||||
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.features.hullhider.HullHiderCommand;
|
||||
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.LinkedInstance;
|
||||
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.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
@@ -45,7 +42,6 @@ import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
@Linked
|
||||
public class XrayCommand extends SWCommand implements Listener {
|
||||
@@ -103,27 +99,12 @@ public class XrayCommand extends SWCommand implements Listener {
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
BiFunction<Player, ServerboundMovePlayerPacket, Object> positionSetter = (player, packet) -> {
|
||||
Region region = Region.getRegion(player.getLocation());
|
||||
if (hidden.containsKey(region) && hidden.get(region).contains(player)) {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
||||
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
|
||||
public void onFailMove(PlayerFailMoveEvent event) {
|
||||
if (event.getFailReason() != FailReason.CLIPPED_INTO_BLOCK) return;
|
||||
Region region = Region.getRegion(event.getTo());
|
||||
if (!hidden.containsKey(region) || !hidden.get(region).contains(event.getPlayer())) return;
|
||||
event.setAllowed(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
||||
@@ -132,6 +132,10 @@ public class FightHullHider {
|
||||
return hullHider.isBlockHidden(player, x, y, z);
|
||||
}
|
||||
|
||||
public boolean isEntityHidden(Player player, int entityId) {
|
||||
return hullHider.isEntityHidden(player, entityId);
|
||||
}
|
||||
|
||||
private void onTick() {
|
||||
Recording.iterateOverEntities(Objects::nonNull, hullHider::checkEntity);
|
||||
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.state.BlockState;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
@@ -133,16 +132,9 @@ public class TechHiderWrapper extends StateDependent implements Listener {
|
||||
return !isHidden(blockX, blockY, blockZ) || !obfuscation.hidesBlockState(blockState);
|
||||
}
|
||||
|
||||
// TODO will require entity tracking on the netty thread to prevent future race conditions
|
||||
@Override
|
||||
public boolean canAccessEntity(int entityId) {
|
||||
net.minecraft.world.entity.Entity nmsEntity = ((CraftWorld) player.getWorld()).getHandle().moonrise$getEntityLookup().get(entityId);
|
||||
|
||||
if (nmsEntity != null) {
|
||||
return !hullHider.isBlockHidden(player, nmsEntity.getBlockX(), nmsEntity.getBlockY(), nmsEntity.getBlockZ());
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
return !hullHider.isEntityHidden(player, entityId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -53,6 +53,7 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
@@ -81,8 +82,9 @@ public class Hull {
|
||||
private final HashSet<IntVector> uncoveredSurface = new HashSet<>();
|
||||
|
||||
private final Viewers viewers;
|
||||
private final HashSet<Entity> entities = new HashSet<>();
|
||||
private final HashSet<REntity> rentities = new HashSet<>();
|
||||
// Concurrent as it is read on netty threads, keyed by entity id
|
||||
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)
|
||||
@@ -162,6 +164,10 @@ public class Hull {
|
||||
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) {
|
||||
return player != null && viewers.isViewer(player);
|
||||
}
|
||||
@@ -187,13 +193,13 @@ public class Hull {
|
||||
private void updateEntities(Player player, boolean wasViewer) {
|
||||
if (isViewer(player)) {
|
||||
if (!wasViewer) {
|
||||
for (Entity entity : entities) {
|
||||
for (Entity entity : entities.values()) {
|
||||
trackEntity(player, entity);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
@@ -210,13 +216,13 @@ public class Hull {
|
||||
public void checkEntity(Entity entity) {
|
||||
Location location = entity.getLocation();
|
||||
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()) {
|
||||
if (!isViewer(player) && !player.equals(entity)) untrackEntity(player, entity);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (entities.remove(entity)) {
|
||||
if (entities.remove(entity.getEntityId()) != null) {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (!isViewer(player) && !player.equals(entity)) trackEntity(player, entity);
|
||||
}
|
||||
@@ -241,7 +247,7 @@ public class Hull {
|
||||
}
|
||||
|
||||
public void removeEntity(Entity entity) {
|
||||
entities.remove(entity);
|
||||
entities.remove(entity.getEntityId());
|
||||
}
|
||||
|
||||
public void checkREntity(REntity entity) {
|
||||
@@ -264,7 +270,7 @@ public class Hull {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (isViewer(player)) continue;
|
||||
|
||||
for (Entity entity : entities) {
|
||||
for (Entity entity : entities.values()) {
|
||||
if (!player.equals(entity)) trackEntity(player, entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,6 +146,16 @@ public class HullHider<K> implements Listener {
|
||||
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)
|
||||
public void onBlockPhysic(BlockPhysicsEvent e) {
|
||||
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.entity.BlockEntityType;
|
||||
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.Arrays;
|
||||
@@ -48,6 +49,15 @@ public class ChunkHider {
|
||||
private final int BLOCKS_PER_SECTION = 4096;
|
||||
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) {
|
||||
int entriesPerLong = Long.SIZE / bitsPerEntry;
|
||||
int dataLengthAsLongCount = (entryCount + entriesPerLong - 1) / entriesPerLong;
|
||||
@@ -67,7 +77,6 @@ public class ChunkHider {
|
||||
}
|
||||
|
||||
public ClientboundLevelChunkWithLightPacket processLevelChunkWithLightPacket(ForPlayer access, ClientboundLevelChunkWithLightPacket packet) {
|
||||
Player player = access.getPlayer();
|
||||
int chunkX = packet.getX();
|
||||
int chunkZ = packet.getZ();
|
||||
ClientboundLevelChunkPacketData chunkData = packet.getChunkData();
|
||||
@@ -75,9 +84,6 @@ public class ChunkHider {
|
||||
ByteBuf in = Unpooled.wrappedBuffer(chunkData.getReadBuffer());
|
||||
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) {
|
||||
short blockCount = in.readShort();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user