diff --git a/FightSystem_10/src/de/steamwar/fightsystem/utils/WaterRemover_10.java b/FightSystem_10/src/de/steamwar/fightsystem/utils/WaterRemover_10.java index fe3ddcc..4583277 100644 --- a/FightSystem_10/src/de/steamwar/fightsystem/utils/WaterRemover_10.java +++ b/FightSystem_10/src/de/steamwar/fightsystem/utils/WaterRemover_10.java @@ -1,11 +1,11 @@ package de.steamwar.fightsystem.utils; -import org.bukkit.Material; +import org.bukkit.block.Block; class WaterRemover_10 { private WaterRemover_10(){} - static boolean isWater(Material type){ - return WaterRemover_8.isWater(type); + static boolean isWater(Block block){ + return WaterRemover_8.isWater(block); } } diff --git a/FightSystem_12/src/de/steamwar/fightsystem/utils/WaterRemover_12.java b/FightSystem_12/src/de/steamwar/fightsystem/utils/WaterRemover_12.java index cefc2ba..0040633 100644 --- a/FightSystem_12/src/de/steamwar/fightsystem/utils/WaterRemover_12.java +++ b/FightSystem_12/src/de/steamwar/fightsystem/utils/WaterRemover_12.java @@ -1,11 +1,11 @@ package de.steamwar.fightsystem.utils; -import org.bukkit.Material; +import org.bukkit.block.Block; class WaterRemover_12 { private WaterRemover_12(){} - static boolean isWater(Material type){ - return WaterRemover_8.isWater(type); + static boolean isWater(Block block){ + return WaterRemover_8.isWater(block); } } diff --git a/FightSystem_14/src/de/steamwar/fightsystem/utils/TechHider_14.java b/FightSystem_14/src/de/steamwar/fightsystem/utils/TechHider_14.java index 46263f9..81c931a 100644 --- a/FightSystem_14/src/de/steamwar/fightsystem/utils/TechHider_14.java +++ b/FightSystem_14/src/de/steamwar/fightsystem/utils/TechHider_14.java @@ -59,8 +59,7 @@ public class TechHider_14 { boolean changed = false; for(int i = nmsTags.size() - 1; i >= 0; i--){ NbtBase nbtBase = nmsTags.get(i); - if(!(nbtBase instanceof NbtCompound)) - throw new SecurityException("Hä?" + nbtBase.getClass().getName()); + assert nbtBase instanceof NbtCompound; NbtCompound nbt = (NbtCompound) nbtBase; if(Config.HiddenBlockEntities.contains(nbt.getString("id"))){ nmsTags.remove(i); diff --git a/FightSystem_14/src/de/steamwar/fightsystem/utils/WaterRemover_14.java b/FightSystem_14/src/de/steamwar/fightsystem/utils/WaterRemover_14.java index 2e173bf..524352f 100644 --- a/FightSystem_14/src/de/steamwar/fightsystem/utils/WaterRemover_14.java +++ b/FightSystem_14/src/de/steamwar/fightsystem/utils/WaterRemover_14.java @@ -1,11 +1,21 @@ package de.steamwar.fightsystem.utils; import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Waterlogged; class WaterRemover_14 { private WaterRemover_14(){} - static boolean isWater(Material type){ - return type == Material.WATER; + static boolean isWater(Block block){ + if(block.getType() == Material.WATER) + return true; + + BlockData data = block.getBlockData(); + if(!(data instanceof Waterlogged)) + return false; + + return ((Waterlogged) data).isWaterlogged(); } } 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 75bbd25..3c39021 100644 --- a/FightSystem_15/src/de/steamwar/fightsystem/utils/TechHider_15.java +++ b/FightSystem_15/src/de/steamwar/fightsystem/utils/TechHider_15.java @@ -1,10 +1,26 @@ package de.steamwar.fightsystem.utils; +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +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.nbt.NbtBase; +import com.comphenix.protocol.wrappers.nbt.NbtCompound; +import de.steamwar.fightsystem.Config; +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.craftbukkit.v1_15_R1.CraftChunk; import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; import org.bukkit.entity.Player; +import java.util.List; + +import static de.steamwar.fightsystem.utils.ITechHider.bypass; + public class TechHider_15 { private TechHider_15(){} @@ -13,7 +29,112 @@ public class TechHider_15 { } static void start(){ - TechHider_14.chunkHider(); + chunkHider(); + } + + static void chunkHider(){ + ProtocolLibrary.getProtocolManager().getAsynchronousManager().registerAsyncHandler(new PacketAdapter(IFightSystem.getPlugin(), PacketType.Play.Server.MAP_CHUNK) { + @Override + public void onPacketSending(PacketEvent e) { + PacketContainer packet = e.getPacket(); + StructureModifier ints = packet.getIntegers(); + + int chunkX = ints.read(0); + int chunkZ = ints.read(1); + Player p = e.getPlayer(); + if(bypass(p, chunkX, chunkZ)) + return; + + PacketContainer cached = ITechHider.packetCache.get(packet); + if(cached != null){ + e.setPacket(cached); + return; + } + + cached = packet.shallowClone(); + ITechHider.packetCache.put(packet, cached); + e.setPacket(cached); + StructureModifier>> list = cached.getListNbtModifier(); + List> nmsTags = list.read(0); + boolean changed = false; + for(int i = nmsTags.size() - 1; i >= 0; i--){ + NbtBase nbtBase = nmsTags.get(i); + assert nbtBase instanceof NbtCompound; + NbtCompound nbt = (NbtCompound) nbtBase; + if(Config.HiddenBlockEntities.contains(nbt.getString("id"))){ + nmsTags.remove(i); + changed = true; + } + } + if(changed){ + list.write(0, nmsTags); + } + + 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){ + buffer.writeBytes(data, i, 2); // Block count + i += 2; + byte bitsPerBlock = data[i++]; + buffer.writeByte(bitsPerBlock); + if(bitsPerBlock < 4) + bitsPerBlock = 4; + else if(bitsPerBlock > 8){ + bitsPerBlock = 14; + buffer.writeByte(data[++i]); + } + + if(bitsPerBlock != 14){ + int paletteLength = ITechHider.readVarInt(data, i); + int paletteLengthLength = ITechHider.readVarIntLength(data, i); + buffer.writeBytes(data, i, paletteLengthLength); + i += paletteLengthLength; + for(int actPaletteId = 0; actPaletteId < paletteLength; actPaletteId++){ + int blockId = ITechHider.readVarInt(data, i); + int actPaletteLength = ITechHider.readVarIntLength(data, i); + + if(Config.HiddenBlocks.contains(blockId)){ + byte[] a = ITechHider.writeVarInt(Config.ObfuscateWith); + buffer.writeBytes(a); + changed = true; + }else{ + buffer.writeBytes(data, i, actPaletteLength); + } + i += actPaletteLength; + } + int dataArrayLength = ITechHider.readVarInt(data, i); + int dataArrayLengthLength = ITechHider.readVarIntLength(data, i); + buffer.writeBytes(data, i, dataArrayLength * 8 + dataArrayLengthLength); + i += dataArrayLengthLength; + i += dataArrayLength * 8; + }else{ + int dataArrayLength = ITechHider.readVarInt(data, i); + int dataArrayLengthLength = ITechHider.readVarIntLength(data, i); + buffer.writeBytes(data, i, dataArrayLength*8 + dataArrayLengthLength); + i += dataArrayLengthLength; + i += dataArrayLength * 8; + } + numChunkSections--; + } + buffer.writeBytes(data, i, data.length - i); + + if(changed){ + data = new byte[buffer.readableBytes()]; + buffer.readBytes(data); + byteArray.write(0, data); + } + } + }).start(ITechHider.threadMultiplier * 4); } } diff --git a/FightSystem_15/src/de/steamwar/fightsystem/utils/WaterRemover_15.java b/FightSystem_15/src/de/steamwar/fightsystem/utils/WaterRemover_15.java index 73bf6e6..2d9191b 100644 --- a/FightSystem_15/src/de/steamwar/fightsystem/utils/WaterRemover_15.java +++ b/FightSystem_15/src/de/steamwar/fightsystem/utils/WaterRemover_15.java @@ -1,11 +1,11 @@ package de.steamwar.fightsystem.utils; -import org.bukkit.Material; +import org.bukkit.block.Block; class WaterRemover_15 { private WaterRemover_15(){} - static boolean isWater(Material type){ - return WaterRemover_14.isWater(type); + static boolean isWater(Block block){ + return WaterRemover_14.isWater(block); } } diff --git a/FightSystem_8/src/de/steamwar/fightsystem/utils/WaterRemover_8.java b/FightSystem_8/src/de/steamwar/fightsystem/utils/WaterRemover_8.java index e4d1c23..0360a49 100644 --- a/FightSystem_8/src/de/steamwar/fightsystem/utils/WaterRemover_8.java +++ b/FightSystem_8/src/de/steamwar/fightsystem/utils/WaterRemover_8.java @@ -1,11 +1,13 @@ package de.steamwar.fightsystem.utils; import org.bukkit.Material; +import org.bukkit.block.Block; public class WaterRemover_8 { private WaterRemover_8(){} - static boolean isWater(Material type){ + static boolean isWater(Block block){ + Material type = block.getType(); return type == Material.WATER || type == Material.STATIONARY_WATER; } } diff --git a/FightSystem_9/src/de/steamwar/fightsystem/utils/WaterRemover_9.java b/FightSystem_9/src/de/steamwar/fightsystem/utils/WaterRemover_9.java index 3243269..ddb621b 100644 --- a/FightSystem_9/src/de/steamwar/fightsystem/utils/WaterRemover_9.java +++ b/FightSystem_9/src/de/steamwar/fightsystem/utils/WaterRemover_9.java @@ -1,11 +1,12 @@ package de.steamwar.fightsystem.utils; import org.bukkit.Material; +import org.bukkit.block.Block; class WaterRemover_9 { private WaterRemover_9(){} - static boolean isWater(Material type){ - return WaterRemover_8.isWater(type); + static boolean isWater(Block block){ + return WaterRemover_8.isWater(block); } } diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/utils/WaterRemover.java b/FightSystem_Main/src/de/steamwar/fightsystem/utils/WaterRemover.java index 08eeeda..64ef49e 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/utils/WaterRemover.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/utils/WaterRemover.java @@ -14,7 +14,7 @@ public class WaterRemover { private WaterRemover(){} - private static final Map explodedBlocks = new HashMap<>(); + private static final Map explodedBlocks = Collections.synchronizedMap(new HashMap<>()); private static Set waterList = new HashSet<>(); public static void init() { @@ -25,18 +25,16 @@ public class WaterRemover { } public static void add(List l) { - synchronized (explodedBlocks){ - l.forEach((Block b) -> explodedBlocks.put(b.getLocation(), 0)); - } + l.forEach((Block b) -> explodedBlocks.put(b.getLocation(), 0)); } private static void wateredCheck() { - synchronized (explodedBlocks){ + try{ Iterator> it = explodedBlocks.entrySet().iterator(); while (it.hasNext()) { Map.Entry e = it.next(); Block b = e.getKey().getBlock(); - if (isWater(b.getType())) + if (isWater(b)) waterList.add(b); if(b.getType() != Material.AIR){ @@ -48,6 +46,8 @@ public class WaterRemover { if(e.getValue() > 15) it.remove(); } + }catch(ConcurrentModificationException e){ + wateredCheck(); } } @@ -57,7 +57,7 @@ public class WaterRemover { while(it.hasNext()){ Block b = it.next(); blocksToRemove.addAll(getSourceBlocksOfWater(b)); - if (!isWater(b.getType())) + if (!isWater(b)) it.remove(); } @@ -72,13 +72,13 @@ public class WaterRemover { private static void collectBlocks(Block anchor, Set collected, Set visitedBlocks) { if( - !isWater(anchor.getType()) || + !isWater(anchor) || visitedBlocks.contains(anchor) ) return; visitedBlocks.add(anchor); - if (isWater(anchor.getType())) + if (isWater(anchor)) collected.add(anchor); if(visitedBlocks.size() > 100) { @@ -92,20 +92,20 @@ public class WaterRemover { collectBlocks(anchor.getRelative(BlockFace.WEST), collected, visitedBlocks); } - public static boolean isWater(Material type){ + public static boolean isWater(Block block){ switch(Core.getVersion()){ case 15: - return WaterRemover_15.isWater(type); + return WaterRemover_15.isWater(block); case 14: - return WaterRemover_14.isWater(type); + return WaterRemover_14.isWater(block); case 10: - return WaterRemover_10.isWater(type); + return WaterRemover_10.isWater(block); case 9: - return WaterRemover_9.isWater(type); + return WaterRemover_9.isWater(block); case 8: - return WaterRemover_8.isWater(type); + return WaterRemover_8.isWater(block); default: - return WaterRemover_12.isWater(type); + return WaterRemover_12.isWater(block); } } } diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/winconditions/WinconditionWaterTechKO.java b/FightSystem_Main/src/de/steamwar/fightsystem/winconditions/WinconditionWaterTechKO.java index f845bca..3b673a1 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/winconditions/WinconditionWaterTechKO.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/winconditions/WinconditionWaterTechKO.java @@ -3,12 +3,11 @@ package de.steamwar.fightsystem.winconditions; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.fight.Fight; -import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.fight.FightTeam; +import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.utils.WaterRemover; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.Material; import org.bukkit.World; import org.bukkit.scheduler.BukkitTask; @@ -96,8 +95,7 @@ public class WinconditionWaterTechKO extends Wincondition { for(int x = minX; x <= maxX; x++) { for(int y = minY; y <= maxY; y++) { for (int z = minZ; z <= maxZ; z++) { - Material type = WORLD.getBlockAt(x, y, z).getType(); - if (WaterRemover.isWater(type)) + if (WaterRemover.isWater(WORLD.getBlockAt(x, y, z))) teamWater.add(new Location(WORLD, x, y, z)); } }