diff --git a/FightSystem_10/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper10.java b/FightSystem_10/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper10.java index d43e00c..e6b9dc8 100644 --- a/FightSystem_10/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper10.java +++ b/FightSystem_10/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper10.java @@ -25,14 +25,8 @@ import net.minecraft.server.v1_10_R1.Chunk; import org.bukkit.World; import org.bukkit.craftbukkit.v1_10_R1.CraftWorld; import org.bukkit.craftbukkit.v1_10_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_10_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_10_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; import java.util.stream.Stream; public class CraftbukkitWrapper10 implements CraftbukkitWrapper { @@ -52,24 +46,11 @@ public class CraftbukkitWrapper10 implements CraftbukkitWrapper { chunk.tileEntities.putAll(backupChunk.tileEntities); } - @Override - public void sendResourcePack(Player player, String pack, String sha1) { - ((CraftPlayer)player).getHandle().setResourcePack(pack, sha1); - } - @Override public float headRotation(Entity e) { return ((CraftEntity)e).getHandle().getHeadRotation(); } - @Override - public boolean hasItems(ItemStack stack) { - Set keys = new HashSet<>(CraftItemStack.asNMSCopy(stack).getTag().c()); - keys.remove("Enchantments"); - keys.remove("Damage"); - return !keys.isEmpty(); - } - @Override public Stream entityIterator() { return ((CraftWorld) Config.world).getHandle().entityList.stream(); diff --git a/FightSystem_12/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper12.java b/FightSystem_12/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper12.java index a637867..36fd0ab 100644 --- a/FightSystem_12/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper12.java +++ b/FightSystem_12/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper12.java @@ -25,14 +25,8 @@ import net.minecraft.server.v1_12_R1.Chunk; import org.bukkit.World; import org.bukkit.craftbukkit.v1_12_R1.CraftWorld; import org.bukkit.craftbukkit.v1_12_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_12_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; import java.util.stream.Stream; public class CraftbukkitWrapper12 implements CraftbukkitWrapper { @@ -52,24 +46,11 @@ public class CraftbukkitWrapper12 implements CraftbukkitWrapper { chunk.tileEntities.putAll(backupChunk.tileEntities); } - @Override - public void sendResourcePack(Player player, String pack, String sha1) { - ((CraftPlayer)player).getHandle().setResourcePack(pack, sha1); - } - @Override public float headRotation(Entity e) { return ((CraftEntity)e).getHandle().getHeadRotation(); } - @Override - public boolean hasItems(ItemStack stack) { - Set keys = new HashSet<>(CraftItemStack.asNMSCopy(stack).getTag().c()); - keys.remove("Enchantments"); - keys.remove("Damage"); - return !keys.isEmpty(); - } - @Override public Stream entityIterator() { return ((CraftWorld) Config.world).getHandle().entityList.stream(); diff --git a/FightSystem_12/src/de/steamwar/fightsystem/utils/ProtocolWrapper12.java b/FightSystem_12/src/de/steamwar/fightsystem/utils/ProtocolWrapper12.java deleted file mode 100644 index 650fb41..0000000 --- a/FightSystem_12/src/de/steamwar/fightsystem/utils/ProtocolWrapper12.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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/src/de/steamwar/fightsystem/utils/BlockIdWrapper14.java b/FightSystem_14/src/de/steamwar/fightsystem/utils/BlockIdWrapper14.java index e2a8bff..916bfb6 100644 --- a/FightSystem_14/src/de/steamwar/fightsystem/utils/BlockIdWrapper14.java +++ b/FightSystem_14/src/de/steamwar/fightsystem/utils/BlockIdWrapper14.java @@ -19,61 +19,41 @@ package de.steamwar.fightsystem.utils; -import de.steamwar.fightsystem.Config; -import net.minecraft.server.v1_14_R1.*; +import com.comphenix.tinyprotocol.Reflection; +import de.steamwar.core.Core; import org.bukkit.World; import org.bukkit.block.Block; -import org.bukkit.craftbukkit.v1_14_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_14_R1.block.CraftBlock; - -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; public class BlockIdWrapper14 implements BlockIdWrapper { + + private static final Class worldServer = Reflection.getClass("{nms.server.level}.WorldServer"); + private static final Class chunkProviderServer = Reflection.getClass("{nms.server.level}.ChunkProviderServer"); + private static final Class block = Reflection.getClass("{nms.world.level.block}.Block"); + private static final Class iBlockData = Reflection.getClass("{nms.world.level.block.state}.IBlockData"); + private static final Class blockPosition = Reflection.getClass("{nms.core}.BlockPosition"); + + private static final Reflection.MethodInvoker getCombinedId = Reflection.getTypedMethod(block, null, int.class, iBlockData); + private static final Reflection.MethodInvoker getNMS = Reflection.getTypedMethod(Reflection.getClass("{obc}.block.CraftBlock"), "getNMS", iBlockData); @Override public int blockToId(Block block) { - return net.minecraft.server.v1_14_R1.Block.REGISTRY_ID.getId(((CraftBlock)block).getNMS()); + return (int) getCombinedId.invoke(null, getNMS.invoke(block)); } + private static final Reflection.MethodInvoker getByCombinedId = Reflection.getTypedMethod(block, null, iBlockData, int.class); + private static final Reflection.MethodInvoker getWorldHandle = Reflection.getTypedMethod(Reflection.getClass("{obc}.CraftWorld"), "getHandle", worldServer); + private static final Reflection.ConstructorInvoker newBlockPosition = Reflection.getConstructor(blockPosition, int.class, int.class, int.class); + private static final Reflection.MethodInvoker getTypeAndData = Reflection.getMethod(worldServer, null, blockPosition, iBlockData, int.class); + private static final Reflection.MethodInvoker removeTileEntity = Reflection.getMethod(worldServer, Core.getVersion() > 15 ? "m" : "removeTileEntity", blockPosition); + private static final Reflection.MethodInvoker getChunkProvider = Reflection.getTypedMethod(worldServer, null, chunkProviderServer); + private static final Reflection.MethodInvoker flagDirty = Reflection.getMethod(chunkProviderServer, null, blockPosition); @Override public void setBlock(World world, int x, int y, int z, int blockState) { - IBlockData blockData = Objects.requireNonNull(net.minecraft.server.v1_14_R1.Block.REGISTRY_ID.fromId(blockState)); - WorldServer cworld = ((CraftWorld)world).getHandle(); - BlockPosition pos = new BlockPosition(x, y, z); - cworld.removeTileEntity(pos); - cworld.setTypeAndData(pos, blockData, 1042); - cworld.getChunkProvider().flagDirty(pos); - } + Object blockData = getByCombinedId.invoke(null, blockState); + Object nworld = getWorldHandle.invoke(world); + Object pos = newBlockPosition.invoke(x, y, z); - @Override - public Set getHiddenBlockIds() { - Set hiddenBlockIds = new HashSet<>(); - for(String tag : Config.HiddenBlocks){ - for(IBlockData data : IRegistry.BLOCK.get(new MinecraftKey(tag)).getStates().a()){ - hiddenBlockIds.add(net.minecraft.server.v1_14_R1.Block.getCombinedId(data)); - } - } - - if(Config.HiddenBlocks.contains("water")){ - Fluid water = FluidTypes.WATER.a(false); - for(IBlockData data : net.minecraft.server.v1_14_R1.Block.REGISTRY_ID){ - if(data.p() == water){ - hiddenBlockIds.add(net.minecraft.server.v1_14_R1.Block.getCombinedId(data)); - } - } - } - - return hiddenBlockIds; - } - - @Override - public int getObfuscateWith() { - return net.minecraft.server.v1_14_R1.Block.getCombinedId(IRegistry.BLOCK.get(new MinecraftKey(Config.ObfuscateWith)).getBlockData()); - } - - @Override - public Object getPose(boolean sneaking) { - return sneaking ? EntityPose.SNEAKING : EntityPose.STANDING; + removeTileEntity.invoke(nworld, pos); + getTypeAndData.invoke(nworld, pos, blockData, 1042); + flagDirty.invoke(getChunkProvider.invoke(nworld), pos); } } diff --git a/FightSystem_14/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper14.java b/FightSystem_14/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper14.java index 54e5ff9..7528fcf 100644 --- a/FightSystem_14/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper14.java +++ b/FightSystem_14/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper14.java @@ -25,14 +25,8 @@ import net.minecraft.server.v1_14_R1.Chunk; import org.bukkit.World; import org.bukkit.craftbukkit.v1_14_R1.CraftWorld; import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_14_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; import java.util.stream.Stream; public class CraftbukkitWrapper14 implements CraftbukkitWrapper { @@ -53,24 +47,11 @@ public class CraftbukkitWrapper14 implements CraftbukkitWrapper { chunk.heightMap.putAll(backupChunk.heightMap); } - @Override - public void sendResourcePack(Player player, String pack, String sha1) { - ((CraftPlayer)player).getHandle().setResourcePack(pack, sha1); - } - @Override public float headRotation(Entity e) { return ((CraftEntity)e).getHandle().getHeadRotation(); } - @Override - public boolean hasItems(ItemStack stack) { - Set keys = new HashSet<>(CraftItemStack.asNMSCopy(stack).getTag().getKeys()); - keys.remove("Enchantments"); - keys.remove("Damage"); - return !keys.isEmpty(); - } - @Override public Stream entityIterator() { return ((CraftWorld) Config.world).getHandle().entitiesById.values().stream(); diff --git a/FightSystem_14/src/de/steamwar/fightsystem/utils/FlatteningWrapper14.java b/FightSystem_14/src/de/steamwar/fightsystem/utils/FlatteningWrapper14.java index ff3a1a9..cda664d 100644 --- a/FightSystem_14/src/de/steamwar/fightsystem/utils/FlatteningWrapper14.java +++ b/FightSystem_14/src/de/steamwar/fightsystem/utils/FlatteningWrapper14.java @@ -25,6 +25,9 @@ import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Waterlogged; +import org.bukkit.block.data.type.Dispenser; +import org.bukkit.entity.Player; +import org.bukkit.entity.Pose; import org.bukkit.event.block.BlockPhysicsEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.BlockDataMeta; @@ -52,7 +55,8 @@ public class FlatteningWrapper14 implements FlatteningWrapper { @Override public boolean removeWater(Block block) { - if(block.getType() == Material.WATER){ + Material type = block.getType(); + if(type == Material.WATER || type == Material.LAVA){ block.setType(Material.AIR); return true; } @@ -80,23 +84,6 @@ public class FlatteningWrapper14 implements FlatteningWrapper { return stack.hasItemMeta() && Objects.requireNonNull(stack.getItemMeta()).hasAttributeModifiers(); } - @Override - public ItemStack onBreak(Block block) { - Material type = block.getType(); - switch(type){ - case REDSTONE_WIRE: - type = Material.REDSTONE; - break; - case PISTON_HEAD: - type = Material.PISTON; - break; - case ICE: - type = Material.AIR; - break; - } - return new ItemStack(type); - } - @Override public boolean doRecord(BlockPhysicsEvent e) { return e.getBlock() == e.getSourceBlock() || e.getChangedType() == Material.AIR; @@ -113,7 +100,12 @@ public class FlatteningWrapper14 implements FlatteningWrapper { } @Override - public void setNamedSpawnPacketDataWatcher(Object packet) { - // field not present + public boolean isFacingWater(Block dispenser) { + return dispenser.getRelative(((Dispenser) dispenser.getBlockData()).getFacing()).isLiquid(); + } + + @Override + public boolean isCrouching(Player player) { + return player.getPose() == Pose.SWIMMING; } } diff --git a/FightSystem_14/src/de/steamwar/fightsystem/utils/TechHider14.java b/FightSystem_14/src/de/steamwar/fightsystem/utils/TechHider14.java deleted file mode 100644 index e5674b6..0000000 --- a/FightSystem_14/src/de/steamwar/fightsystem/utils/TechHider14.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - This file is a part of the SteamWar software. - - Copyright (C) 2020 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 io.netty.buffer.ByteBuf; -import io.netty.buffer.UnpooledByteBufAllocator; - -import java.nio.ByteBuffer; -import java.nio.LongBuffer; - -public class TechHider14 extends TechHider9 { - - @Override - protected byte[] dataHider(byte[] data, Integer primaryBitMask) { - ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100); - int i = 0; - - while(primaryBitMask != 0){ - while((primaryBitMask & 1) == 0){ - primaryBitMask >>= 1; - } - - buffer.writeBytes(data, i, 2); // Block count - i += 2; - byte bitsPerBlock = data[i++]; - buffer.writeByte(bitsPerBlock); - - if(bitsPerBlock < 9){ - 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 blockId = TechHider.readVarInt(data, i); - int actPaletteLength = TechHider.readVarIntLength(data, i); - - if(hiddenBlockIds.contains(blockId)){ - buffer.writeBytes(TechHider.writeVarInt(obfuscateWith)); - }else{ - buffer.writeBytes(data, i, actPaletteLength); - } - i += actPaletteLength; - } - - //We modify only the chunk palette for performance reasons - int dataArrayLength = TechHider.readVarInt(data, i); - int dataArrayLengthLength = TechHider.readVarIntLength(data, i); - buffer.writeBytes(data, i, dataArrayLength * 8 + dataArrayLengthLength); - i += dataArrayLengthLength; - i += dataArrayLength * 8; - }else{ - //Full Chunk/no palette, so the chunk has to be crawled through - int dataArrayLength = TechHider.readVarInt(data, i); - int dataArrayLengthLength = TechHider.readVarIntLength(data, i); - buffer.writeBytes(data, i, dataArrayLengthLength); - i += dataArrayLengthLength; - - ByteBuffer source = ByteBuffer.wrap(data, i, 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 += dataArrayLength * 8; - } - - primaryBitMask >>= 1; - } - buffer.writeBytes(data, i, data.length - i); // MC appends a 0 byte at the end if there is a full chunk, idk why - - data = new byte[buffer.readableBytes()]; - buffer.readBytes(data); - return data; - } - - private static final class VariableValueArray { - private final long[] backing; - private final int bitsPerValue; - private final long valueMask; - - 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; - } - - public int get(int index) { - index *= bitsPerValue; - int i0 = index >> 6; - int i1 = index & 0x3f; - - long value = backing[i0] >>> i1; - - // The value is divided over two long values - if (i1 + bitsPerValue > 64) { - value |= backing[++i0] << 64 - i1; - } - - return (int) (value & valueMask); - } - - public void set(int index, int value) { - index *= bitsPerValue; - int i0 = index >> 6; - int i1 = index & 0x3f; - - backing[i0] = this.backing[i0] & ~(this.valueMask << i1) | (value & valueMask) << i1; - int i2 = i1 + bitsPerValue; - // The value is divided over two long values - if (i2 > 64) { - i0++; - backing[i0] = backing[i0] & -(1L << i2 - 64) | value >> 64 - i1; - } - } - } -} diff --git a/FightSystem_14/src/de/steamwar/fightsystem/utils/WorldeditWrapper14.java b/FightSystem_14/src/de/steamwar/fightsystem/utils/WorldeditWrapper14.java index 4ee7a4d..288b89e 100644 --- a/FightSystem_14/src/de/steamwar/fightsystem/utils/WorldeditWrapper14.java +++ b/FightSystem_14/src/de/steamwar/fightsystem/utils/WorldeditWrapper14.java @@ -42,6 +42,7 @@ import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockTypes; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; +import de.steamwar.sql.SchematicData; import de.steamwar.sql.SchematicNode; import org.bukkit.DyeColor; import org.bukkit.Location; @@ -143,6 +144,6 @@ public class WorldeditWrapper14 implements WorldeditWrapper { throw new SecurityException(e); } - schem.saveFromBytes(outputStream.toByteArray(), true); + new SchematicData(schem).saveFromBytes(outputStream.toByteArray(), true); } } diff --git a/FightSystem_15/src/de/steamwar/fightsystem/utils/BlockIdWrapper15.java b/FightSystem_15/src/de/steamwar/fightsystem/utils/BlockIdWrapper15.java deleted file mode 100644 index 9ec0283..0000000 --- a/FightSystem_15/src/de/steamwar/fightsystem/utils/BlockIdWrapper15.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - 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.server.v1_15_R1.*; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.craftbukkit.v1_15_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_15_R1.block.CraftBlock; - -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; - -public class BlockIdWrapper15 implements BlockIdWrapper { - @Override - public int blockToId(Block block) { - return net.minecraft.server.v1_15_R1.Block.REGISTRY_ID.getId(((CraftBlock)block).getNMS()); - } - - @Override - public void setBlock(World world, int x, int y, int z, int blockState) { - IBlockData blockData = Objects.requireNonNull(net.minecraft.server.v1_15_R1.Block.REGISTRY_ID.fromId(blockState)); - WorldServer cworld = ((CraftWorld)world).getHandle(); - BlockPosition pos = new BlockPosition(x, y, z); - cworld.removeTileEntity(pos); - cworld.setTypeAndData(pos, blockData, 1042); - cworld.getChunkProvider().flagDirty(pos); - } - - @Override - public Set getHiddenBlockIds() { - Set hiddenBlockIds = new HashSet<>(); - for(String tag : Config.HiddenBlocks){ - for(IBlockData data : IRegistry.BLOCK.get(new MinecraftKey(tag)).getStates().a()){ - hiddenBlockIds.add(net.minecraft.server.v1_15_R1.Block.getCombinedId(data)); - } - } - - if(Config.HiddenBlocks.contains("water")){ - Fluid water = FluidTypes.WATER.a(false); - for(IBlockData data : net.minecraft.server.v1_15_R1.Block.REGISTRY_ID){ - if(data.getFluid() == water){ - hiddenBlockIds.add(net.minecraft.server.v1_15_R1.Block.getCombinedId(data)); - } - } - } - - return hiddenBlockIds; - } - - @Override - public int getObfuscateWith() { - return net.minecraft.server.v1_15_R1.Block.getCombinedId(IRegistry.BLOCK.get(new MinecraftKey(Config.ObfuscateWith)).getBlockData()); - } - - @Override - public Object getPose(boolean sneaking) { - return sneaking ? EntityPose.CROUCHING : EntityPose.STANDING; - } -} diff --git a/FightSystem_15/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper15.java b/FightSystem_15/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper15.java index 2fe700e..f06902b 100644 --- a/FightSystem_15/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper15.java +++ b/FightSystem_15/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper15.java @@ -25,14 +25,8 @@ import net.minecraft.server.v1_15_R1.Chunk; import org.bukkit.World; import org.bukkit.craftbukkit.v1_15_R1.CraftWorld; import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_15_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; import java.util.stream.Stream; public class CraftbukkitWrapper15 implements CraftbukkitWrapper { @@ -53,24 +47,11 @@ public class CraftbukkitWrapper15 implements CraftbukkitWrapper { chunk.heightMap.putAll(backupChunk.heightMap); } - @Override - public void sendResourcePack(Player player, String pack, String sha1) { - ((CraftPlayer)player).getHandle().setResourcePack(pack, sha1); - } - @Override public float headRotation(Entity e) { return ((CraftEntity)e).getHandle().getHeadRotation(); } - @Override - public boolean hasItems(ItemStack stack) { - Set keys = new HashSet<>(CraftItemStack.asNMSCopy(stack).getTag().getKeys()); - keys.remove("Enchantments"); - keys.remove("Damage"); - return !keys.isEmpty(); - } - @Override public Stream entityIterator() { return ((CraftWorld) Config.world).getHandle().entitiesById.values().stream(); diff --git a/FightSystem_18/src/de/steamwar/fightsystem/utils/BlockIdWrapper18.java b/FightSystem_18/src/de/steamwar/fightsystem/utils/BlockIdWrapper18.java deleted file mode 100644 index 243aa24..0000000 --- a/FightSystem_18/src/de/steamwar/fightsystem/utils/BlockIdWrapper18.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - 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_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_18_R2.block.CraftBlock; - -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; - -public class BlockIdWrapper18 implements BlockIdWrapper { - - @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.U.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.o) { - if(data.o() == 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.U.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 index de77d54..72c14f8 100644 --- a/FightSystem_18/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper18.java +++ b/FightSystem_18/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper18.java @@ -19,53 +19,47 @@ package de.steamwar.fightsystem.utils; +import com.comphenix.tinyprotocol.Reflection; import de.steamwar.fightsystem.Config; +import net.minecraft.server.level.WorldServer; import net.minecraft.world.level.chunk.Chunk; +import net.minecraft.world.level.chunk.ChunkSection; +import net.minecraft.world.level.entity.LevelEntityGetter; import org.bukkit.World; -import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_18_R2.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; import java.util.stream.Stream; import java.util.stream.StreamSupport; public class CraftbukkitWrapper18 implements CraftbukkitWrapper { - @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); + private static final Reflection.MethodInvoker getWorld = Reflection.getMethod(Reflection.getClass("{obc}.CraftWorld"), "getHandle"); + private static final Reflection.MethodInvoker getChunk = Reflection.getTypedMethod(net.minecraft.world.level.World.class, null, Chunk.class, int.class, int.class); + private static final Reflection.MethodInvoker getChunkSections = Reflection.getTypedMethod(Chunk.class, null, ChunkSection[].class); + private ChunkSection[] getChunkSections(World world, int x, int z) { + return (ChunkSection[]) getChunkSections.invoke(getChunk.invoke(getWorld.invoke(world), x, z)); } @Override - public void sendResourcePack(Player player, String pack, String sha1) { - ((CraftPlayer)player).getHandle().a(pack, sha1, true, null); + public void resetChunk(World world, World backup, int x, int z) { + ChunkSection[] sections = getChunkSections(world, x, z); + System.arraycopy(getChunkSections(backup, x, z), 0, sections, 0, sections.length); + } + + private static final Reflection.MethodInvoker getEntity = Reflection.getTypedMethod(Reflection.getClass("{obc}.entity.CraftEntity"), "getHandle", net.minecraft.world.entity.Entity.class); + protected net.minecraft.world.entity.Entity getEntity(Entity e) { + return (net.minecraft.world.entity.Entity) getEntity.invoke(e); } @Override public float headRotation(Entity e) { - return ((CraftEntity)e).getHandle().ce(); - } - - @Override - public boolean hasItems(ItemStack stack) { - Set keys = new HashSet<>(CraftItemStack.asNMSCopy(stack).t().d()); - keys.remove("Enchantments"); - keys.remove("Damage"); - return !keys.isEmpty(); + return getEntity(e).ce(); } + private static final Reflection.MethodInvoker getWorldEntities = Reflection.getTypedMethod(WorldServer.class, null, LevelEntityGetter.class); + private static final Reflection.MethodInvoker getIterable = Reflection.getTypedMethod(LevelEntityGetter.class, null, Iterable.class); @Override public Stream entityIterator() { - return StreamSupport.stream(((CraftWorld) Config.world).getHandle().H().a().spliterator(), false); + return StreamSupport.stream(((Iterable) getIterable.invoke(getWorldEntities.invoke(getWorld.invoke(Config.world)))).spliterator(), false); } } diff --git a/FightSystem_18/src/de/steamwar/fightsystem/utils/ProtocolWrapper18.java b/FightSystem_18/src/de/steamwar/fightsystem/utils/ProtocolWrapper18.java deleted file mode 100644 index 52f2704..0000000 --- a/FightSystem_18/src/de/steamwar/fightsystem/utils/ProtocolWrapper18.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - 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.U.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 deleted file mode 100644 index 98c1a28..0000000 --- a/FightSystem_18/src/de/steamwar/fightsystem/utils/TechHider18.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - 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.util.SimpleBitStorage; -import net.minecraft.world.level.block.entity.TileEntityTypes; -import org.bukkit.World; -import org.bukkit.entity.Player; - -import java.nio.ByteBuffer; -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"); - protected 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(this::tileEntityVisible).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; - } - - protected boolean tileEntityVisible(Object tile) { - return !Config.HiddenBlockEntities.contains(IRegistry.aa.b(entityType.get(tile)).a()); - } - - 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); - long[] array = new long[dataArrayLength]; - source.asLongBuffer().get(array); - SimpleBitStorage values = new SimpleBitStorage(bitsPerBlock, 4096, array); - - for (int pos = 0; pos < 4096; pos++) { - if (hiddenBlockIds.contains(values.a(pos))) { - values.b(pos, obfuscateWith); - } - } - - for (long l : values.a()) - 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; - } -} diff --git a/FightSystem_19/src/de/steamwar/fightsystem/utils/BlockIdWrapper19.java b/FightSystem_19/src/de/steamwar/fightsystem/utils/BlockIdWrapper19.java deleted file mode 100644 index e7b861f..0000000 --- a/FightSystem_19/src/de/steamwar/fightsystem/utils/BlockIdWrapper19.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - 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_19_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R1.block.CraftBlock; - -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; - -public class BlockIdWrapper19 implements BlockIdWrapper { - - @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.V.a(new MinecraftKey(tag)).k().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.o) { - if(data.p() == 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.V.a(new MinecraftKey(Config.ObfuscateWith)).m()); - } - - @Override - public Object getPose(boolean sneaking) { - return sneaking ? EntityPose.f : EntityPose.a; - } -} diff --git a/FightSystem_19/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper19.java b/FightSystem_19/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper19.java index 5193f15..1a18a2a 100644 --- a/FightSystem_19/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper19.java +++ b/FightSystem_19/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper19.java @@ -19,53 +19,12 @@ package de.steamwar.fightsystem.utils; -import de.steamwar.fightsystem.Config; -import net.minecraft.world.level.chunk.Chunk; -import org.bukkit.World; -import org.bukkit.craftbukkit.v1_19_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_19_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; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; - -public class CraftbukkitWrapper19 implements CraftbukkitWrapper { - - @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); - } +public class CraftbukkitWrapper19 extends CraftbukkitWrapper18 { @Override public float headRotation(Entity e) { - return ((CraftEntity)e).getHandle().ch(); - } - - @Override - public boolean hasItems(ItemStack stack) { - Set keys = new HashSet<>(CraftItemStack.asNMSCopy(stack).u().d()); - keys.remove("Enchantments"); - keys.remove("Damage"); - return !keys.isEmpty(); - } - - @Override - public Stream entityIterator() { - return StreamSupport.stream(((CraftWorld) Config.world).getHandle().F().a().spliterator(), false); + return getEntity(e).ck(); } } diff --git a/FightSystem_19/src/de/steamwar/fightsystem/utils/ProtocolWrapper19.java b/FightSystem_19/src/de/steamwar/fightsystem/utils/ProtocolWrapper19.java deleted file mode 100644 index 4626f83..0000000 --- a/FightSystem_19/src/de/steamwar/fightsystem/utils/ProtocolWrapper19.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - 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.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 ProtocolWrapper19 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 null; - } - - private static final Reflection.ConstructorInvoker playerInfoDataConstructor = Reflection.getConstructor(Fight.playerInfoDataClass, GameProfile.class, int.class, Fight.enumGamemode, Fight.iChatBaseComponent, Reflection.getClass("net.minecraft.world.entity.player.ProfilePublicKey$a")); - @Override - public Object playerInfoDataConstructor(Object packet, GameProfile profile, Object mode) { - return playerInfoDataConstructor.invoke(profile, 0, mode, null, null); - } - - @Override - public boolean iBlockDataHidden(Object iBlockData) { - return Config.HiddenBlocks.contains(IRegistry.V.b(((IBlockData) iBlockData).b()).a()); - } -} diff --git a/FightSystem_19/src/de/steamwar/fightsystem/utils/TechHider19.java b/FightSystem_19/src/de/steamwar/fightsystem/utils/TechHider19.java deleted file mode 100644 index eb61b75..0000000 --- a/FightSystem_19/src/de/steamwar/fightsystem/utils/TechHider19.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - 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.IRegistry; - -public class TechHider19 extends TechHider18 { - - @Override - protected boolean tileEntityVisible(Object tile) { - return !Config.HiddenBlockEntities.contains(IRegistry.ab.b(entityType.get(tile)).a()); - } -} diff --git a/FightSystem_8/src/de/steamwar/fightsystem/utils/BlockIdWrapper8.java b/FightSystem_8/src/de/steamwar/fightsystem/utils/BlockIdWrapper8.java index da5d971..aedd2e8 100644 --- a/FightSystem_8/src/de/steamwar/fightsystem/utils/BlockIdWrapper8.java +++ b/FightSystem_8/src/de/steamwar/fightsystem/utils/BlockIdWrapper8.java @@ -19,14 +19,9 @@ package de.steamwar.fightsystem.utils; -import de.steamwar.fightsystem.Config; -import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; -import java.util.HashSet; -import java.util.Set; - public class BlockIdWrapper8 implements BlockIdWrapper { @Override @SuppressWarnings("deprecation") @@ -37,27 +32,9 @@ public class BlockIdWrapper8 implements BlockIdWrapper { @Override @SuppressWarnings("deprecation") public void setBlock(World world, int x, int y, int z, int blockState) { + if((blockState >> 4) > 256) // Illegal blockstate / corrupted replay + blockState = 0; + world.getBlockAt(x, y, z).setTypeIdAndData(blockState >> 4, (byte)(blockState & 0b1111), false); } - - @Override - @SuppressWarnings("deprecation") - public Set getHiddenBlockIds() { - Set hiddenBlockIds = new HashSet<>(); - for(String tag : Config.HiddenBlocks){ - hiddenBlockIds.add(Material.matchMaterial(tag).getId() << 4); - } - return hiddenBlockIds; - } - - @Override - @SuppressWarnings("deprecation") - public int getObfuscateWith() { - return Material.matchMaterial(Config.ObfuscateWith).getId() << 4; - } - - @Override - public Object getPose(boolean sneaking) { - return Byte.valueOf((byte)(sneaking ? 2 : 0)); - } } diff --git a/FightSystem_8/src/de/steamwar/fightsystem/utils/BountifulWrapper8.java b/FightSystem_8/src/de/steamwar/fightsystem/utils/BountifulWrapper8.java index 4b08cf2..3d124ff 100644 --- a/FightSystem_8/src/de/steamwar/fightsystem/utils/BountifulWrapper8.java +++ b/FightSystem_8/src/de/steamwar/fightsystem/utils/BountifulWrapper8.java @@ -19,24 +19,25 @@ package de.steamwar.fightsystem.utils; -import com.comphenix.tinyprotocol.Reflection; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.fight.FightTeam; import de.steamwar.fightsystem.listener.Recording; import de.steamwar.fightsystem.record.GlobalRecorder; -import de.steamwar.fightsystem.record.REntity; import net.minecraft.server.v1_8_R3.DataWatcher; import net.minecraft.server.v1_8_R3.EntityEnderDragon; import net.minecraft.server.v1_8_R3.PacketPlayOutEntityMetadata; import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving; -import net.royawesome.jlibnoise.MathHelper; -import org.bukkit.*; +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; import org.bukkit.entity.Player; import org.bukkit.event.Listener; import org.bukkit.scoreboard.Team; -import java.util.*; +import java.util.HashSet; +import java.util.Set; public class BountifulWrapper8 implements BountifulWrapper { @@ -92,47 +93,6 @@ public class BountifulWrapper8 implements BountifulWrapper { world.playEffect(new Location(world, x, y, z), Effect.valueOf(particleName), 1); } - @Override - public Object getDataWatcherObject(int index, Class type) { - return index; - } - - private static final Class watchableObject = Reflection.getClass("{nms}.DataWatcher$WatchableObject"); - private static final Reflection.ConstructorInvoker watchableObjectConstructor = Reflection.getConstructor(watchableObject, int.class, int.class, Object.class); - private static final Map, Integer> watchableDatatypes = new HashMap<>(); - static { - watchableDatatypes.put(byte.class, 0); - watchableDatatypes.put(short.class, 1); - watchableDatatypes.put(int.class, 2); - watchableDatatypes.put(float.class, 3); - watchableDatatypes.put(String.class, 4); - } - - @Override - public Object getDataWatcherItem(Object dwo, Object value) { - return watchableObjectConstructor.invoke(watchableDatatypes.get(value.getClass()), dwo, value); - } - - private static final Reflection.FieldAccessor teleportX = Reflection.getField(REntity.teleportPacket, int.class, 1); - private static final Reflection.FieldAccessor teleportY = Reflection.getField(REntity.teleportPacket, int.class, 2); - private static final Reflection.FieldAccessor teleportZ = Reflection.getField(REntity.teleportPacket, int.class, 3); - @Override - public void setTeleportPacketPosition(Object packet, double x, double y, double z) { - teleportX.set(packet, MathHelper.floor(x * 32)); - teleportY.set(packet, MathHelper.floor(y * 32)); - teleportZ.set(packet, MathHelper.floor(z * 32)); - } - - @Override - public void setSpawnPacketUUID(Object packet, UUID uuid) { - // field not present - } - - @Override - public void setNamedSpawnPosition(Object packet, double x, double y, double z) { - //no implementation for 1.8 - } - private final Set seesDragon = new HashSet<>(); private final PacketPlayOutSpawnEntityLiving spawnDragon; private final int spawnDragonId; diff --git a/FightSystem_8/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper8.java b/FightSystem_8/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper8.java index 07d75e9..8d743ae 100644 --- a/FightSystem_8/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper8.java +++ b/FightSystem_8/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper8.java @@ -24,14 +24,8 @@ import net.minecraft.server.v1_8_R3.Chunk; import org.bukkit.World; import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_8_R3.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; import java.util.stream.Stream; public class CraftbukkitWrapper8 implements CraftbukkitWrapper { @@ -49,24 +43,11 @@ public class CraftbukkitWrapper8 implements CraftbukkitWrapper { chunk.tileEntities.putAll(backupChunk.tileEntities); } - @Override - public void sendResourcePack(Player player, String pack, String sha1) { - ((CraftPlayer)player).getHandle().setResourcePack(pack, sha1); - } - @Override public float headRotation(Entity e) { return ((CraftEntity)e).getHandle().getHeadRotation(); } - @Override - public boolean hasItems(ItemStack stack) { - Set keys = new HashSet<>(CraftItemStack.asNMSCopy(stack).getTag().c()); - keys.remove("Enchantments"); - keys.remove("Damage"); - return !keys.isEmpty(); - } - @Override public Stream entityIterator() { return ((CraftWorld) Config.world).getHandle().entityList.stream(); diff --git a/FightSystem_8/src/de/steamwar/fightsystem/utils/FlatteningWrapper8.java b/FightSystem_8/src/de/steamwar/fightsystem/utils/FlatteningWrapper8.java index b88cca2..6a0e132 100644 --- a/FightSystem_8/src/de/steamwar/fightsystem/utils/FlatteningWrapper8.java +++ b/FightSystem_8/src/de/steamwar/fightsystem/utils/FlatteningWrapper8.java @@ -19,12 +19,11 @@ 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.entity.Player; import org.bukkit.event.block.BlockPhysicsEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; @@ -38,7 +37,7 @@ public class FlatteningWrapper8 implements FlatteningWrapper { @Override public boolean isWater(Block block) { Material type = block.getType(); - return type == Material.WATER || type == Material.STATIONARY_WATER; + return type == Material.WATER || type == Material.STATIONARY_WATER || type == Material.LAVA || type == Material.STATIONARY_LAVA; } @Override @@ -60,11 +59,6 @@ public class FlatteningWrapper8 implements FlatteningWrapper { return false; } - @Override - public ItemStack onBreak(Block block) { - return block.getDrops().stream().findAny().orElse(new ItemStack(Material.AIR)); - } - @Override public boolean doRecord(BlockPhysicsEvent e) { return e.getChangedType() != e.getBlock().getType(); @@ -80,12 +74,13 @@ public class FlatteningWrapper8 implements FlatteningWrapper { return block.getType() == Material.PISTON_MOVING_PIECE; } - private static final Class dataWatcher = Reflection.getClass("{nms}.DataWatcher"); - private static final Reflection.FieldAccessor namedSpawnDataWatcher = Reflection.getField(REntity.namedSpawnPacket, dataWatcher, 0); - private static final Class entity = Reflection.getClass("{nms}.Entity"); - private static final Reflection.ConstructorInvoker dataWatcherConstructor = Reflection.getConstructor(dataWatcher, entity); @Override - public void setNamedSpawnPacketDataWatcher(Object packet) { - namedSpawnDataWatcher.set(packet, dataWatcherConstructor.invoke((Object) null)); + public boolean isFacingWater(Block dispenser) { + return false; + } + + @Override + public boolean isCrouching(Player player) { + return false; } } diff --git a/FightSystem_8/src/de/steamwar/fightsystem/utils/ProtocolWrapper8.java b/FightSystem_8/src/de/steamwar/fightsystem/utils/ProtocolWrapper8.java deleted file mode 100644 index 80c1135..0000000 --- a/FightSystem_8/src/de/steamwar/fightsystem/utils/ProtocolWrapper8.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - 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 deleted file mode 100644 index d299c3d..0000000 --- a/FightSystem_8/src/de/steamwar/fightsystem/utils/TechHider8.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - 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; - -public class TechHider8 implements TechHider.ChunkHider { - - protected static final Class mapChunkPacket = Reflection.getClass("{nms}.PacketPlayOutMapChunk"); - @Override - public Class mapChunkPacket() { - return mapChunkPacket; - } - - @Override - public Object mapChunkHider(Player p, Object packet) { - return packet; - } -} diff --git a/FightSystem_8/src/de/steamwar/fightsystem/utils/WorldeditWrapper8.java b/FightSystem_8/src/de/steamwar/fightsystem/utils/WorldeditWrapper8.java index c8588f4..19854db 100644 --- a/FightSystem_8/src/de/steamwar/fightsystem/utils/WorldeditWrapper8.java +++ b/FightSystem_8/src/de/steamwar/fightsystem/utils/WorldeditWrapper8.java @@ -39,6 +39,7 @@ import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.world.World; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; +import de.steamwar.sql.SchematicData; import de.steamwar.sql.SchematicNode; import org.bukkit.DyeColor; import org.bukkit.Location; @@ -141,6 +142,6 @@ public class WorldeditWrapper8 implements WorldeditWrapper { throw new SecurityException(e); } - schem.saveFromBytes(outputStream.toByteArray(), false); + new SchematicData(schem).saveFromBytes(outputStream.toByteArray(), false); } } diff --git a/FightSystem_9/src/de/steamwar/fightsystem/utils/BountifulWrapper9.java b/FightSystem_9/src/de/steamwar/fightsystem/utils/BountifulWrapper9.java index 27e6e28..96cc943 100644 --- a/FightSystem_9/src/de/steamwar/fightsystem/utils/BountifulWrapper9.java +++ b/FightSystem_9/src/de/steamwar/fightsystem/utils/BountifulWrapper9.java @@ -24,7 +24,6 @@ import de.steamwar.fightsystem.fight.Fight; import de.steamwar.fightsystem.fight.FightTeam; import de.steamwar.fightsystem.listener.Recording; import de.steamwar.fightsystem.record.GlobalRecorder; -import de.steamwar.fightsystem.record.REntity; import org.bukkit.*; import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeInstance; @@ -39,11 +38,8 @@ import org.bukkit.event.player.PlayerPickupArrowEvent; import org.bukkit.event.player.PlayerSwapHandItemsEvent; import org.bukkit.scoreboard.Team; -import java.lang.reflect.Field; -import java.lang.reflect.ParameterizedType; import java.util.HashMap; import java.util.Map; -import java.util.UUID; public class BountifulWrapper9 implements BountifulWrapper { @@ -120,58 +116,6 @@ public class BountifulWrapper9 implements BountifulWrapper { world.spawnParticle(Particle.valueOf(particleName), x, y, z, 1); } - - 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) { - for(Field field : dataWatcherRegistry.getFields()) { - if(dataWatcherSerializer.isAssignableFrom(field.getType()) && type.equals(((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0])) { - try { - return dataWatcherObjectConstructor.invoke(index, field.get(null)); - } catch (IllegalAccessException e) { - throw new SecurityException("Could not get field", e); - } - } - } - throw new SecurityException("Could not find Serializer for " + type.getName()); - } - - 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) { - return itemConstructor.invoke(dwo, value); - } - - private static final Reflection.FieldAccessor teleportX = Reflection.getField(REntity.teleportPacket, double.class, 0); - private static final Reflection.FieldAccessor teleportY = Reflection.getField(REntity.teleportPacket, double.class, 1); - private static final Reflection.FieldAccessor teleportZ = Reflection.getField(REntity.teleportPacket, double.class, 2); - @Override - public void setTeleportPacketPosition(Object packet, double x, double y, double z) { - teleportX.set(packet, x); - teleportY.set(packet, y); - teleportZ.set(packet, z); - } - - private static final Reflection.FieldAccessor spawnUUID = Reflection.getField(REntity.spawnPacket, UUID.class, 0); - @Override - public void setSpawnPacketUUID(Object packet, UUID uuid) { - spawnUUID.set(packet, uuid); - } - - private static final Reflection.FieldAccessor namedSpawnX = Reflection.getField(REntity.namedSpawnPacket, double.class, 0); - private static final Reflection.FieldAccessor namedSpawnY = Reflection.getField(REntity.namedSpawnPacket, double.class, 1); - private static final Reflection.FieldAccessor namedSpawnZ = Reflection.getField(REntity.namedSpawnPacket, double.class, 2); - @Override - public void setNamedSpawnPosition(Object packet, double x, double y, double z) { - namedSpawnX.set(packet, x); - namedSpawnY.set(packet, y); - namedSpawnZ.set(packet, z); - } - private final Map barMap = new HashMap<>(); @Override public void sendBar(Player player, FightTeam team, double progress, String text) { diff --git a/FightSystem_9/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper9.java b/FightSystem_9/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper9.java index 0873f8a..a0ddcd9 100644 --- a/FightSystem_9/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper9.java +++ b/FightSystem_9/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper9.java @@ -25,14 +25,8 @@ import net.minecraft.server.v1_9_R2.Chunk; import org.bukkit.World; import org.bukkit.craftbukkit.v1_9_R2.CraftWorld; import org.bukkit.craftbukkit.v1_9_R2.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_9_R2.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_9_R2.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; import java.util.stream.Stream; public class CraftbukkitWrapper9 implements CraftbukkitWrapper { @@ -52,24 +46,11 @@ public class CraftbukkitWrapper9 implements CraftbukkitWrapper { chunk.tileEntities.putAll(backupChunk.tileEntities); } - @Override - public void sendResourcePack(Player player, String pack, String sha1) { - ((CraftPlayer)player).getHandle().setResourcePack(pack, sha1); - } - @Override public float headRotation(Entity e) { return ((CraftEntity)e).getHandle().getHeadRotation(); } - @Override - public boolean hasItems(ItemStack stack) { - Set keys = new HashSet<>(CraftItemStack.asNMSCopy(stack).getTag().c()); - keys.remove("Enchantments"); - keys.remove("Damage"); - return !keys.isEmpty(); - } - @Override public Stream entityIterator() { return ((CraftWorld) Config.world).getHandle().entityList.stream(); diff --git a/FightSystem_9/src/de/steamwar/fightsystem/utils/TechHider9.java b/FightSystem_9/src/de/steamwar/fightsystem/utils/TechHider9.java deleted file mode 100644 index e9b0ba9..0000000 --- a/FightSystem_9/src/de/steamwar/fightsystem/utils/TechHider9.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - 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 org.bukkit.Bukkit; -import org.bukkit.entity.Player; - -import java.util.List; -import java.util.Set; -import java.util.function.UnaryOperator; -import java.util.logging.Level; -import java.util.stream.Collectors; - -public class TechHider9 extends TechHider8 { - - 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 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; - - while(i < data.length){ - byte bitsPerBlock = data[i++]; - buffer.writeByte(bitsPerBlock); - - if(bitsPerBlock != 13){ - 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 entry = TechHider.readVarInt(data, i); - i += TechHider.readVarIntLength(data, i); - - if(hiddenBlockIds.contains(entry)){ - entry = obfuscateWith; - } - buffer.writeBytes(TechHider.writeVarInt(entry)); - } - }else{ - buffer.writeByte(data[++i]); //Empty palette - Bukkit.getLogger().log(Level.SEVERE, "Full chunk occured"); - } - - int dataArrayLength = TechHider.readVarInt(data, i); - int dataArrayLengthLength = TechHider.readVarIntLength(data, i); - buffer.writeBytes(data, i, dataArrayLength*8 + dataArrayLengthLength); - i += dataArrayLengthLength; - i += dataArrayLength * 8; - - buffer.writeBytes(data, i, 4096); - i += 4096; //Skylight (Not in Nether/End!!!) 2048 + Blocklight 2048 - } - - data = new byte[buffer.readableBytes()]; - buffer.readBytes(data); - return data; - } -} diff --git a/FightSystem_Core/src/config.yml b/FightSystem_Core/src/config.yml index 711d1d2..350f6df 100644 --- a/FightSystem_Core/src/config.yml +++ b/FightSystem_Core/src/config.yml @@ -20,7 +20,7 @@ Ranks: [] # Disables ranks for this schematic type if missing Times: # Time in seconds the server stops after starting if nobody joins - NoPlayersOnlineDuration: 30 # defaults to 30 if missing + NoPlayersOnlineDuration: 300 # defaults to 300 if missing # Time in seconds the team leaders have to choose their schematic PreSchemPasteDuration: 120 # defaults to 120 if missing # Time in seconds for preparing @@ -72,6 +72,8 @@ Schematic: ReplaceObsidianBedrock: false # defaults to false if missing # If the replacement should happen with block updates ReplaceWithBlockupdates: false # defaults to false if missing + # If the schematic perparation arena mode is time limited + UnlimitedPrepare: false # defaults to false if missing # Maximal amount of blocks allowed in the schematic MaxBlocks: 0 # defaults to 0 (ignored) if missing # Maximal amount of items per dispenser diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/ArenaMode.java b/FightSystem_Core/src/de/steamwar/fightsystem/ArenaMode.java index e291fd7..ad4e2a3 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/ArenaMode.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/ArenaMode.java @@ -43,10 +43,11 @@ public enum ArenaMode { public static final Set AntiReplay = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(REPLAY))); public static final Set AntiTest = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(TEST, CHECK))); public static final Set AntiEvent = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(EVENT))); + public static final Set AntiTestCheckPrepare = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(TEST, CHECK, PREPARE))); public static final Set AntiPrepare = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(PREPARE))); public static final Set VariableTeams = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(EVENT, REPLAY))); public static final Set RankedEvent = Collections.unmodifiableSet(EnumSet.of(EVENT, REPLAY)); - public static final Set Restartable = Collections.unmodifiableSet(EnumSet.of(NORMAL)); + public static final Set Restartable = Collections.unmodifiableSet(EnumSet.of(NORMAL, TEST)); public static final Set NotRestartable = Collections.unmodifiableSet(EnumSet.of(EVENT, REPLAY)); public static final Set SoloLeader = Collections.unmodifiableSet(EnumSet.of(TEST, CHECK, PREPARE)); public static final Set NotOnBau = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(TEST, CHECK, PREPARE, REPLAY))); diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/Config.java b/FightSystem_Core/src/de/steamwar/fightsystem/Config.java index 86026c6..2632f0b 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/Config.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/Config.java @@ -61,6 +61,7 @@ public class Config { public static final Region BlueExtendRegion; public static final Region RedExtendRegion; public static final Region ArenaRegion; + public static final Region PlayerRegion; public static final Location TeamBlueSpawn; public static final Location TeamRedSpawn; @@ -87,6 +88,7 @@ public class Config { public static final boolean PasteAligned; public static final boolean ReplaceObsidianBedrock; public static final boolean ReplaceWithBlockupdates; + public static final boolean UnlimitedPrepare; //team parameter public static final String TeamRedName; @@ -155,7 +157,7 @@ public class Config { } FileConfiguration worldconfig = YamlConfiguration.loadConfiguration(worldConfigFile); - NoPlayerOnlineDuration = config.getInt("Times.NoPlayersOnlineDuration", 30); + NoPlayerOnlineDuration = config.getInt("Times.NoPlayersOnlineDuration", 300); PreSchemPasteDuration = config.getInt("Times.PreSchemPasteDuration", 120); SetupDuration = config.getInt("Times.SetupDuration", 300); PreFightDuration = config.getInt("Times.PreFightDuration", 30); @@ -184,6 +186,7 @@ public class Config { PasteAligned = config.getBoolean("Schematic.PasteAligned", false); ReplaceObsidianBedrock = config.getBoolean("Schematic.ReplaceObsidianBedrock", false); ReplaceWithBlockupdates = config.getBoolean("Schematic.ReplaceWithBlockupdates", false); + UnlimitedPrepare = config.getBoolean("Schematic.UnlimitedPrepare", false); GameName = config.getString("GameName", "WarGear"); TeamChatDetection = config.getString("TeamChatPrefix", "+"); @@ -204,7 +207,7 @@ public class Config { ForbiddenItems = Collections.unmodifiableSet(config.getStringList("Kits.ForbiddenItems").stream().map(Material::valueOf).collect(Collectors.toSet())); TechhiderActive = config.getBoolean("Techhider.Active", false); - ObfuscateWith = config.getString("Techhider.ObfuscateWith", "end_stone"); + ObfuscateWith = config.getString("Techhider.ObfuscateWith", "end_stone").toUpperCase(); HiddenBlocks = Collections.unmodifiableSet(new HashSet<>(config.getStringList("Techhider.HiddenBlocks"))); HiddenBlockEntities = Collections.unmodifiableSet(new HashSet<>(config.getStringList("Techhider.HiddenBlockEntities"))); @@ -300,14 +303,13 @@ public class Config { RedRotate = teamRedRotate; BlueRotate = teamBlueRotate; - int arenaYSize = blueCornerY - underBorder + schemsizeY + PreperationArea; - RedPasteRegion = new Region(teamRedCornerX, teamRedCornerY, teamRedCornerZ, schemsizeX, schemsizeY, schemsizeZ); BluePasteRegion = new Region(blueCornerX, blueCornerY, blueCornerZ, schemsizeX, schemsizeY, schemsizeZ); - RedExtendRegion = new Region(teamRedCornerX, underBorder, teamRedCornerZ, schemsizeX, arenaYSize, schemsizeZ, PreperationArea, PreperationArea); - BlueExtendRegion = new Region(blueCornerX, underBorder, blueCornerZ, schemsizeX, arenaYSize, schemsizeZ, PreperationArea, PreperationArea); - ArenaRegion = new Region(arenaMinX, underBorder, arenaMinZ, arenaMaxX - arenaMinX, arenaYSize, arenaMaxZ - arenaMinZ); + RedExtendRegion = new Region(teamRedCornerX, teamRedCornerY, teamRedCornerZ, schemsizeX, schemsizeY, schemsizeZ, PreperationArea, PreperationArea, PreperationArea); + BlueExtendRegion = new Region(blueCornerX, blueCornerY, blueCornerZ, schemsizeX, schemsizeY, schemsizeZ, PreperationArea, PreperationArea, PreperationArea); + ArenaRegion = new Region(arenaMinX, blueCornerY, arenaMinZ, arenaMaxX - arenaMinX, schemsizeY, arenaMaxZ - arenaMinZ, 0, PreperationArea, 0); + PlayerRegion = new Region(arenaMinX, underBorder, arenaMinZ, arenaMaxX - arenaMinX, world.getMaxHeight() - underBorder, arenaMaxZ - arenaMinZ); EventKampfID = Integer.parseInt(System.getProperty("fightID", "0")); if(EventKampfID >= 1){ diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java index a3f6b49..2d5c04e 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java @@ -48,6 +48,7 @@ public class FightSystem extends JavaPlugin { private Message message; private FightTeam lastWinner; private String lastWinreason; + private TechHiderWrapper techHider; @Override public void onLoad() { @@ -66,7 +67,12 @@ public class FightSystem extends JavaPlugin { new EntityDamage(); new WaterRemover(); new Permanent(); - new PistonListener(); + new PistonListener(ArenaMode.AntiTestCheckPrepare, e -> e.setCancelled(true)); + new PistonListener(ArenaMode.Test, e -> getMessage().broadcastActionbar("PISTON_PUSHED_OUTSIDE")); + new PistonListener(ArenaMode.Prepare, e -> { + getMessage().broadcast("PISTON_PUSHED_OUTSIDE"); + shutdown(); + }); new Chat(); new ArenaBorder(); new TeamArea(); @@ -77,7 +83,6 @@ public class FightSystem extends JavaPlugin { new DenyInventoryMovement(); new EventJoin(); new Recording(); - //new ResourcePack(); new Check(); new Shutdown(); new SetupQuit(); @@ -90,12 +95,14 @@ public class FightSystem extends JavaPlugin { new ArrowPickup(); new BlockFadeListener(); new LeaveableArena(); + new ClickAnalyzer(); + new BlockPlaceCollision(); new HotbarKit.HotbarKitListener(); new JoinRequestListener(); new OneShotStateDependent(ArenaMode.All, FightState.PreSchemSetup, () -> Fight.playSound(SWSound.BLOCK_NOTE_PLING.getSound(), 100.0f, 2.0f)); new EnterHandler(); - new TechHider(); + techHider = new TechHiderWrapper(); new FightWorld(); new FightUI(); new FightStatistics(); @@ -118,6 +125,7 @@ public class FightSystem extends JavaPlugin { new HellsBells(); new Meteor(); + new WinconditionAmongUs(); new NoPlayersOnlineCountdown(); new PreSchemCountdown(); @@ -146,7 +154,6 @@ public class FightSystem extends JavaPlugin { new LiveRecorder(); new FileRecorder(); - REntity.initWatchers(); FileSource.startReplay(); if(Config.mode == ArenaMode.EVENT) { @@ -161,6 +168,7 @@ public class FightSystem extends JavaPlugin { @Override public void onDisable() { GlobalRecorder.getInstance().close(); + ClickAnalyzer.close(); } public static void setSpectateState(FightTeam winFightTeam, String winreason, String subtitle, Object... params) { @@ -192,6 +200,10 @@ public class FightSystem extends JavaPlugin { return plugin.lastWinreason; } + public static TechHiderWrapper getTechHider() { + return plugin.techHider; + } + public static void shutdown() { //Staggered kick to prevent lobby overloading if(Bukkit.getOnlinePlayers().isEmpty()){ diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties index 15cf595..98b92ac 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties +++ b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties @@ -145,7 +145,6 @@ NO_FRIENDLY_FIRE=§cNo friendly fire allowed NO_TNT_PLACE=§cYou are not allowed to place tnt NO_TELEPORT=§cYou are not allowed to use this teleport function OPEN_INVENTORY_TO_CUSTOMIZE=§eOpen inventory to customize your kit -RESOURCEPACK_REQUIRED=§cYou can only join on the event server with the SteamWar resourcepack\n§cPlease allow the use of server resourcepacks in the server list! NO_ENTERN=§cYou may not board NO_TEAMAREA=§cYou are not allowed in the team area TEST_BECOME_LEADER=§7Become a team leader with §8/§eleader @@ -157,6 +156,7 @@ PREPARE_SENT_IN=§aA team member will review the schematic soon PARTICIPANT_CHAT={0} {1}§8» §7{2} FIGHTLEADER_CHAT=§e{0}§8» §e{1} SPECTATOR_CHAT=§7{0}§8» §7{1} +PISTON_PUSHED_OUTSIDE=§cA piston pushed a block outside the allowed area! # Replay @@ -239,6 +239,11 @@ WIN_LESS_DAMAGE={0} §7less damaged WIN_POINTS={0} has more points WIN_POINTS_EQUAL=§7Equal points WIN_TECHKO={0} §7is tech K.O. +WIN_IMPOSTER_DEAD={0} §7killed the imposter +WIN_CREWMATE_DEAD={0} §7killed all team mates + +AMONG_US_IMPOSTER_MESSAGE = §4You are the Imposter§8! §7Kill all your team mates to win the game! +AMONG_US_IMPOSTER_AMONG_MESSAGE = §4There is an Imposter among us§8! §7Kill him to win the game! # Invites diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties index 69ddf0e..fb8b946 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties +++ b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties @@ -142,7 +142,6 @@ NO_FRIENDLY_FIRE=§cDu darfst deinen Teamkollegen keinen Schaden zufügen NO_TNT_PLACE=§cDu darfst kein TNT setzen NO_TELEPORT=§cDu darfst diese Teleportfunktion nicht benutzen OPEN_INVENTORY_TO_CUSTOMIZE=§eInventar zum Anpassen des Kits öffnen -RESOURCEPACK_REQUIRED=§cAuf Eventserver kann nur mit dem SteamWar-Resourcepack beigetreten werden\n§cDa du abgelehnt hast, musst du nun in der Serverliste erst einmal wieder Ressourcenpakete von SteamWar aktivieren NO_ENTERN=§cDu darfst nicht entern NO_TEAMAREA=§cDu darfst nicht zu den Teams TEST_BECOME_LEADER=§7Werde zum Teamleader mit §8/§eleader @@ -151,6 +150,7 @@ PREPARE_SCHEM_EXISTS=§cEs existiert bereits eine Schem mit Namenszusatz -prepar PREPARE_ACTIVE_PISTON=§cIm Teambereich wurden sich noch bewegende Pistons gefunden, Einsenden wird abgebrochen. PREPARE_FAILED_SAVING=§cDie Schematic konnte nicht gespeichert werden, Einsenden wird abgebrochen. PREPARE_SENT_IN=§aDie Schematic wird nun zeitnah von einem Teammitglied überprüft +PISTON_PUSHED_OUTSIDE=§cEin Kolben hat einen Block aus dem erlaubten Bereich geschoben! # Replay @@ -224,7 +224,11 @@ WIN_LESS_DAMAGE={0} §7weniger beschädigt WIN_POINTS={0} hat mehr Punkte WIN_POINTS_EQUAL=§7Gleicher Punktestand WIN_TECHKO={0} §7ist Tech K.O. +WIN_IMPOSTER_DEAD={0} §7 hat den Imposter getötet +WIN_CREWMATE_DEAD={0} §7 hat alle Kameraden getötet +AMONG_US_IMPOSTER_MESSAGE = §4Du bist ein Imposter§8! §7Du musst alle Kameraden töten, um zu gewinnen. +AMONG_US_IMPOSTER_AMONG_MESSAGE = §4Es ist ein Imposter unter uns§8! §7Tötet ihn, um das Spiel zu gewinnen! # Invites JOIN_REQUEST=§7Teambeitritt anfragen diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/countdown/EnternCountdown.java b/FightSystem_Core/src/de/steamwar/fightsystem/countdown/EnternCountdown.java index fa13c7c..c5c19b5 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/countdown/EnternCountdown.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/countdown/EnternCountdown.java @@ -24,7 +24,7 @@ import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.fight.FightPlayer; import de.steamwar.fightsystem.utils.Message; import de.steamwar.fightsystem.utils.SWSound; -import de.steamwar.fightsystem.utils.TechHider; +import de.steamwar.techhider.ProtocolUtils; import de.steamwar.fightsystem.winconditions.Wincondition; import net.md_5.bungee.api.ChatMessageType; @@ -47,7 +47,7 @@ public class EnternCountdown extends Countdown { } private final FightPlayer fightPlayer; - private List chunkPos; + private List chunkPos; public EnternCountdown(FightPlayer fp) { super(calcTime(fp), new Message("ENTERN_COUNTDOWN"), SWSound.BLOCK_NOTE_PLING, false); @@ -58,12 +58,12 @@ public class EnternCountdown extends Countdown { @Override public void countdownFinished() { FightSystem.getMessage().sendPrefixless("ENTERN_ALLOWED", fightPlayer.getPlayer(), ChatMessageType.ACTION_BAR); - TechHider.reloadChunks(fightPlayer.getPlayer(), chunkPos, false); + FightSystem.getTechHider().reloadChunks(fightPlayer.getPlayer(), chunkPos, false); } @Override protected void prepareFinish() { - chunkPos = TechHider.prepareChunkReload(fightPlayer.getPlayer(), false); + chunkPos = FightSystem.getTechHider().prepareChunkReload(fightPlayer.getPlayer(), false); } @Override diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/countdown/NoPlayersOnlineCountdown.java b/FightSystem_Core/src/de/steamwar/fightsystem/countdown/NoPlayersOnlineCountdown.java index 11cb3c9..94e54e2 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/countdown/NoPlayersOnlineCountdown.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/countdown/NoPlayersOnlineCountdown.java @@ -23,31 +23,16 @@ import de.steamwar.fightsystem.ArenaMode; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.StateDependentCountdown; -import de.steamwar.fightsystem.states.StateDependentListener; import de.steamwar.fightsystem.utils.Message; import org.bukkit.Bukkit; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; -public class NoPlayersOnlineCountdown extends Countdown implements Listener { +public class NoPlayersOnlineCountdown extends Countdown { public NoPlayersOnlineCountdown() { super(Config.NoPlayerOnlineDuration, new Message("SHUTDOWN_COUNTDOWN"), null, false); - new StateDependentListener(ArenaMode.AntiReplay, FightState.PreLeaderSetup, this); - new StateDependentCountdown(ArenaMode.AntiReplay, FightState.PreLeaderSetup, this) { - @Override - public void enable() { - if(Bukkit.getOnlinePlayers().isEmpty()) - super.enable(); - } - }; - } - - @EventHandler - public void handlePlayerJoin(PlayerJoinEvent event) { - disable(); + if (!Config.ArenaLeaveable) + new StateDependentCountdown(ArenaMode.AntiReplay, FightState.PreLeaderSetup, this); } @Override diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/countdown/PostSchemCountdown.java b/FightSystem_Core/src/de/steamwar/fightsystem/countdown/PostSchemCountdown.java index 877dfe0..cb5f2db 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/countdown/PostSchemCountdown.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/countdown/PostSchemCountdown.java @@ -29,6 +29,9 @@ public class PostSchemCountdown extends Countdown { public PostSchemCountdown() { super(Config.SetupDuration, new Message("POST_SCHEM_COUNTDOWN"), null, false); + if(Config.mode == ArenaMode.PREPARE && Config.UnlimitedPrepare) + return; + new StateDependentCountdown(ArenaMode.SeriousFight, FightState.PostSchemSetup, this); } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/countdown/SpectateOverCountdown.java b/FightSystem_Core/src/de/steamwar/fightsystem/countdown/SpectateOverCountdown.java index 7e1b6eb..9f3cb10 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/countdown/SpectateOverCountdown.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/countdown/SpectateOverCountdown.java @@ -29,7 +29,7 @@ import de.steamwar.fightsystem.utils.SWSound; public class SpectateOverCountdown extends Countdown { public SpectateOverCountdown() { - super(Config.SpectatorDuration, new Message("SPECTATE_COUNTDOWN"), SWSound.BLOCK_NOTE_PLING, false); + super(Config.test() ? 3600 : Config.SpectatorDuration, new Message("SPECTATE_COUNTDOWN"), SWSound.BLOCK_NOTE_PLING, false); new StateDependentCountdown(ArenaMode.Restartable.contains(Config.mode) || Config.replayserver(), FightState.Spectate, this); } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java b/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java index e4d0bf2..6f465e8 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java @@ -19,21 +19,20 @@ package de.steamwar.fightsystem.fight; -import com.comphenix.tinyprotocol.Reflection; import com.comphenix.tinyprotocol.TinyProtocol; import com.mojang.authlib.GameProfile; -import de.steamwar.core.Core; +import de.steamwar.core.ProtocolWrapper; 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.ProtocolWrapper; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Sound; import org.bukkit.entity.Player; -import java.util.*; +import java.util.Collection; +import java.util.HashSet; public class Fight { private Fight(){} @@ -135,28 +134,8 @@ public class Fight { } } - 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); - 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"); - 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 = Reflection.newInstance(playerInfoPacket); - playerInfoAction.set(packet, action); - playerInfoData.set(packet, Collections.singletonList(ProtocolWrapper.impl.playerInfoDataConstructor(packet, profile, mode))); - return packet; + TinyProtocol.instance.sendPacket(player, ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.GAMEMODE, new GameProfile(player.getUniqueId(), player.getName()), enable ? GameMode.CREATIVE : GameMode.SPECTATOR)); } public static int getMaxRank(){ diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightSchematic.java b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightSchematic.java index 0d3398c..51c75cf 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightSchematic.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightSchematic.java @@ -31,10 +31,13 @@ import de.steamwar.fightsystem.states.StateDependent; import de.steamwar.fightsystem.utils.ColorConverter; import de.steamwar.fightsystem.utils.Region; import de.steamwar.fightsystem.utils.WorldeditWrapper; +import de.steamwar.sql.SchematicData; import de.steamwar.sql.SchematicNode; -import org.bukkit.*; +import org.bukkit.Bukkit; +import org.bukkit.DyeColor; +import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.block.Block; -import org.bukkit.event.HandlerList; import org.bukkit.util.Vector; import java.io.IOException; @@ -70,7 +73,7 @@ public class FightSchematic extends StateDependent { public void setSchematic(SchematicNode schem) { schematic = schem.getId(); try { - clipboard = schem.load(); + clipboard = new SchematicData(schem).load(); if(schem.replaceColor()) replaceTeamColor(clipboard); @@ -153,7 +156,7 @@ public class FightSchematic extends StateDependent { replaceSync(Material.BEDROCK, Material.SLIME_BLOCK); if(!Config.ReplaceWithBlockupdates) - HandlerList.unregisterAll(freezer); + freezer.disable(); } public void pasteTeamName(){ diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java index cb5b4b2..b396a3e 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java @@ -26,15 +26,18 @@ import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.commands.GUI; import de.steamwar.fightsystem.countdown.Countdown; import de.steamwar.fightsystem.listener.FightScoreboard; +import de.steamwar.fightsystem.listener.Permanent; import de.steamwar.fightsystem.listener.PersonalKitCreator; import de.steamwar.fightsystem.record.GlobalRecorder; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.OneShotStateDependent; import de.steamwar.fightsystem.states.StateDependent; import de.steamwar.fightsystem.utils.*; +import de.steamwar.fightsystem.winconditions.Winconditions; import de.steamwar.inventory.SWItem; import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SteamwarUser; +import de.steamwar.techhider.ProtocolUtils; import net.md_5.bungee.api.ChatMessageType; import org.bukkit.*; import org.bukkit.enchantments.Enchantment; @@ -69,7 +72,7 @@ public class FightTeam { } if(Config.test()) - notReadyKit.setItem(1, "CHOOSE_SCHEMATIC", new ItemBuilder(SWItem.getMaterial("CAULDRON_ITEM")).removeAllAttributes().addEnchantment(Enchantment.DURABILITY, 1).build(), GUI::preSchemDialog); + notReadyKit.setItem(5, "CHOOSE_SCHEMATIC", new ItemBuilder(SWItem.getMaterial("CAULDRON_ITEM")).removeAllAttributes().addEnchantment(Enchantment.DURABILITY, 1).build(), GUI::preSchemDialog); notReadyKit.setItem(4, "TEAM_NOT_READY", new ItemBuilder(SWItem.getDye(10), (short) 10).removeAllAttributes().addEnchantment(Enchantment.DURABILITY, 1).build(), player -> Objects.requireNonNull(Fight.getPlayerTeam(player)).setReady(true)); } @@ -118,19 +121,17 @@ public class FightTeam { new KitLoader(); new SpectateHandler(); - if(FightScoreboard.getBukkit().getTeam(name) == null) - team = FightScoreboard.getBukkit().registerNewTeam(name); - else - team = FightScoreboard.getBukkit().getTeam(name); - assert team != null; + team = FightScoreboard.getBukkitTeam(name); WorldOfColorWrapper.impl.setTeamColor(team, color); BountifulWrapper.impl.setNametagVisibility(team); team.setNameTagVisibility(NameTagVisibility.HIDE_FOR_OTHER_TEAMS); - team.setAllowFriendlyFire(false); + if (!Config.ActiveWinconditions.contains(Winconditions.AMONG_US)) { + team.setAllowFriendlyFire(false); + } new OneShotStateDependent(ArenaMode.Restartable, FightState.PreLeaderSetup, () -> Bukkit.getScheduler().runTask(FightSystem.getPlugin(), this::reset)); new OneShotStateDependent(Config.replayserver(), FightState.PreLeaderSetup, () -> Bukkit.getScheduler().runTask(FightSystem.getPlugin(), this::reset)); - new OneShotStateDependent(ArenaMode.AntiTest, FightState.PostSchemSetup, () -> { + new OneShotStateDependent(ArenaMode.All, FightState.PostSchemSetup, () -> { if(leader != null) notReadyKit.loadToPlayer(leader.getPlayer()); }); @@ -216,7 +217,9 @@ public class FightTeam { playerSet.forEach(p -> addMember(p, true)); if(ArenaMode.VariableTeams.contains(Config.mode) && isLeaderless()){ - for(Player player : Bukkit.getOnlinePlayers()){ + List onlinePlayers = new ArrayList<>(Bukkit.getOnlinePlayers()); + Collections.shuffle(onlinePlayers); + for(Player player : onlinePlayers) { if(Fight.getPlayerTeam(player) == null && canbeLeader(player)){ addMember(player); break; @@ -242,10 +245,11 @@ public class FightTeam { } private void addMember(Player player, boolean silent) { - final List chunksToReload = TechHider.prepareChunkReload(player, false); + final List chunksToReload = FightSystem.getTechHider().prepareChunkReload(player, false); FightPlayer fightPlayer = getFightPlayer(player) != null ? getFightPlayer(player) : new FightPlayer(player, this); fightPlayer.revive(); players.put(player, fightPlayer); + Permanent.getSpectatorTeam().removeEntry(player.getName()); team.addEntry(player.getName()); player.setHealth(20); @@ -264,7 +268,7 @@ public class FightTeam { fightPlayer.startEnternCountdown(); GlobalRecorder.getInstance().playerJoins(player); - TechHider.reloadChunks(player, chunksToReload, false); + FightSystem.getTechHider().reloadChunks(player, chunksToReload, false); if(isLeaderless()) setLeader(fightPlayer, silent); @@ -276,9 +280,10 @@ public class FightTeam { FightPlayer fightPlayer = getFightPlayer(player); PersonalKitCreator.closeIfInKitCreator(player); - List chunksToReload = TechHider.prepareChunkReload(player, true); + List chunksToReload = FightSystem.getTechHider().prepareChunkReload(player, true); players.remove(player); team.removeEntry(player.getName()); + Permanent.getSpectatorTeam().addEntry(player.getName()); FightUI.addSubtitle("UI_PLAYER_LEAVES", prefix, player.getName()); @@ -291,7 +296,7 @@ public class FightTeam { player.getInventory().clear(); if(player.isOnline()){ - TechHider.reloadChunks(player, chunksToReload, true); + FightSystem.getTechHider().reloadChunks(player, chunksToReload, true); HotbarKit.spectatorKit.loadToPlayer(player); } } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FreezeWorld.java b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FreezeWorld.java index b94fc72..7b58543 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FreezeWorld.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FreezeWorld.java @@ -27,6 +27,7 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.block.*; +import org.bukkit.event.entity.ItemSpawnEvent; import org.bukkit.event.inventory.InventoryMoveItemEvent; import org.bukkit.event.player.PlayerInteractEvent; @@ -83,6 +84,10 @@ public class FreezeWorld implements Listener { public void onBlockExplosion(BlockExplodeEvent e){ e.setCancelled(true); } + @EventHandler + public void onBlockExplosion(ItemSpawnEvent e){ + e.setCancelled(true); + } @EventHandler(priority = EventPriority.LOW) public void handlePlayerInteract(PlayerInteractEvent event) { diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java b/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java index 9ea2135..044fea5 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java @@ -27,6 +27,7 @@ import de.steamwar.fightsystem.commands.GUI; import de.steamwar.fightsystem.listener.PersonalKitCreator; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.StateDependentListener; +import de.steamwar.fightsystem.states.StateDependentTask; import de.steamwar.fightsystem.utils.ItemBuilder; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -40,7 +41,9 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.potion.PotionEffect; import java.util.Collection; +import java.util.HashSet; import java.util.Objects; +import java.util.Set; import java.util.function.Consumer; public class HotbarKit extends Kit { @@ -90,8 +93,11 @@ public class HotbarKit extends Kit { public static class HotbarKitListener implements Listener { + private static final Set clicked = new HashSet<>(); + public HotbarKitListener() { new StateDependentListener(ArenaMode.AntiReplay, FightState.All, this); + new StateDependentTask(ArenaMode.AntiReplay, FightState.All, clicked::clear, 10, 10); } @EventHandler @@ -106,6 +112,9 @@ public class HotbarKit extends Kit { return; event.setCancelled(true); + if(!clicked.add(player)) + return; + ((HotbarKit)activeKit).onClicks[slot].accept(player); } } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/fight/Kit.java b/FightSystem_Core/src/de/steamwar/fightsystem/fight/Kit.java index 50fcd69..0ba4628 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/fight/Kit.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/fight/Kit.java @@ -19,12 +19,12 @@ package de.steamwar.fightsystem.fight; +import com.comphenix.tinyprotocol.Reflection; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.commands.Commands; import de.steamwar.fightsystem.commands.GUI; import de.steamwar.fightsystem.listener.PersonalKitCreator; -import de.steamwar.fightsystem.utils.CraftbukkitWrapper; import de.steamwar.fightsystem.utils.FlatteningWrapper; import de.steamwar.inventory.SWInventory; import de.steamwar.inventory.SWItem; @@ -52,6 +52,10 @@ public class Kit { protected static final Map activeKits = new HashMap<>(); + public static Kit getActiveKit(Player player) { + return activeKits.get(player); + } + static { if(!kits.exists()) { Bukkit.getLogger().log(Level.SEVERE, "Kitconfig fehlend!" + kits.getAbsolutePath()); @@ -156,6 +160,18 @@ public class Kit { return inventory; } + public boolean contains(ItemStack stack) { + for(ItemStack i : inventory) { + if(similar(i, stack)) + return true; + } + for(ItemStack i : armor) { + if(similar(i, stack)) + return true; + } + return false; + } + public ItemStack[] getArmor() { return armor; } @@ -207,7 +223,7 @@ public class Kit { if(FlatteningWrapper.impl.containsBlockMeta(meta)) return true; //Blocks always upwards slabs etc. - if(CraftbukkitWrapper.impl.hasItems(stack)) + if(hasItems(stack)) return true; //Blocks prefilled inventories } @@ -216,6 +232,18 @@ public class Kit { return !normal.isEnchantmentInKit(stack) && !stack.getEnchantments().isEmpty(); } + private static final Class itemStack = Reflection.getClass("{nms.world.item}.ItemStack"); + private static final Reflection.MethodInvoker asNMSCopy = Reflection.getTypedMethod(Reflection.getClass("{obc}.inventory.CraftItemStack"), "asNMSCopy", itemStack, ItemStack.class); + private static final Class nbtTagCompound = Reflection.getClass("{nms.nbt}.NBTTagCompound"); + private static final Reflection.MethodInvoker getTag = Reflection.getTypedMethod(itemStack, null, nbtTagCompound); + private static final Reflection.MethodInvoker getKeys = Reflection.getTypedMethod(nbtTagCompound, null, Set.class); + public static boolean hasItems(ItemStack stack) { + Set keys = new HashSet<>((Set) getKeys.invoke(getTag.invoke(asNMSCopy.invoke(null, stack)))); + keys.remove("Enchantments"); + keys.remove("Damage"); + return !keys.isEmpty(); + } + private boolean isEnchantmentInKit(ItemStack stack){ for(ItemStack is : inventory){ if(similar(stack, is)) diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/ArenaBorder.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/ArenaBorder.java index 600a798..9eab82d 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/listener/ArenaBorder.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/listener/ArenaBorder.java @@ -26,7 +26,9 @@ import de.steamwar.fightsystem.fight.Fight; import de.steamwar.fightsystem.fight.FightTeam; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.StateDependentListener; +import de.steamwar.fightsystem.states.StateDependentTask; import net.md_5.bungee.api.ChatMessageType; +import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.entity.Player; @@ -38,40 +40,39 @@ public class ArenaBorder implements Listener { public ArenaBorder() { new StateDependentListener(ArenaMode.All, FightState.All, this); + new StateDependentTask(ArenaMode.All, FightState.Running, this::damage, 2, 2); } @EventHandler public void arenaBorder(PlayerMoveEvent event){ Player player = event.getPlayer(); - if(Config.ArenaLeaveable && !Fight.fighting(player)) + FightTeam team = Fight.getPlayerTeam(player); + + if(Config.ArenaLeaveable && team == null) return; Location to = event.getTo(); assert to != null; - if(!Config.ArenaRegion.in2dRegion(to)){ - reset(event); + if(Config.PlayerRegion.inRegion(to)) return; - } - FightTeam team = Fight.getPlayerTeam(player); - if(team == null || player.getGameMode() == GameMode.SPECTATOR){ - if(to.getY() <= Config.ArenaRegion.getMinY()) - reset(event); - return; - } - - if(to.getY() <= Config.ArenaRegion.getMinY()) { - if(FightState.infight()) - player.damage(2); - else if(!Config.GroundWalkable) + if(to.getY() <= Config.PlayerRegion.getMinY() && player.getGameMode() != GameMode.SPECTATOR && team != null) { + if(!Config.GroundWalkable && !FightState.infight()) player.teleport(team.getSpawn()); - } - } - private void reset(PlayerMoveEvent event){ - Player player = event.getPlayer(); + return; + } + player.teleport(event.getFrom()); FightSystem.getMessage().sendPrefixless("NO_ARENA_LEAVING", player, ChatMessageType.ACTION_BAR); } + + private void damage() { + for(Player player : Bukkit.getServer().getOnlinePlayers()) { + FightTeam team = Fight.getPlayerTeam(player); + if(team != null && player.getLocation().getY() <= Config.PlayerRegion.getMinY()) + player.damage(1); + } + } } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/BlockPlaceCollision.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/BlockPlaceCollision.java new file mode 100644 index 0000000..7b3bf54 --- /dev/null +++ b/FightSystem_Core/src/de/steamwar/fightsystem/listener/BlockPlaceCollision.java @@ -0,0 +1,61 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 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.listener; + +import de.steamwar.fightsystem.ArenaMode; +import de.steamwar.fightsystem.states.FightState; +import de.steamwar.fightsystem.states.StateDependentListener; +import de.steamwar.fightsystem.utils.FlatteningWrapper; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockPlaceEvent; + +public class BlockPlaceCollision implements Listener { + + public BlockPlaceCollision() { + new StateDependentListener(ArenaMode.All, FightState.All, this); + } + + @EventHandler + public void onBlockPlace(BlockPlaceEvent event) { + Block block = event.getBlock(); + if(!block.getType().isSolid()) + return; + + // Hitbox size: 0.6xz, 1.8y, 1.5y when sneaking + Player player = event.getPlayer(); + Location min = player.getLocation().add(-0.3, 0, -0.3); + Location max = player.getLocation().add(0.3, FlatteningWrapper.impl.isCrouching(player) ? 0.6 : (player.isSneaking() ? 1.5 : 1.8), 0.3); + + Location blockmin = block.getLocation(); + Location blockmax = block.getLocation().add(1.0, 1.0, 1.0); + if( + max.getX() <= blockmin.getX() || min.getX() >= blockmax.getX() || + max.getY() <= blockmin.getY() || min.getY() >= blockmax.getY() || + max.getZ() <= blockmin.getZ() || min.getZ() >= blockmax.getZ() + ) + return; + + event.setCancelled(true); + } +} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/ClickAnalyzer.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/ClickAnalyzer.java index dbc5b07..73e2afa 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/listener/ClickAnalyzer.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/listener/ClickAnalyzer.java @@ -19,6 +19,9 @@ package de.steamwar.fightsystem.listener; +import com.comphenix.tinyprotocol.Reflection; +import com.comphenix.tinyprotocol.TinyProtocol; +import de.steamwar.core.Core; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.utils.CraftbukkitWrapper; import org.bukkit.entity.Player; @@ -26,7 +29,6 @@ import org.bukkit.entity.Player; import java.io.*; public class ClickAnalyzer { - private ClickAnalyzer() {} private static final PrintStream output; @@ -38,7 +40,20 @@ public class ClickAnalyzer { } } - public static void onBlockPlace(Player player) { - output.println(player.getName() + "," + System.nanoTime() + "," + CraftbukkitWrapper.impl.headRotation(player) + "," + player.getLocation().getPitch()); + public ClickAnalyzer() { + TinyProtocol.instance.addFilter(Recording.blockPlacePacket, this::onBlockPlace); + if(Core.getVersion() > 8) + TinyProtocol.instance.addFilter(Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUseItem"), this::onBlockPlace); + } + + public Object onBlockPlace(Player player, Object packet) { + synchronized(output) { + output.println(player.getName() + "," + System.nanoTime() + "," + CraftbukkitWrapper.impl.headRotation(player) + "," + player.getLocation().getPitch()); + } + return packet; + } + + public static void close() { + output.close(); } } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/DenyWorldInteraction.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/DenyWorldInteraction.java index 2850476..f494d0b 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/listener/DenyWorldInteraction.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/listener/DenyWorldInteraction.java @@ -30,10 +30,12 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockIgniteEvent; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.ProjectileLaunchEvent; import org.bukkit.event.hanging.HangingBreakEvent; +import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerKickEvent; public class DenyWorldInteraction implements Listener { @@ -52,6 +54,14 @@ public class DenyWorldInteraction implements Listener { } } + @EventHandler + public void handleItemDrop(PlayerDropItemEvent event) { + Player player = event.getPlayer(); + if(Fight.fighting(player)) { + event.setCancelled(true); + } + } + @EventHandler public void handleHangingBreak(HangingBreakEvent event) { if(Config.ArenaRegion.inRegion(event.getEntity().getLocation())) { @@ -74,6 +84,12 @@ public class DenyWorldInteraction implements Listener { event.setCancelled(true); } + @EventHandler + public void handleBlockBurn(BlockIgniteEvent event) { + if(!Config.ArenaLeaveable || Config.ArenaRegion.inRegion(event.getBlock())) + event.setCancelled(true); + } + @EventHandler public void handlePlayerKickEvent(PlayerKickEvent e){ if(e.getReason().contains("Flying is not enabled")) diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/FightScoreboard.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/FightScoreboard.java index 957f085..63ca402 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/listener/FightScoreboard.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/listener/FightScoreboard.java @@ -30,14 +30,20 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; import java.util.HashMap; import java.util.Objects; public class FightScoreboard implements Listener, ScoreboardCallback { - public static Scoreboard getBukkit() { - return Objects.requireNonNull(Bukkit.getScoreboardManager()).getMainScoreboard(); + public static Team getBukkitTeam(String name) { + Scoreboard scoreboard = Objects.requireNonNull(Bukkit.getScoreboardManager()).getMainScoreboard(); + Team team = scoreboard.getTeam(name); + if(team != null) + return team; + + return scoreboard.registerNewTeam(name); } private static FightScoreboard scoreboard; diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/InFightDamage.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/InFightDamage.java index 09ec33a..9be2167 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/listener/InFightDamage.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/listener/InFightDamage.java @@ -20,10 +20,12 @@ package de.steamwar.fightsystem.listener; import de.steamwar.fightsystem.ArenaMode; +import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.fight.Fight; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.StateDependentListener; +import de.steamwar.fightsystem.winconditions.Winconditions; import net.md_5.bungee.api.ChatMessageType; import org.bukkit.entity.Arrow; import org.bukkit.entity.Player; @@ -36,7 +38,7 @@ import java.util.Objects; public class InFightDamage implements Listener { public InFightDamage() { - new StateDependentListener(ArenaMode.AntiReplay, FightState.Running, this); + new StateDependentListener(!Config.ActiveWinconditions.contains(Winconditions.AMONG_US), FightState.Running, this); } @EventHandler diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/InFightInventory.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/InFightInventory.java index 85eb983..ad41d0a 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/listener/InFightInventory.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/listener/InFightInventory.java @@ -20,7 +20,6 @@ package de.steamwar.fightsystem.listener; import de.steamwar.fightsystem.ArenaMode; -import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.fight.Fight; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.StateDependentListener; @@ -28,7 +27,6 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockDispenseEvent; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryDragEvent; import org.bukkit.event.inventory.InventoryType; @@ -74,10 +72,4 @@ public class InFightInventory implements Listener { } } } - - @EventHandler - public void onBlockDispense(BlockDispenseEvent e) { - if(Config.ArenaRegion.inRegion(e.getBlock()) && e.getItem().getType() == Material.TNT) - e.setCancelled(true); - } } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java index 0d7d7e4..4ae1875 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java @@ -23,30 +23,47 @@ import de.steamwar.fightsystem.ArenaMode; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.fight.Fight; +import de.steamwar.fightsystem.fight.FightPlayer; import de.steamwar.fightsystem.fight.FightTeam; -import de.steamwar.fightsystem.record.REntity; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.StateDependentListener; +import de.steamwar.fightsystem.utils.BountifulWrapper; +import de.steamwar.fightsystem.utils.FlatteningWrapper; import net.md_5.bungee.api.ChatMessageType; import org.bukkit.GameMode; import org.bukkit.Material; +import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockDispenseEvent; import org.bukkit.event.block.BlockFromToEvent; import org.bukkit.event.entity.FoodLevelChangeEvent; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.SpawnerSpawnEvent; import org.bukkit.event.inventory.CraftItemEvent; import org.bukkit.event.inventory.FurnaceSmeltEvent; -import org.bukkit.event.inventory.InventoryPickupItemEvent; import org.bukkit.event.player.*; import org.bukkit.event.weather.WeatherChangeEvent; import org.bukkit.event.world.WorldLoadEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scoreboard.NameTagVisibility; +import org.bukkit.scoreboard.Team; public class Permanent implements Listener { + private static final Team spectatorTeam = FightScoreboard.getBukkitTeam("Spectator"); + static { + BountifulWrapper.impl.setNametagVisibility(spectatorTeam); + spectatorTeam.setNameTagVisibility(NameTagVisibility.NEVER); + } + + public static Team getSpectatorTeam() { + return spectatorTeam; + } + public Permanent() { new StateDependentListener(ArenaMode.All, FightState.All, this); } @@ -79,10 +96,9 @@ public class Permanent implements Listener { if (!Config.ArenaLeaveable && !Fight.fighting(player)) { Fight.setPlayerGamemode(player, GameMode.SPECTATOR); + spectatorTeam.addEntry(player.getName()); player.teleport(Config.SpecSpawn); } - - REntity.playerJoins(player); } @EventHandler(priority = EventPriority.MONITOR) @@ -121,7 +137,7 @@ public class Permanent implements Listener { } @EventHandler - public void onCrafting(CraftItemEvent e){ + public void onCrafting(CraftItemEvent e) { if(Fight.fighting((Player) e.getWhoClicked())) e.setCancelled(true); } @@ -132,16 +148,34 @@ public class Permanent implements Listener { e.setCancelled(true); } - @EventHandler - public void onDropPickup(InventoryPickupItemEvent e){ - if(Config.ArenaRegion.inRegion(e.getItem().getLocation())) - e.setCancelled(true); + @SuppressWarnings("deprecation") + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent e) { + Block block = e.getBlock(); + for(ItemStack stack : block.getDrops(e.getPlayer().getItemInHand())) + Config.world.dropItemNaturally(block.getLocation(), stack); } @EventHandler - public void onDropping(PlayerDropItemEvent e){ - if(Fight.fighting(e.getPlayer())) - e.setCancelled(true); + public void onDropPickup(PlayerPickupItemEvent e) { + if(!(Config.ArenaRegion.inRegion(e.getItem().getLocation()))) + return; + Player player = e.getPlayer(); + + ItemStack stack = e.getItem().getItemStack(); + if(Config.PersonalKits) { + if(Config.ForbiddenItems.contains(stack.getType())) { + e.setCancelled(true); + } + } else { + FightPlayer fp = Fight.getFightPlayer(player); + if(fp == null) + return; + + if(!fp.getKit().contains(stack)) { + e.setCancelled(true); + } + } } @EventHandler @@ -164,4 +198,15 @@ public class Permanent implements Listener { event.setCancelled(true); } + + @EventHandler + public void onBlockDispense(BlockDispenseEvent e) { + Block block = e.getBlock(); + + if(!Config.ArenaRegion.inRegion(block)) + return; + + if(e.getItem().getType() == Material.TNT || FlatteningWrapper.impl.isFacingWater(block)) + e.setCancelled(true); + } } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/PersonalKitCreator.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/PersonalKitCreator.java index ef57d60..f9a3b2d 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/listener/PersonalKitCreator.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/listener/PersonalKitCreator.java @@ -37,6 +37,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.inventory.InventoryAction; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.ItemStack; @@ -108,6 +109,15 @@ public class PersonalKitCreator implements Listener { backup.close(); } + @EventHandler + public void onOpenEvent(InventoryOpenEvent e){ + InventoryBackup backup = openKitCreators.get(e.getPlayer()); + if(backup == null) + return; + + backup.close(); + } + @EventHandler public void onInventoryClose(InventoryCloseEvent e) { InventoryBackup backup = openKitCreators.get(e.getPlayer()); @@ -134,7 +144,7 @@ public class PersonalKitCreator implements Listener { private InventoryBackup(Player player, PersonalKit kit){ openKitCreators.put(player, this); this.player = player; - this.backup = new Kit("backup", player); + this.backup = Kit.getActiveKit(player); this.kit = kit; } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/PistonListener.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/PistonListener.java index 7aba189..26c2fb8 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/listener/PistonListener.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/listener/PistonListener.java @@ -28,17 +28,25 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.PistonMoveReaction; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockPistonEvent; import org.bukkit.event.block.BlockPistonExtendEvent; import org.bukkit.event.block.BlockPistonRetractEvent; +import java.util.Set; +import java.util.function.Consumer; + public class PistonListener implements Listener { - public PistonListener() { + private final Consumer leftAreaHandler; + + public PistonListener(Set condition, Consumer leftAreaHandler) { + this.leftAreaHandler = leftAreaHandler; + if(!condition.contains(Config.mode)) + return; + //Wenn Entern aktiv ist, sollen Raketen etc. entern können - if(!ArenaMode.Check.contains(Config.mode)) { - new StateDependentListener(!Config.AllowMissiles, FightState.All, this); - new StateDependentListener(Config.AllowMissiles, FightState.Setup, this); - } + new StateDependentListener(!Config.AllowMissiles, FightState.All, this); + new StateDependentListener(Config.AllowMissiles, FightState.Setup, this); } @EventHandler @@ -50,7 +58,7 @@ public class PistonListener implements Listener { for(Block block : e.getBlocks()){ Block target = block.getRelative(face); if(!Config.BlueExtendRegion.inRegion(target) && !Config.RedExtendRegion.inRegion(target) && block.getPistonMoveReaction() != PistonMoveReaction.BREAK) { - e.setCancelled(true); + leftAreaHandler.accept(e); return; } } @@ -63,7 +71,7 @@ public class PistonListener implements Listener { for(Block block : e.getBlocks()){ if(!Config.BlueExtendRegion.inRegion(block) && !Config.RedExtendRegion.inRegion(block)) { - e.setCancelled(true); + leftAreaHandler.accept(e); return; } } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/Recording.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/Recording.java index 7cec941..ca3c654 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/listener/Recording.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/listener/Recording.java @@ -20,6 +20,7 @@ package de.steamwar.fightsystem.listener; import com.comphenix.tinyprotocol.Reflection; +import com.comphenix.tinyprotocol.TinyProtocol; import de.steamwar.fightsystem.ArenaMode; import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.fight.Fight; @@ -48,6 +49,7 @@ import org.bukkit.event.player.*; import org.bukkit.inventory.ItemStack; import java.util.Random; +import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Predicate; @@ -89,16 +91,19 @@ public class Recording implements Listener { } }.register(); new StateDependent(ArenaMode.AntiReplay, FightState.Ingame) { + private final BiFunction place = Recording.this::blockPlace; + private final BiFunction dig = Recording.this::blockDig; + @Override public void enable() { - ProtocolAPI.setIncomingHandler(blockPlacePacket, Recording.this::blockPlace); - ProtocolAPI.setIncomingHandler(blockDigPacket, Recording.this::blockDig); + TinyProtocol.instance.addFilter(blockPlacePacket, place); + TinyProtocol.instance.addFilter(blockDigPacket, dig); } @Override public void disable() { - ProtocolAPI.removeIncomingHandler(blockPlacePacket); - ProtocolAPI.removeIncomingHandler(blockDigPacket); + TinyProtocol.instance.removeFilter(blockPlacePacket, place); + TinyProtocol.instance.removeFilter(blockDigPacket, dig); } }.register(); new StateDependentTask(ArenaMode.AntiReplay, FightState.All, () -> { @@ -128,8 +133,6 @@ public class Recording implements Listener { public static final Class blockPlacePacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInBlockPlace"); private Object blockPlace(Player p, Object packet) { - ClickAnalyzer.onBlockPlace(p); - boolean mainHand = BountifulWrapper.impl.mainHand(packet); if(!isNotSent(p) && BountifulWrapper.impl.bowInHand(mainHand, p)) GlobalRecorder.getInstance().bowSpan(p, true, !mainHand); diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/ResourcePack.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/ResourcePack.java deleted file mode 100644 index 80bb614..0000000 --- a/FightSystem_Core/src/de/steamwar/fightsystem/listener/ResourcePack.java +++ /dev/null @@ -1,35 +0,0 @@ -package de.steamwar.fightsystem.listener; - -import de.steamwar.fightsystem.ArenaMode; -import de.steamwar.fightsystem.FightSystem; -import de.steamwar.fightsystem.states.FightState; -import de.steamwar.fightsystem.states.StateDependentListener; -import de.steamwar.fightsystem.utils.CraftbukkitWrapper; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerResourcePackStatusEvent; - -public class ResourcePack implements Listener { - - public ResourcePack(){ - new StateDependentListener(ArenaMode.Event, FightState.All, this); - } - - @EventHandler - public void handlePlayerJoin(PlayerJoinEvent event) { - Player player = event.getPlayer(); - CraftbukkitWrapper.impl.sendResourcePack(player, "https://steamwar.de/antixray.zip", "3e94f5abeb07cc95067b27705615ec14666abe7b"); - } - - @EventHandler - public void onResourcepack(PlayerResourcePackStatusEvent e){ - if(e.getStatus() == PlayerResourcePackStatusEvent.Status.ACCEPTED || e.getStatus() == PlayerResourcePackStatusEvent.Status.SUCCESSFULLY_LOADED) - return; - - Player player = e.getPlayer(); - FightSystem.getMessage().sendPrefixless("RESOURCEPACK_REQUIRED", player); - player.kickPlayer(null); - } -} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/RunningWorldInteraction.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/RunningWorldInteraction.java index a2a9067..7c00a9f 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/listener/RunningWorldInteraction.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/listener/RunningWorldInteraction.java @@ -25,15 +25,11 @@ import de.steamwar.fightsystem.fight.Fight; import de.steamwar.fightsystem.fight.FightPlayer; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.StateDependentListener; -import de.steamwar.fightsystem.utils.FlatteningWrapper; import net.md_5.bungee.api.ChatMessageType; import org.bukkit.Material; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; public class RunningWorldInteraction implements Listener { @@ -41,35 +37,6 @@ public class RunningWorldInteraction implements Listener { new StateDependentListener(ArenaMode.AntiReplay, FightState.Running, this); } - @EventHandler - public void onBlockBreak(BlockBreakEvent event) { - if(!Fight.fighting(event.getPlayer())) - return; - - Inventory inventory = event.getPlayer().getInventory(); - - ItemStack stack = FlatteningWrapper.impl.onBreak(event.getBlock()); - - for (int i = 0; i <= 35; i++) { //35 is the last normal inventory slot - ItemStack itemStack = inventory.getItem(i); - if (itemStack != null && itemStack.isSimilar(stack) && itemStack.getAmount() != itemStack.getMaxStackSize()) { - itemStack.setAmount(itemStack.getAmount() + 1); - inventory.setItem(i, itemStack); - event.getPlayer().updateInventory(); - return; - } - } - - for (int i = 0; i <= 35; i++) { //35 is the last normal inventory slot - ItemStack itemStack = inventory.getItem(i); - if (itemStack == null || itemStack.getType().equals(Material.AIR)) { - inventory.setItem(i, stack); - event.getPlayer().updateInventory(); - return; - } - } - } - @EventHandler public void onBlockPlace(BlockPlaceEvent e) { FightPlayer fp = Fight.getFightPlayer(e.getPlayer()); diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/TeamArea.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/TeamArea.java index 44aef93..e091c92 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/listener/TeamArea.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/listener/TeamArea.java @@ -80,7 +80,7 @@ public class TeamArea implements Listener { @EventHandler public void blockBreak(BlockBreakEvent event) { Block block = event.getBlock(); - if(Config.BluePasteRegion.getMinY() <= block.getY()) + if(Config.BlueExtendRegion.getMinY() <= block.getY()) return; event.setCancelled(true); diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/record/FileSource.java b/FightSystem_Core/src/de/steamwar/fightsystem/record/FileSource.java index 6d75d2b..2fcaa59 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/record/FileSource.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/record/FileSource.java @@ -20,10 +20,11 @@ package de.steamwar.fightsystem.record; import de.steamwar.fightsystem.Config; +import de.steamwar.sql.Replay; -import java.io.*; -import java.nio.file.Files; -import java.nio.file.StandardCopyOption; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; import java.util.zip.GZIPInputStream; public class FileSource extends PacketSource { @@ -39,19 +40,8 @@ public class FileSource extends PacketSource { } if(Config.ReplayID > 0) { - de.steamwar.sql.Fight.getReplay(Config.ReplayID, input -> { - try { - Files.copy( - input, - FileRecorder.getFile().toPath(), - StandardCopyOption.REPLACE_EXISTING); - } catch (IOException e) { - throw new SecurityException("Could not start replay", e); - } - }); - try { - new FileSource(FileRecorder.getFile()); + new FileSource(Replay.get(Config.ReplayID).getReplay()); } catch (IOException e) { throw new SecurityException("Could not start replay", e); } @@ -60,6 +50,7 @@ public class FileSource extends PacketSource { public FileSource(File fightFile) throws IOException { super(new GZIPInputStream(new FileInputStream(fightFile))); + new PacketProcessor(this); } @Override diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/record/LiveSource.java b/FightSystem_Core/src/de/steamwar/fightsystem/record/LiveSource.java index 3a1fad5..313ff85 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/record/LiveSource.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/record/LiveSource.java @@ -31,6 +31,7 @@ public class LiveSource extends PacketSource { protected LiveSource(Socket socket) throws IOException { super(socket.getInputStream()); this.socket = socket; + new PacketProcessor(this); } @Override diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java b/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java index f94c3ed..d7c31fd 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java @@ -21,6 +21,9 @@ package de.steamwar.fightsystem.record; import com.sk89q.worldedit.extent.clipboard.Clipboard; import de.steamwar.core.Core; +import de.steamwar.entity.REntity; +import de.steamwar.entity.REntityServer; +import de.steamwar.entity.RPlayer; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.countdown.Countdown; @@ -31,23 +34,44 @@ import de.steamwar.fightsystem.fight.FreezeWorld; import de.steamwar.fightsystem.listener.FightScoreboard; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.utils.*; +import de.steamwar.sql.SchematicData; import de.steamwar.sql.SchematicNode; +import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.Team; +import de.steamwar.techhider.BlockIds; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.TextComponent; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.Sound; +import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.ItemStack; import org.bukkit.scheduler.BukkitTask; +import org.bukkit.scoreboard.NameTagVisibility; import java.io.EOFException; +import java.io.FilterInputStream; import java.io.IOException; import java.util.*; import java.util.logging.Level; +import java.util.stream.Collectors; -public class PacketProcessor { +public class PacketProcessor implements Listener { + + private static final org.bukkit.scoreboard.Team team = FightScoreboard.getBukkitTeam("Replay"); + static { + BountifulWrapper.impl.setNametagVisibility(team); + team.setNameTagVisibility(NameTagVisibility.NEVER); + } private static PacketProcessor currentProcessor = null; @@ -64,9 +88,11 @@ public class PacketProcessor { private final PacketSource source; private final BukkitTask task; private final LinkedList syncList = new LinkedList<>(); - private final Set hiddenBlockIds = BlockIdWrapper.impl.getHiddenBlockIds(); - private final int obfuscateWith = BlockIdWrapper.impl.getObfuscateWith(); + private final Set hiddenBlockIds = Config.HiddenBlocks.stream().map(String::toUpperCase).map(Material::getMaterial).flatMap(m -> BlockIds.impl.materialToAllIds(m).stream()).collect(Collectors.toSet()); + private final int obfuscateWith = BlockIds.impl.materialToId(Material.getMaterial(Config.ObfuscateWith.toUpperCase())); private final FreezeWorld freezer = new FreezeWorld(); + private final REntityServer entityServer = new REntityServer(); + private final Map entities = new HashMap<>(); private boolean rotateZ = false; private int arenaMinX = Config.ArenaRegion.getMinX(); @@ -78,7 +104,7 @@ public class PacketProcessor { private boolean tickFinished = false; private final List lastPackets = new LinkedList<>(); - public PacketProcessor(PacketSource source){ + public PacketProcessor(PacketSource source) { this.source = source; currentProcessor = this; @@ -95,13 +121,15 @@ public class PacketProcessor { packetDecoder[0x0a] = this::bow; packetDecoder[0x0b] = this::damage; packetDecoder[0x0c] = this::fireTick; - packetDecoder[0x20] = this::arenaInfo; - packetDecoder[0x30] = this::block; + packetDecoder[0x20] = this::oldArenaInfo; + packetDecoder[0x21] = this::arenaInfo; + packetDecoder[0x30] = this::byteWorldHeightBlock; packetDecoder[0x31] = this::particle; packetDecoder[0x32] = this::sound; packetDecoder[0x33] = this::shortBlock; packetDecoder[0x34] = this::soundAtPlayer; packetDecoder[0x35] = this::shortRelativeBlock; + packetDecoder[0x36] = this::block; packetDecoder[0xa0] = () -> send(ChatMessageType.CHAT); packetDecoder[0xa1] = () -> send(ChatMessageType.ACTION_BAR); packetDecoder[0xa2] = () -> send(ChatMessageType.SYSTEM); @@ -131,6 +159,15 @@ public class PacketProcessor { task = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), this::runSync, 1, 1); }else task = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), this::process, 1, 1); + + Bukkit.getPluginManager().registerEvents(this, FightSystem.getPlugin()); + for(Player player : Bukkit.getOnlinePlayers()) + entityServer.addPlayer(player); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerJoin(PlayerJoinEvent e) { + entityServer.addPlayer(e.getPlayer()); } public void skipToSubtitle() { @@ -196,7 +233,11 @@ public class PacketProcessor { int entityId = source.readInt(); int userId = source.readInt(); - execSync(() -> new REntity(entityId, userId)); + execSync(() -> { + SteamwarUser user = SteamwarUser.get(userId); + entities.put(entityId, new RPlayer(entityServer, user.getUUID(), user.getUserName(), Config.SpecSpawn)); + team.addEntry(user.getUserName()); + }); } private void entityMoves() throws IOException { @@ -214,14 +255,18 @@ public class PacketProcessor { float yaw = source.readFloat() + (rotateZ ? 180 : 0); byte headYaw = (byte)((source.readByte() + (rotateZ ? 128 : 0)) % 256); - execSync(() -> REntity.getEntity(entityId).move(locX, locY, locZ, pitch, yaw, headYaw)); + execSync(() -> { + REntity entity = entities.get(entityId); + if(entity != null) + entity.move(locX, locY, locZ, pitch, yaw, headYaw); + }); } private void entityDespawns() throws IOException { int entityId = source.readInt(); execSync(() -> { - REntity entity = REntity.getEntity(entityId); + REntity entity = entities.remove(entityId); if(entity != null) entity.die(); }); @@ -231,20 +276,20 @@ public class PacketProcessor { int entityId = source.readInt(); boolean sneaking = source.readBoolean(); - execSync(() -> REntity.getEntity(entityId).sneak(sneaking)); + execSync(() -> entities.get(entityId).setPose(sneaking ? de.steamwar.core.FlatteningWrapper.EntityPose.SNEAKING : de.steamwar.core.FlatteningWrapper.EntityPose.NORMAL)); } private void entityAnimation() throws IOException { int entityId = source.readInt(); byte animation = source.readByte(); - execSync(() -> REntity.getEntity(entityId).animation(animation)); + execSync(() -> entities.get(entityId).showAnimation(animation)); } private void tntSpawn() throws IOException { int entityId = source.readInt(); - execSync(() -> new REntity(entityId, EntityType.PRIMED_TNT)); + execSync(() -> entities.put(entityId, new REntity(entityServer, EntityType.PRIMED_TNT, Config.SpecSpawn))); } private void entityVelocity() throws IOException { @@ -255,7 +300,7 @@ public class PacketProcessor { double dZ = rotateZ ? -source.readDouble() : source.readDouble(); execSync(() -> { - REntity entity = REntity.getEntity(entityId); + REntity entity = entities.get(entityId); if(entity != null) entity.setVelocity(dX, dY, dZ); }); @@ -265,21 +310,47 @@ public class PacketProcessor { int entityId = source.readInt(); String item = source.readUTF(); boolean enchanted = source.readBoolean(); - String slot = source.readUTF(); + String slotName = source.readUTF(); - execSync(() -> REntity.getEntity(entityId).setItem(item, enchanted, slot)); + ItemStack stack = new ItemStack(Material.valueOf(item.replace("minecraft:", "").toUpperCase()), 1); + if(enchanted) + stack.addUnsafeEnchantment(Enchantment.DURABILITY, 1); + + Object slot; + switch(slotName){ + case "HEAD": + slot = de.steamwar.core.ProtocolWrapper.itemSlots[5]; + break; + case "CHEST": + slot = de.steamwar.core.ProtocolWrapper.itemSlots[4]; + break; + case "LEGS": + slot = de.steamwar.core.ProtocolWrapper.itemSlots[3]; + break; + case "FEET": + slot = de.steamwar.core.ProtocolWrapper.itemSlots[2]; + break; + case "OFFHAND": + slot = de.steamwar.core.ProtocolWrapper.itemSlots[1]; + break; + case "MAINHAND": + default: + slot = de.steamwar.core.ProtocolWrapper.itemSlots[0]; + } + + execSync(() -> entities.get(entityId).setItem(slot, stack)); } private void arrowSpawn() throws IOException { int entityId = source.readInt(); - execSync(() -> new REntity(entityId, EntityType.ARROW)); + execSync(() -> entities.put(entityId, new REntity(entityServer, EntityType.ARROW, Config.SpecSpawn))); } private void fireballSpawn() throws IOException { int entityId = source.readInt(); - execSync(() -> new REntity(entityId, EntityType.FIREBALL)); + execSync(() -> entities.put(entityId, new REntity(entityServer, EntityType.FIREBALL, Config.SpecSpawn))); } private void send(ChatMessageType type) throws IOException { @@ -297,13 +368,20 @@ public class PacketProcessor { Bukkit.getOnlinePlayers().forEach(p -> Countdown.sendCountdownMessage(p, message, displaytime, appendix)); } - private void arenaInfo() throws IOException { + private void oldArenaInfo() throws IOException { rotateZ = source.readBoolean() != Config.blueNegZ(); arenaMinY = Byte.toUnsignedInt(source.readByte()); arenaMinX = source.readInt(); arenaMinZ = source.readInt(); } + private void arenaInfo() throws IOException { + rotateZ = source.readBoolean() != Config.blueNegZ(); + arenaMinX = source.readInt(); + arenaMinY = source.readInt(); + arenaMinZ = source.readInt(); + } + private void shortBlock() throws IOException { int x = Byte.toUnsignedInt(source.readByte()) + Config.ArenaRegion.getMinX(); int y = Byte.toUnsignedInt(source.readByte()); @@ -327,7 +405,7 @@ public class PacketProcessor { setBlock(x + Config.ArenaRegion.getMinX(), y + Config.BluePasteRegion.getMinY(), z + Config.ArenaRegion.getMinZ(), blockState); } - private void block() throws IOException { + private void byteWorldHeightBlock() throws IOException { int x = source.readInt() - arenaMinX; int y = Byte.toUnsignedInt(source.readByte()) - arenaMinY; int z = source.readInt() - arenaMinZ; @@ -341,11 +419,25 @@ public class PacketProcessor { setBlock(x + Config.ArenaRegion.getMinX(), y + Config.BluePasteRegion.getMinY(), z + Config.ArenaRegion.getMinZ(), blockState); } + private void block() throws IOException { + int x = source.readInt() - arenaMinX; + int y = source.readShort() - arenaMinY; + int z = source.readInt() - arenaMinZ; + int blockState = source.readInt(); + + if(rotateZ) { + x = Config.ArenaRegion.getSizeX() - x; + z = Config.ArenaRegion.getSizeZ() - z; + } + + setBlock(x + Config.ArenaRegion.getMinX(), y + Config.BluePasteRegion.getMinY(), z + Config.ArenaRegion.getMinZ(), blockState); + } + private void setBlock(int x, int y, int z, int blockState){ if(!Config.ArenaRegion.in2dRegion(x, z)) return; //Outside of the arena - execSync(() -> BlockIdWrapper.impl.setBlock(Config.world, x, y, z, TechHider.ENABLED && hiddenBlockIds.contains(blockState) ? obfuscateWith : blockState)); + execSync(() -> BlockIdWrapper.impl.setBlock(Config.world, x, y, z, TechHiderWrapper.ENABLED && hiddenBlockIds.contains(blockState) ? obfuscateWith : blockState)); } private void particle() throws IOException { @@ -401,13 +493,20 @@ public class PacketProcessor { private void pasteSchem(FightTeam team) throws IOException { int schemId = source.readInt(); + if(schemId == 0) + return; execSync(() -> team.pasteSchem(SchematicNode.getSchematicNode(schemId))); } private void pasteEmbeddedSchem(FightTeam team) throws IOException { int schemId = source.readInt(); - Clipboard clipboard = SchematicNode.clipboardFromStream(source, Core.getVersion() > 12); + Clipboard clipboard = SchematicData.clipboardFromStream(new FilterInputStream(source) { + @Override + public void close() { + // FAWE 1.12 calls close... + } + }, Core.getVersion() > 12); execSync(() -> team.pasteSchem(schemId, clipboard)); } @@ -477,7 +576,10 @@ public class PacketProcessor { } private void endReplay() { - REntity.dieAll(); + HandlerList.unregisterAll(this); + entityServer.close(); + entities.clear(); + freezer.disable(); if(!Config.replayserver()) { FightSystem.getMessage().broadcast("REPLAY_ENDS"); @@ -493,6 +595,7 @@ public class PacketProcessor { } FightState.setFightState(FightState.SPECTATE); currentProcessor = null; + task.cancel(); } private void bow() throws IOException { @@ -500,24 +603,25 @@ public class PacketProcessor { boolean drawn = source.readBoolean(); boolean offHand = source.readBoolean(); - execSync(() -> REntity.getEntity(entityId).setBowDrawn(drawn, offHand)); + execSync(() -> entities.get(entityId).setBowDrawn(drawn, offHand)); } private void damage() throws IOException { int entityId = source.readInt(); - execSync(() -> REntity.getEntity(entityId).damage()); + execSync(() -> entities.get(entityId).showDamage()); } private void fireTick() throws IOException { int entityId = source.readInt(); boolean perma = source.readBoolean(); - execSync(() -> REntity.getEntity(entityId).setOnFire(perma)); + execSync(() -> entities.get(entityId).setOnFire(perma)); } private void tick(){ - execSync(REntity::tickFire); + execSync(entityServer::tick); + if(!source.async() && !skipToSubtitle) tickFinished = true; } @@ -527,6 +631,11 @@ public class PacketProcessor { try{ while(!source.isClosed() && !tickFinished){ int packetType = Byte.toUnsignedInt(source.readByte()); + + lastPackets.add(packetType); + if (lastPackets.size() > 10) + lastPackets.remove(0); + PacketParser parser = packetDecoder[packetType]; if(parser != null){ parser.process(); @@ -534,9 +643,6 @@ public class PacketProcessor { Bukkit.getLogger().log(Level.SEVERE, "Unknown packet " + packetType + " recieved, closing. LastPacket: " + Arrays.toString(lastPackets.toArray())); source.close(); } - lastPackets.add(packetType); - if (lastPackets.size() > 10) - lastPackets.remove(0); } } catch (EOFException e) { Bukkit.getLogger().log(Level.INFO, "The FightServer is offline"); @@ -547,10 +653,7 @@ public class PacketProcessor { } if(source.isClosed()){ - execSync(() -> { - Bukkit.getScheduler().runTask(FightSystem.getPlugin(), this::endReplay); - task.cancel(); - }); + execSync(() -> Bukkit.getScheduler().runTask(FightSystem.getPlugin(), this::endReplay)); } } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketSource.java b/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketSource.java index 855959f..e3d994c 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketSource.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketSource.java @@ -30,7 +30,6 @@ public abstract class PacketSource extends DataInputStream { protected PacketSource(InputStream inputStream){ super(inputStream); - new PacketProcessor(this); } @Override diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/record/REntity.java b/FightSystem_Core/src/de/steamwar/fightsystem/record/REntity.java deleted file mode 100644 index 2be8a48..0000000 --- a/FightSystem_Core/src/de/steamwar/fightsystem/record/REntity.java +++ /dev/null @@ -1,348 +0,0 @@ -/* - This file is a part of the SteamWar software. - - Copyright (C) 2020 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.record; - -import com.comphenix.tinyprotocol.Reflection; -import com.comphenix.tinyprotocol.TinyProtocol; -import com.mojang.authlib.GameProfile; -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.*; -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; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.scoreboard.NameTagVisibility; -import org.bukkit.scoreboard.Team; - -import java.util.*; -import java.util.logging.Level; - -public class REntity { - - private static final Map entities = new HashMap<>(); - - public static REntity getEntity(int internalId){ - return entities.get(internalId); - } - - private static Object entityStatusWatcher; - private static Object sneakingDataWatcher; - private static Object bowDrawnWatcher; - public static void initWatchers() { - // not during to prevent cyclic class init. - entityStatusWatcher = BountifulWrapper.impl.getDataWatcherObject(0, Byte.class); - sneakingDataWatcher = BountifulWrapper.impl.getDataWatcherObject(Core.getVersion() > 12 ? 6 : 0, BlockIdWrapper.impl.getPose(true).getClass()); - bowDrawnWatcher = BountifulWrapper.impl.getDataWatcherObject(Core.getVersion() > 12 ? 7 : 6, Byte.class); - } - - - public static void tickFire() { - entities.forEach((integer, entity) -> { - if(entity.fireTick > 0) { - entity.fireTick--; - if(entity.fireTick == 0) { - ProtocolAPI.broadcastPacket(entity.getDataWatcherPacket(entityStatusWatcher, (byte)0)); - } - } - }); - } - - public static void playerJoins(Player player) { - for(REntity entity : entities.values()){ - if(entity.entityType == EntityType.PLAYER){ - TinyProtocol.instance.sendPacket(player, entity.getPlayerInfoPacket()); - TinyProtocol.instance.sendPacket(player, entity.getNamedSpawnPacket()); - for (Map.Entry entry : entity.itemSlots.entrySet()) { - TinyProtocol.instance.sendPacket(player, entity.getEquipmentPacket(entry.getKey(), entry.getValue())); - } - }else{ - TinyProtocol.instance.sendPacket(player, entity.getSpawnEntityPacket()); - } - TinyProtocol.instance.sendPacket(player, entity.getTeleportPacket()); - TinyProtocol.instance.sendPacket(player, entity.getHeadRotationPacket()); - - if(entity.fireTick != 0) { - TinyProtocol.instance.sendPacket(player, entity.getDataWatcherPacket(entityStatusWatcher, (byte) 1)); - } - if(entity.sneaks) { - TinyProtocol.instance.sendPacket(player, entity.getDataWatcherPacket(sneakingDataWatcher, BlockIdWrapper.impl.getPose(true))); - } - } - } - - public static void dieAll(){ - entities.forEach((id, entity) -> entity.broadcastDeath()); - entities.clear(); - } - - private static final String SCOREBOARD_TEAMNAME = "Replay"; - private static final Team team; - - static { - if(FightScoreboard.getBukkit().getTeam(SCOREBOARD_TEAMNAME) == null) - team = FightScoreboard.getBukkit().registerNewTeam(SCOREBOARD_TEAMNAME); - else - team = FightScoreboard.getBukkit().getTeam(SCOREBOARD_TEAMNAME); - team.setNameTagVisibility(NameTagVisibility.NEVER); - } - - private static int entityCount = Integer.MAX_VALUE; - private static final Random random = new Random(); - - private final int internalId; - private final int entityId; - private final UUID uuid; - private final EntityType entityType; - private final String name; - private final Map itemSlots = new HashMap<>(); - - private double locX; - private double locY; - private double locZ; - private byte yaw; - private byte pitch; - private byte headYaw; - private int fireTick; - private boolean sneaks; - - private boolean playerSpawned = false; - - public REntity(int internalId, int userId){ - this.internalId = internalId; - this.entityType = EntityType.PLAYER; - this.entityId = entityCount--; - - SteamwarUser user; - try { - user = SteamwarUser.get(userId); - } catch (SecurityException e) { - FightSystem.getPlugin().getLogger().log(Level.SEVERE, "Could not load user " + userId); - throw e; - } - - this.uuid = user.getUUID(); - this.name = user.getUserName(); - entities.put(internalId, this); - - ProtocolAPI.broadcastPacket(getPlayerInfoPacket()); - team.addEntry(name); - } - - public REntity(int internalId, EntityType entityType){ - this.internalId = internalId; - this.entityType = entityType; - this.entityId = entityCount--; - this.name = null; - this.uuid = new UUID(random.nextLong() & -61441L | 16384L, random.nextLong() & 4611686018427387903L | -9223372036854775808L); - entities.put(internalId, this); - - ProtocolAPI.broadcastPacket(getSpawnEntityPacket()); - } - - public void move(double locX, double locY, double locZ, float pitch, float yaw, byte headYaw){ - this.locX = locX; - this.locY = locY; - this.locZ = locZ; - if(entityType == EntityType.PLAYER && !playerSpawned) { - ProtocolAPI.broadcastPacket(getNamedSpawnPacket()); - playerSpawned = true; - } - - this.yaw = (byte)((int)(yaw * 256.0F / 360.0F)); - this.pitch = (byte)((int)(pitch * 256.0F / 360.0F)); - this.headYaw = headYaw; - ProtocolAPI.broadcastPacket(getTeleportPacket()); - ProtocolAPI.broadcastPacket(getHeadRotationPacket()); - } - - private static final Class animationPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutAnimation"); - private static final Reflection.FieldAccessor animationEntity = Reflection.getField(animationPacket, int.class, Core.getVersion() > 15 ? 6 : 0); - private static final Reflection.FieldAccessor animationAnimation = Reflection.getField(animationPacket, int.class, Core.getVersion() > 15 ? 7 : 1); - public void animation(byte animation) { - Object packet = Reflection.newInstance(animationPacket); - animationEntity.set(packet, entityId); - animationAnimation.set(packet, (int) animation); - ProtocolAPI.broadcastPacket(packet); - } - - 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 = Reflection.newInstance(velocityPacket); - velocityEntity.set(packet, entityId); - velocityX.set(packet, calcVelocity(dX)); - velocityY.set(packet, calcVelocity(dY)); - velocityZ.set(packet, calcVelocity(dZ)); - ProtocolAPI.broadcastPacket(packet); - } - - 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 = Reflection.newInstance(statusPacket); - statusEntity.set(packet, entityId); - statusStatus.set(packet, (byte) 2); - ProtocolAPI.broadcastPacket(packet); - } - - public void sneak(boolean sneaking) { - sneaks = sneaking; - ProtocolAPI.broadcastPacket(getDataWatcherPacket(sneakingDataWatcher, BlockIdWrapper.impl.getPose(sneaking))); - } - - public void setOnFire(boolean perma) { - if(!perma) { - fireTick = 21; - } else { - fireTick = -1; - } - - ProtocolAPI.broadcastPacket(getDataWatcherPacket(entityStatusWatcher, (byte) 1)); - } - - public void setBowDrawn(boolean drawn, boolean offHand) { - if(Core.getVersion() > 8){ - ProtocolAPI.broadcastPacket(getDataWatcherPacket(bowDrawnWatcher, (byte) ((drawn ? 1 : 0) + (offHand ? 2 : 0)))); - }else{ - ProtocolAPI.broadcastPacket(getDataWatcherPacket(entityStatusWatcher, (byte)0x10)); - } - } - - public void setItem(String item, boolean enchanted, String slot) { - ItemStack stack = new ItemStack(Material.valueOf(item.replace("minecraft:", "").toUpperCase()), 1); - if(enchanted) - stack.addUnsafeEnchantment(Enchantment.DURABILITY, 1); - itemSlots.put(slot, stack); - - ProtocolAPI.broadcastPacket(getEquipmentPacket(slot, stack)); - } - - public void die(){ - broadcastDeath(); - entities.remove(internalId); - } - - 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 = Reflection.newInstance(destroyPacket); - destroyEntities.set(packet, Core.getVersion() > 15 ? new IntArrayList(new int[]{entityId}) : new int[]{entityId}); - ProtocolAPI.broadcastPacket(packet); - } - - private int calcVelocity(double value) { - return (int)(Math.max(-3.9, Math.min(value, 3.9)) * 8000); - } - - 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 = Reflection.newInstance(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.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 = Reflection.newInstance(teleportPacket); - teleportEntity.set(packet, entityId); - BountifulWrapper.impl.setTeleportPacketPosition(packet, locX, locY, locZ); - teleportYaw.set(packet, yaw); - teleportPitch.set(packet, pitch); - return packet; - } - - 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 = Reflection.newInstance(headRotationPacket); - headRotationEntity.set(packet, entityId); - headRotationYaw.set(packet, headYaw); - return packet; - } - - 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 = Reflection.newInstance(spawnPacket); - spawnEntity.set(packet, entityId); - BountifulWrapper.impl.setSpawnPacketUUID(packet, uuid); - ProtocolWrapper.impl.setSpawnPacketType(packet, entityType); - return packet; - } - - public static final Class equipmentPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityEquipment"); - private static final Reflection.FieldAccessor equipmentEntity = Reflection.getField(equipmentPacket, int.class, 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(REntity.craftItemStack, "asNMSCopy", REntity.itemStack, ItemStack.class); - private Object getEquipmentPacket(String slot, ItemStack stack){ - Object packet = Reflection.newInstance(equipmentPacket); - equipmentEntity.set(packet, entityId); - ProtocolWrapper.impl.setEquipmentPacketStack(packet, slot, asNMSCopy.invoke(null, stack)); - return packet; - } - - private Object getPlayerInfoPacket(){ - return Fight.playerInfoPacket(Fight.addPlayer, new GameProfile(uuid, name), Fight.creative); - } - - 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 = Reflection.newInstance(namedSpawnPacket); - namedSpawnEntity.set(packet, entityId); - namedSpawnUUID.set(packet, uuid); - BountifulWrapper.impl.setNamedSpawnPosition(packet, locX, locY, locZ); - FlatteningWrapper.impl.setNamedSpawnPacketDataWatcher(packet); - return packet; - } -} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/record/Recorder.java b/FightSystem_Core/src/de/steamwar/fightsystem/record/Recorder.java index eb31336..2b5f3c7 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/record/Recorder.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/record/Recorder.java @@ -29,6 +29,7 @@ import de.steamwar.fightsystem.utils.BlockIdWrapper; import de.steamwar.fightsystem.utils.CraftbukkitWrapper; import de.steamwar.fightsystem.utils.Message; import de.steamwar.fightsystem.utils.SWSound; +import de.steamwar.sql.NodeData; import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SteamwarUser; import org.bukkit.Bukkit; @@ -97,14 +98,16 @@ public interface Recorder { * PlayerDamagePacket (0x0b) + int EntityId * SetOnFire (0x0c) + int EntityId + boolean perma * - * ArenaInfo (0x20) + bool blueNegZ + byte arenaY + int arenaMinX + int arenaMinZ + * DEPRECATED ArenaInfo (0x20) + bool blueNegZ + byte arenaY + int arenaMinX + int arenaMinZ + * ArenaInfo (0x21) + bool blueNegZ + int arenaMinX + int arenaMinY + int arenaMinZ * - * BlockPacket (0x30) + pos int, byte, int + int BlockState + * DEPRECATED BlockPacket (0x30) + pos int, byte, int + int BlockState * ParticlePacket (0x31) + double x, y, z + string particleType * SoundPacket (0x32) + int x, y, z + string soundType + string soundCategory + float volume, pitch * DEPRECATED ShortBlockPacket (0x33) + pos relative to ArenaMinX,ArenaMinZ byte, byte, byte + short BlockState * SoundAtPlayerPacket (0x34) + string (soundType, soundCategory) + float volume, pitch * ShortBlockPacket (0x35) + pos relative to ArenaMinX,BluePasteY,ArenaMinZ byte, byte, byte + short BlockState + * BlockPacket (0x36) + pos int, short, int + int BlockState * * * DEPRECATED ChatPacket (0xa0) + String message @@ -211,8 +214,7 @@ public interface Recorder { } default void arenaInfo(){ - write(0x20, Config.blueNegZ(), (byte)Config.BluePasteRegion.getMinY(), - Config.ArenaRegion.getMinX(), Config.ArenaRegion.getMinZ()); + write(0x21, Config.blueNegZ(), Config.ArenaRegion.getMinX(), Config.BluePasteRegion.getMinY(), Config.ArenaRegion.getMinZ()); } default void blockChange(Block block){ @@ -226,7 +228,7 @@ public interface Recorder { write(0x35, (byte)shortX, (byte)shortY, (byte)shortZ, (short)blockState); }else{ //Block packet - write(0x30, block.getX(), (byte)block.getY(), block.getZ(), blockState); + write(0x36, block.getX(), (short)block.getY(), block.getZ(), blockState); } } @@ -274,7 +276,7 @@ public interface Recorder { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); try{ - copy(SchematicNode.getSchematicNode(schemId).schemData(), buffer); + copy(NodeData.get(SchematicNode.getSchematicNode(schemId)).schemData(), buffer); }catch (EOFException e) { Bukkit.getLogger().log(Level.INFO, "EOFException ignored"); } catch (IOException e) { diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/BlockIdWrapper.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/BlockIdWrapper.java index f9e65e7..6cda218 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/BlockIdWrapper.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/BlockIdWrapper.java @@ -24,16 +24,9 @@ import de.steamwar.fightsystem.FightSystem; import org.bukkit.World; import org.bukkit.block.Block; -import java.util.Set; - public interface BlockIdWrapper { BlockIdWrapper impl = VersionDependent.getVersionImpl(FightSystem.getPlugin()); int blockToId(Block block); void setBlock(World world, int x, int y, int z, int blockState); - - Set getHiddenBlockIds(); - int getObfuscateWith(); - - Object getPose(boolean sneaking); } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/BountifulWrapper.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/BountifulWrapper.java index e40939e..3e96c85 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/BountifulWrapper.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/BountifulWrapper.java @@ -27,8 +27,6 @@ import org.bukkit.entity.Player; import org.bukkit.event.Listener; import org.bukkit.scoreboard.Team; -import java.util.UUID; - public interface BountifulWrapper { BountifulWrapper impl = VersionDependent.getVersionImpl(FightSystem.getPlugin()); @@ -47,11 +45,5 @@ public interface BountifulWrapper { void spawnParticle(World world, String particleName, double x, double y, double z); - Object getDataWatcherObject(int index, Class type); - Object getDataWatcherItem(Object dataWatcherObject, Object value); - void setTeleportPacketPosition(Object packet, double x, double y, double z); - void setSpawnPacketUUID(Object packet, UUID uuid); - void setNamedSpawnPosition(Object packet, double x, double y, double z); - void sendBar(Player player, FightTeam team, double progress, String text); } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper.java index 1771d79..242119f 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper.java @@ -23,8 +23,6 @@ import de.steamwar.core.VersionDependent; import de.steamwar.fightsystem.FightSystem; import org.bukkit.World; import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; import java.util.stream.Stream; @@ -32,9 +30,7 @@ public interface CraftbukkitWrapper { CraftbukkitWrapper impl = VersionDependent.getVersionImpl(FightSystem.getPlugin()); void resetChunk(World world, World backup, int x, int z); - void sendResourcePack(Player player, String pack, String sha1); float headRotation(Entity e); - boolean hasItems(ItemStack stack); Stream entityIterator(); } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/FightStatistics.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/FightStatistics.java index fa61303..7816d08 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/FightStatistics.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/FightStatistics.java @@ -32,18 +32,17 @@ import de.steamwar.fightsystem.states.OneShotStateDependent; import de.steamwar.fightsystem.winconditions.Wincondition; import de.steamwar.network.NetworkSender; import de.steamwar.network.packets.common.FightEndsPacket; +import de.steamwar.sql.Replay; import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SteamwarUser; import org.bukkit.Bukkit; -import java.io.FileInputStream; import java.sql.Timestamp; import java.time.Instant; import java.util.logging.Level; import java.util.stream.Collectors; import static de.steamwar.sql.Fight.create; -import static de.steamwar.sql.Fight.setReplay; public class FightStatistics { @@ -79,6 +78,7 @@ public class FightStatistics { FightTeam winner = FightSystem.getLastWinner(); String windescription = FightSystem.getLastWinreason(); String gameMode = Config.SchematicType.toDB(); + Instant endTime = Instant.now(); int blueLeader = getLeader(Fight.getBlueTeam()); int redLeader = getLeader(Fight.getRedTeam()); @@ -123,7 +123,7 @@ public class FightStatistics { } try { - setReplay(fightId, new FileInputStream(FileRecorder.getFile())); + Replay.save(fightId, FileRecorder.getFile()); } catch (Exception e) { Bukkit.getLogger().log(Level.INFO, "Failed to save replay", e); } @@ -132,7 +132,7 @@ public class FightStatistics { } if (!Bukkit.getOnlinePlayers().isEmpty() && !unranked) { - NetworkSender.send(new FightEndsPacket((byte) win, blueSchem == null ? 0 : blueSchem, redSchem == null ? 0 : redSchem, Fight.getBlueTeam().getPlayers().stream().map(FightPlayer::getPlayer).map(SteamwarUser::get).map(SteamwarUser::getId).collect(Collectors.toList()), Fight.getRedTeam().getPlayers().stream().map(FightPlayer::getPlayer).map(SteamwarUser::get).map(SteamwarUser::getId).collect(Collectors.toList()), gameMode)); + NetworkSender.send(new FightEndsPacket((byte) win, blueSchem == null ? 0 : blueSchem, redSchem == null ? 0 : redSchem, Fight.getBlueTeam().getPlayers().stream().map(FightPlayer::getPlayer).map(p -> SteamwarUser.get(p.getUniqueId())).map(SteamwarUser::getId).collect(Collectors.toList()), Fight.getRedTeam().getPlayers().stream().map(FightPlayer::getPlayer).map(p -> SteamwarUser.get(p.getUniqueId())).map(SteamwarUser::getId).collect(Collectors.toList()), gameMode, (int)(endTime.getEpochSecond() - starttime.toInstant().getEpochSecond()))); } unranked = false; diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/FlatteningWrapper.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/FlatteningWrapper.java index 57a9b27..4f76656 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/FlatteningWrapper.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/FlatteningWrapper.java @@ -24,6 +24,7 @@ import de.steamwar.fightsystem.FightSystem; import org.bukkit.DyeColor; import org.bukkit.World; import org.bukkit.block.Block; +import org.bukkit.entity.Player; import org.bukkit.event.block.BlockPhysicsEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; @@ -39,13 +40,13 @@ public interface FlatteningWrapper { boolean containsBlockMeta(ItemMeta meta); boolean hasAttributeModifier(ItemStack stack); - ItemStack onBreak(Block type); - boolean doRecord(BlockPhysicsEvent e); void forceLoadChunk(World world, int cX, int cZ); boolean checkPistonMoving(Block block); - void setNamedSpawnPacketDataWatcher(Object packet); + boolean isFacingWater(Block dispenser); + + boolean isCrouching(Player player); } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/ProtocolAPI.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/ProtocolAPI.java deleted file mode 100644 index a66f932..0000000 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/ProtocolAPI.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - 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.comphenix.tinyprotocol.TinyProtocol; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; - -import java.lang.reflect.Array; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.UnaryOperator; - -public class ProtocolAPI { - private ProtocolAPI() {} - - private static final Map, BiFunction> outgoingHandler = new HashMap<>(); - private static final Map, BiFunction> incomingHandler = new HashMap<>(); - - static { - TinyProtocol.instance.setOutFilter((receiver, channel, packet) -> { - BiFunction handler = outgoingHandler.get(packet.getClass()); - if(handler == null) - return packet; - return handler.apply(receiver, packet); - }); - TinyProtocol.instance.setInFilter((sender, channel, packet) -> { - BiFunction handler = incomingHandler.get(packet.getClass()); - if(handler == null) - return packet; - return handler.apply(sender, packet); - }); - } - - public static void setOutgoingHandler(Class packetClass, BiFunction handler) { - outgoingHandler.put(packetClass, handler); - } - - public static void removeOutgoingHandler(Class packetClass) { - outgoingHandler.remove(packetClass); - } - - public static void setIncomingHandler(Class packetClass, BiFunction handler) { - incomingHandler.put(packetClass, handler); - } - - public static void removeIncomingHandler(Class packetClass) { - incomingHandler.remove(packetClass); - } - - public static void broadcastPacket(Object packet) { - Bukkit.getOnlinePlayers().stream().map(TinyProtocol.instance::getChannel).filter(TinyProtocol.instance::hasInjected).forEach(channel -> TinyProtocol.instance.sendPacket(channel, packet)); - } - - public static BiFunction, Object> arrayCloneGenerator(Class elementClass) { - return (array, worker) -> { - int length = Array.getLength(array); - Object result = Array.newInstance(elementClass, length); - - for(int i = 0; i < length; i++) - Array.set(result, i, worker.apply(Array.get(array, i))); - - return result; - }; - } - - public static UnaryOperator shallowCloneGenerator(Class clazz) { - BiConsumer filler = shallowFill(clazz); - - return source -> { - Object clone = Reflection.newInstance(clazz); - filler.accept(source, clone); - return clone; - }; - } - - private static BiConsumer shallowFill(Class clazz) { - if(clazz == null) - return (source, clone) -> {}; - - BiConsumer superFiller = shallowFill(clazz.getSuperclass()); - - Field[] fds = clazz.getDeclaredFields(); - List fields = new ArrayList<>(); - for(Field field : fds) { - if (Modifier.isStatic(field.getModifiers())) - continue; - - field.setAccessible(true); - fields.add(field); - } - - return (source, clone) -> { - superFiller.accept(source, clone); - try { - for(Field field : fields) { - field.set(clone, field.get(source)); - } - } catch (IllegalAccessException e) { - throw new IllegalStateException("Could not set field", e); - } - - }; - } -} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/ProtocolWrapper.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/ProtocolWrapper.java deleted file mode 100644 index 1ca485a..0000000 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/ProtocolWrapper.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - 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/Region.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/Region.java index ac6d9a3..9e547c8 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/Region.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/Region.java @@ -33,9 +33,9 @@ public class Region { private final int maxY; private final int maxZ; - public Region(int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ, int extendX, int extendZ) { - this(minX - extendX, minY, minZ - extendZ, - sizeX + extendX * 2, sizeY, sizeZ + extendZ * 2); + public Region(int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ, int extendX, int extendY, int extendZ) { + this(minX - extendX, minY - extendY, minZ - extendZ, + sizeX + extendX * 2, sizeY + extendY * 2, sizeZ + extendZ * 2); } public Region(int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ) { diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHider.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHider.java deleted file mode 100644 index 0cdb6fa..0000000 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHider.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - This file is a part of the SteamWar software. - - Copyright (C) 2020 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.google.common.primitives.Bytes; -import de.steamwar.core.Core; -import de.steamwar.core.CraftbukkitWrapper; -import de.steamwar.core.VersionDependent; -import de.steamwar.fightsystem.Config; -import de.steamwar.fightsystem.FightSystem; -import de.steamwar.fightsystem.fight.Fight; -import de.steamwar.fightsystem.fight.FightTeam; -import de.steamwar.fightsystem.states.FightState; -import de.steamwar.fightsystem.states.StateDependent; -import org.bukkit.Bukkit; -import org.bukkit.GameMode; -import org.bukkit.Material; -import org.bukkit.entity.Player; - -import java.util.*; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.function.UnaryOperator; - -public class TechHider extends StateDependent { - - 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); - - 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); - - 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; - - public static final Object obfuscateIBlockData = getBlockDataByBlock.invoke(getBlockByMaterial.invoke(null, Material.getMaterial(Config.ObfuscateWith.toUpperCase()))); - private final Map, BiFunction> techhiders = new HashMap<>(); - - public interface ChunkHider { - Class mapChunkPacket(); - Object mapChunkHider(Player p, Object packet); - } - - public TechHider(){ - super(ENABLED, FightState.Schem); - - techhiders.put(blockActionPacket, this::blockActionHider); - techhiders.put(blockChangePacket, this::blockChangeHider); - techhiders.put(tileEntityDataPacket, this::tileEntityDataHider); - techhiders.put(multiBlockChangePacket, ProtocolWrapper.impl::multiBlockChangeHider); - - ChunkHider chunkHider = VersionDependent.getVersionImpl(FightSystem.getPlugin()); - techhiders.put(chunkHider.mapChunkPacket(), chunkHider::mapChunkHider); - - if(Core.getVersion() > 12 && Core.getVersion() < 19) { - 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.network.protocol.game}.PacketPlayInUseItem"), (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(); - } - - @Override - public void enable() { - techhiders.forEach(ProtocolAPI::setOutgoingHandler); - } - - @Override - public void disable() { - techhiders.keySet().forEach(ProtocolAPI::removeOutgoingHandler); - } - - 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 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); - private Object blockChangeHider(Player p, Object packet) { - Object pos = blockChangePosition.get(packet); - if(bypass(p, posToChunk(blockPositionX.get(pos)), posToChunk(blockPositionZ.get(pos)))) - return packet; - - 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.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); - if(bypass(p, posToChunk(blockPositionX.get(pos)), posToChunk(blockPositionZ.get(pos)))) - return packet; - return null; - } - - public static final Class tileEntityDataPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutTileEntityData"); - private static final Reflection.FieldAccessor tileEntityDataPosition = Reflection.getField(tileEntityDataPacket, blockPosition, 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(ProtocolWrapper.impl.unfilteredTileEntityDataAction(packet)) - return packet; - return null; - } - - public static List prepareChunkReload(Player p, boolean hide){ - if(!ENABLED) - return Collections.emptyList(); - List chunksToReload = new ArrayList<>(); - Config.ArenaRegion.forEachChunk((x, z) -> { - if(bypass(p, x, z) == hide) - chunksToReload.add(new ChunkPos(x, z)); - }); - return chunksToReload; - } - - public static void reloadChunks(Player p, List chunksToReload, boolean hide){ - if(!ENABLED || !FightState.Schem.contains(FightState.getFightState())) - return; - Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> { - for(ChunkPos chunk : chunksToReload){ - if(bypass(p, chunk.x(), chunk.z()) != hide) - CraftbukkitWrapper.impl.sendChunk(p, chunk.x(), chunk.z()); - } - }, 40); - } - - public static boolean bypass(Player p, int chunkX, int chunkZ){ - if(Config.isReferee(p)) - return true; - - FightTeam ft = Fight.getPlayerTeam(p); - if(ft == null){ - return Config.ArenaRegion.chunkOutside(chunkX, chunkZ); - }else if(ft.isBlue()){ - return ft.canPlayerEntern(p) || Config.RedExtendRegion.chunkOutside(chunkX, chunkZ); - }else{ - return ft.canPlayerEntern(p) || Config.BlueExtendRegion.chunkOutside(chunkX, chunkZ); - } - } - - public static int posToChunk(int c){ - int chunk = c / 16; - if(c<0) - chunk--; - return chunk; - } - - 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; - } - - 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; - } - - static byte[] writeVarInt(int value) { - List buffer = new ArrayList<>(5); - 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 class ChunkPos{ - final int x; - final int z; - - ChunkPos(int x, int z){ - this.x = x; - this.z = z; - } - - final int x(){ - return x; - } - - final int z(){ - return z; - } - } -} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java new file mode 100644 index 0000000..284c174 --- /dev/null +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java @@ -0,0 +1,98 @@ +/* + 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.core.CraftbukkitWrapper; +import de.steamwar.fightsystem.Config; +import de.steamwar.fightsystem.FightSystem; +import de.steamwar.fightsystem.fight.Fight; +import de.steamwar.fightsystem.fight.FightTeam; +import de.steamwar.fightsystem.states.FightState; +import de.steamwar.fightsystem.states.StateDependent; +import de.steamwar.techhider.ProtocolUtils; +import de.steamwar.techhider.TechHider; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class TechHiderWrapper extends StateDependent { + + public static final boolean ENABLED = !Config.OnlyPublicSchematics && !Config.test() && Config.TechhiderActive; + private final TechHider techHider; + + public TechHiderWrapper() { + super(ENABLED, FightState.Schem); + techHider = new TechHider(this::bypass, Material.getMaterial(Config.ObfuscateWith), Config.HiddenBlocks.stream().map(String::toUpperCase).map(Material::getMaterial).collect(Collectors.toSet()), Config.HiddenBlockEntities); + register(); + } + + @Override + public void enable() { + techHider.enable(); + } + + @Override + public void disable() { + techHider.disable(); + } + + public List prepareChunkReload(Player p, boolean hide) { + if(!ENABLED) + return Collections.emptyList(); + + List chunksToReload = new ArrayList<>(); + Config.ArenaRegion.forEachChunk((x, z) -> { + if(bypass(p, x, z) == hide) + chunksToReload.add(new ProtocolUtils.ChunkPos(x, z)); + }); + return chunksToReload; + } + + public void reloadChunks(Player p, List chunksToReload, boolean hide) { + if(!ENABLED || !FightState.Schem.contains(FightState.getFightState())) + return; + + Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> { + for(ProtocolUtils.ChunkPos chunk : chunksToReload){ + if(bypass(p, chunk.x(), chunk.z()) != hide) + CraftbukkitWrapper.impl.sendChunk(p, chunk.x(), chunk.z()); + } + }, 40); + } + + private boolean bypass(Player p, int chunkX, int chunkZ){ + if(Config.isReferee(p)) + return true; + + FightTeam ft = Fight.getPlayerTeam(p); + if(ft == null){ + return Config.ArenaRegion.chunkOutside(chunkX, chunkZ); + }else if(ft.isBlue()){ + return ft.canPlayerEntern(p) || Config.RedExtendRegion.chunkOutside(chunkX, chunkZ); + }else{ + return ft.canPlayerEntern(p) || Config.BlueExtendRegion.chunkOutside(chunkX, chunkZ); + } + } +} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionAmongUs.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionAmongUs.java new file mode 100644 index 0000000..0be9472 --- /dev/null +++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionAmongUs.java @@ -0,0 +1,87 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 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.winconditions; + +import de.steamwar.fightsystem.FightSystem; +import de.steamwar.fightsystem.fight.Fight; +import de.steamwar.fightsystem.fight.FightPlayer; +import de.steamwar.fightsystem.fight.FightTeam; +import de.steamwar.fightsystem.states.FightState; +import de.steamwar.fightsystem.states.OneShotStateDependent; +import de.steamwar.fightsystem.states.StateDependentListener; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import java.util.*; + +public class WinconditionAmongUs extends Wincondition implements Listener { + + private Map imposter = new HashMap<>(); + + private final Random random = new Random(); + + public WinconditionAmongUs() { + super("AmongUs"); + new OneShotStateDependent(Winconditions.AMONG_US, FightState.Ingame, () -> { + imposter.put(Fight.getRedTeam(), sendMessageAndReturnImposter(Fight.getRedTeam().getPlayers())); + imposter.put(Fight.getBlueTeam(), sendMessageAndReturnImposter(Fight.getBlueTeam().getPlayers())); + }); + new StateDependentListener(Winconditions.AMONG_US, FightState.Ingame, this); + } + + private FightPlayer sendMessageAndReturnImposter(Collection fightPlayers) { + List fightPlayerList = new ArrayList<>(fightPlayers); + FightPlayer imposter = fightPlayerList.get(random.nextInt(fightPlayerList.size())); + for (FightPlayer fightPlayer : fightPlayerList) { + if (fightPlayer == imposter) { + FightSystem.getMessage().send("AMONG_US_IMPOSTER_MESSAGE", fightPlayer.getPlayer()); + } else { + FightSystem.getMessage().send("AMONG_US_IMPOSTER_AMONG_MESSAGE", fightPlayer.getPlayer()); + } + } + return imposter; + } + + @EventHandler + public void handlePlayerDeath(PlayerDeathEvent event) { + handleDeath(event.getEntity().getPlayer()); + } + + @EventHandler + public void handlePlayerQuit(PlayerQuitEvent event) { + handleDeath(event.getPlayer()); + } + + private void handleDeath(Player player){ + FightTeam team = isTarget(player); + if(team == null) + return; + + FightPlayer current = team.getFightPlayer(player); + if (current == imposter.get(team)) { + win(team, "WIN_IMPOSTER_DEAD", team.getPrefix()); + } else if (team.getAlivePlayers() <= 2 && imposter.get(team).isLiving()) { + win(Fight.getOpposite(team), "WIN_CREWMATE_DEAD", Fight.getOpposite(team).getPrefix()); + } + } +} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java index 9d7ae2a..620a247 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java @@ -38,5 +38,6 @@ public enum Winconditions { PUMPKIN_TECH_KO, HELLS_BELLS, - METEOR + METEOR, + AMONG_US } diff --git a/build.gradle b/build.gradle index b07c8aa..3cacf6e 100644 --- a/build.gradle +++ b/build.gradle @@ -17,10 +17,6 @@ * along with this program. If not, see . */ - - -import org.apache.tools.ant.taskdefs.condition.Os - plugins { // Adding the base plugin fixes the following gradle warnings in IntelliJ: // @@ -33,43 +29,12 @@ plugins { id 'application' id 'com.github.johnrengelman.shadow' version '5.0.0' -} - -ext.swdep = { s -> - if (file("${rootDir}/lib/${s}.jar").exists()) { - return files("${rootDir}/lib/${s}.jar") - } else { - if (s.contains("-")) { - return "de.steamwar:${s.toLowerCase().replace('-', ':')}" - } else { - return "de.steamwar:${s.toLowerCase()}:RELEASE" - } - } + id 'de.steamwar.gradle' version 'RELEASE' } group 'de.steamwar' version '' -Properties steamwarProperties = new Properties() -if (file("steamwar.properties").exists()) { - steamwarProperties.load(file("steamwar.properties").newDataInputStream()) -} - -ext { - buildName = 'FightSystem' - artifactName = 'fightsystem' - - uberJarName = "${buildName}-all.jar" - jarName = "${artifactName}.jar" - libs = "${buildDir}/libs" - - if (Os.isFamily(Os.FAMILY_WINDOWS)) { - operatingSystem = "windows" - } else { - operatingSystem = "unix" - } -} - compileJava.options.encoding = 'UTF-8' compileJava.options.compilerArgs << '-parameter' @@ -94,14 +59,6 @@ allprojects { maven { url = uri('https://libraries.minecraft.net') } - - maven { - url = uri('https://steamwar.de/maven') - credentials { - username = steamwarProperties.getProperty("maven.username") - password = steamwarProperties.getProperty("maven.password") - } - } } } @@ -115,151 +72,3 @@ dependencies { } } } - -task buildProject { - description 'Build this project' - group "Steamwar" - - dependsOn build, tasks.getByPath(':FightSystem_Standalone:shadowJar') -} - -task finalizeProject { - description 'Finalize this project' - group "Steamwar" - - doLast { - if ("${buildDir}" == null) { - return - } - delete fileTree("${libs}").matching { - exclude("${uberJarName}") - } - file(libs + "/" + uberJarName).renameTo(file(libs + "/" + jarName)) - } -} -build.finalizedBy(finalizeProject) - -if (steamwarProperties.containsKey("hostname")) { - String hostname = steamwarProperties.get("hostname") - String uploadPath = steamwarProperties.getOrDefault("uploadPath", "~") - - String server = steamwarProperties.getOrDefault("server", "Dev1.15") - String serverStartFlags = steamwarProperties.getOrDefault("serverStartFlags", "") - - task uploadProject { - description 'Upload this project' - group "Steamwar" - - doLast { - await(shell("scp ${libs}/${jarName} ${hostname}:${uploadPath}/${server}/plugins")) - if (steamwarProperties.getOrDefault("directStart", "false") == "false" && !answer("Start ${server} server?")) { - return - } - serverStart(server, serverStartFlags, hostname) - } - } - uploadProject.dependsOn(buildProject) - - task startDevServer { - description 'Start the DevServer' - group "Steamwar" - - doLast { - serverStart(server, serverStartFlags, hostname) - } - } -} - -private def await(Process proc) { - def out = new StringBuilder() - def err = new StringBuilder() - proc.waitForProcessOutput(out, err) - return [out, err, proc.exitValue()] -} - -private def shell(String command) { - if (operatingSystem == "unix") { - return ['bash', '-c', command].execute() - } else { - return ["cmd", "/c", command].execute() - } -} - -private def serverStart(String serverName, String serverFlags, String hostname) { - def proc = shell("ssh -t ${hostname} \"./mc ${serverFlags} ${serverName}\"") - - Set strings = new HashSet<>() - File file = new File("${projectDir}/ignoredlog"); - if (file.exists()) { - new BufferedReader(new InputStreamReader(new FileInputStream(file))).readLines().forEach({ s -> - strings.add(s) - }) - } - - Thread outputThread = new Thread({ - Reader reader = proc.getInputStream().newReader(); - Writer writer = System.out.newWriter(); - try { - while (proc.alive) { - String s = reader.readLine() - if (s == null) { - return - } - if (strings.stream().anyMatch({check -> s.contains(check)})) { - continue - } - writer.write(s + "\n") - writer.flush() - } - } catch (IOException e) { - // Ignored - } - }) - outputThread.setName("${serverName} - OutputThread") - outputThread.start() - - Writer writer - Thread inputThread = new Thread({ - Reader reader = System.in.newReader() - writer = proc.getOutputStream().newWriter() - try { - while (proc.alive) { - String s = reader.readLine() - writer.write(s + "\n") - writer.flush() - } - } catch (IOException e) { - // Ignored - } - }) - inputThread.setName("${serverName} - InputThread") - inputThread.start() - - gradle.buildFinished { buildResult -> - if (!proc.alive) { - return - } - writer = proc.getOutputStream().newWriter() - writer.write("stop\n") - writer.flush() - awaitClose(proc, outputThread, inputThread) - } - awaitClose(proc, outputThread, inputThread) -}; - -private static def awaitClose(Process proc, Thread outputThread, Thread inputThread) { - while (proc.alive) { - Thread.sleep(10) - } - proc.closeStreams() - outputThread.interrupt() - inputThread.interrupt() -} - -private def answer(String question) { - while (System.in.available() > 0) System.in.read() - println(question) - boolean valid = "Yy".contains(((char) System.in.read()).toString()) - while (System.in.available() > 0) System.in.read() - return valid -} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index d28b327..5f1e450 100644 --- a/settings.gradle +++ b/settings.gradle @@ -17,6 +17,15 @@ * along with this program. If not, see . */ +pluginManagement { + repositories { + gradlePluginPortal() + maven { + url = uri("https://steamwar.de/maven/") + } + } +} + rootProject.name = 'FightSystem' file('.').listFiles().each { diff --git a/steamwarci.yml b/steamwarci.yml index e3c22f5..c5d1010 100644 --- a/steamwarci.yml +++ b/steamwarci.yml @@ -1,7 +1,9 @@ -build: +setup: - "ln -s /home/gitea/lib" - - "cp ~/gradle.properties ." + +build: - "./gradlew buildProject" + - "./gradlew --stop" artifacts: "/binarys/fightsystem.jar": "build/libs/fightsystem.jar"