TechHider refactoring, simple Blocktagging

This commit is contained in:
Lixfel
2024-12-21 16:53:49 +01:00
parent 1b47700c19
commit 793fc31b5c
16 changed files with 269 additions and 208 deletions
@@ -22,8 +22,10 @@ package de.steamwar.techhider;
import de.steamwar.core.Core;
import de.steamwar.core.VersionDependent;
import io.netty.buffer.ByteBuf;
import lombok.Getter;
import org.bukkit.entity.Player;
import java.util.Collections;
import java.util.Set;
import java.util.function.BiFunction;
@@ -31,29 +33,124 @@ public interface ChunkHider {
ChunkHider impl = VersionDependent.getVersionImpl(Core.getInstance());
Class<?> mapChunkPacket();
BiFunction<Player, Object, Object> chunkHiderGenerator(TechHider.LocationEvaluator locationEvaluator, int obfuscationTarget, Set<Integer> obfuscate, Set<String> hiddenBlockEntities);
BiFunction<Player, Object, Object> chunkHiderGenerator(TechHider techHider);
static int processPalette(int obfuscationTarget, Set<Integer> obfuscate, ByteBuf in, ByteBuf out) {
int paletteLength = ProtocolUtils.readVarInt(in);
ProtocolUtils.writeVarInt(out, paletteLength);
@Getter
class SectionHider {
private final Player player;
private final TechHider techHider;
private final ByteBuf in;
private final ByteBuf out;
int paletteTarget = 0;
private final int chunkX;
private final int chunkY;
private final int chunkZ;
private final int offsetX;
private final int offsetY;
private final int offsetZ;
for(int i = 0; i < paletteLength; i++) {
int entry = ProtocolUtils.readVarInt(in);
if(obfuscate.contains(entry))
entry = obfuscationTarget;
private final boolean skipSection;
if(entry == obfuscationTarget)
paletteTarget = i;
private boolean paletted;
private int bitsPerBlock;
private int air;
private int target;
private Set<Integer> obfuscate;
ProtocolUtils.writeVarInt(out, entry);
public SectionHider(Player player, TechHider techHider, ByteBuf in, ByteBuf out, int chunkX, int chunkY, int chunkZ) {
this.player = player;
this.techHider = techHider;
this.in = in;
this.out = out;
this.chunkX = chunkX;
this.chunkY = chunkY;
this.chunkZ = chunkZ;
this.offsetX = 16*chunkX;
this.offsetY = 16*chunkY;
this.offsetZ = 16*chunkZ;
this.skipSection = techHider.getLocationEvaluator().skipChunkSection(player, chunkX, chunkY, chunkZ);
this.paletted = false;
this.bitsPerBlock = 0;
this.air = TechHider.AIR_ID;
this.target = techHider.getObfuscationTargetId();
this.obfuscate = techHider.getObfuscateIds();
}
return paletteTarget;
}
public boolean blockPrecise() {
return techHider.getLocationEvaluator().blockPrecise(player, chunkX, chunkY, chunkZ);
}
interface PosEvaluator {
TechHider.State test(int x, int y, int z);
public TechHider.State test(int x, int y, int z) {
return techHider.getLocationEvaluator().check(player, offsetX+x, offsetY+y, offsetZ+z);
}
public void copyBlockCount() {
out.writeShort(in.readShort());
}
public void copyBitsPerBlock() {
bitsPerBlock = in.readByte();
out.writeByte(bitsPerBlock);
}
public int copyVarInt() {
int value = ProtocolUtils.readVarInt(in);
ProtocolUtils.writeVarInt(out, value);
return value;
}
public void skipPalette() {
int paletteLength = copyVarInt();
for(int i = 0; i < paletteLength; i++)
copyVarInt();
}
public void processPalette() {
if(skipSection) {
skipPalette();
return;
}
int paletteLength = copyVarInt();
if(paletteLength == 0)
return;
paletted = true;
air = 0;
target = 0;
for(int i = 0; i < paletteLength; i++) {
int entry = ProtocolUtils.readVarInt(in);
if(obfuscate.contains(entry))
entry = techHider.getObfuscationTargetId();
if(entry == TechHider.AIR_ID)
air = i;
else if(entry == techHider.getObfuscationTargetId())
target = i;
ProtocolUtils.writeVarInt(out, entry);
}
obfuscate = Collections.emptySet();
}
public void skipDataArray() {
int dataArrayLength = copyVarInt();
out.writeBytes(in, dataArrayLength*8);
}
public long[] readDataArray() {
long[] array = new long[copyVarInt()];
for(int i = 0; i < array.length; i++)
array[i] = in.readLong();
return array;
}
public void writeDataArray(long[] array) {
for(long l : array)
out.writeLong(l);
}
}
}
@@ -20,10 +20,8 @@
package de.steamwar.techhider;
import com.comphenix.tinyprotocol.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import com.google.common.primitives.Bytes;
import io.netty.buffer.ByteBuf;
import org.bukkit.Bukkit;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
@@ -37,10 +35,6 @@ import java.util.function.UnaryOperator;
public class ProtocolUtils {
private ProtocolUtils() {}
public static void broadcastPacket(Object packet) {
Bukkit.getOnlinePlayers().forEach(player -> TinyProtocol.instance.sendPacket(player, packet));
}
@Deprecated
public static BiFunction<Object, UnaryOperator<Object>, Object> arrayCloneGenerator(Class<?> elementClass) {
return (array, worker) -> {
@@ -21,10 +21,8 @@ package de.steamwar.techhider;
import de.steamwar.core.Core;
import de.steamwar.core.VersionDependent;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.Set;
import java.util.function.BiFunction;
public interface ProtocolWrapper {
@@ -33,7 +31,7 @@ public interface ProtocolWrapper {
boolean unfilteredTileEntityDataAction(Object packet);
BiFunction<Player, Object, Object> blockBreakHiderGenerator(Class<?> blockBreakPacket, Object obfuscationTarget, Set<Material> obfuscate, TechHider.LocationEvaluator locationEvaluator);
BiFunction<Player, Object, Object> blockBreakHiderGenerator(Class<?> blockBreakPacket, TechHider techHider);
BiFunction<Player, Object, Object> multiBlockChangeGenerator(Object obfuscationTarget, Set<Material> obfuscate, TechHider.LocationEvaluator locationEvaluator);
BiFunction<Player, Object, Object> multiBlockChangeGenerator(TechHider techHider);
}
@@ -22,6 +22,7 @@ package de.steamwar.techhider;
import com.comphenix.tinyprotocol.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.core.Core;
import lombok.Getter;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@@ -49,34 +50,44 @@ public class TechHider {
private static final Reflection.MethodInvoker getBlockByBlockData = Reflection.getTypedMethod(iBlockData, null, block);
private static final Reflection.MethodInvoker getMaterialByBlock = Reflection.getTypedMethod(craftMagicNumbers, "getMaterial", Material.class, block);
public static boolean iBlockDataHidden(Set<Material> obfuscate, Object iBlockData) {
public boolean iBlockDataHidden(Object iBlockData) {
return obfuscate.contains((Material) getMaterialByBlock.invoke(null, getBlockByBlockData.invoke(iBlockData)));
}
private final Map<Class<?>, BiFunction<Player, Object, Object>> techhiders = new HashMap<>();
private final LocationEvaluator locationEvaluator;
private final Object obfuscationTarget;
private final Set<Material> obfuscate;
public static final Object AIR = getBlockDataByBlock.invoke(getBlockByMaterial.invoke(null, Material.AIR));
public static final int AIR_ID = BlockIds.impl.materialToId(Material.AIR);
@Deprecated
public TechHider(BypassEvaluator bypass, Material obfuscationTarget, Set<Material> obfuscate, Set<String> hiddenBlockEntities) {
this((LocationEvaluator) (player, x, z) -> bypass.bypass(player, ProtocolUtils.posToChunk(x), ProtocolUtils.posToChunk(z)), obfuscationTarget, obfuscate, hiddenBlockEntities);
}
private final Map<Class<?>, BiFunction<Player, Object, Object>> techhiders = new HashMap<>();
@Getter
private final LocationEvaluator locationEvaluator;
@Getter
private final Object obfuscationTarget;
@Getter
private final int obfuscationTargetId;
@Getter
private final Set<Material> obfuscate;
@Getter
private final Set<Integer> obfuscateIds;
@Getter
private final Set<String> hiddenBlockEntities;
public TechHider(LocationEvaluator locationEvaluator, Material obfuscationTarget, Set<Material> obfuscate, Set<String> hiddenBlockEntities) {
this.locationEvaluator = locationEvaluator;
this.obfuscate = obfuscate;
this.obfuscateIds = obfuscate.stream().flatMap(m -> BlockIds.impl.materialToAllIds(m).stream()).collect(Collectors.toSet());
this.hiddenBlockEntities = hiddenBlockEntities;
this.obfuscationTarget = getBlockDataByBlock.invoke(getBlockByMaterial.invoke(null, obfuscationTarget));
this.obfuscationTargetId = BlockIds.impl.materialToId(obfuscationTarget);
techhiders.put(blockActionPacket, this::blockActionHider);
techhiders.put(blockChangePacket, this::blockChangeHider);
techhiders.put(tileEntityDataPacket, this::tileEntityDataHider);
techhiders.put(multiBlockChangePacket, ProtocolWrapper.impl.multiBlockChangeGenerator(this.obfuscationTarget, obfuscate, locationEvaluator));
techhiders.put(ChunkHider.impl.mapChunkPacket(), ChunkHider.impl.chunkHiderGenerator(locationEvaluator, BlockIds.impl.materialToId(obfuscationTarget), obfuscate.stream().flatMap(m -> BlockIds.impl.materialToAllIds(m).stream()).collect(Collectors.toSet()), hiddenBlockEntities));
techhiders.put(multiBlockChangePacket, ProtocolWrapper.impl.multiBlockChangeGenerator(this));
techhiders.put(ChunkHider.impl.mapChunkPacket(), ChunkHider.impl.chunkHiderGenerator(this));
if(Core.getVersion() > 12 && Core.getVersion() < 19) {
Class<?> blockBreakClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutBlockBreak");
techhiders.put(blockBreakClass, ProtocolWrapper.impl.blockBreakHiderGenerator(blockBreakClass, this.obfuscationTarget, obfuscate, locationEvaluator));
techhiders.put(blockBreakClass, ProtocolWrapper.impl.blockBreakHiderGenerator(blockBreakClass, this));
}
if(Core.getVersion() > 8){
@@ -106,12 +117,17 @@ public class TechHider {
case SKIP:
return packet;
case CHECK:
if(!iBlockDataHidden(obfuscate, blockChangeBlockData.get(packet)))
if(!iBlockDataHidden(blockChangeBlockData.get(packet)))
return packet;
default:
case HIDE:
packet = blockChangeCloner.apply(packet);
blockChangeBlockData.set(packet, obfuscationTarget);
return packet;
case HIDE_AIR:
default:
packet = blockChangeCloner.apply(packet);
blockChangeBlockData.set(packet, AIR);
return packet;
}
}
@@ -137,15 +153,11 @@ public class TechHider {
}
}
@Deprecated
public interface BypassEvaluator {
boolean bypass(Player p, int chunkX, int chunkZ);
}
public enum State {
SKIP,
CHECK,
HIDE
HIDE,
HIDE_AIR
}
public interface LocationEvaluator {