diff --git a/FightSystem_15/src/de/steamwar/fightsystem/utils/TechHider_15.java b/FightSystem_15/src/de/steamwar/fightsystem/utils/TechHider_15.java index e61ebb9..a872ef0 100644 --- a/FightSystem_15/src/de/steamwar/fightsystem/utils/TechHider_15.java +++ b/FightSystem_15/src/de/steamwar/fightsystem/utils/TechHider_15.java @@ -6,6 +6,9 @@ import com.comphenix.protocol.events.PacketAdapter; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketEvent; import com.comphenix.protocol.reflect.StructureModifier; +import com.comphenix.protocol.wrappers.ChunkCoordIntPair; +import com.comphenix.protocol.wrappers.MultiBlockChangeInfo; +import com.comphenix.protocol.wrappers.WrappedBlockData; import com.comphenix.protocol.wrappers.nbt.NbtBase; import com.comphenix.protocol.wrappers.nbt.NbtCompound; import de.steamwar.fightsystem.Config; @@ -13,10 +16,15 @@ import de.steamwar.fightsystem.IFightSystem; import io.netty.buffer.ByteBuf; import io.netty.buffer.UnpooledByteBufAllocator; import net.minecraft.server.v1_15_R1.PacketPlayOutMapChunk; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; import org.bukkit.craftbukkit.v1_15_R1.CraftChunk; import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; import org.bukkit.entity.Player; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; import java.util.List; import static de.steamwar.fightsystem.utils.ITechHider.bypass; @@ -24,6 +32,9 @@ import static de.steamwar.fightsystem.utils.ITechHider.bypass; public class TechHider_15 { private TechHider_15(){} + private static final World WORLD = Bukkit.getWorlds().get(0); + private static final WrappedBlockData WRAPPED_BLOCK_DATA = WrappedBlockData.createData(ITechHider.obfuscateMaterial); + static void reloadChunk(Player p, ITechHider.ChunkPos chunk){ ((CraftPlayer)p).getHandle().playerConnection.sendPacket(new PacketPlayOutMapChunk(((CraftChunk)p.getWorld().getChunkAt(chunk.x(), chunk.z())).getHandle(), 65535)); } @@ -76,16 +87,17 @@ public class TechHider_15 { changed = false; StructureModifier byteArray = cached.getByteArrays(); int primaryBitMask = ints.read(2); - int numChunkSections = 0; - while(primaryBitMask != 0){ - numChunkSections += primaryBitMask & 1; - primaryBitMask >>= 1; - } byte [] data = byteArray.read(0); ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100); int i = 0; - while(numChunkSections > 0){ + int chunkY = 0; + while(primaryBitMask != 0){ + while((primaryBitMask & 1) == 0){ + primaryBitMask >>= 1; + chunkY++; + } + buffer.writeBytes(data, i, 2); // Block count i += 2; byte bitsPerBlock = data[i++]; @@ -123,11 +135,13 @@ public class TechHider_15 { i += dataArrayLength * 8; }else{ //Full Chunk/no palette, so the chunk has to be crawled through + //This didn't work, so workaround with MultiBlockChange-Packets was created int dataArrayLength = ITechHider.readVarInt(data, i); int dataArrayLengthLength = ITechHider.readVarIntLength(data, i); - buffer.writeBytes(data, i, dataArrayLengthLength); - i += dataArrayLengthLength; + buffer.writeBytes(data, i, dataArrayLengthLength + dataArrayLength * 8); + i += dataArrayLengthLength + dataArrayLength * 8; + /* ByteBuf chunkData = UnpooledByteBufAllocator.DEFAULT.directBuffer(dataArrayLength * 8); chunkData.writeBytes(data, i, dataArrayLength * 8); @@ -153,7 +167,6 @@ public class TechHider_15 { if(Config.HiddenBlocks.contains(blockId)) blockId = Config.ObfuscateWith; - //TODO: Fix last edge cases of Full Chunk techhider //if(blockId > 11336) Should not occur, but occurs result <<= 14; @@ -176,9 +189,15 @@ public class TechHider_15 { buffer.writeLong(result); i += 8; - } + }*/ + + final int cY = chunkY; + Bukkit.getScheduler().runTaskAsynchronously(IFightSystem.getPlugin(), + () -> fullChunkHider(p, chunkX, cY, chunkZ)); } - numChunkSections--; + + primaryBitMask >>= 1; + chunkY++; } buffer.writeBytes(data, i, data.length - i); // MC appends a 0 byte at the end if there is a full chunk, idk why @@ -191,4 +210,39 @@ public class TechHider_15 { }).start(ITechHider.threadMultiplier * 4); } + private static void fullChunkHider(Player player, int chunkX, int chunkY, int chunkZ){ + ArrayList blockChangeList = new ArrayList<>(); + + Location location = new Location(WORLD, chunkX * 16f, chunkY * 16f, chunkZ * 16f); + int maxXp1 = (chunkX+1) * 16; + int maxYp1 = (chunkY+1) * 16; + int maxZp1 = (chunkZ+1) * 16; + while(location.getBlockX() < maxXp1){ + while(location.getBlockY() < maxYp1){ + while(location.getBlockZ() < maxZp1){ + if(Config.HiddenBlockTags.contains(WORLD.getBlockAt(location).getType().name())) + blockChangeList.add(new MultiBlockChangeInfo(location, WRAPPED_BLOCK_DATA)); + location.setZ(location.getZ() + 1); + } + location.setY(location.getY() + 1); + location.setZ(chunkZ * 16f); + } + location.setX(location.getX() + 1); + location.setY(chunkY * 16f); + location.setZ(chunkZ * 16f); + } + + if(blockChangeList.isEmpty()) + return; + + PacketContainer packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.MULTI_BLOCK_CHANGE); + packet.getChunkCoordIntPairs().write(0, new ChunkCoordIntPair(chunkX, chunkZ)); + packet.getMultiBlockChangeInfoArrays().write(0, blockChangeList.toArray(new MultiBlockChangeInfo[0])); + + try { + ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); + } catch (InvocationTargetException e) { + throw new SecurityException("Something went wrong sending the multiblockchange packet", e); + } + } }