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); } }