diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java index 1160b650..9f1ab63b 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java @@ -74,29 +74,30 @@ public class TechHiderWrapper extends StateDependent implements Listener { @Override public boolean isPlayerPrivilegedToAccessBlock(Player p, int blockX, int blockY, int blockZ, Block block) { Region hiddenRegion = getHiddenRegion(p); - return !hiddenRegion.inRegion(blockX, blockY, blockZ) || !blocksToObfuscate.contains(block) ; + return !hiddenRegion.inRegion(blockX, blockY, blockZ) || !blocksToObfuscate.contains(block); } + // TODO @Override public boolean isPlayerPrivilegedToAccessEntity(Player p, int entityId) { - return false; + return true; } @Override public boolean isPlayerPrivilegedToAccessBlocEntity(Player p, int blockX, int blockY, int blockZ, BlockEntityType type) { //Region hiddenRegion = getHiddenRegion(p); //return !hiddenRegion.inRegion(blockX, blockY, blockZ) || !blockEntityTypeToObfuscate.contains(type); - return false; + return true; } @Override public boolean isPlayerPrivilegedToAccessContainer(Player p, int containerId) { - return false; + return true; } @Override public boolean isPlayerPrivilegedToAccessSound(Player p, ResourceLocation soundId) { - return false; + return true; } }; diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java index d643dd44..01a0fdfe 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java @@ -22,27 +22,20 @@ package de.steamwar.techhider; import de.steamwar.Reflection; import io.netty.buffer.ByteBuf; 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.Int2IntOpenHashMap; -import lombok.Getter; -import net.minecraft.core.Registry; +import it.unimi.dsi.fastutil.ints.IntArrayList; 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.ClientboundLevelChunkWithLightPacket; -import net.minecraft.resources.ResourceLocation; import net.minecraft.util.SimpleBitStorage; import net.minecraft.world.level.block.Block; 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 java.util.*; -import java.util.function.BiFunction; import java.util.function.UnaryOperator; -import java.util.stream.Collectors; public abstract class ChunkHider { @@ -63,16 +56,21 @@ public abstract class ChunkHider { private final byte BITS_PER_LONG = 64; - private final int blockIdUsedForHiding = 121; + private final int blockIdUsedForHiding = 315; public ChunkHider(Block blockUsedForObfuscation) { // 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 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]; for(int i = 0; i < dataLengthAsLongCount; i++){ @@ -109,8 +107,6 @@ public abstract class ChunkHider { int palletLength = ProtocolUtils.readVarInt(in); int[] pallet = ProtocolUtils.readVarIntArray(in, palletLength); - System.out.println(Arrays.toString(pallet)); - long[] rawData = readSectionDataFromBuffer(in, bitsPerBlock, BLOCKS_PER_SECTION); SimpleBitStorage data = new SimpleBitStorage(bitsPerBlock, BLOCKS_PER_SECTION, rawData); @@ -120,42 +116,30 @@ public abstract class ChunkHider { resolvedData[i] = pallet[palletReference]; } - int[] obfuscatedData = new int[BLOCKS_PER_SECTION]; - 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[] obfuscatedBlockData = obfuscateBlockDataArray(player, chunkX, chunkZ, yOffset, resolvedData); - int worldX = sectionX * chunkX; - int worldY = sectionY * yOffset; - int worldZ = sectionZ * chunkZ; + long[] reEncodedData = encodeDirectBlockDataArray(obfuscatedBlockData); - 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)) { - obfuscatedData[blockDataIndex] = blockId; - } - else { - obfuscatedData[blockDataIndex] = blockIdUsedForHiding; - } - } - } + out.writeShort(blockCount); + out.writeByte(15); + for(long rawDataSegment : reEncodedData) { + out.writeLong(rawDataSegment); } - + /* Int2IntMap blockIdToPalletIndex = new Int2IntOpenHashMap(); - int[] newPallet = new int[palletLength]; - int runningIndex = 0; + IntArrayList newPallet = new IntArrayList(); for(int blockId : obfuscatedData) { if(!blockIdToPalletIndex.containsKey(blockId)) { - newPallet[runningIndex] = blockId; - blockIdToPalletIndex.put(blockId, runningIndex); - runningIndex++; + newPallet.add(blockId); + blockIdToPalletIndex.put(blockId, newPallet.size()); } } + 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]); for(int i = 0; i < obfuscatedData.length; i++) { int blockId = obfuscatedData[i]; @@ -164,56 +148,28 @@ public abstract class ChunkHider { reEncodedData.set(i, palletReference); } - out.writeByte(blockCount); - out.writeByte(bitsPerBlock); + out.writeShort(blockCount); + out.writeByte(newBitsPerBlock); ProtocolUtils.writeVarInt(out, palletLength); - ProtocolUtils.writeVarIntArray(out, pallet); + ProtocolUtils.writeVarIntArray(out, newPalletRaw); for(long rawDataSegment : reEncodedData.getRaw()) { out.writeLong(rawDataSegment); - } + }*/ + } else { long[] rawData = readSectionDataFromBuffer(in, bitsPerBlock, BLOCKS_PER_SECTION); - SimpleBitStorage data = new SimpleBitStorage(bitsPerBlock, BLOCKS_PER_SECTION, rawData); - int[] resolvedData = new int[BLOCKS_PER_SECTION]; - for(int i = 0; i < BLOCKS_PER_SECTION; i++){ - resolvedData[i] = data.get(i); - } + int[] blockData = resolveDirectBlockDataArray(rawData, bitsPerBlock); - int[] obfuscatedData = new int[BLOCKS_PER_SECTION]; - 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[] obfuscatedBlockData = obfuscateBlockDataArray(player, chunkX, chunkZ, yOffset, blockData); - int worldX = sectionX * chunkX; - int worldY = sectionY * yOffset; - int worldZ = sectionZ * chunkZ; + long[] reEncodedData = encodeDirectBlockDataArray(obfuscatedBlockData); - int blockId = resolvedData[blockDataIndex]; - Block block = BuiltInRegistries.BLOCK.get(blockId).get().value(); - if(isPlayerPrivilegedToAccessPosition(player, worldX, worldY, worldZ) && isPlayerPrivilegedToAccessBlock(player, worldX, worldY, worldZ, block)) { - obfuscatedData[blockDataIndex] = blockId; - } - 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.writeShort(blockCount); + out.writeByte(15); + for(long rawDataSegment : reEncodedData) { 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 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); @@ -273,9 +283,8 @@ public abstract class ChunkHider { } private void copyOverSectionBiomeData(ByteBuf oldData, ByteBuf newData){ - short bitsPerBiome = oldData.readShort(); - newData.writeShort(bitsPerBiome); - System.out.println(bitsPerBiome); + short bitsPerBiome = oldData.readByte(); + newData.writeByte(bitsPerBiome); if(bitsPerBiome == 0) { int sectionBiomeId = ProtocolUtils.readVarInt(oldData); ProtocolUtils.writeVarInt(newData, sectionBiomeId); diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java index 43d27615..f1ec20e0 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java @@ -319,7 +319,10 @@ public abstract class TechHider { ClientboundUpdateTagsPacket.class, // 7.1.133 Update Tags (play) ClientboundPlayerInfoRemovePacket.class, // 7.1.68 Player Info Remove 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, Packet> tossPacket = (p, packet) -> null; @@ -368,6 +371,10 @@ public abstract class TechHider { processors.put(ClientboundPlayerCombatKillPacket.class, this.buildEntityPacketProcessor(ClientboundPlayerCombatKillPacket::playerId)); // 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.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. processors.put(ClientboundRotateHeadPacket.class, (p, packet) -> this.processRotateHeadPacket(p, (ClientboundRotateHeadPacket) packet)); // 7.1.76 Remove Entities: entity id visibility side channel. @@ -445,18 +452,19 @@ public abstract class TechHider { this.packetProcessors = processors; TinyProtocol.instance.addGlobalClientboundFilter((player, packet) -> { - System.out.println(packet.getClass().toString()); + if(bypassingPackets.contains(packet.getClass())) { - System.out.println("bypassing"); return packet; } 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) packet); } else { System.out.println("dropping"); + System.out.println(packet.getClass()); return null; } }); @@ -608,9 +616,12 @@ public abstract class TechHider { int worldZ = sectionPos.relativeToBlockZ(posShort); if (isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ) && isPlayerPrivilegedToAccessBlock(p, worldX, worldY, worldZ, block)) { + // TODO statefull !!! + modified = true; filteredPos.add(posShort); filteredStates.add(state); } else if(isPlayerPrivilegedToAccessPosition(p, worldX, worldY, worldZ)){ + modified = true; filteredPos.add(posShort); filteredStates.add(blockStateUsedForObfuscation); }