diff --git a/FightSystem_12/src/de/steamwar/fightsystem/utils/ProtocolWrapper12.java b/FightSystem_12/src/de/steamwar/fightsystem/utils/ProtocolWrapper12.java new file mode 100644 index 0000000..650fb41 --- /dev/null +++ b/FightSystem_12/src/de/steamwar/fightsystem/utils/ProtocolWrapper12.java @@ -0,0 +1,48 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2021 SteamWar.de-Serverteam + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ + +package de.steamwar.fightsystem.utils; + +import com.comphenix.tinyprotocol.Reflection; +import org.bukkit.entity.Player; + +import java.util.function.BiFunction; +import java.util.function.UnaryOperator; + +public class ProtocolWrapper12 extends ProtocolWrapper8 { + + @Override + public BiFunction blockBreakHiderGenerator(Class blockBreakPacket){ + UnaryOperator blockBreakCloner = ProtocolAPI.shallowCloneGenerator(blockBreakPacket); + Reflection.FieldAccessor blockBreakPosition = Reflection.getField(blockBreakPacket, TechHider.blockPosition, 0); + Reflection.FieldAccessor blockBreakBlockData = Reflection.getField(blockBreakPacket, TechHider.iBlockData, 0); + + return (p, packet) -> { + Object pos = blockBreakPosition.get(packet); + if(TechHider.bypass(p, TechHider.posToChunk(TechHider.blockPositionX.get(pos)), TechHider.posToChunk(TechHider.blockPositionZ.get(pos)))) + return packet; + + if(ProtocolWrapper.impl.iBlockDataHidden(blockBreakBlockData.get(packet))){ + packet = blockBreakCloner.apply(packet); + blockBreakBlockData.set(packet, TechHider.obfuscateIBlockData); + } + return packet; + }; + } +} diff --git a/FightSystem_14/pom.xml b/FightSystem_14/pom.xml index ad025b7..7b82230 100644 --- a/FightSystem_14/pom.xml +++ b/FightSystem_14/pom.xml @@ -37,5 +37,10 @@ FightSystem_Core 1.0 + + steamwar + FightSystem_9 + 1.0 + \ No newline at end of file diff --git a/FightSystem_14/src/de/steamwar/fightsystem/utils/FlatteningWrapper14.java b/FightSystem_14/src/de/steamwar/fightsystem/utils/FlatteningWrapper14.java index 3cd74c0..239c774 100644 --- a/FightSystem_14/src/de/steamwar/fightsystem/utils/FlatteningWrapper14.java +++ b/FightSystem_14/src/de/steamwar/fightsystem/utils/FlatteningWrapper14.java @@ -19,15 +19,12 @@ package de.steamwar.fightsystem.utils; -import com.comphenix.tinyprotocol.Reflection; -import de.steamwar.fightsystem.record.REntity; import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Waterlogged; -import org.bukkit.entity.EntityType; import org.bukkit.event.block.BlockPhysicsEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.BlockDataMeta; @@ -119,24 +116,4 @@ public class FlatteningWrapper14 implements FlatteningWrapper.IFlatteningWrapper public void setNamedSpawnPacketDataWatcher(Object packet) { // field not present } - - private static final Class entityTypes = Reflection.getClass("{nms}.EntityTypes"); - private static final Reflection.FieldAccessor spawnType = Reflection.getField(REntity.spawnPacket, entityTypes, 0); - private static final Object tnt = Reflection.getField(entityTypes, "TNT", entityTypes).get(null); - private static final Object arrow = Reflection.getField(entityTypes, "ARROW", entityTypes).get(null); - private static final Object fireball = Reflection.getField(entityTypes, "FIREBALL", entityTypes).get(null); - @Override - public void setSpawnPacketType(Object packet, EntityType type) { - switch(type) { - case PRIMED_TNT: - spawnType.set(packet, tnt); - break; - case ARROW: - spawnType.set(packet, arrow); - break; - case FIREBALL: - spawnType.set(packet, fireball); - break; - } - } } diff --git a/FightSystem_14/src/de/steamwar/fightsystem/utils/TechHider14.java b/FightSystem_14/src/de/steamwar/fightsystem/utils/TechHider14.java index a391a50..e5674b6 100644 --- a/FightSystem_14/src/de/steamwar/fightsystem/utils/TechHider14.java +++ b/FightSystem_14/src/de/steamwar/fightsystem/utils/TechHider14.java @@ -24,16 +24,11 @@ import io.netty.buffer.UnpooledByteBufAllocator; import java.nio.ByteBuffer; import java.nio.LongBuffer; -import java.util.Set; -import java.util.function.BiFunction; -public class TechHider14 implements BiFunction { - - private final Set hiddenBlockIds = BlockIdWrapper.impl.getHiddenBlockIds(); - private final int obfuscateWith = BlockIdWrapper.impl.getObfuscateWith(); +public class TechHider14 extends TechHider9 { @Override - public byte[] apply(byte[] data, Integer primaryBitMask) { + protected byte[] dataHider(byte[] data, Integer primaryBitMask) { ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100); int i = 0; diff --git a/FightSystem_18/pom.xml b/FightSystem_18/pom.xml new file mode 100644 index 0000000..c3c4daa --- /dev/null +++ b/FightSystem_18/pom.xml @@ -0,0 +1,84 @@ + + + + + 4.0.0 + + + steamwar + FightSystem + 1.0 + + + + ${project.basedir}/.. + + + FightSystem_18 + 1.0 + + + + org.spigotmc + spigot-api + 1.18-R0.1-SNAPSHOT + provided + + + com.mojang + datafixerupper + 4.0.26 + provided + + + io.netty + netty-all + 4.1.68.Final + provided + + + com.mojang + authlib + 1.5.25 + provided + + + steamwar + Spigot + 1.18 + system + ${main.basedir}/lib/Spigot-1.18.jar + + + steamwar + WorldEdit + 1.0 + system + ${main.basedir}/lib/WorldEdit-1.15.jar + + + steamwar + FightSystem_Core + 1.0 + + + \ No newline at end of file diff --git a/FightSystem_18/src/de/steamwar/fightsystem/utils/BlockIdWrapper18.java b/FightSystem_18/src/de/steamwar/fightsystem/utils/BlockIdWrapper18.java new file mode 100644 index 0000000..59811e5 --- /dev/null +++ b/FightSystem_18/src/de/steamwar/fightsystem/utils/BlockIdWrapper18.java @@ -0,0 +1,87 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2021 SteamWar.de-Serverteam + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ + +package de.steamwar.fightsystem.utils; + +import de.steamwar.fightsystem.Config; +import net.minecraft.core.BlockPosition; +import net.minecraft.core.IRegistry; +import net.minecraft.resources.MinecraftKey; +import net.minecraft.server.level.WorldServer; +import net.minecraft.world.entity.EntityPose; +import net.minecraft.world.level.block.state.IBlockData; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.FluidTypes; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.v1_18_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_18_R1.block.CraftBlock; + +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +public class BlockIdWrapper18 implements BlockIdWrapper.IBlockIdWrapper { + + @Override + public int blockToId(Block block) { + return net.minecraft.world.level.block.Block.i(((CraftBlock)block).getNMS()); + } + + @Override + public void setBlock(World world, int x, int y, int z, int blockState) { + IBlockData blockData = Objects.requireNonNull(net.minecraft.world.level.block.Block.a(blockState)); + WorldServer cworld = ((CraftWorld)world).getHandle(); + BlockPosition pos = new BlockPosition(x, y, z); + cworld.m(pos); + cworld.a(pos, blockData, 1042); + cworld.k().a(pos); + } + + @Override + public Set getHiddenBlockIds() { + Set hiddenBlockIds = new HashSet<>(); + for(String tag : Config.HiddenBlocks){ + for(IBlockData data : IRegistry.X.a(new MinecraftKey(tag)).m().a()){ + hiddenBlockIds.add(net.minecraft.world.level.block.Block.i(data)); + } + } + + if(Config.HiddenBlocks.contains("water")){ + Fluid water = FluidTypes.c.h(); + for(IBlockData data : net.minecraft.world.level.block.Block.p) { + if(data.n() == water) { + hiddenBlockIds.add(net.minecraft.world.level.block.Block.i(data)); + } + } + } + + return hiddenBlockIds; + } + + @Override + public int getObfuscateWith() { //ResourceLocation, DefaultedRegistry + return net.minecraft.world.level.block.Block.i(IRegistry.X.a(new MinecraftKey(Config.ObfuscateWith)).n()); + } + + @Override + public Object getPose(boolean sneaking) { + return sneaking ? EntityPose.f : EntityPose.a; + } +} diff --git a/FightSystem_18/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper18.java b/FightSystem_18/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper18.java new file mode 100644 index 0000000..617d61f --- /dev/null +++ b/FightSystem_18/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper18.java @@ -0,0 +1,63 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2021 SteamWar.de-Serverteam + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ + +package de.steamwar.fightsystem.utils; + +import net.minecraft.world.level.chunk.Chunk; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_18_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_18_R1.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_18_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.HashSet; +import java.util.Set; + +public class CraftbukkitWrapper18 implements CraftbukkitWrapper.ICraftbukkitWrapper { + + @Override + public void resetChunk(World world, World backup, int x, int z) { + net.minecraft.world.level.World w = ((CraftWorld) world).getHandle(); + Chunk chunk = w.d(x, z); + Chunk backupChunk = ((CraftWorld) backup).getHandle().d(x, z); + + System.arraycopy(backupChunk.d(), 0, chunk.d(), 0, chunk.d().length); + } + + @Override + public void sendResourcePack(Player player, String pack, String sha1) { + ((CraftPlayer)player).getHandle().a(pack, sha1, true, null); + } + + @Override + public float headRotation(Entity e) { + return ((CraftEntity)e).getHandle().ce(); + } + + @Override + public boolean hasItems(ItemStack stack) { + Set keys = new HashSet<>(CraftItemStack.asNMSCopy(stack).s().d()); + keys.remove("Enchantments"); + keys.remove("Damage"); + return !keys.isEmpty(); + } +} diff --git a/FightSystem_18/src/de/steamwar/fightsystem/utils/ProtocolWrapper18.java b/FightSystem_18/src/de/steamwar/fightsystem/utils/ProtocolWrapper18.java new file mode 100644 index 0000000..54ee416 --- /dev/null +++ b/FightSystem_18/src/de/steamwar/fightsystem/utils/ProtocolWrapper18.java @@ -0,0 +1,130 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2021 SteamWar.de-Serverteam + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ + +package de.steamwar.fightsystem.utils; + +import com.comphenix.tinyprotocol.Reflection; +import com.mojang.authlib.GameProfile; +import com.mojang.datafixers.util.Pair; +import de.steamwar.fightsystem.Config; +import de.steamwar.fightsystem.fight.Fight; +import de.steamwar.fightsystem.record.REntity; +import net.minecraft.core.IRegistry; +import net.minecraft.core.SectionPosition; +import net.minecraft.network.protocol.game.PacketPlayOutBlockBreak; +import net.minecraft.world.entity.EntityTypes; +import net.minecraft.world.level.block.entity.TileEntityTypes; +import net.minecraft.world.level.block.state.IBlockData; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +import java.util.Collections; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.UnaryOperator; + +public class ProtocolWrapper18 implements ProtocolWrapper { + + private static final Reflection.FieldAccessor equipmentStack = Reflection.getField(REntity.equipmentPacket, List.class, 0); + @Override + public void setEquipmentPacketStack(Object packet, String slot, Object stack) { + equipmentStack.set(packet, Collections.singletonList(new Pair<>(getSlot(slot), stack))); + } + + private static final Reflection.FieldAccessor spawnType = Reflection.getField(REntity.spawnPacket, EntityTypes.class, 0); + @Override + public void setSpawnPacketType(Object packet, EntityType type) { + switch(type) { + case PRIMED_TNT: + spawnType.set(packet, EntityTypes.as); + break; + case ARROW: + spawnType.set(packet, EntityTypes.d); + break; + case FIREBALL: + spawnType.set(packet, EntityTypes.S); + break; + } + } + + private static final Class enumItemSlot = Reflection.getClass("{nms.world.entity}.EnumItemSlot"); + private static final Object[] itemSlots = enumItemSlot.getEnumConstants(); + private static Object getSlot(String slot) { + switch(slot){ + case "HEAD": + return itemSlots[5]; + case "CHEST": + return itemSlots[4]; + case "LEGS": + return itemSlots[3]; + case "FEET": + return itemSlots[2]; + case "OFFHAND": + return itemSlots[1]; + case "MAINHAND": + default: + return itemSlots[0]; + } + } + + private static final Reflection.FieldAccessor multiBlockChangeChunk = Reflection.getField(TechHider.multiBlockChangePacket, SectionPosition.class, 0); + private static final Reflection.FieldAccessor multiBlockChangeBlocks = Reflection.getField(TechHider.multiBlockChangePacket, IBlockData[].class, 0); + private static final BiFunction, Object> iBlockDataArrayCloner = ProtocolAPI.arrayCloneGenerator(TechHider.iBlockData); + @Override + public Object multiBlockChangeHider(Player p, Object packet) { + Object chunkCoords = multiBlockChangeChunk.get(packet); + if(TechHider.bypass(p, TechHider.blockPositionX.get(chunkCoords), TechHider.blockPositionZ.get(chunkCoords))) + return packet; + + packet = TechHider.multiBlockChangeCloner.apply(packet); + multiBlockChangeBlocks.set(packet, iBlockDataArrayCloner.apply(multiBlockChangeBlocks.get(packet), block -> ProtocolWrapper.impl.iBlockDataHidden(block) ? TechHider.obfuscateIBlockData : block)); + return packet; + } + + private static final Reflection.FieldAccessor tileEntityType = Reflection.getField(TechHider.tileEntityDataPacket, TileEntityTypes.class, 0); + @Override + public boolean unfilteredTileEntityDataAction(Object packet) { + return tileEntityType.get(packet) != TileEntityTypes.h; + } + + @Override + public BiFunction blockBreakHiderGenerator(Class blockBreakPacket) { + return (p, packet) -> { + PacketPlayOutBlockBreak breakPacket = (PacketPlayOutBlockBreak) packet; + if(TechHider.bypass(p, TechHider.posToChunk(TechHider.blockPositionX.get(breakPacket.b())), TechHider.posToChunk(TechHider.blockPositionZ.get(breakPacket.b())))) + return packet; + + if(!ProtocolWrapper.impl.iBlockDataHidden(breakPacket.c())) + return packet; + + return new PacketPlayOutBlockBreak(breakPacket.b(), (IBlockData) TechHider.obfuscateIBlockData, breakPacket.d(), breakPacket.a()); + }; + } + + private static final Reflection.ConstructorInvoker playerInfoDataConstructor = Reflection.getConstructor(Fight.playerInfoDataClass, GameProfile.class, int.class, Fight.enumGamemode, Fight.iChatBaseComponent); + @Override + public Object playerInfoDataConstructor(Object packet, GameProfile profile, Object mode) { + return playerInfoDataConstructor.invoke(profile, 0, mode, null); + } + + @Override + public boolean iBlockDataHidden(Object iBlockData) { + return Config.HiddenBlocks.contains(IRegistry.X.b(((IBlockData) iBlockData).b()).a()); + } +} diff --git a/FightSystem_18/src/de/steamwar/fightsystem/utils/TechHider18.java b/FightSystem_18/src/de/steamwar/fightsystem/utils/TechHider18.java new file mode 100644 index 0000000..b5fc924 --- /dev/null +++ b/FightSystem_18/src/de/steamwar/fightsystem/utils/TechHider18.java @@ -0,0 +1,174 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2021 SteamWar.de-Serverteam + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ + +package de.steamwar.fightsystem.utils; + +import com.comphenix.tinyprotocol.Reflection; +import de.steamwar.fightsystem.Config; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import net.minecraft.core.IRegistry; +import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData; +import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; +import net.minecraft.world.level.block.entity.TileEntityTypes; +import org.bukkit.World; +import org.bukkit.entity.Player; + +import java.nio.ByteBuffer; +import java.nio.LongBuffer; +import java.util.List; +import java.util.Set; +import java.util.function.IntFunction; +import java.util.function.UnaryOperator; +import java.util.stream.Collectors; + +public class TechHider18 implements TechHider.ChunkHider { + + @Override + public Class mapChunkPacket() { + return ClientboundLevelChunkWithLightPacket.class; + } + + private static final UnaryOperator chunkPacketCloner = ProtocolAPI.shallowCloneGenerator(ClientboundLevelChunkWithLightPacket.class); + private static final UnaryOperator chunkDataCloner = ProtocolAPI.shallowCloneGenerator(ClientboundLevelChunkPacketData.class); + + private static final Reflection.FieldAccessor chunkX = Reflection.getField(ClientboundLevelChunkWithLightPacket.class, int.class, 0); + private static final Reflection.FieldAccessor chunkZ = Reflection.getField(ClientboundLevelChunkWithLightPacket.class, int.class, 1); + private static final Reflection.FieldAccessor chunkData = Reflection.getField(ClientboundLevelChunkWithLightPacket.class, ClientboundLevelChunkPacketData.class, 0); + + private static final Reflection.FieldAccessor dataField = Reflection.getField(ClientboundLevelChunkPacketData.class, byte[].class, 0); + private static final Reflection.FieldAccessor tileEntities = Reflection.getField(ClientboundLevelChunkPacketData.class, List.class, 0); + public static final Class tileEntity = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData$a"); + private static final Reflection.FieldAccessor entityType = Reflection.getField(tileEntity, TileEntityTypes.class, 0); + + private final Set hiddenBlockIds = BlockIdWrapper.impl.getHiddenBlockIds(); + private final int obfuscateWith = BlockIdWrapper.impl.getObfuscateWith(); + + @Override + public Object mapChunkHider(Player p, Object packet) { + if(TechHider.bypass(p, chunkX.get(packet), chunkZ.get(packet))) + return packet; + + packet = chunkPacketCloner.apply(packet); + Object data = chunkDataCloner.apply(chunkData.get(packet)); + + tileEntities.set(data, ((List)tileEntities.get(data)).stream().filter( + tile -> Config.HiddenBlockEntities.contains(IRegistry.ad.b(entityType.get(tile)).a()) + ).collect(Collectors.toList())); + + World world = p.getWorld(); + int sections = (world.getMaxHeight() - world.getMinHeight()) / 16; + dataField.set(data, dataHider(dataField.get(data), sections)); + + chunkData.set(packet, data); + return packet; + } + + private byte[] dataHider(byte[] data, int sections) { + ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100); + int i = 0; + + while(sections-- > 0) { + buffer.writeBytes(data, i, 2); // Block count + i += 2; + + i = containerWalker(data, buffer, i, 15, blockId -> hiddenBlockIds.contains(blockId) ? obfuscateWith : blockId, (curI, dataArrayLength, bitsPerBlock) -> { + if(bitsPerBlock < 15) { + buffer.writeBytes(data, curI, dataArrayLength * 8); + } else { + ByteBuffer source = ByteBuffer.wrap(data, curI, dataArrayLength * 8); + VariableValueArray values = new VariableValueArray(bitsPerBlock, dataArrayLength, source.asLongBuffer()); + + for (int pos = 0; pos < 4096; pos++) { + if (hiddenBlockIds.contains(values.get(pos))) { + values.set(pos, obfuscateWith); + } + } + + for (long l : values.backing) + buffer.writeLong(l); + } + }); + i = containerWalker(data, buffer, i, 6, value -> value, (curI, dataArrayLength, bitsPerBlock) -> buffer.writeBytes(data, curI, dataArrayLength * 8)); + } + buffer.writeBytes(data, i, data.length - i); // MC appends a 0 byte at the end if there is a full chunk, idk why + + byte[] outdata = new byte[buffer.readableBytes()]; + buffer.readBytes(outdata); + return outdata; + } + + private int containerWalker(byte[] data, ByteBuf buffer, int i, int globalPalette, IntFunction palette, Region.TriConsumer dataArray) { + byte bitsPerBlock = data[i++]; + buffer.writeByte(bitsPerBlock); + + if(bitsPerBlock == 0) { + int paletteValue = TechHider.readVarInt(data, i); + i += TechHider.readVarIntLength(data, i); + buffer.writeBytes(TechHider.writeVarInt(palette.apply(paletteValue))); + }else if(bitsPerBlock < globalPalette) { + int paletteLength = TechHider.readVarInt(data, i); + int paletteLengthLength = TechHider.readVarIntLength(data, i); + buffer.writeBytes(data, i, paletteLengthLength); + i += paletteLengthLength; + + for(int actPaletteId = 0; actPaletteId < paletteLength; actPaletteId++) { + int paletteValue = TechHider.readVarInt(data, i); + i += TechHider.readVarIntLength(data, i); + buffer.writeBytes(TechHider.writeVarInt(palette.apply(paletteValue))); + } + } + + int dataArrayLength = TechHider.readVarInt(data, i); + int dataArrayLengthLength = TechHider.readVarIntLength(data, i); + buffer.writeBytes(data, i, dataArrayLengthLength); + i += dataArrayLengthLength; + + dataArray.accept(i, dataArrayLength, bitsPerBlock); + i += dataArrayLength * 8; + + return i; + } + + private static final class VariableValueArray { + private final long[] backing; + private final int bitsPerValue; + private final long valueMask; + private final int valuesPerLong; + + public VariableValueArray(int bitsPerEntry, int dataArrayLength, LongBuffer buffer) { + this.bitsPerValue = bitsPerEntry; + this.backing = new long[dataArrayLength]; + buffer.get(backing); + this.valueMask = (1L << this.bitsPerValue) - 1; + this.valuesPerLong = 64 / bitsPerEntry; + } + + public int get(int index) { + return (int)((backing[index / valuesPerLong] >> ((index % valuesPerLong) * bitsPerValue)) & valueMask); + } + + public void set(int index, int value) { + int i0 = index / valuesPerLong; + int i1 = index % valuesPerLong; + + backing[i0] = backing[i0] & ~(this.valueMask << i1) | (value & valueMask) << i1; + } + } +} diff --git a/FightSystem_8/src/de/steamwar/fightsystem/utils/BountifulWrapper8.java b/FightSystem_8/src/de/steamwar/fightsystem/utils/BountifulWrapper8.java index dc31f36..2a838a6 100644 --- a/FightSystem_8/src/de/steamwar/fightsystem/utils/BountifulWrapper8.java +++ b/FightSystem_8/src/de/steamwar/fightsystem/utils/BountifulWrapper8.java @@ -128,29 +128,6 @@ public class BountifulWrapper8 implements BountifulWrapper.IBountifulWrapper { // field not present } - private static final Reflection.FieldAccessor equipmentSlot = Reflection.getField(REntity.equipmentPacket, int.class, 1); - @Override - public void setEquipmentPacketSlot(Object packet, String slot) { - switch(slot){ - case "HEAD": - equipmentSlot.set(packet, 4); - break; - case "CHEST": - equipmentSlot.set(packet, 3); - break; - case "LEGS": - equipmentSlot.set(packet, 2); - break; - case "FEET": - equipmentSlot.set(packet, 1); - break; - case "MAINHAND": - case "OFFHAND": - default: - equipmentSlot.set(packet, 0); - } - } - private final Set seesDragon = new HashSet<>(); private final PacketPlayOutSpawnEntityLiving spawnDragon; private final int spawnDragonId; diff --git a/FightSystem_8/src/de/steamwar/fightsystem/utils/FlatteningWrapper8.java b/FightSystem_8/src/de/steamwar/fightsystem/utils/FlatteningWrapper8.java index e672541..95fd263 100644 --- a/FightSystem_8/src/de/steamwar/fightsystem/utils/FlatteningWrapper8.java +++ b/FightSystem_8/src/de/steamwar/fightsystem/utils/FlatteningWrapper8.java @@ -20,13 +20,11 @@ package de.steamwar.fightsystem.utils; import com.comphenix.tinyprotocol.Reflection; -import de.steamwar.core.Core; import de.steamwar.fightsystem.record.REntity; import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; -import org.bukkit.entity.EntityType; import org.bukkit.event.block.BlockPhysicsEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; @@ -90,20 +88,4 @@ public class FlatteningWrapper8 implements FlatteningWrapper.IFlatteningWrapper public void setNamedSpawnPacketDataWatcher(Object packet) { namedSpawnDataWatcher.set(packet, dataWatcherConstructor.invoke((Object) null)); } - - private static final Reflection.FieldAccessor spawnType = Reflection.getField(REntity.spawnPacket, int.class, Core.getVersion() > 8 ? 6 : 9); - @Override - public void setSpawnPacketType(Object packet, EntityType type) { - switch(type) { - case PRIMED_TNT: - spawnType.set(packet, 50); - break; - case ARROW: - spawnType.set(packet, 60); - break; - case FIREBALL: - spawnType.set(packet, 63); - break; - } - } } diff --git a/FightSystem_8/src/de/steamwar/fightsystem/utils/ProtocolWrapper8.java b/FightSystem_8/src/de/steamwar/fightsystem/utils/ProtocolWrapper8.java new file mode 100644 index 0000000..80c1135 --- /dev/null +++ b/FightSystem_8/src/de/steamwar/fightsystem/utils/ProtocolWrapper8.java @@ -0,0 +1,158 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2021 SteamWar.de-Serverteam + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ + +package de.steamwar.fightsystem.utils; + +import com.comphenix.tinyprotocol.Reflection; +import com.mojang.authlib.GameProfile; +import de.steamwar.core.Core; +import de.steamwar.fightsystem.Config; +import de.steamwar.fightsystem.fight.Fight; +import de.steamwar.fightsystem.record.REntity; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +import java.util.function.BiFunction; +import java.util.function.UnaryOperator; + +public class ProtocolWrapper8 implements ProtocolWrapper { + + private static final Reflection.FieldAccessor equipmentSlot; + private static final Object[] itemSlots; + static { + if(Core.getVersion() == 8) { + equipmentSlot = Reflection.getField(REntity.equipmentPacket, int.class, 1); + itemSlots = new Integer[]{0, 0, 1, 2, 3, 4}; + } else { + Class enumItemSlot = Reflection.getClass("{nms.world.entity}.EnumItemSlot"); + equipmentSlot = Reflection.getField(REntity.equipmentPacket, enumItemSlot, 0); + itemSlots = enumItemSlot.getEnumConstants(); + } + } + + private static final Reflection.FieldAccessor equipmentStack = Reflection.getField(REntity.equipmentPacket, REntity.itemStack, 0); + @Override + public void setEquipmentPacketStack(Object packet, String slot, Object stack) { + switch(slot){ + case "HEAD": + equipmentSlot.set(packet, itemSlots[5]); + break; + case "CHEST": + equipmentSlot.set(packet, itemSlots[4]); + break; + case "LEGS": + equipmentSlot.set(packet, itemSlots[3]); + break; + case "FEET": + equipmentSlot.set(packet, itemSlots[2]); + break; + case "OFFHAND": + equipmentSlot.set(packet, itemSlots[1]); + break; + case "MAINHAND": + default: + equipmentSlot.set(packet, itemSlots[0]); + } + equipmentStack.set(packet, stack); + } + + private static final Reflection.FieldAccessor spawnType; + private static final Object tnt; + private static final Object arrow; + private static final Object fireball; + static { + if(Core.getVersion() < 14) { + spawnType = Reflection.getField(REntity.spawnPacket, int.class, Core.getVersion() > 8 ? 6 : 9); + tnt = 50; + arrow = 60; + fireball = 63; + } else { + Class entityTypes = Reflection.getClass("{nms.world.entity}.EntityTypes"); + spawnType = Reflection.getField(REntity.spawnPacket, entityTypes, 0); + tnt = Reflection.getField(entityTypes, "TNT", entityTypes).get(null); + arrow = Reflection.getField(entityTypes, "ARROW", entityTypes).get(null); + fireball = Reflection.getField(entityTypes, "FIREBALL", entityTypes).get(null); + } + } + @Override + public void setSpawnPacketType(Object packet, EntityType type) { + switch(type) { + case PRIMED_TNT: + spawnType.set(packet, tnt); + break; + case ARROW: + spawnType.set(packet, arrow); + break; + case FIREBALL: + spawnType.set(packet, fireball); + break; + } + } + + private static final Class chunkCoordinateIntPair = Reflection.getClass("{nms}.ChunkCoordIntPair"); + private static final Reflection.FieldAccessor multiBlockChangeChunk = Reflection.getField(TechHider.multiBlockChangePacket, chunkCoordinateIntPair, 0); + private static final Reflection.FieldAccessor chunkCoordinateX = Reflection.getField(chunkCoordinateIntPair, int.class, 0); + private static final Reflection.FieldAccessor chunkCoordinateZ = Reflection.getField(chunkCoordinateIntPair, int.class, 1); + private static final Class multiBlockChangeInfo = Reflection.getClass("{nms}.PacketPlayOutMultiBlockChange$MultiBlockChangeInfo"); + private static final Reflection.ConstructorInvoker multiBlockChangeInfoConstructor = Reflection.getConstructor(multiBlockChangeInfo, TechHider.multiBlockChangePacket, short.class, TechHider.iBlockData); + private static final BiFunction, Object> multiBlockChangeInfoArrayCloner = ProtocolAPI.arrayCloneGenerator(multiBlockChangeInfo); + private static final Reflection.FieldAccessor multiBlockChangeInfoBlock = Reflection.getField(multiBlockChangeInfo, TechHider.iBlockData, 0); + private static final Reflection.FieldAccessor multiBlockChangeInfoPos = Reflection.getField(multiBlockChangeInfo, short.class, 0); + private static final Class multiBlockChangeInfoArray = Reflection.getClass("[L{nms}.PacketPlayOutMultiBlockChange$MultiBlockChangeInfo;"); + private static final Reflection.FieldAccessor multiBlockChangeInfos = Reflection.getField(TechHider.multiBlockChangePacket, multiBlockChangeInfoArray, 0); + @Override + public Object multiBlockChangeHider(Player p, Object packet) { + Object chunkCoords = multiBlockChangeChunk.get(packet); + if(TechHider.bypass(p, chunkCoordinateX.get(chunkCoords), chunkCoordinateZ.get(chunkCoords))) + return packet; + + Object modpacket = TechHider.multiBlockChangeCloner.apply(packet); + multiBlockChangeInfos.set(modpacket, multiBlockChangeInfoArrayCloner.apply(multiBlockChangeInfos.get(modpacket), mbci -> { + if(ProtocolWrapper.impl.iBlockDataHidden(multiBlockChangeInfoBlock.get(mbci))) + return multiBlockChangeInfoConstructor.invoke(modpacket, multiBlockChangeInfoPos.get(mbci), TechHider.obfuscateIBlockData); + return mbci; + })); + return modpacket; + } + + private static final Reflection.FieldAccessor tileEntityDataAction = Reflection.getField(TechHider.tileEntityDataPacket, int.class, 0); + @Override + public boolean unfilteredTileEntityDataAction(Object packet) { + return tileEntityDataAction.get(packet) != 9; + } + + @Override + public BiFunction blockBreakHiderGenerator(Class blockBreakPacket) { + return null; + } + + private static final Reflection.ConstructorInvoker playerInfoDataConstructor = Reflection.getConstructor(Fight.playerInfoDataClass, Fight.playerInfoPacket, GameProfile.class, int.class, Fight.enumGamemode, Fight.iChatBaseComponent); + @Override + public Object playerInfoDataConstructor(Object packet, GameProfile profile, Object mode) { + return playerInfoDataConstructor.invoke(packet, profile, 0, mode, null); + } + + private static final Reflection.MethodInvoker getBlockByBlockData = Reflection.getTypedMethod(TechHider.iBlockData, null, TechHider.block); + private static final Reflection.MethodInvoker getMaterialByBlock = Reflection.getTypedMethod(TechHider.craftMagicNumbers, "getMaterial", Material.class, TechHider.block); + @Override + public boolean iBlockDataHidden(Object iBlockData) { + return Config.HiddenBlocks.contains(((Material) getMaterialByBlock.invoke(null, getBlockByBlockData.invoke(iBlockData))).name().toLowerCase()); + } +} diff --git a/FightSystem_8/src/de/steamwar/fightsystem/utils/TechHider8.java b/FightSystem_8/src/de/steamwar/fightsystem/utils/TechHider8.java index 39aaecc..d299c3d 100644 --- a/FightSystem_8/src/de/steamwar/fightsystem/utils/TechHider8.java +++ b/FightSystem_8/src/de/steamwar/fightsystem/utils/TechHider8.java @@ -19,13 +19,19 @@ package de.steamwar.fightsystem.utils; -import java.util.function.BiFunction; +import com.comphenix.tinyprotocol.Reflection; +import org.bukkit.entity.Player; -public class TechHider8 implements BiFunction { +public class TechHider8 implements TechHider.ChunkHider { + + protected static final Class mapChunkPacket = Reflection.getClass("{nms}.PacketPlayOutMapChunk"); + @Override + public Class mapChunkPacket() { + return mapChunkPacket; + } @Override - public byte[] apply(byte[] data, Integer primaryBitMask) { - // No implementation availible - return data; + public Object mapChunkHider(Player p, Object packet) { + return packet; } } diff --git a/FightSystem_9/pom.xml b/FightSystem_9/pom.xml index 8cf317c..1dd055b 100644 --- a/FightSystem_9/pom.xml +++ b/FightSystem_9/pom.xml @@ -23,6 +23,11 @@ FightSystem_Core 1.0 + + steamwar + FightSystem_8 + 1.0 + steamwar WorldEdit diff --git a/FightSystem_9/src/de/steamwar/fightsystem/utils/BountifulWrapper9.java b/FightSystem_9/src/de/steamwar/fightsystem/utils/BountifulWrapper9.java index a21a46c..8e86735 100644 --- a/FightSystem_9/src/de/steamwar/fightsystem/utils/BountifulWrapper9.java +++ b/FightSystem_9/src/de/steamwar/fightsystem/utils/BountifulWrapper9.java @@ -46,7 +46,7 @@ import java.util.UUID; public class BountifulWrapper9 implements BountifulWrapper.IBountifulWrapper { - private static final Class enumHand = Reflection.getClass("{nms}.EnumHand"); + private static final Class enumHand = Reflection.getClass("{nms.world}.EnumHand"); private static final Object mainHand = enumHand.getEnumConstants()[0]; private static final Reflection.FieldAccessor blockPlaceHand = Reflection.getField(Recording.blockPlacePacket, enumHand, 0); @@ -118,9 +118,9 @@ public class BountifulWrapper9 implements BountifulWrapper.IBountifulWrapper { } - private static final Class dataWatcherObject = Reflection.getClass("{nms}.DataWatcherObject"); - private static final Class dataWatcherRegistry = Reflection.getClass("{nms}.DataWatcherRegistry"); - private static final Class dataWatcherSerializer = Reflection.getClass("{nms}.DataWatcherSerializer"); + private static final Class dataWatcherObject = Reflection.getClass("{nms.network.syncher}.DataWatcherObject"); + private static final Class dataWatcherRegistry = Reflection.getClass("{nms.network.syncher}.DataWatcherRegistry"); + private static final Class dataWatcherSerializer = Reflection.getClass("{nms.network.syncher}.DataWatcherSerializer"); private static final Reflection.ConstructorInvoker dataWatcherObjectConstructor = Reflection.getConstructor(dataWatcherObject, int.class, dataWatcherSerializer); @Override public Object getDataWatcherObject(int index, Class type) { @@ -136,7 +136,7 @@ public class BountifulWrapper9 implements BountifulWrapper.IBountifulWrapper { throw new SecurityException("Could not find Serializer for " + type.getName()); } - private static final Class item = Reflection.getClass("{nms}.DataWatcher$Item"); + private static final Class item = Reflection.getClass("{nms.network.syncher}.DataWatcher$Item"); private static final Reflection.ConstructorInvoker itemConstructor = Reflection.getConstructor(item, dataWatcherObject, Object.class); @Override public Object getDataWatcherItem(Object dwo, Object value) { @@ -159,32 +159,6 @@ public class BountifulWrapper9 implements BountifulWrapper.IBountifulWrapper { spawnUUID.set(packet, uuid); } - private static final Class enumItemSlot = Reflection.getClass("{nms}.EnumItemSlot"); - private static final Reflection.FieldAccessor equipmentSlot = Reflection.getField(REntity.equipmentPacket, enumItemSlot, 0); - private static final Object[] itemSlots = enumItemSlot.getEnumConstants(); - @Override - public void setEquipmentPacketSlot(Object packet, String slot) { - switch(slot){ - case "HEAD": - equipmentSlot.set(packet, itemSlots[5]); - break; - case "CHEST": - equipmentSlot.set(packet, itemSlots[4]); - break; - case "LEGS": - equipmentSlot.set(packet, itemSlots[3]); - break; - case "FEET": - equipmentSlot.set(packet, itemSlots[2]); - break; - case "OFFHAND": - equipmentSlot.set(packet, itemSlots[1]); - break; - case "MAINHAND": - default: - equipmentSlot.set(packet, itemSlots[0]); - } - } private final Map barMap = new HashMap<>(); @Override diff --git a/FightSystem_9/src/de/steamwar/fightsystem/utils/TechHider9.java b/FightSystem_9/src/de/steamwar/fightsystem/utils/TechHider9.java index e1f6bef..c07bcb2 100644 --- a/FightSystem_9/src/de/steamwar/fightsystem/utils/TechHider9.java +++ b/FightSystem_9/src/de/steamwar/fightsystem/utils/TechHider9.java @@ -19,21 +19,52 @@ package de.steamwar.fightsystem.utils; +import com.comphenix.tinyprotocol.Reflection; +import de.steamwar.fightsystem.Config; import io.netty.buffer.ByteBuf; import io.netty.buffer.UnpooledByteBufAllocator; import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import java.util.List; import java.util.Set; -import java.util.function.BiFunction; +import java.util.function.UnaryOperator; import java.util.logging.Level; +import java.util.stream.Collectors; -public class TechHider9 implements BiFunction { +public class TechHider9 extends TechHider8 { - private final Set hiddenBlockIds = BlockIdWrapper.impl.getHiddenBlockIds(); - private final int obfuscateWith = BlockIdWrapper.impl.getObfuscateWith(); + private static final UnaryOperator mapChunkCloner = ProtocolAPI.shallowCloneGenerator(mapChunkPacket); + + private static final Reflection.FieldAccessor mapChunkX = Reflection.getField(mapChunkPacket, int.class, 0); + private static final Reflection.FieldAccessor mapChunkZ = Reflection.getField(mapChunkPacket, int.class, 1); + private static final Reflection.FieldAccessor mapChunkBitMask = Reflection.getField(mapChunkPacket, int.class, 2); + private static final Reflection.FieldAccessor mapChunkBlockEntities = Reflection.getField(mapChunkPacket, List.class, 0); + private static final Reflection.FieldAccessor mapChunkData = Reflection.getField(mapChunkPacket, byte[].class, 0); + + private static final Class nbtTagCompound = Reflection.getClass("{nms.nbt}.NBTTagCompound"); + private static final Reflection.MethodInvoker nbtTagGetString = Reflection.getTypedMethod(nbtTagCompound, null, String.class, String.class); + + protected final Set hiddenBlockIds = BlockIdWrapper.impl.getHiddenBlockIds(); + protected final int obfuscateWith = BlockIdWrapper.impl.getObfuscateWith(); @Override - public byte[] apply(byte[] data, Integer primaryBitMask) { + public Object mapChunkHider(Player p, Object packet) { + if(TechHider.bypass(p, mapChunkX.get(packet), mapChunkZ.get(packet))) + return packet; + + packet = mapChunkCloner.apply(packet); + mapChunkBlockEntities.set(packet, ((List)mapChunkBlockEntities.get(packet)).stream().filter( + nbttag -> Config.HiddenBlockEntities.contains((String) nbtTagGetString.invoke(nbttag, "id")) + ).collect(Collectors.toList())); + + byte[] data = dataHider(mapChunkData.get(packet), mapChunkBitMask.get(packet)); + mapChunkData.set(packet, data); + + return packet; + } + + protected byte[] dataHider(byte[] data, Integer primaryBitMask) { ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100); int i = 0; diff --git a/FightSystem_Core/pom.xml b/FightSystem_Core/pom.xml index a9f81ed..2ce9c10 100644 --- a/FightSystem_Core/pom.xml +++ b/FightSystem_Core/pom.xml @@ -19,11 +19,28 @@ - steamwar - Spigot - 1.15 - system - ${main.basedir}/lib/Spigot-1.15.jar + org.spigotmc + spigot-api + 1.18-R0.1-SNAPSHOT + provided + + + it.unimi.dsi + fastutil + 8.5.6 + provided + + + io.netty + netty-all + 4.1.68.Final + provided + + + com.mojang + authlib + 1.5.25 + provided steamwar diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java b/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java index 6a1a3c6..80e3cfa 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java @@ -27,6 +27,8 @@ import de.steamwar.fightsystem.ArenaMode; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.record.GlobalRecorder; +import de.steamwar.fightsystem.utils.ProtocolAPI; +import de.steamwar.fightsystem.utils.ProtocolWrapper; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Sound; @@ -130,29 +132,27 @@ public class Fight { } } - private static final Class playerInfoPacket = Reflection.getClass("{nms}.PacketPlayOutPlayerInfo"); - private static final Reflection.ConstructorInvoker playerInfoConstructor = Reflection.getConstructor(playerInfoPacket); - private static final Class playerInfoActionClass = Reflection.getClass("{nms}.PacketPlayOutPlayerInfo$EnumPlayerInfoAction"); + public static final Class playerInfoPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutPlayerInfo"); + private static final Class playerInfoActionClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutPlayerInfo$EnumPlayerInfoAction"); public static final Object addPlayer = playerInfoActionClass.getEnumConstants()[0]; private static final Reflection.FieldAccessor playerInfoAction = Reflection.getField(playerInfoPacket, playerInfoActionClass, 0); private static final Object updateGamemode = playerInfoActionClass.getEnumConstants()[1]; public static final Object removePlayer = playerInfoActionClass.getEnumConstants()[4]; private static final Reflection.FieldAccessor playerInfoData = Reflection.getField(playerInfoPacket, List.class, 0); - private static final Class playerInfoDataClass = Reflection.getClass("{nms}.PacketPlayOutPlayerInfo$PlayerInfoData"); - private static final Class enumGamemode = Reflection.getClass(Core.getVersion() > 9 ? "{nms}.EnumGamemode" : "{nms}.WorldSettings$EnumGamemode"); - public static final Object creative = enumGamemode.getEnumConstants()[2]; - private static final Object spectator = enumGamemode.getEnumConstants()[4]; - private static final Class iChatBaseComponent = Reflection.getClass("{nms}.IChatBaseComponent"); + public static final Class playerInfoDataClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutPlayerInfo$PlayerInfoData"); + public static final Class enumGamemode = Reflection.getClass(Core.getVersion() > 9 ? "{nms.world.level}.EnumGamemode" : "{nms}.WorldSettings$EnumGamemode"); + public static final Object creative = enumGamemode.getEnumConstants()[Core.getVersion() > 15 ? 1 : 2]; + private static final Object spectator = enumGamemode.getEnumConstants()[Core.getVersion() > 15 ? 3 : 4]; + public static final Class iChatBaseComponent = Reflection.getClass("{nms.network.chat}.IChatBaseComponent"); - private static final Reflection.ConstructorInvoker playerInfoDataConstructor = Reflection.getConstructor(playerInfoDataClass, playerInfoPacket, GameProfile.class, int.class, enumGamemode, iChatBaseComponent); public static void pseudoSpectator(Player player, boolean enable) { TinyProtocol.instance.sendPacket(player, playerInfoPacket(updateGamemode, new GameProfile(player.getUniqueId(), player.getName()), enable ? creative : spectator)); } public static Object playerInfoPacket(Object action, GameProfile profile, Object mode) { - Object packet = playerInfoConstructor.invoke(); + Object packet = ProtocolAPI.construct(playerInfoPacket); playerInfoAction.set(packet, action); - playerInfoData.set(packet, Collections.singletonList(playerInfoDataConstructor.invoke(packet, profile, 0, mode, null))); + playerInfoData.set(packet, Collections.singletonList(ProtocolWrapper.impl.playerInfoDataConstructor(packet, profile, mode))); return packet; } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/Recording.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/Recording.java index 1d2f412..0b158b6 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/listener/Recording.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/listener/Recording.java @@ -115,7 +115,7 @@ public class Recording implements Listener { }, 1, 1); } - private static final Class blockDigPacket = Reflection.getClass("{nms}.PacketPlayInBlockDig"); + private static final Class blockDigPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInBlockDig"); private static final Class playerDigType = blockDigPacket.getDeclaredClasses()[0]; private static final Reflection.FieldAccessor blockDigType = Reflection.getField(blockDigPacket, playerDigType, 0); private static final Object releaseUseItem = playerDigType.getEnumConstants()[5]; @@ -125,7 +125,7 @@ public class Recording implements Listener { return packet; } - public static final Class blockPlacePacket = Reflection.getClass("{nms}.PacketPlayInBlockPlace"); + public static final Class blockPlacePacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInBlockPlace"); private Object blockPlace(Player p, Object packet) { boolean mainHand = BountifulWrapper.impl.mainHand(packet); if(BountifulWrapper.impl.bowInHand(mainHand, p)) diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/record/REntity.java b/FightSystem_Core/src/de/steamwar/fightsystem/record/REntity.java index 2523cf0..3da799d 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/record/REntity.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/record/REntity.java @@ -26,11 +26,10 @@ import de.steamwar.core.Core; import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.fight.Fight; import de.steamwar.fightsystem.listener.FightScoreboard; -import de.steamwar.fightsystem.utils.BlockIdWrapper; -import de.steamwar.fightsystem.utils.BountifulWrapper; -import de.steamwar.fightsystem.utils.FlatteningWrapper; -import de.steamwar.fightsystem.utils.ProtocolAPI; +import de.steamwar.fightsystem.utils.*; import de.steamwar.sql.SteamwarUser; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.EntityType; @@ -174,25 +173,23 @@ public class REntity { ProtocolAPI.broadcastPacket(getHeadRotationPacket()); } - private static final Class animationPacket = Reflection.getClass("{nms}.PacketPlayOutAnimation"); - private static final Reflection.ConstructorInvoker animationConstructor = Reflection.getConstructor(animationPacket); + private static final Class animationPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutAnimation"); private static final Reflection.FieldAccessor animationEntity = Reflection.getField(animationPacket, int.class, 0); private static final Reflection.FieldAccessor animationAnimation = Reflection.getField(animationPacket, int.class, 1); public void animation(byte animation) { - Object packet = animationConstructor.invoke(); + Object packet = ProtocolAPI.construct(animationPacket); animationEntity.set(packet, entityId); animationAnimation.set(packet, (int) animation); ProtocolAPI.broadcastPacket(packet); } - private static final Class velocityPacket = Reflection.getClass("{nms}.PacketPlayOutEntityVelocity"); - private static final Reflection.ConstructorInvoker velocityConstructor = Reflection.getConstructor(velocityPacket); + private static final Class velocityPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityVelocity"); private static final Reflection.FieldAccessor velocityEntity = Reflection.getField(velocityPacket, int.class, 0); private static final Reflection.FieldAccessor velocityX = Reflection.getField(velocityPacket, int.class, 1); private static final Reflection.FieldAccessor velocityY = Reflection.getField(velocityPacket, int.class, 2); private static final Reflection.FieldAccessor velocityZ = Reflection.getField(velocityPacket, int.class, 3); public void setVelocity(double dX, double dY, double dZ) { - Object packet = velocityConstructor.invoke(); + Object packet = ProtocolAPI.construct(velocityPacket); velocityEntity.set(packet, entityId); velocityX.set(packet, calcVelocity(dX)); velocityY.set(packet, calcVelocity(dY)); @@ -200,12 +197,11 @@ public class REntity { ProtocolAPI.broadcastPacket(packet); } - private static final Class statusPacket = Reflection.getClass("{nms}.PacketPlayOutEntityStatus"); - private static final Reflection.ConstructorInvoker statusConstructor = Reflection.getConstructor(statusPacket); + private static final Class statusPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityStatus"); private static final Reflection.FieldAccessor statusEntity = Reflection.getField(statusPacket, int.class, 0); private static final Reflection.FieldAccessor statusStatus = Reflection.getField(statusPacket, byte.class, 0); public void damage() { - Object packet = statusConstructor.invoke(); + Object packet = ProtocolAPI.construct(statusPacket); statusEntity.set(packet, entityId); statusStatus.set(packet, (byte) 2); ProtocolAPI.broadcastPacket(packet); @@ -248,17 +244,23 @@ public class REntity { entities.remove(internalId); } - private static final Class destroyPacket = Reflection.getClass("{nms}.PacketPlayOutEntityDestroy"); - private static final Reflection.ConstructorInvoker destroyConstructor = Reflection.getConstructor(destroyPacket); - private static final Reflection.FieldAccessor destroyEntities = Reflection.getField(destroyPacket, int[].class, 0); + private static final Class destroyPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityDestroy"); + private static final Reflection.FieldAccessor destroyEntities; + static { + if(Core.getVersion() > 15) + destroyEntities = Reflection.getField(destroyPacket, IntList.class, 0); + else + destroyEntities = Reflection.getField(destroyPacket, int[].class, 0); + } + private void broadcastDeath(){ if(entityType == EntityType.PLAYER){ ProtocolAPI.broadcastPacket(Fight.playerInfoPacket(Fight.removePlayer, new GameProfile(uuid, name), Fight.creative)); team.removeEntry(name); } - Object packet = destroyConstructor.invoke(); - destroyEntities.set(packet, new int[]{entityId}); + Object packet = ProtocolAPI.construct(destroyPacket); + destroyEntities.set(packet, Core.getVersion() > 15 ? new IntArrayList(new int[]{entityId}) : new int[]{entityId}); ProtocolAPI.broadcastPacket(packet); } @@ -266,24 +268,22 @@ public class REntity { return (int)(Math.max(-3.9, Math.min(value, 3.9)) * 8000); } - private static final Class metadataPacket = Reflection.getClass("{nms}.PacketPlayOutEntityMetadata"); - private static final Reflection.ConstructorInvoker metadataConstructor = Reflection.getConstructor(metadataPacket); + private static final Class metadataPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityMetadata"); private static final Reflection.FieldAccessor metadataEntity = Reflection.getField(metadataPacket, int.class, 0); private static final Reflection.FieldAccessor metadataMetadata = Reflection.getField(metadataPacket, List.class, 0); private Object getDataWatcherPacket(Object dataWatcherObject, Object value) { - Object packet = metadataConstructor.invoke(); + Object packet = ProtocolAPI.construct(metadataPacket); metadataEntity.set(packet, entityId); metadataMetadata.set(packet, Collections.singletonList(BountifulWrapper.impl.getDataWatcherItem(dataWatcherObject, value))); return packet; } - public static final Class teleportPacket = Reflection.getClass("{nms}.PacketPlayOutEntityTeleport"); - private static final Reflection.ConstructorInvoker teleportConstructor = Reflection.getConstructor(teleportPacket); + public static final Class teleportPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityTeleport"); private static final Reflection.FieldAccessor teleportEntity = Reflection.getField(teleportPacket, int.class, 0); private static final Reflection.FieldAccessor teleportYaw = Reflection.getField(teleportPacket, byte.class, 0); private static final Reflection.FieldAccessor teleportPitch = Reflection.getField(teleportPacket, byte.class, 1); private Object getTeleportPacket(){ - Object packet = teleportConstructor.invoke(); + Object packet = ProtocolAPI.construct(teleportPacket); teleportEntity.set(packet, entityId); BountifulWrapper.impl.setTeleportPacketPosition(packet, locX, locY, locZ); teleportYaw.set(packet, yaw); @@ -291,40 +291,36 @@ public class REntity { return packet; } - private static final Class headRotationPacket = Reflection.getClass("{nms}.PacketPlayOutEntityHeadRotation"); - private static final Reflection.ConstructorInvoker headRotationConstructor = Reflection.getConstructor(headRotationPacket); + private static final Class headRotationPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityHeadRotation"); private static final Reflection.FieldAccessor headRotationEntity = Reflection.getField(headRotationPacket, int.class, 0); private static final Reflection.FieldAccessor headRotationYaw = Reflection.getField(headRotationPacket, byte.class, 0); private Object getHeadRotationPacket(){ - Object packet = headRotationConstructor.invoke(); + Object packet = ProtocolAPI.construct(headRotationPacket); headRotationEntity.set(packet, entityId); headRotationYaw.set(packet, headYaw); return packet; } - public static final Class spawnPacket = Reflection.getClass("{nms}.PacketPlayOutSpawnEntity"); - private static final Reflection.ConstructorInvoker spawnConstructor = Reflection.getConstructor(spawnPacket); + public static final Class spawnPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutSpawnEntity"); private static final Reflection.FieldAccessor spawnEntity = Reflection.getField(spawnPacket, int.class, 0); private Object getSpawnEntityPacket(){ - Object packet = spawnConstructor.invoke(); + Object packet = ProtocolAPI.construct(spawnPacket); spawnEntity.set(packet, entityId); BountifulWrapper.impl.setSpawnPacketUUID(packet, uuid); - FlatteningWrapper.impl.setSpawnPacketType(packet, entityType); + ProtocolWrapper.impl.setSpawnPacketType(packet, entityType); return packet; } - public static final Class equipmentPacket = Reflection.getClass("{nms}.PacketPlayOutEntityEquipment"); - private static final Reflection.ConstructorInvoker equipmentConstructor = Reflection.getConstructor(equipmentPacket); + public static final Class equipmentPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityEquipment"); private static final Reflection.FieldAccessor equipmentEntity = Reflection.getField(equipmentPacket, int.class, 0); - private static final Class itemStack = Reflection.getClass("{nms}.ItemStack"); - private static final Reflection.FieldAccessor equipmentStack = Reflection.getField(equipmentPacket, itemStack, 0); + + public static final Class itemStack = Reflection.getClass("{nms.world.item}.ItemStack"); private static final Class craftItemStack = Reflection.getClass("{obc}.inventory.CraftItemStack"); - private static final Reflection.MethodInvoker asNMSCopy = Reflection.getTypedMethod(craftItemStack, "asNMSCopy", itemStack, ItemStack.class); + private static final Reflection.MethodInvoker asNMSCopy = Reflection.getTypedMethod(REntity.craftItemStack, "asNMSCopy", REntity.itemStack, ItemStack.class); private Object getEquipmentPacket(String slot, ItemStack stack){ - Object packet = equipmentConstructor.invoke(); + Object packet = ProtocolAPI.construct(equipmentPacket); equipmentEntity.set(packet, entityId); - BountifulWrapper.impl.setEquipmentPacketSlot(packet, slot); - equipmentStack.set(packet, asNMSCopy.invoke(null, stack)); + ProtocolWrapper.impl.setEquipmentPacketStack(packet, slot, asNMSCopy.invoke(null, stack)); return packet; } @@ -332,12 +328,11 @@ public class REntity { return Fight.playerInfoPacket(Fight.addPlayer, new GameProfile(uuid, name), Fight.creative); } - public static final Class namedSpawnPacket = Reflection.getClass("{nms}.PacketPlayOutNamedEntitySpawn"); - private static final Reflection.ConstructorInvoker namedSpawnConstructor = Reflection.getConstructor(namedSpawnPacket); + public static final Class namedSpawnPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutNamedEntitySpawn"); private static final Reflection.FieldAccessor namedSpawnEntity = Reflection.getField(namedSpawnPacket, int.class, 0); private static final Reflection.FieldAccessor namedSpawnUUID = Reflection.getField(namedSpawnPacket, UUID.class, 0); private Object getNamedSpawnPacket(){ - Object packet = namedSpawnConstructor.invoke(); + Object packet = ProtocolAPI.construct(namedSpawnPacket); namedSpawnEntity.set(packet, entityId); namedSpawnUUID.set(packet, uuid); FlatteningWrapper.impl.setNamedSpawnPacketDataWatcher(packet); diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/BountifulWrapper.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/BountifulWrapper.java index 18a2706..ffc6217 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/BountifulWrapper.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/BountifulWrapper.java @@ -54,7 +54,6 @@ public class BountifulWrapper { Object getDataWatcherItem(Object dataWatcherObject, Object value); void setTeleportPacketPosition(Object packet, double x, double y, double z); void setSpawnPacketUUID(Object packet, UUID uuid); - void setEquipmentPacketSlot(Object packet, String slot); void sendBar(Player player, FightTeam team, double progress, String text); } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/FlatteningWrapper.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/FlatteningWrapper.java index 13a5ab1..34c4c4f 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/FlatteningWrapper.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/FlatteningWrapper.java @@ -24,7 +24,6 @@ import de.steamwar.fightsystem.FightSystem; import org.bukkit.DyeColor; import org.bukkit.World; import org.bukkit.block.Block; -import org.bukkit.entity.EntityType; import org.bukkit.event.block.BlockPhysicsEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; @@ -52,6 +51,5 @@ public class FlatteningWrapper { boolean checkPistonMoving(Block block); void setNamedSpawnPacketDataWatcher(Object packet); - void setSpawnPacketType(Object packet, EntityType type); } } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/ProtocolAPI.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/ProtocolAPI.java index 28ad17a..31a6788 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/ProtocolAPI.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/ProtocolAPI.java @@ -20,6 +20,7 @@ package de.steamwar.fightsystem.utils; import com.comphenix.tinyprotocol.TinyProtocol; +import jdk.internal.misc.Unsafe; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -87,16 +88,19 @@ public class ProtocolAPI { }; } + public static T construct(Class clazz) { + try { + return (T) Unsafe.getUnsafe().allocateInstance(clazz); + } catch (InstantiationException e) { + throw new IllegalStateException(e); + } + } + public static UnaryOperator shallowCloneGenerator(Class clazz) { BiConsumer filler = shallowFill(clazz); return source -> { - Object clone; - try { - clone = clazz.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { - throw new IllegalStateException("Could not clone " + clazz.getName(), e); - } + Object clone = construct(clazz); filler.accept(source, clone); return clone; }; diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/ProtocolWrapper.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/ProtocolWrapper.java new file mode 100644 index 0000000..1ca485a --- /dev/null +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/ProtocolWrapper.java @@ -0,0 +1,46 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2021 SteamWar.de-Serverteam + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ + +package de.steamwar.fightsystem.utils; + +import com.mojang.authlib.GameProfile; +import de.steamwar.core.VersionDependent; +import de.steamwar.fightsystem.FightSystem; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; + +import java.util.function.BiFunction; + +public interface ProtocolWrapper { + ProtocolWrapper impl = VersionDependent.getVersionImpl(FightSystem.getPlugin()); + + void setEquipmentPacketStack(Object packet, String slot, Object stack); + + void setSpawnPacketType(Object packet, EntityType type); + + Object multiBlockChangeHider(Player p, Object packet); + + boolean unfilteredTileEntityDataAction(Object packet); + + BiFunction blockBreakHiderGenerator(Class blockBreakPacket); + + Object playerInfoDataConstructor(Object packet, GameProfile profile, Object mode); + + boolean iBlockDataHidden(Object iBlockData); +} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHider.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHider.java index 5427fc5..933dae9 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHider.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHider.java @@ -39,51 +39,51 @@ import java.util.*; import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.UnaryOperator; -import java.util.stream.Collectors; public class TechHider extends StateDependent { - private static final Class blockPosition = Reflection.getClass("{nms}.BlockPosition"); - private static final Class baseBlockPosition = Reflection.getClass("{nms}.BaseBlockPosition"); - private static final Reflection.FieldAccessor blockPositionX = Reflection.getField(baseBlockPosition, int.class, 0); - private static final Reflection.FieldAccessor blockPositionZ = Reflection.getField(baseBlockPosition, int.class, 2); + public static final Class blockPosition = Reflection.getClass("{nms.core}.BlockPosition"); + private static final Class baseBlockPosition = Reflection.getClass("{nms.core}.BaseBlockPosition"); + public static final Reflection.FieldAccessor blockPositionX = Reflection.getField(baseBlockPosition, int.class, 0); + public static final Reflection.FieldAccessor blockPositionZ = Reflection.getField(baseBlockPosition, int.class, 2); - private static final Class iBlockData = Reflection.getClass("{nms}.IBlockData"); - private static final Class block = Reflection.getClass("{nms}.Block"); - private static final Reflection.MethodInvoker getBlockByBlockData = Reflection.getTypedMethod(iBlockData, "getBlock", block); - private static final Reflection.MethodInvoker getBlockDataByBlock = Reflection.getTypedMethod(block, "getBlockData", iBlockData); + public static final Class iBlockData = Reflection.getClass("{nms.world.level.block.state}.IBlockData"); + public static final Class block = Reflection.getClass("{nms.world.level.block}.Block"); + private static final Reflection.MethodInvoker getBlockDataByBlock = Reflection.getTypedMethod(block, null, iBlockData); - private static final Class craftMagicNumbers = Reflection.getClass("{obc}.util.CraftMagicNumbers"); - private static final Reflection.MethodInvoker getMaterialByBlock = Reflection.getTypedMethod(craftMagicNumbers, "getMaterial", Material.class, block); + public static final Class craftMagicNumbers = Reflection.getClass("{obc}.util.CraftMagicNumbers"); private static final Reflection.MethodInvoker getBlockByMaterial = Reflection.getTypedMethod(craftMagicNumbers, "getBlock", block, Material.class); public static final boolean ENABLED = !Config.OnlyPublicSchematics && !Config.test() && Config.TechhiderActive; - private final Object obfuscateIBlockData = getBlockDataByBlock.invoke(getBlockByMaterial.invoke(null, Material.getMaterial(Config.ObfuscateWith.toUpperCase()))); + public static final Object obfuscateIBlockData = getBlockDataByBlock.invoke(getBlockByMaterial.invoke(null, Material.getMaterial(Config.ObfuscateWith.toUpperCase()))); private final Map, BiFunction> techhiders = new HashMap<>(); - private final BiFunction chunkDataHider; + + public interface ChunkHider { + Class mapChunkPacket(); + Object mapChunkHider(Player p, Object packet); + } public TechHider(){ super(ENABLED, FightState.Schem); - chunkDataHider = VersionDependent.getVersionImpl(FightSystem.getPlugin()); - techhiders.put(blockActionPacket, this::blockActionHider); techhiders.put(blockChangePacket, this::blockChangeHider); techhiders.put(tileEntityDataPacket, this::tileEntityDataHider); - techhiders.put(multiBlockChangePacket, this::multiBlockChangeHider); - if(Core.getVersion() > 8) { - techhiders.put(mapChunkPacket, this::mapChunkHider); - } + techhiders.put(multiBlockChangePacket, ProtocolWrapper.impl::multiBlockChangeHider); + + ChunkHider chunkHider = VersionDependent.getVersionImpl(FightSystem.getPlugin()); + techhiders.put(chunkHider.mapChunkPacket(), chunkHider::mapChunkHider); + if(Core.getVersion() > 12) { - Class blockBreakClass = Reflection.getClass("{nms}.PacketPlayOutBlockBreak"); - techhiders.put(blockBreakClass, blockBreakHiderGenerator(blockBreakClass)); + Class blockBreakClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutBlockBreak"); + techhiders.put(blockBreakClass, ProtocolWrapper.impl.blockBreakHiderGenerator(blockBreakClass)); } if(Core.getVersion() > 8){ - ProtocolAPI.setIncomingHandler(Reflection.getClass("{nms}.PacketPlayInUseItem"), (p, packet) -> p.getGameMode() == GameMode.SPECTATOR ? null : packet); + ProtocolAPI.setIncomingHandler(Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUseItem"), (p, packet) -> p.getGameMode() == GameMode.SPECTATOR ? null : packet); } - ProtocolAPI.setIncomingHandler(Reflection.getClass("{nms}.PacketPlayInUseEntity"), (p, packet) -> p.getGameMode() == GameMode.SPECTATOR ? null : packet); + ProtocolAPI.setIncomingHandler(Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUseEntity"), (p, packet) -> p.getGameMode() == GameMode.SPECTATOR ? null : packet); register(); } @@ -98,70 +98,10 @@ public class TechHider extends StateDependent { techhiders.keySet().forEach(ProtocolAPI::removeOutgoingHandler); } - private static final Class nbtTagCompound = Reflection.getClass("{nms}.NBTTagCompound"); - private static final Reflection.MethodInvoker nbtTagGetString = Reflection.getTypedMethod(nbtTagCompound, "getString", String.class, String.class); + public static final Class multiBlockChangePacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutMultiBlockChange"); + public static final UnaryOperator multiBlockChangeCloner = ProtocolAPI.shallowCloneGenerator(TechHider.multiBlockChangePacket); - private static final Class mapChunkPacket = Reflection.getClass("{nms}.PacketPlayOutMapChunk"); - private static final UnaryOperator mapChunkCloner = ProtocolAPI.shallowCloneGenerator(mapChunkPacket); - private static final Reflection.FieldAccessor mapChunkX = Reflection.getField(mapChunkPacket, int.class, 0); - private static final Reflection.FieldAccessor mapChunkZ = Reflection.getField(mapChunkPacket, int.class, 1); - private static final Reflection.FieldAccessor mapChunkBitMask; - private static final Reflection.FieldAccessor mapChunkBlockEntities; - private static final Reflection.FieldAccessor mapChunkData; - static { - if(Core.getVersion() > 8) { - mapChunkBitMask = Reflection.getField(mapChunkPacket, int.class, 2); - mapChunkBlockEntities = Reflection.getField(mapChunkPacket, List.class, 0); - mapChunkData = Reflection.getField(mapChunkPacket, byte[].class, 0); - }else { - mapChunkBitMask = null; - mapChunkBlockEntities = null; - mapChunkData = null; - } - } - private Object mapChunkHider(Player p, Object packet) { - if(bypass(p, mapChunkX.get(packet), mapChunkZ.get(packet))) - return packet; - - packet = mapChunkCloner.apply(packet); - mapChunkBlockEntities.set(packet, ((List)mapChunkBlockEntities.get(packet)).stream().filter( - nbttag -> Config.HiddenBlockEntities.contains((String) nbtTagGetString.invoke(nbttag, "id")) - ).collect(Collectors.toList())); - - byte[] data = chunkDataHider.apply(mapChunkData.get(packet), mapChunkBitMask.get(packet)); - mapChunkData.set(packet, data); - - return packet; - } - - private static final Class multiBlockChangePacket = Reflection.getClass("{nms}.PacketPlayOutMultiBlockChange"); - private static final UnaryOperator multiBlockChangeCloner = ProtocolAPI.shallowCloneGenerator(multiBlockChangePacket); - private static final Class chunkCoordinateIntPair = Reflection.getClass("{nms}.ChunkCoordIntPair"); - private static final Reflection.FieldAccessor multiBlockChangeChunk = Reflection.getField(multiBlockChangePacket, chunkCoordinateIntPair, 0); - private static final Reflection.FieldAccessor chunkCoordinateX = Reflection.getField(chunkCoordinateIntPair, int.class, 0); - private static final Reflection.FieldAccessor chunkCoordinateZ = Reflection.getField(chunkCoordinateIntPair, int.class, 1); - private static final Class multiBlockChangeInfo = Reflection.getClass("{nms}.PacketPlayOutMultiBlockChange$MultiBlockChangeInfo"); - private static final Reflection.ConstructorInvoker multiBlockChangeInfoConstructor = Reflection.getConstructor(multiBlockChangeInfo, multiBlockChangePacket, short.class, iBlockData); - private static final BiFunction, Object> multiBlockChangeInfoArrayCloner = ProtocolAPI.arrayCloneGenerator(multiBlockChangeInfo); - private static final Reflection.FieldAccessor multiBlockChangeInfoBlock = Reflection.getField(multiBlockChangeInfo, iBlockData, 0); - private static final Reflection.FieldAccessor multiBlockChangeInfoPos = Reflection.getField(multiBlockChangeInfo, short.class, 0); - private static final Class multiBlockChangeInfoArray = Reflection.getClass("[L{nms}.PacketPlayOutMultiBlockChange$MultiBlockChangeInfo;"); - private static final Reflection.FieldAccessor multiBlockChangeInfos = Reflection.getField(multiBlockChangePacket, multiBlockChangeInfoArray, 0); - private Object multiBlockChangeHider(Player p, Object packet) { - Object chunkCoords = multiBlockChangeChunk.get(packet); - if(bypass(p, chunkCoordinateX.get(chunkCoords), chunkCoordinateZ.get(chunkCoords))) - return packet; - - Object modpacket = multiBlockChangeCloner.apply(packet); - multiBlockChangeInfos.set(modpacket, multiBlockChangeInfoArrayCloner.apply(multiBlockChangeInfos.get(modpacket), mbci -> { - if(Config.HiddenBlocks.contains(getMaterialByIBlockData(multiBlockChangeInfoBlock.get(mbci)).name().toLowerCase())) - return multiBlockChangeInfoConstructor.invoke(modpacket, multiBlockChangeInfoPos.get(mbci), obfuscateIBlockData); - return mbci; - })); - return modpacket; - } - - private static final Class blockChangePacket = Reflection.getClass("{nms}.PacketPlayOutBlockChange"); + private static final Class blockChangePacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutBlockChange"); private static final Function blockChangeCloner = ProtocolAPI.shallowCloneGenerator(blockChangePacket); private static final Reflection.FieldAccessor blockChangePosition = Reflection.getField(blockChangePacket, blockPosition, 0); private static final Reflection.FieldAccessor blockChangeBlockData = Reflection.getField(blockChangePacket, iBlockData, 0); @@ -170,14 +110,14 @@ public class TechHider extends StateDependent { if(bypass(p, posToChunk(blockPositionX.get(pos)), posToChunk(blockPositionZ.get(pos)))) return packet; - if(Config.HiddenBlocks.contains(getMaterialByIBlockData(blockChangeBlockData.get(packet)).name().toLowerCase())){ + if(ProtocolWrapper.impl.iBlockDataHidden(blockChangeBlockData.get(packet))) { packet = blockChangeCloner.apply(packet); blockChangeBlockData.set(packet, obfuscateIBlockData); } return packet; } - private static final Class blockActionPacket = Reflection.getClass("{nms}.PacketPlayOutBlockAction"); + private static final Class blockActionPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutBlockAction"); private static final Reflection.FieldAccessor blockActionPosition = Reflection.getField(blockActionPacket, blockPosition, 0); private Object blockActionHider(Player p, Object packet) { Object pos = blockActionPosition.get(packet); @@ -186,33 +126,14 @@ public class TechHider extends StateDependent { return null; } - private BiFunction blockBreakHiderGenerator(Class blockBreakPacket){ - UnaryOperator blockBreakCloner = ProtocolAPI.shallowCloneGenerator(blockBreakPacket); - Reflection.FieldAccessor blockBreakPosition = Reflection.getField(blockBreakPacket, blockPosition, 0); - Reflection.FieldAccessor blockBreakBlockData = Reflection.getField(blockBreakPacket, iBlockData, 0); - - return (p, packet) -> { - Object pos = blockBreakPosition.get(packet); - if(bypass(p, posToChunk(blockPositionX.get(pos)), posToChunk(blockPositionZ.get(pos)))) - return packet; - - if(Config.HiddenBlocks.contains(getMaterialByIBlockData(blockBreakBlockData.get(packet)).name().toLowerCase())){ - packet = blockBreakCloner.apply(packet); - blockBreakBlockData.set(packet, obfuscateIBlockData); - } - return packet; - }; - } - - private static final Class tileEntityDataPacket = Reflection.getClass("{nms}.PacketPlayOutTileEntityData"); + public static final Class tileEntityDataPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutTileEntityData"); private static final Reflection.FieldAccessor tileEntityDataPosition = Reflection.getField(tileEntityDataPacket, blockPosition, 0); - private static final Reflection.FieldAccessor tileEntityDataAction = Reflection.getField(tileEntityDataPacket, int.class, 0); private Object tileEntityDataHider(Player p, Object packet) { Object pos = tileEntityDataPosition.get(packet); if(bypass(p, posToChunk(blockPositionX.get(pos)), posToChunk(blockPositionZ.get(pos)))) return packet; - if(tileEntityDataAction.get(packet) != 9) + if(ProtocolWrapper.impl.unfilteredTileEntityDataAction(packet)) return packet; return null; } @@ -239,7 +160,7 @@ public class TechHider extends StateDependent { }, 40); } - static boolean bypass(Player p, int chunkX, int chunkZ){ + public static boolean bypass(Player p, int chunkX, int chunkZ){ if(p == FightSystem.getEventLeiter()) return true; @@ -253,11 +174,7 @@ public class TechHider extends StateDependent { } } - private static Material getMaterialByIBlockData(Object iBlockData) { - return (Material) getMaterialByBlock.invoke(null, getBlockByBlockData.invoke(iBlockData)); - } - - private static int posToChunk(int c){ + public static int posToChunk(int c){ int chunk = c / 16; if(c<0) chunk--; diff --git a/FightSystem_Main/pom.xml b/FightSystem_Main/pom.xml index 2cd94da..a42f01d 100644 --- a/FightSystem_Main/pom.xml +++ b/FightSystem_Main/pom.xml @@ -92,6 +92,12 @@ 1.0 compile + + steamwar + FightSystem_18 + 1.0 + compile + steamwar FightSystem_Core diff --git a/pom.xml b/pom.xml index 35a72ae..aeee40f 100644 --- a/pom.xml +++ b/pom.xml @@ -57,10 +57,23 @@ FightSystem_12 FightSystem_14 FightSystem_15 + FightSystem_18 FightSystem_Core FightSystem_Main + + + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + steamwar