forked from SteamWar/SteamWar
TechHider refactoring, simple Blocktagging
This commit is contained in:
@@ -31,7 +31,6 @@ import net.minecraft.util.SimpleBitStorage;
|
||||
import net.minecraft.world.level.block.entity.TileEntityTypes;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
@@ -55,26 +54,27 @@ public class ChunkHider18 implements ChunkHider {
|
||||
private static final Reflection.FieldAccessor<List> tileEntities = Reflection.getField(ClientboundLevelChunkPacketData.class, List.class, 0);
|
||||
|
||||
@Override
|
||||
public BiFunction<Player, Object, Object> chunkHiderGenerator(TechHider.LocationEvaluator locationEvaluator, int obfuscationTarget, Set<Integer> obfuscate, Set<String> hiddenBlockEntities) {
|
||||
public BiFunction<Player, Object, Object> chunkHiderGenerator(TechHider techHider) {
|
||||
return (p, packet) -> {
|
||||
int chunkX = chunkXField.get(packet);
|
||||
int chunkZ = chunkZField.get(packet);
|
||||
if (locationEvaluator.skipChunk(p, chunkX, chunkZ))
|
||||
if (techHider.getLocationEvaluator().skipChunk(p, chunkX, chunkZ))
|
||||
return packet;
|
||||
|
||||
packet = chunkPacketCloner.apply(packet);
|
||||
Object dataWrapper = chunkDataCloner.apply(chunkData.get(packet));
|
||||
|
||||
Set<String> hiddenBlockEntities = techHider.getHiddenBlockEntities();
|
||||
tileEntities.set(dataWrapper, ((List<?>)tileEntities.get(dataWrapper)).stream().filter(te -> tileEntityVisible(hiddenBlockEntities, te)).collect(Collectors.toList()));
|
||||
|
||||
ByteBuf in = Unpooled.wrappedBuffer(dataField.get(dataWrapper));
|
||||
ByteBuf out = Unpooled.buffer(in.readableBytes() + 64);
|
||||
int xOffset = 16*chunkX;
|
||||
int zOffset = 16*chunkZ;
|
||||
for(int yOffset = p.getWorld().getMinHeight(); yOffset < p.getWorld().getMaxHeight(); yOffset += 16) {
|
||||
int finalYOffset = yOffset;
|
||||
int chunkY = yOffset/16;
|
||||
dataHider((x, y, z) -> locationEvaluator.check(p, x+xOffset, y+finalYOffset, z+zOffset), obfuscationTarget, obfuscate, in, out, locationEvaluator.skipChunkSection(p, chunkX, chunkY, chunkZ), locationEvaluator.blockPrecise(p, chunkX, chunkY, chunkZ));
|
||||
SectionHider section = new SectionHider(p, techHider, in, out, chunkX, yOffset/16, chunkZ);
|
||||
|
||||
section.copyBlockCount();
|
||||
blocks(section);
|
||||
biomes(section);
|
||||
}
|
||||
out.writeBytes(in); // MC appends a 0 byte at the end if there is a full chunk, idk why
|
||||
|
||||
@@ -96,70 +96,57 @@ public class ChunkHider18 implements ChunkHider {
|
||||
return !hiddenBlockEntities.contains((String) getName.invoke(getKey.invoke(tileEntityTypes, entityType.get(tile))));
|
||||
}
|
||||
|
||||
private void dataHider(PosEvaluator locationEvaluator, int obfuscationTarget, Set<Integer> obfuscate, ByteBuf in, ByteBuf out, boolean skip, boolean blockPrecise) {
|
||||
out.writeShort(in.readShort()); // Block count
|
||||
private void blocks(SectionHider section) {
|
||||
section.copyBitsPerBlock();
|
||||
|
||||
containerWalker(in, out, 15, obfuscationTarget, skip ? Collections.emptySet() : obfuscate, (paletteTarget, dataArrayLength, bitsPerBlock) -> {
|
||||
Set<Integer> palettedObfuscate;
|
||||
if(bitsPerBlock < 15) {
|
||||
palettedObfuscate = Collections.emptySet();
|
||||
} else {
|
||||
paletteTarget = obfuscationTarget;
|
||||
palettedObfuscate = obfuscate;
|
||||
}
|
||||
boolean singletonPalette = section.getBitsPerBlock() == 0;
|
||||
if(singletonPalette) {
|
||||
int value = ProtocolUtils.readVarInt(section.getIn());
|
||||
ProtocolUtils.writeVarInt(section.getOut(), !section.isSkipSection() && section.getObfuscate().contains(value) ? section.getTarget() : value);
|
||||
}else if(section.getBitsPerBlock() < 15) {
|
||||
section.processPalette();
|
||||
}
|
||||
|
||||
if(skip || dataArrayLength == 0 || (!blockPrecise && bitsPerBlock < 15)) {
|
||||
out.writeBytes(in, dataArrayLength*8);
|
||||
return;
|
||||
}
|
||||
if(section.isSkipSection() || singletonPalette || (!section.blockPrecise() && section.isPaletted())) {
|
||||
section.skipDataArray();
|
||||
return;
|
||||
}
|
||||
|
||||
long[] array = new long[dataArrayLength];
|
||||
for(int i = 0; i < dataArrayLength; i++)
|
||||
array[i] = in.readLong();
|
||||
SimpleBitStorage values = new SimpleBitStorage(bitsPerBlock, 4096, array);
|
||||
SimpleBitStorage values = new SimpleBitStorage(section.getBitsPerBlock(), 4096, section.readDataArray());
|
||||
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
int pos = (((y * 16) + z) * 16) + x;
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
int pos = (((y * 16) + z) * 16) + x;
|
||||
|
||||
switch (locationEvaluator.test(x, y, z)) {
|
||||
case SKIP:
|
||||
switch (section.test(x, y, z)) {
|
||||
case SKIP:
|
||||
break;
|
||||
case CHECK:
|
||||
if(!section.getObfuscate().contains(values.a(pos)))
|
||||
break;
|
||||
case CHECK:
|
||||
if(!palettedObfuscate.contains(values.a(pos)))
|
||||
break;
|
||||
default:
|
||||
values.b(pos, paletteTarget);
|
||||
}
|
||||
case HIDE:
|
||||
values.b(pos, section.getTarget());
|
||||
break;
|
||||
case HIDE_AIR:
|
||||
default:
|
||||
values.b(pos, section.getAir());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (long l : values.a())
|
||||
out.writeLong(l);
|
||||
});
|
||||
containerWalker(in, out, 6, 0, Collections.emptySet(), (paletteTarget, dataArrayLength, bitsPerBlock) -> out.writeBytes(in, dataArrayLength * 8)); // Biomes
|
||||
}
|
||||
|
||||
private void containerWalker(ByteBuf in, ByteBuf out, int globalPalette, int obfuscationTarget, Set<Integer> obfuscate, TriConsumer<Integer, Integer, Byte> dataArray) {
|
||||
byte bitsPerBlock = in.readByte();
|
||||
out.writeByte(bitsPerBlock);
|
||||
|
||||
//blockId -> obfuscate.contains(blockId) ? obfuscationTarget : blockId
|
||||
if(bitsPerBlock == 0) {
|
||||
int value = ProtocolUtils.readVarInt(in);
|
||||
ProtocolUtils.writeVarInt(out, obfuscate.contains(value) ? obfuscationTarget : value);
|
||||
}else if(bitsPerBlock < globalPalette) {
|
||||
obfuscationTarget = ChunkHider.processPalette(obfuscationTarget, obfuscate, in, out);
|
||||
}
|
||||
|
||||
int dataArrayLength = ProtocolUtils.readVarInt(in);
|
||||
ProtocolUtils.writeVarInt(out, dataArrayLength);
|
||||
dataArray.accept(obfuscationTarget, dataArrayLength, bitsPerBlock);
|
||||
section.writeDataArray(values.a());
|
||||
}
|
||||
|
||||
private interface TriConsumer<X, Y, Z> {
|
||||
void accept(X x, Y y, Z z);
|
||||
private void biomes(SectionHider section) {
|
||||
section.copyBitsPerBlock();
|
||||
boolean singletonPalette = section.getBitsPerBlock() == 0;
|
||||
if(singletonPalette)
|
||||
section.copyVarInt();
|
||||
else if(section.getBitsPerBlock() < 6)
|
||||
section.skipPalette();
|
||||
|
||||
section.skipDataArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,11 +25,9 @@ import net.minecraft.network.protocol.game.PacketPlayOutBlockBreak;
|
||||
import net.minecraft.world.level.block.entity.TileEntitySign;
|
||||
import net.minecraft.world.level.block.entity.TileEntityTypes;
|
||||
import net.minecraft.world.level.block.state.IBlockData;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class ProtocolWrapper18 implements ProtocolWrapper {
|
||||
@@ -38,8 +36,9 @@ public class ProtocolWrapper18 implements ProtocolWrapper {
|
||||
private static final Reflection.FieldAccessor<short[]> multiBlockChangePos = Reflection.getField(TechHider.multiBlockChangePacket, short[].class, 0);
|
||||
private static final Reflection.FieldAccessor<IBlockData[]> multiBlockChangeBlocks = Reflection.getField(TechHider.multiBlockChangePacket, IBlockData[].class, 0);
|
||||
@Override
|
||||
public BiFunction<Player, Object, Object> multiBlockChangeGenerator(Object obfuscationTarget, Set<Material> obfuscate, TechHider.LocationEvaluator locationEvaluator) {
|
||||
public BiFunction<Player, Object, Object> multiBlockChangeGenerator(TechHider techHider) {
|
||||
return (p, packet) -> {
|
||||
TechHider.LocationEvaluator locationEvaluator = techHider.getLocationEvaluator();
|
||||
Object chunkCoords = multiBlockChangeChunk.get(packet);
|
||||
int chunkX = TechHider.blockPositionX.get(chunkCoords);
|
||||
int chunkY = TechHider.blockPositionY.get(chunkCoords);
|
||||
@@ -62,7 +61,7 @@ public class ProtocolWrapper18 implements ProtocolWrapper {
|
||||
break;
|
||||
case CHECK:
|
||||
poss.add(pos);
|
||||
blocks.add(TechHider.iBlockDataHidden(obfuscate, block) ? (IBlockData) obfuscationTarget : block);
|
||||
blocks.add(techHider.iBlockDataHidden(block) ? (IBlockData) techHider.getObfuscationTarget() : block);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -90,17 +89,20 @@ public class ProtocolWrapper18 implements ProtocolWrapper {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiFunction<Player, Object, Object> blockBreakHiderGenerator(Class<?> blockBreakPacket, Object obfuscationTarget, Set<Material> obfuscate, TechHider.LocationEvaluator locationEvaluator) {
|
||||
public BiFunction<Player, Object, Object> blockBreakHiderGenerator(Class<?> blockBreakPacket, TechHider techHider) {
|
||||
return (p, packet) -> {
|
||||
PacketPlayOutBlockBreak breakPacket = (PacketPlayOutBlockBreak) packet;
|
||||
switch (locationEvaluator.checkBlockPos(p, breakPacket.b())) {
|
||||
switch (techHider.getLocationEvaluator().checkBlockPos(p, breakPacket.b())) {
|
||||
case SKIP:
|
||||
return packet;
|
||||
case CHECK:
|
||||
if(!TechHider.iBlockDataHidden(obfuscate, breakPacket.c()))
|
||||
if(!techHider.iBlockDataHidden(breakPacket.c()))
|
||||
return packet;
|
||||
case HIDE:
|
||||
return new PacketPlayOutBlockBreak(breakPacket.b(), (IBlockData) techHider.getObfuscationTarget(), breakPacket.d(), breakPacket.a());
|
||||
case HIDE_AIR:
|
||||
default:
|
||||
return new PacketPlayOutBlockBreak(breakPacket.b(), (IBlockData) obfuscationTarget, breakPacket.d(), breakPacket.a());
|
||||
return new PacketPlayOutBlockBreak(breakPacket.b(), (IBlockData) TechHider.AIR, breakPacket.d(), breakPacket.a());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user