diff --git a/src/config.yml b/src/config.yml index ec01552..ed5e18e 100644 --- a/src/config.yml +++ b/src/config.yml @@ -50,4 +50,72 @@ Money: Draw: 0 Kits: MemberDefault: default - LeaderDefault: default \ No newline at end of file + LeaderDefault: default +HiddenBlocks: + - 7 + - 8 + - 9 + - 25 + - 27 + - 28 + - 29 + - 33 + - 34 + - 46 + - 49 + - 54 + - 55 + - 63 + - 68 + - 69 + - 70 + - 71 + - 72 + - 75 + - 76 + - 77 + - 93 + - 94 + - 117 + - 131 + - 132 + - 143 + - 146 + - 147 + - 148 + - 149 + - 150 + - 152 + - 154 + - 157 + - 158 + - 165 + - 167 + - 218 + - 219 + - 220 + - 221 + - 223 + - 224 + - 225 + - 226 + - 227 + - 228 + - 229 + - 230 + - 231 + - 232 + - 233 + - 234 +HiddenBlockEntites: + - minecraft:sign + - minecraft:dispenser + - minecraft:chest + - minecraft:trapped_chest + - minecraft:furnace + - minecraft:brewing_stand + - minecraft:hopper + - minecraft:dropper + - minecraft:shulker_box + - minecraft:jukebox + - minecraft:comparator \ No newline at end of file diff --git a/src/me/yaruma/fightsystem/FightSystem.java b/src/me/yaruma/fightsystem/FightSystem.java index 1a015d3..665dc97 100644 --- a/src/me/yaruma/fightsystem/FightSystem.java +++ b/src/me/yaruma/fightsystem/FightSystem.java @@ -6,6 +6,7 @@ import me.yaruma.fightsystem.fight.*; import me.yaruma.fightsystem.kit.KitManager; import me.yaruma.fightsystem.listener.*; import me.yaruma.fightsystem.utils.Config; +import me.yaruma.fightsystem.utils.TechHider; import me.yaruma.fightsystem.utils.WorldEdit; import me.yaruma.fightsystem.utils.countdown.Countdown; import me.yaruma.fightsystem.utils.countdown.FinishNoPlayersOnline; @@ -66,12 +67,7 @@ public class FightSystem extends JavaPlugin { Countdown countdown = new Countdown(Config.NoPlayerOnlineDuration, new FinishNoPlayersOnline()); countdown.startTimer(getPlugin()); - /*ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(this, ListenerPriority.NORMAL, PacketType.Play.Server.MAP_CHUNK) { - @Override - public void onPacketSending(PacketEvent e) { - e.getPacket(); - } - });*/ + TechHider.init(); } public void onDisable() { diff --git a/src/me/yaruma/fightsystem/utils/Config.java b/src/me/yaruma/fightsystem/utils/Config.java index 344107b..01b483b 100644 --- a/src/me/yaruma/fightsystem/utils/Config.java +++ b/src/me/yaruma/fightsystem/utils/Config.java @@ -9,6 +9,7 @@ import org.bukkit.World; import org.bukkit.configuration.file.FileConfiguration; import java.io.File; +import java.util.List; public class Config { @@ -78,6 +79,9 @@ public class Config { public static int ArenaMaxX; public static int ArenaMaxZ; + public static List HiddenBlocks; + public static List HiddenBlockEntities; + public static void load(){ if(!new File("plugins/" + FightSystem.getPlugin().getName() + "/config.yml").exists()) { FightSystem.getPlugin().saveDefaultConfig(); @@ -135,6 +139,9 @@ public class Config { MemberDefault = config.getString("Kits.MemberDefault"); LeaderDefault = config.getString("Kits.LeaderDefault"); + HiddenBlocks = config.getIntegerList("HiddenBlocks"); + HiddenBlockEntities = config.getStringList("HiddenBlockEntities"); + if(SchemsizeX < 0){ SchemsizeX = -SchemsizeX; TeamBlueCornerX -= SchemsizeX; diff --git a/src/me/yaruma/fightsystem/utils/TechHider.java b/src/me/yaruma/fightsystem/utils/TechHider.java new file mode 100644 index 0000000..24631e8 --- /dev/null +++ b/src/me/yaruma/fightsystem/utils/TechHider.java @@ -0,0 +1,265 @@ +package me.yaruma.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.MultiBlockChangeInfo; +import com.comphenix.protocol.wrappers.WrappedBlockData; +import com.comphenix.protocol.wrappers.nbt.NbtCompound; +import com.comphenix.protocol.wrappers.nbt.NbtFactory; +import com.google.common.primitives.Bytes; +import me.yaruma.fightsystem.FightSystem; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + +public class TechHider { + + public static void init(){ + ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Server.MAP_CHUNK) { + @Override + public void onPacketSending(PacketEvent e) { + Player p = e.getPlayer(); + + //TODO: Check for Which chunks to hide + + PacketContainer packet = e.getPacket(); + StructureModifier ints = packet.getIntegers(); + StructureModifier byteArray = packet.getByteArrays(); + StructureModifier list = packet.getSpecificModifier(List.class); + List nmsTags = list.read(0); + + int chunkX = ints.read(0); + int chunkZ = ints.read(1); + + boolean changed = false; + for(int i = nmsTags.size() - 1; i >= 0; i--){ + NbtCompound nbt = NbtFactory.fromNMSCompound(nmsTags.get(i)); + if(nbt.getString("id").equals("minecraft:sign")){ + nmsTags.remove(i); + changed = true; + } + } + if(changed){ + list.write(0, nmsTags); + } + + changed = false; + byte [] data = byteArray.read(0); + List newData = new ArrayList<>(Bytes.asList(data)); + int i = 0; + + while(i < newData.size()){ + byte bitsPerBlock = newData.get(i++); + if(bitsPerBlock < 4) + bitsPerBlock = 4; + else if(bitsPerBlock > 8){ + bitsPerBlock = 13; + i++; + } + + if(bitsPerBlock != 13){ + int paletteLength = readVarInt(Bytes.toArray(newData), i); + i += readVarIntLength(Bytes.toArray(newData), i); + for(int actPaletteId = 0; actPaletteId < paletteLength; actPaletteId++){ + int actPalette = readVarInt(Bytes.toArray(newData), i); + int actPaletteLength = readVarIntLength(Bytes.toArray(newData), i); + + int blockId = actPalette >> 4; + if(Config.HiddenBlocks.contains(blockId)){ + byte[] a = writeVarInt(16); + for(int j = 0; j < actPaletteLength; j++){ + newData.remove(i); + } + for(byte b : a){ + newData.add(i++, b); + } + changed = true; + }else{ + i += actPaletteLength; + } + } + int dataArrayLength = readVarInt(Bytes.toArray(newData), i); + i += readVarIntLength(Bytes.toArray(newData), i); + i += dataArrayLength * 8; + }else{ + System.out.println("Chunk with global palette!"); + int dataArrayLength = readVarInt(Bytes.toArray(newData), i); + i += readVarIntLength(Bytes.toArray(newData), i); + int arrayEnd = dataArrayLength * 8 + i; + int bitsOver = 8; //9 bits (id) + 4 bits (metadata) + final int globalMask = 0x000001FF; + final byte replacement = 0x01; + while(i < arrayEnd){ + int blockId = (newData.get(i++) & (globalMask >> 9 - bitsOver)) << 9-bitsOver; + blockId += newData.get(i) >> bitsOver-1; + if(Config.HiddenBlocks.contains(blockId)){ + System.out.println("Hidden Block found!"); + } + bitsOver -= 5; // 13-8 + if(bitsOver < 1){ + i++; + bitsOver += 8; + } + } + //i += dataArrayLength * 8; + } + + i += 4096; //Skylight (Not in Nether/End!!!) 2048 + Blocklight 2048 + } + + if(changed){ + byteArray.write(0, Bytes.toArray(newData)); + } + } + }); + ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Server.BLOCK_CHANGE) { + @Override + public void onPacketSending(PacketEvent e) { + Player p = e.getPlayer(); + //TODO: Check for Which chunks to hide + + PacketContainer packet = e.getPacket(); + StructureModifier blockStructure = packet.getBlockData(); + + WrappedBlockData block = packet.getBlockData().read(0); + if(Config.HiddenBlocks.contains(block.getType().getId())){ + block.setType(Material.STONE); + blockStructure.write(0, block); + e.setCancelled(true); + } + } + }); + ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Server.MULTI_BLOCK_CHANGE) { + @Override + public void onPacketSending(PacketEvent e) { + Player p = e.getPlayer(); + //TODO: Check for Which chunks to hide + + PacketContainer packet = e.getPacket(); + StructureModifier blockStructure = packet.getMultiBlockChangeInfoArrays(); + MultiBlockChangeInfo[] changes = blockStructure.read(0); + boolean changed = false; + + int i = 0; + for(MultiBlockChangeInfo mbci : changes){ + WrappedBlockData block = mbci.getData(); + if(Config.HiddenBlocks.contains(block.getType().getId())){ + changed = true; + block.setType(Material.STONE); + mbci.setData(block); + } + i++; + } + + if(changed){ + blockStructure.write(0, changes); + } + } + }); + ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Server.BLOCK_ACTION) { + @Override + public void onPacketSending(PacketEvent e) { + Player p = e.getPlayer(); + //TODO: Check for Which chunks to hide + + PacketContainer packet = e.getPacket(); + + e.setCancelled(true); + } + }); + ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(FightSystem.getPlugin(), PacketType.Play.Client.USE_ITEM) { + @Override + public void onPacketReceiving(PacketEvent e) { + Player p = e.getPlayer(); + //TODO: Check for Which chunks to hide + + PacketContainer packet = e.getPacket(); + + System.out.println("EntityUse!"); + e.setCancelled(true); + } + }); + } + + public static int readVarInt(byte[] array, int startPos) { + int numRead = 0; + int result = 0; + byte read; + do { + read = array[startPos + numRead]; + int value = (read & 0b01111111); + result |= (value << (7 * numRead)); + + numRead++; + if (numRead > 5) { + break; + } + } while ((read & 0b10000000) != 0); + + return result; + } + + public static int readVarIntLength(byte[] array, int startPos) { + int numRead = 0; + byte read; + do { + read = array[startPos + numRead]; + numRead++; + if (numRead > 5) { + break; + } + } while ((read & 0b10000000) != 0); + + return numRead; + } + + public static long readVarLong() { + int numRead = 0; + long result = 0; + byte read = 0; + do { + //read = readByte(); + int value = (read & 0b01111111); + result |= (value << (7 * numRead)); + + numRead++; + if (numRead > 10) { + break; + } + } while ((read & 0b10000000) != 0); + + return result; + } + + public static byte[] writeVarInt(int value) { + ArrayList buffer = new ArrayList<>(); + do { + byte temp = (byte)(value & 0b01111111); + // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone + value >>>= 7; + if (value != 0) { + temp |= 0b10000000; + } + buffer.add(temp); + } while (value != 0); + return Bytes.toArray(buffer); + } + + public static void writeVarLong(long value) { + do { + byte temp = (byte)(value & 0b01111111); + // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone + value >>>= 7; + if (value != 0) { + temp |= 0b10000000; + } + //writeByte(temp); + } while (value != 0); + } +}