Erste bugs ausgemerzt

This commit is contained in:
D4rkr34lm
2026-05-21 15:06:33 +02:00
parent dc0365834a
commit a2caa79f99
3 changed files with 110 additions and 89 deletions
@@ -74,29 +74,30 @@ public class TechHiderWrapper extends StateDependent implements Listener {
@Override @Override
public boolean isPlayerPrivilegedToAccessBlock(Player p, int blockX, int blockY, int blockZ, Block block) { public boolean isPlayerPrivilegedToAccessBlock(Player p, int blockX, int blockY, int blockZ, Block block) {
Region hiddenRegion = getHiddenRegion(p); Region hiddenRegion = getHiddenRegion(p);
return !hiddenRegion.inRegion(blockX, blockY, blockZ) || !blocksToObfuscate.contains(block) ; return !hiddenRegion.inRegion(blockX, blockY, blockZ) || !blocksToObfuscate.contains(block);
} }
// TODO
@Override @Override
public boolean isPlayerPrivilegedToAccessEntity(Player p, int entityId) { public boolean isPlayerPrivilegedToAccessEntity(Player p, int entityId) {
return false; return true;
} }
@Override @Override
public boolean isPlayerPrivilegedToAccessBlocEntity(Player p, int blockX, int blockY, int blockZ, BlockEntityType<?> type) { public boolean isPlayerPrivilegedToAccessBlocEntity(Player p, int blockX, int blockY, int blockZ, BlockEntityType<?> type) {
//Region hiddenRegion = getHiddenRegion(p); //Region hiddenRegion = getHiddenRegion(p);
//return !hiddenRegion.inRegion(blockX, blockY, blockZ) || !blockEntityTypeToObfuscate.contains(type); //return !hiddenRegion.inRegion(blockX, blockY, blockZ) || !blockEntityTypeToObfuscate.contains(type);
return false; return true;
} }
@Override @Override
public boolean isPlayerPrivilegedToAccessContainer(Player p, int containerId) { public boolean isPlayerPrivilegedToAccessContainer(Player p, int containerId) {
return false; return true;
} }
@Override @Override
public boolean isPlayerPrivilegedToAccessSound(Player p, ResourceLocation soundId) { public boolean isPlayerPrivilegedToAccessSound(Player p, ResourceLocation soundId) {
return false; return true;
} }
}; };
@@ -22,27 +22,20 @@ package de.steamwar.techhider;
import de.steamwar.Reflection; import de.steamwar.Reflection;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import lombok.Getter; import it.unimi.dsi.fastutil.ints.IntArrayList;
import net.minecraft.core.Registry;
import net.minecraft.core.SectionPos; import net.minecraft.core.SectionPos;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData; import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData;
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.SimpleBitStorage; 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 org.bukkit.craftbukkit.util.CraftMagicNumbers; import net.minecraft.world.level.block.state.BlockState;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.*; import java.util.*;
import java.util.function.BiFunction;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
public abstract class ChunkHider { public abstract class ChunkHider {
@@ -63,16 +56,21 @@ public abstract class ChunkHider {
private final byte BITS_PER_LONG = 64; private final byte BITS_PER_LONG = 64;
private final int blockIdUsedForHiding = 121; private final int blockIdUsedForHiding = 315;
public ChunkHider(Block blockUsedForObfuscation) { public ChunkHider(Block blockUsedForObfuscation) {
// blockIdUsedForHiding = Block.BLOCK_STATE_REGISTRY.getId(blockUsedForObfuscation.defaultBlockState()); // blockIdUsedForHiding = Block.BLOCK_STATE_REGISTRY.getId(blockUsedForObfuscation.defaultBlockState());
} }
private long[] readSectionDataFromBuffer(ByteBuf dataSource, short bitsPerEntry, int entryCount) { private int getLongsRequiredToEncodeEntries(int bitsPerEntry, int entryCount) {
int entriesPerLong = BITS_PER_LONG / bitsPerEntry; int entriesPerLong = BITS_PER_LONG / bitsPerEntry;
int dataLengthAsLongCount = (entryCount + entriesPerLong - 1) / entriesPerLong; int dataLengthAsLongCount = (entryCount + entriesPerLong - 1) / entriesPerLong;
return dataLengthAsLongCount;
}
private long[] readSectionDataFromBuffer(ByteBuf dataSource, short bitsPerEntry, int entryCount) {
int dataLengthAsLongCount = getLongsRequiredToEncodeEntries(bitsPerEntry, entryCount);
long[] dataArray = new long[dataLengthAsLongCount]; long[] dataArray = new long[dataLengthAsLongCount];
for(int i = 0; i < dataLengthAsLongCount; i++){ for(int i = 0; i < dataLengthAsLongCount; i++){
@@ -109,8 +107,6 @@ public abstract class ChunkHider {
int palletLength = ProtocolUtils.readVarInt(in); int palletLength = ProtocolUtils.readVarInt(in);
int[] pallet = ProtocolUtils.readVarIntArray(in, palletLength); int[] pallet = ProtocolUtils.readVarIntArray(in, palletLength);
System.out.println(Arrays.toString(pallet));
long[] rawData = readSectionDataFromBuffer(in, bitsPerBlock, BLOCKS_PER_SECTION); long[] rawData = readSectionDataFromBuffer(in, bitsPerBlock, BLOCKS_PER_SECTION);
SimpleBitStorage data = new SimpleBitStorage(bitsPerBlock, BLOCKS_PER_SECTION, rawData); SimpleBitStorage data = new SimpleBitStorage(bitsPerBlock, BLOCKS_PER_SECTION, rawData);
@@ -120,42 +116,30 @@ public abstract class ChunkHider {
resolvedData[i] = pallet[palletReference]; resolvedData[i] = pallet[palletReference];
} }
int[] obfuscatedData = new int[BLOCKS_PER_SECTION]; int[] obfuscatedBlockData = obfuscateBlockDataArray(player, chunkX, chunkZ, yOffset, resolvedData);
for (int sectionY = 0; sectionY < 16; sectionY++) {
for (int sectionZ = 0; sectionZ < 16; sectionZ++) {
for (int sectionX = 0; sectionX < 16; sectionX++) {
int blockDataIndex = (((sectionY * 16) + sectionZ) * 16) + sectionX;
int worldX = sectionX * chunkX; long[] reEncodedData = encodeDirectBlockDataArray(obfuscatedBlockData);
int worldY = sectionY * yOffset;
int worldZ = sectionZ * chunkZ;
int blockId = resolvedData[blockDataIndex];
System.out.println("DEV - " + blockId);
Block block = BuiltInRegistries.BLOCK.get(blockId).get().value();
if(isPlayerPrivilegedToAccessPosition(player, worldX, worldY, worldZ) && isPlayerPrivilegedToAccessBlock(player, worldX, worldY, worldZ, block)) { out.writeShort(blockCount);
obfuscatedData[blockDataIndex] = blockId; out.writeByte(15);
for(long rawDataSegment : reEncodedData) {
out.writeLong(rawDataSegment);
} }
else { /*
obfuscatedData[blockDataIndex] = blockIdUsedForHiding;
}
}
}
}
Int2IntMap blockIdToPalletIndex = new Int2IntOpenHashMap(); Int2IntMap blockIdToPalletIndex = new Int2IntOpenHashMap();
int[] newPallet = new int[palletLength]; IntArrayList newPallet = new IntArrayList();
int runningIndex = 0;
for(int blockId : obfuscatedData) { for(int blockId : obfuscatedData) {
if(!blockIdToPalletIndex.containsKey(blockId)) { if(!blockIdToPalletIndex.containsKey(blockId)) {
newPallet[runningIndex] = blockId; newPallet.add(blockId);
blockIdToPalletIndex.put(blockId, runningIndex); blockIdToPalletIndex.put(blockId, newPallet.size());
runningIndex++;
} }
} }
byte newBitsPerBlock = (byte) getUnsignedBitLength(newPallet.size());
int[] newPalletRaw = newPallet.toArray(new int[newPallet.size()]);
SimpleBitStorage reEncodedData = new SimpleBitStorage(bitsPerBlock, BLOCKS_PER_SECTION, new long[rawData.length]); SimpleBitStorage reEncodedData = new SimpleBitStorage(bitsPerBlock, BLOCKS_PER_SECTION, new long[rawData.length]);
for(int i = 0; i < obfuscatedData.length; i++) { for(int i = 0; i < obfuscatedData.length; i++) {
int blockId = obfuscatedData[i]; int blockId = obfuscatedData[i];
@@ -164,56 +148,28 @@ public abstract class ChunkHider {
reEncodedData.set(i, palletReference); reEncodedData.set(i, palletReference);
} }
out.writeByte(blockCount); out.writeShort(blockCount);
out.writeByte(bitsPerBlock); out.writeByte(newBitsPerBlock);
ProtocolUtils.writeVarInt(out, palletLength); ProtocolUtils.writeVarInt(out, palletLength);
ProtocolUtils.writeVarIntArray(out, pallet); ProtocolUtils.writeVarIntArray(out, newPalletRaw);
for(long rawDataSegment : reEncodedData.getRaw()) { for(long rawDataSegment : reEncodedData.getRaw()) {
out.writeLong(rawDataSegment); out.writeLong(rawDataSegment);
} }*/
} }
else { else {
long[] rawData = readSectionDataFromBuffer(in, bitsPerBlock, BLOCKS_PER_SECTION); long[] rawData = readSectionDataFromBuffer(in, bitsPerBlock, BLOCKS_PER_SECTION);
SimpleBitStorage data = new SimpleBitStorage(bitsPerBlock, BLOCKS_PER_SECTION, rawData);
int[] resolvedData = new int[BLOCKS_PER_SECTION]; int[] blockData = resolveDirectBlockDataArray(rawData, bitsPerBlock);
for(int i = 0; i < BLOCKS_PER_SECTION; i++){
resolvedData[i] = data.get(i);
}
int[] obfuscatedData = new int[BLOCKS_PER_SECTION]; int[] obfuscatedBlockData = obfuscateBlockDataArray(player, chunkX, chunkZ, yOffset, blockData);
for (int sectionY = 0; sectionY < 16; sectionY++) {
for (int sectionZ = 0; sectionZ < 16; sectionZ++) {
for (int sectionX = 0; sectionX < 16; sectionX++) {
int blockDataIndex = (((sectionY * 16) + sectionZ) * 16) + sectionX;
int worldX = sectionX * chunkX; long[] reEncodedData = encodeDirectBlockDataArray(obfuscatedBlockData);
int worldY = sectionY * yOffset;
int worldZ = sectionZ * chunkZ;
int blockId = resolvedData[blockDataIndex];
Block block = BuiltInRegistries.BLOCK.get(blockId).get().value();
if(isPlayerPrivilegedToAccessPosition(player, worldX, worldY, worldZ) && isPlayerPrivilegedToAccessBlock(player, worldX, worldY, worldZ, block)) { out.writeShort(blockCount);
obfuscatedData[blockDataIndex] = blockId; out.writeByte(15);
} for(long rawDataSegment : reEncodedData) {
else {
obfuscatedData[blockDataIndex] = blockIdUsedForHiding;
}
}
}
}
SimpleBitStorage reEncodedData = new SimpleBitStorage(bitsPerBlock, BLOCKS_PER_SECTION, new long[rawData.length]);
for(int i = 0; i < obfuscatedData.length; i++) {
int blockId = obfuscatedData[i];
reEncodedData.set(i, blockId);
}
out.writeByte(blockCount);
out.writeByte(bitsPerBlock);
for(long rawDataSegment : reEncodedData.getRaw()) {
out.writeLong(rawDataSegment); out.writeLong(rawDataSegment);
} }
} }
@@ -235,6 +191,60 @@ public abstract class ChunkHider {
} }
private int[] obfuscateBlockDataArray(Player player, int chunkX, int chunkZ, int yOffset, int[] blockDataArray) {
int[] obfuscatedData = new int[BLOCKS_PER_SECTION];
for (int sectionY = 0; sectionY < SECTION_SPAN_SIZE; sectionY++) {
for (int sectionZ = 0; sectionZ < SECTION_SPAN_SIZE; sectionZ++) {
for (int sectionX = 0; sectionX < SECTION_SPAN_SIZE; sectionX++) {
int blockDataIndex = (((sectionY * SECTION_SPAN_SIZE) + sectionZ) * SECTION_SPAN_SIZE) + sectionX;
int worldX = sectionX + (SECTION_SPAN_SIZE * chunkX);
int worldY = sectionY + yOffset;
int worldZ = sectionZ + (SECTION_SPAN_SIZE * chunkZ);
int blockId = blockDataArray[blockDataIndex];
BlockState blockState = Block.BLOCK_STATE_REGISTRY.byId(blockId);
Block block = blockState.getBlock();
if(isPlayerPrivilegedToAccessPosition(player, worldX, worldY, worldZ) && isPlayerPrivilegedToAccessBlock(player, worldX, worldY, worldZ, block)) {
obfuscatedData[blockDataIndex] = blockId;
}
else {
obfuscatedData[blockDataIndex] = blockIdUsedForHiding;
}
}
}
}
return obfuscatedData;
}
private int[] resolveDirectBlockDataArray(long[] rawDataArray, byte bitsPerBlock) {
SimpleBitStorage data = new SimpleBitStorage(bitsPerBlock, BLOCKS_PER_SECTION, rawDataArray);
int[] resolvedData = new int[BLOCKS_PER_SECTION];
for(int i = 0; i < BLOCKS_PER_SECTION; i++){
resolvedData[i] = data.get(i);
}
return resolvedData;
}
private long[] encodeDirectBlockDataArray(int[] blockDataArray) {
int longsRequiredToEncodeData = getLongsRequiredToEncodeEntries(15, blockDataArray.length);
SimpleBitStorage reEncodedData = new SimpleBitStorage(15, BLOCKS_PER_SECTION, new long[longsRequiredToEncodeData]);
for(int i = 0; i < blockDataArray.length; i++) {
int blockId = blockDataArray[i];
reEncodedData.set(i, blockId);
}
return reEncodedData.getRaw();
}
public abstract boolean isPlayerPrivilegedToAccessPosition(Player p, int blockX, int blockY, int blockZ); public abstract boolean isPlayerPrivilegedToAccessPosition(Player p, int blockX, int blockY, int blockZ);
public abstract boolean isPlayerPrivilegedToAccessBlock(Player p, int blockX, int blockY, int blockZ, Block block); public abstract boolean isPlayerPrivilegedToAccessBlock(Player p, int blockX, int blockY, int blockZ, Block block);
public abstract boolean isPlayerPrivilegedToAccessBlockEntity(Player p, int blockX, int blockY, int blockZ, BlockEntityType<?> type); public abstract boolean isPlayerPrivilegedToAccessBlockEntity(Player p, int blockX, int blockY, int blockZ, BlockEntityType<?> type);
@@ -273,9 +283,8 @@ public abstract class ChunkHider {
} }
private void copyOverSectionBiomeData(ByteBuf oldData, ByteBuf newData){ private void copyOverSectionBiomeData(ByteBuf oldData, ByteBuf newData){
short bitsPerBiome = oldData.readShort(); short bitsPerBiome = oldData.readByte();
newData.writeShort(bitsPerBiome); newData.writeByte(bitsPerBiome);
System.out.println(bitsPerBiome);
if(bitsPerBiome == 0) { if(bitsPerBiome == 0) {
int sectionBiomeId = ProtocolUtils.readVarInt(oldData); int sectionBiomeId = ProtocolUtils.readVarInt(oldData);
ProtocolUtils.writeVarInt(newData, sectionBiomeId); ProtocolUtils.writeVarInt(newData, sectionBiomeId);
@@ -319,7 +319,10 @@ public abstract class TechHider {
ClientboundUpdateTagsPacket.class, // 7.1.133 Update Tags (play) ClientboundUpdateTagsPacket.class, // 7.1.133 Update Tags (play)
ClientboundPlayerInfoRemovePacket.class, // 7.1.68 Player Info Remove ClientboundPlayerInfoRemovePacket.class, // 7.1.68 Player Info Remove
ClientboundPlayerInfoUpdatePacket.class, // 7.1.69 Player Info Update ClientboundPlayerInfoUpdatePacket.class, // 7.1.69 Player Info Update
ClientboundMoveVehiclePacket.class // 7.1.56 Move Vehicle (vehicle the player is in) ClientboundMoveVehiclePacket.class, // 7.1.56 Move Vehicle (vehicle the player is in)
//TODO rem later
ClientboundBundlePacket.class
)); ));
BiFunction<Player, Packet<? extends PacketListener>, Packet<? extends PacketListener>> tossPacket = (p, packet) -> null; BiFunction<Player, Packet<? extends PacketListener>, Packet<? extends PacketListener>> tossPacket = (p, packet) -> null;
@@ -368,6 +371,10 @@ public abstract class TechHider {
processors.put(ClientboundPlayerCombatKillPacket.class, this.buildEntityPacketProcessor(ClientboundPlayerCombatKillPacket::playerId)); processors.put(ClientboundPlayerCombatKillPacket.class, this.buildEntityPacketProcessor(ClientboundPlayerCombatKillPacket::playerId));
// 7.1.52/53/55 Update Entity Position/Rotation: entity id and movement signal. // 7.1.52/53/55 Update Entity Position/Rotation: entity id and movement signal.
processors.put(ClientboundMoveEntityPacket.class, (p, packet) -> this.processMoveEntityPacket(p, (ClientboundMoveEntityPacket) packet)); processors.put(ClientboundMoveEntityPacket.class, (p, packet) -> this.processMoveEntityPacket(p, (ClientboundMoveEntityPacket) packet));
processors.put(ClientboundMoveEntityPacket.Pos.class, (p, packet) -> this.processMoveEntityPacket(p, (ClientboundMoveEntityPacket.Pos) packet));
processors.put(ClientboundMoveEntityPacket.Rot.class, (p, packet) -> this.processMoveEntityPacket(p, (ClientboundMoveEntityPacket.Rot) packet));
processors.put(ClientboundMoveEntityPacket.PosRot.class, (p, packet) -> this.processMoveEntityPacket(p, (ClientboundMoveEntityPacket.PosRot) packet));
// 7.1.82 Set Head Rotation: entity id and rotation. // 7.1.82 Set Head Rotation: entity id and rotation.
processors.put(ClientboundRotateHeadPacket.class, (p, packet) -> this.processRotateHeadPacket(p, (ClientboundRotateHeadPacket) packet)); processors.put(ClientboundRotateHeadPacket.class, (p, packet) -> this.processRotateHeadPacket(p, (ClientboundRotateHeadPacket) packet));
// 7.1.76 Remove Entities: entity id visibility side channel. // 7.1.76 Remove Entities: entity id visibility side channel.
@@ -445,18 +452,19 @@ public abstract class TechHider {
this.packetProcessors = processors; this.packetProcessors = processors;
TinyProtocol.instance.addGlobalClientboundFilter((player, packet) -> { TinyProtocol.instance.addGlobalClientboundFilter((player, packet) -> {
System.out.println(packet.getClass().toString());
if(bypassingPackets.contains(packet.getClass())) { if(bypassingPackets.contains(packet.getClass())) {
System.out.println("bypassing");
return packet; return packet;
} }
else if(packetProcessors.containsKey(packet.getClass())) { else if(packetProcessors.containsKey(packet.getClass())) {
System.out.println("processing"); //System.out.println("processing");
//System.out.println(packet.getClass());
return packetProcessors.get(packet.getClass()).apply(player, (Packet<? extends PacketListener>) packet); return packetProcessors.get(packet.getClass()).apply(player, (Packet<? extends PacketListener>) packet);
} }
else { else {
System.out.println("dropping"); System.out.println("dropping");
System.out.println(packet.getClass());
return null; return null;
} }
}); });
@@ -608,9 +616,12 @@ public abstract class TechHider {
int worldZ = sectionPos.relativeToBlockZ(posShort); int worldZ = sectionPos.relativeToBlockZ(posShort);
if (isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ) && isPlayerPrivilegedToAccessBlock(p, worldX, worldY, worldZ, block)) { if (isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ) && isPlayerPrivilegedToAccessBlock(p, worldX, worldY, worldZ, block)) {
// TODO statefull !!!
modified = true;
filteredPos.add(posShort); filteredPos.add(posShort);
filteredStates.add(state); filteredStates.add(state);
} else if(isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ)){ } else if(isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ)){
modified = true;
filteredPos.add(posShort); filteredPos.add(posShort);
filteredStates.add(blockStateUsedForObfuscation); filteredStates.add(blockStateUsedForObfuscation);
} }