forked from SteamWar/SteamWar
TechHider refactoring, simple Blocktagging
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user