From cf52b503334a56cf1181947e185f9dec0aca2938 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Thu, 31 Jul 2025 10:43:40 +0200 Subject: [PATCH 001/214] Introduce support for Minecraft 1.21: Add ReflectionWrapper21, ChunkHider21, and enhance version compatibility across systems. --- .../features/techhider/TechHiderCommand.java | 5 +- FightSystem/FightSystem_21/build.gradle.kts | 1 + .../fightsystem/utils/BlockIdWrapper21.java | 87 ++++++++++ .../utils/ReflectionWrapper21.java | 36 ++++ .../fightsystem/utils/ReflectionWrapper8.java | 59 +++++++ .../de/steamwar/fightsystem/fight/Kit.java | 12 +- .../steamwar/fightsystem/utils/HullHider.java | 11 +- .../fightsystem/utils/ReflectionWrapper.java | 37 +++++ .../fightsystem/utils/TechHiderWrapper.java | 4 +- FightSystem/FightSystem_Core/src/plugin.yml | 2 +- FightSystem/build.gradle.kts | 11 ++ SpigotCore/SpigotCore_21/build.gradle.kts | 3 + .../de/steamwar/techhider/ChunkHider21.java | 155 ++++++++++++++++++ .../src/de/steamwar/Reflection.java | 11 +- .../src/de/steamwar/techhider/ChunkHider.java | 26 ++- .../de/steamwar/techhider/ProtocolUtils.java | 10 ++ .../src/de/steamwar/techhider/TechHider.java | 1 + SpigotCore/SpigotCore_Main/src/plugin.yml | 2 +- settings.gradle.kts | 2 +- 19 files changed, 448 insertions(+), 27 deletions(-) create mode 100644 FightSystem/FightSystem_21/src/de/steamwar/fightsystem/utils/BlockIdWrapper21.java create mode 100644 FightSystem/FightSystem_21/src/de/steamwar/fightsystem/utils/ReflectionWrapper21.java create mode 100644 FightSystem/FightSystem_8/src/de/steamwar/fightsystem/utils/ReflectionWrapper8.java create mode 100644 FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/ReflectionWrapper.java create mode 100644 SpigotCore/SpigotCore_21/src/de/steamwar/techhider/ChunkHider21.java diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/techhider/TechHiderCommand.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/techhider/TechHiderCommand.java index 38725cf0..17d3563c 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/techhider/TechHiderCommand.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/techhider/TechHiderCommand.java @@ -34,6 +34,7 @@ import de.steamwar.linkage.LinkedInstance; import de.steamwar.techhider.TechHider; import net.md_5.bungee.api.ChatMessageType; import org.bukkit.Bukkit; +import org.bukkit.Chunk; import org.bukkit.Material; import org.bukkit.command.CommandSender; import org.bukkit.configuration.file.FileConfiguration; @@ -86,8 +87,8 @@ public class TechHiderCommand extends SWCommand implements Listener, ScoreboardE Set hiddenBlockEntities = Collections.unmodifiableSet(new HashSet<>(config.getStringList("Techhider.HiddenBlockEntities"))); TechHider current = new TechHider((TechHider.LocationEvaluator) (p, cX, cY) -> { - if (rg.buildChunkOutside(cX, cY)) return true; - return !hidden.get(rg).contains(p); + Chunk playerChunk = p.getLocation().getChunk(); + return playerChunk.getX() == cX && playerChunk.getZ() == cY; }, Material.valueOf(obfuscateWith.toUpperCase()), hiddenBlocks.stream().map(String::toUpperCase).map(Material::valueOf).collect(Collectors.toSet()), hiddenBlockEntities); current.enable(); diff --git a/FightSystem/FightSystem_21/build.gradle.kts b/FightSystem/FightSystem_21/build.gradle.kts index a05590d1..3309134f 100644 --- a/FightSystem/FightSystem_21/build.gradle.kts +++ b/FightSystem/FightSystem_21/build.gradle.kts @@ -24,6 +24,7 @@ plugins { dependencies { compileOnly(project(":FightSystem:FightSystem_Core", "default")) compileOnly(project(":FightSystem:FightSystem_18", "default")) + compileOnly(project(":SpigotCore", "default")) compileOnly(libs.paperapi21) { attributes { diff --git a/FightSystem/FightSystem_21/src/de/steamwar/fightsystem/utils/BlockIdWrapper21.java b/FightSystem/FightSystem_21/src/de/steamwar/fightsystem/utils/BlockIdWrapper21.java new file mode 100644 index 00000000..32e2e6e4 --- /dev/null +++ b/FightSystem/FightSystem_21/src/de/steamwar/fightsystem/utils/BlockIdWrapper21.java @@ -0,0 +1,87 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2025 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.Reflection; +import de.steamwar.fightsystem.Config; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ChunkMap; +import net.minecraft.server.level.ServerChunkCache; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.block.CraftBlockState; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +public class BlockIdWrapper21 implements BlockIdWrapper { + static Int2ObjectMap tracker; + + static Reflection.Field chunkMap = Reflection.getField(ServerChunkCache.class, "chunkMap", Object.class); + static { + ServerChunkCache chunkCache = ((CraftWorld) Config.world).getHandle().getChunkSource(); + Object map = chunkMap.get(chunkCache); + Reflection.Field eMapField = Reflection.getField(map.getClass(), "entityMap", Int2ObjectMap.class); + tracker = eMapField.get(map); + } + + @Override + public Material idToMaterial(int blockState) { + return CraftMagicNumbers.getMaterial(net.minecraft.world.level.block.Block.stateById(blockState)).getItemType(); + } + + @Override + public int blockToId(Block block) { + return net.minecraft.world.level.block.Block.getId(((CraftBlockState) block.getState()).getHandle()); + } + + @Override + public void setBlock(World world, int x, int y, int z, int blockState) { + BlockState blockData = net.minecraft.world.level.block.Block.stateById(blockState); + ServerLevel level = ((CraftWorld) world).getHandle(); + BlockPos pos = new BlockPos(x, y, z); + + level.removeBlockEntity(pos); + level.setBlock(pos, blockData, blockState); + level.getChunkSource().blockChanged(pos); + } + + @Override + public void trackEntity(Player player, Entity entity) { + ChunkMap.TrackedEntity trackedEntity = tracker.get(entity.getEntityId()); + if (trackedEntity != null) { + trackedEntity.updatePlayer(((CraftPlayer) player).getHandle()); + } + } + + @Override + public void untrackEntity(Player player, Entity entity) { + ChunkMap.TrackedEntity trackedEntity = tracker.get(entity.getEntityId()); + if (trackedEntity != null) { + trackedEntity.removePlayer(((CraftPlayer) player).getHandle()); + } + } +} diff --git a/FightSystem/FightSystem_21/src/de/steamwar/fightsystem/utils/ReflectionWrapper21.java b/FightSystem/FightSystem_21/src/de/steamwar/fightsystem/utils/ReflectionWrapper21.java new file mode 100644 index 00000000..118bfba1 --- /dev/null +++ b/FightSystem/FightSystem_21/src/de/steamwar/fightsystem/utils/ReflectionWrapper21.java @@ -0,0 +1,36 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2025 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.papermc.paper.datacomponent.DataComponentTypes; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class ReflectionWrapper21 implements ReflectionWrapper { + @Override + public Object explosionHider(Player player, Object packet, PacketHiderFunction packetHiderFunction) { + return packet; + } + + @Override + public boolean hasItems(ItemStack stack) { + return stack.getDataTypes().stream().anyMatch(dataComponentType -> dataComponentType != DataComponentTypes.ENCHANTMENTS || dataComponentType != DataComponentTypes.DAMAGE); + } +} diff --git a/FightSystem/FightSystem_8/src/de/steamwar/fightsystem/utils/ReflectionWrapper8.java b/FightSystem/FightSystem_8/src/de/steamwar/fightsystem/utils/ReflectionWrapper8.java new file mode 100644 index 00000000..6da5308a --- /dev/null +++ b/FightSystem/FightSystem_8/src/de/steamwar/fightsystem/utils/ReflectionWrapper8.java @@ -0,0 +1,59 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2025 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.Reflection; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Function; + +public class ReflectionWrapper8 implements ReflectionWrapper { + + private static final Class packetPlayOutExplosion = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundExplodePacket"); + private static final Reflection.Field explosionBlocks = Reflection.getField(packetPlayOutExplosion, List.class, 0); + private static final Function explosionLocation = HullHider.posPacketToLocation(packetPlayOutExplosion, double.class, 1.0); + + @Override + public Object explosionHider(Player player, Object packet, PacketHiderFunction packetHiderFunction) { + if(explosionBlocks.get(packet).isEmpty()) + return packetHiderFunction.hide(player, packet, explosionLocation.apply(packet)); + + return packet; + } + + + private static final Class itemStack = Reflection.getClass("net.minecraft.world.item.ItemStack"); + private static final Reflection.Method asNMSCopy = Reflection.getTypedMethod(Reflection.getClass("org.bukkit.craftbukkit.inventory.CraftItemStack"), "asNMSCopy", itemStack, ItemStack.class); + private static final Class nbtTagCompound = Reflection.getClass("net.minecraft.nbt.CompoundTag"); + private static final Reflection.Method getTag = Reflection.getTypedMethod(itemStack, null, nbtTagCompound); + private static final Reflection.Method getKeys = Reflection.getTypedMethod(nbtTagCompound, null, Set.class); + @Override + public 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(); + } +} diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/Kit.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/Kit.java index db97aa27..48a18bde 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/Kit.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/Kit.java @@ -26,6 +26,7 @@ import de.steamwar.fightsystem.commands.Commands; import de.steamwar.fightsystem.commands.GUI; import de.steamwar.fightsystem.listener.PersonalKitCreator; import de.steamwar.fightsystem.utils.FlatteningWrapper; +import de.steamwar.fightsystem.utils.ReflectionWrapper; import de.steamwar.inventory.SWInventory; import de.steamwar.inventory.SWItem; import de.steamwar.sql.PersonalKit; @@ -214,17 +215,8 @@ public class Kit { assert normal != null; return !normal.isEnchantmentInKit(stack) && !stack.getEnchantments().isEmpty(); } - - private static final Class itemStack = Reflection.getClass("net.minecraft.world.item.ItemStack"); - private static final Reflection.Method asNMSCopy = Reflection.getTypedMethod(Reflection.getClass("org.bukkit.craftbukkit.inventory.CraftItemStack"), "asNMSCopy", itemStack, ItemStack.class); - private static final Class nbtTagCompound = Reflection.getClass("net.minecraft.nbt.CompoundTag"); - private static final Reflection.Method getTag = Reflection.getTypedMethod(itemStack, null, nbtTagCompound); - private static final Reflection.Method 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(); + return ReflectionWrapper.impl.hasItems(stack); } private boolean isEnchantmentInKit(ItemStack stack){ diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHider.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHider.java index c050656d..137e2082 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHider.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHider.java @@ -62,6 +62,7 @@ public class HullHider implements Listener { private final Hull[] hulls; private final Map, BiFunction> packetHiders = new HashMap<>(); + private static final Class packetPlayOutExplosion = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundExplodePacket"); public HullHider() { if(!TechHiderWrapper.ENABLED) { hulls = new Hull[0]; @@ -208,14 +209,8 @@ public class HullHider implements Listener { return packetHider(player, packet, new Location(Config.world, TechHider.blockPositionX.get(baseBlock), blockPositionY.get(baseBlock), TechHider.blockPositionZ.get(baseBlock))); } - private static final Class packetPlayOutExplosion = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundExplodePacket"); - private static final Reflection.Field explosionBlocks = Reflection.getField(packetPlayOutExplosion, List.class, 0); - private static final Function explosionLocation = posPacketToLocation(packetPlayOutExplosion, double.class, 1.0); private Object explosionHider(Player player, Object packet) { - if(explosionBlocks.get(packet).isEmpty()) - return packetHider(player, packet, explosionLocation.apply(packet)); - - return packet; + return ReflectionWrapper.impl.explosionHider(player, packet, this::packetHider); } private void posHiderGenerator(String typeName, Class posType, double factor) { @@ -224,7 +219,7 @@ public class HullHider implements Listener { packetHiders.put(type, (player, packet) -> packetHider(player, packet, location.apply(packet))); } - private static Function posPacketToLocation(Class type, Class posType, double factor) { + public static Function posPacketToLocation(Class type, Class posType, double factor) { Reflection.Field x = Reflection.getField(type, posType, 0); Reflection.Field y = Reflection.getField(type, posType, 1); Reflection.Field z = Reflection.getField(type, posType, 2); diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/ReflectionWrapper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/ReflectionWrapper.java new file mode 100644 index 00000000..cbc9f807 --- /dev/null +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/ReflectionWrapper.java @@ -0,0 +1,37 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2025 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.VersionDependent; +import de.steamwar.fightsystem.FightSystem; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public interface ReflectionWrapper { + ReflectionWrapper impl = VersionDependent.getVersionImpl(FightSystem.getPlugin()); + + Object explosionHider(Player player, Object packet, PacketHiderFunction packetHiderFunction); + boolean hasItems(ItemStack stack); + + public interface PacketHiderFunction { + Object hide(Player player, Object packet, Location location); + } +} diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java index bf890168..fde87959 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java @@ -59,7 +59,7 @@ public class TechHiderWrapper extends StateDependent implements TechHider.Locati private final SecretKey key; public TechHiderWrapper() { - super(ENABLED, FightState.Schem); + super(ENABLED, FightState.All); techHider = new TechHider(this, Config.ObfuscateWith, Config.HiddenBlocks, Config.HiddenBlockEntities); try { @@ -68,7 +68,7 @@ public class TechHiderWrapper extends StateDependent implements TechHider.Locati throw new SecurityException(e); } - new StateDependentListener(ENABLED, FightState.Schem, this); + new StateDependentListener(ENABLED, FightState.All, this); register(); } diff --git a/FightSystem/FightSystem_Core/src/plugin.yml b/FightSystem/FightSystem_Core/src/plugin.yml index 6925bf69..09702025 100644 --- a/FightSystem/FightSystem_Core/src/plugin.yml +++ b/FightSystem/FightSystem_Core/src/plugin.yml @@ -8,7 +8,7 @@ softdepend: - SpigotCore depend: - WorldEdit -api-version: "1.13" +api-version: "1.21.6" commands: ak: diff --git a/FightSystem/build.gradle.kts b/FightSystem/build.gradle.kts index 9013824d..6338609a 100644 --- a/FightSystem/build.gradle.kts +++ b/FightSystem/build.gradle.kts @@ -50,6 +50,17 @@ tasks.register("WarGear20") { config = "WarGear20.yml" } +tasks.register("WarGear21") { + group = "run" + description = "Run a WarGear 1.21 Fight Server" + dependsOn(":SpigotCore:shadowJar") + dependsOn(":FightSystem:shadowJar") + template = "WarGear21" + worldName = "arenas/Pentraki" + config = "WarGear20.yml" + jar = "/jars/paper-1.21.6.jar" +} + tasks.register("SpaceCraftDev20") { group = "run" description = "Run a SpaceCraftDev 1.20 Fight Server" diff --git a/SpigotCore/SpigotCore_21/build.gradle.kts b/SpigotCore/SpigotCore_21/build.gradle.kts index 8f2acba4..4b26ba16 100644 --- a/SpigotCore/SpigotCore_21/build.gradle.kts +++ b/SpigotCore/SpigotCore_21/build.gradle.kts @@ -37,4 +37,7 @@ dependencies { compileOnly(libs.paperapi21) compileOnly(libs.nms21) + compileOnly(libs.datafixer) + compileOnly(libs.netty) + compileOnly(libs.authlib) } diff --git a/SpigotCore/SpigotCore_21/src/de/steamwar/techhider/ChunkHider21.java b/SpigotCore/SpigotCore_21/src/de/steamwar/techhider/ChunkHider21.java new file mode 100644 index 00000000..c31e5f8f --- /dev/null +++ b/SpigotCore/SpigotCore_21/src/de/steamwar/techhider/ChunkHider21.java @@ -0,0 +1,155 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2025 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.techhider; + +import de.steamwar.Reflection; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +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.BlockEntityType; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.Set; +import java.util.function.BiFunction; +import java.util.function.UnaryOperator; +import java.util.stream.Collectors; + +public class ChunkHider21 implements ChunkHider { + @Override + public Class mapChunkPacket() { + return ClientboundLevelChunkWithLightPacket.class; + } + + private static final UnaryOperator chunkPacketCloner = ProtocolUtils.shallowCloneGenerator(ClientboundLevelChunkWithLightPacket.class); + private static final UnaryOperator chunkDataCloner = ProtocolUtils.shallowCloneGenerator(ClientboundLevelChunkPacketData.class); + + private static final Reflection.Field chunkXField = Reflection.getField(ClientboundLevelChunkWithLightPacket.class, int.class, 0); + private static final Reflection.Field chunkZField = Reflection.getField(ClientboundLevelChunkWithLightPacket.class, int.class, 1); + private static final Reflection.Field chunkData = Reflection.getField(ClientboundLevelChunkWithLightPacket.class, ClientboundLevelChunkPacketData.class, 0); + + private static final Reflection.Field dataField = Reflection.getField(ClientboundLevelChunkPacketData.class, byte[].class, 0); + private static final Reflection.Field tileEntities = Reflection.getField(ClientboundLevelChunkPacketData.class, List.class, 0); + + @Override + public BiFunction chunkHiderGenerator(TechHider techHider) { + return (p, packet) -> { + int chunkX = chunkXField.get(packet); + int chunkZ = chunkZField.get(packet); + if (techHider.getLocationEvaluator().skipChunk(p, chunkX, chunkZ)) + return packet; + + packet = chunkPacketCloner.apply(packet); + Object dataWrapper = chunkDataCloner.apply(chunkData.get(packet)); + + Set hiddenBlockEntities = techHider.getHiddenBlockEntities(); + tileEntities.set(dataWrapper, ((List)tileEntities.get(dataWrapper)).stream().filter(te -> tileEntityVisible(hiddenBlockEntities, te)).collect(Collectors.toList())); + + ByteBuf in = Unpooled.wrappedBuffer(dataField.get(dataWrapper)); + ByteBuf out = Unpooled.buffer(in.readableBytes() + 64); + for(int yOffset = p.getWorld().getMinHeight(); yOffset < p.getWorld().getMaxHeight(); yOffset += 16) { + SectionHider section = new SectionHider(p, techHider, in, out, chunkX, yOffset/16, chunkZ); + section.copyBlockCount(); + + blocks(section); + biomes(section); + } + + if (in.readableBytes() != 0) { + throw new IllegalStateException("ChunkHider21: Incomplete chunk data, " + in.readableBytes() + " bytes left"); + } + + byte[] data = new byte[out.readableBytes()]; + out.readBytes(data); + dataField.set(dataWrapper, data); + + chunkData.set(packet, dataWrapper); + return packet; + }; + } + + public static final Class tileEntity = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData$BlockEntityInfo"); + protected static final Reflection.Field entityType = Reflection.getField(tileEntity, BlockEntityType.class, 0); + private static final Class builtInRegestries = Reflection.getClass("net.minecraft.core.registries.BuiltInRegistries"); + private static final Class registry = Reflection.getClass("net.minecraft.core.Registry"); + private static final Reflection.Field nameField = Reflection.getField(builtInRegestries, "BLOCK_ENTITY_TYPE", registry); + private static final Class resourceLocation = Reflection.getClass("net.minecraft.resources.ResourceLocation"); + private static final Reflection.Method getKey = Reflection.getTypedMethod(registry, "getKey", resourceLocation, Object.class); + private static final Reflection.Method getName = Reflection.getTypedMethod(resourceLocation, "getPath", String.class); + protected boolean tileEntityVisible(Set hiddenBlockEntities, Object tile) { + return !hiddenBlockEntities.contains(getName.invoke(getKey.invoke(nameField.get(null), entityType.get(tile)))); + } + + private void blocks(SectionHider section) { + section.copyBitsPerBlock(); + + boolean singleValued = section.getBitsPerBlock() == 0; + if (singleValued) { + int value = ProtocolUtils.readVarInt(section.getIn()); + ProtocolUtils.writeVarInt(section.getOut(), !section.isSkipSection() && section.getObfuscate().contains(value) ? section.getTarget() : value); + return; + } else { + section.processPalette(); + } + + if (section.isSkipSection() || (!section.blockPrecise() && section.isPaletted())) { + section.skipNewDataArray(4096); + return; + } + + SimpleBitStorage values = new SimpleBitStorage(section.getBitsPerBlock(), 4096, section.readNewDataArray(4096)); + + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + int pos = (((y * 16) + z) * 16) + x; + + switch (section.test(x, y, z)) { + case SKIP: + break; + case CHECK: + if (!section.getObfuscate().contains(values.get(pos))) + break; + case HIDE: + values.set(pos, section.getTarget()); + break; + case HIDE_AIR: + default: + values.set(pos, section.getAir()); + } + } + } + } + + section.writeDataArray(values.getRaw()); + } + + private void biomes(SectionHider section) { + section.copyBitsPerBlock(); + if(section.getBitsPerBlock() == 0) { + section.copyVarInt(); + } else if(section.getBitsPerBlock() < 6) { + section.skipPalette(); + section.skipNewDataArray(64); + } + } +} diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/Reflection.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/Reflection.java index 86dca0bf..7c34fca9 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/Reflection.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/Reflection.java @@ -157,7 +157,16 @@ public final class Reflection { } else if(MAJOR_VERSION < 21 || MINOR_VERSION < 4) { return Class.forName(spigotClassnames.getOrDefault(name, name)); } else { - return Class.forName(name); + Class clazz = Class.forName(name); + if (clazz.getName().equals(name)) { + return clazz; + } + + try { + return Core.class.getClassLoader().getParent().loadClass(name); + } catch (ClassNotFoundException e) { + return clazz; + } } } catch (ClassNotFoundException e) { throw new IllegalArgumentException("Cannot find " + name, e); diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java index a74feb42..fbd6e364 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java @@ -53,6 +53,7 @@ public interface ChunkHider { private boolean paletted; private int bitsPerBlock; + private int blockCount; private int air; private int target; private Set obfuscate; @@ -86,7 +87,8 @@ public interface ChunkHider { } public void copyBlockCount() { - out.writeShort(in.readShort()); + this.blockCount = in.readShort(); + out.writeShort(blockCount); } public void copyBitsPerBlock() { @@ -140,6 +142,15 @@ public interface ChunkHider { out.writeBytes(in, dataArrayLength*8); } + public void skipNewDataArray(int entries) { + if (bitsPerBlock == 0) { + return; + } + + int longs = (int) (((long) entries * bitsPerBlock + 63) >> 6); + out.writeBytes(in, longs * Long.BYTES); + } + public long[] readDataArray() { long[] array = new long[copyVarInt()]; for(int i = 0; i < array.length; i++) @@ -148,6 +159,19 @@ public interface ChunkHider { return array; } + public long[] readNewDataArray(int entries) { + if (bitsPerBlock == 0) { + return new long[entries]; + } + + int longs = (int) (((long) entries * bitsPerBlock + 63) >> 6); + long[] array = new long[longs]; + for(int i = 0; i < longs; i++) + array[i] = in.readLong(); + + return array; + } + public void writeDataArray(long[] array) { for(long l : array) out.writeLong(l); diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ProtocolUtils.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ProtocolUtils.java index 57f27921..3949d7ed 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ProtocolUtils.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ProtocolUtils.java @@ -58,6 +58,16 @@ public class ProtocolUtils { }; } + public static UnaryOperator shallowTypedCloneGenerator(Class clazz) { + BiConsumer filler = shallowFill(clazz); + + return source -> { + Object clone = Reflection.newInstance(clazz); + filler.accept(source, clone); + return (T) clone; + }; + } + private static BiConsumer shallowFill(Class clazz) { if(clazz == null) return (source, clone) -> {}; diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java index 021d2fe4..b231e97f 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java @@ -79,6 +79,7 @@ public class TechHider { techhiders.put(blockChangePacket, this::blockChangeHider); techhiders.put(tileEntityDataPacket, this::tileEntityDataHider); techhiders.put(multiBlockChangePacket, ProtocolWrapper.impl.multiBlockChangeGenerator(this)); + System.out.println(ChunkHider.impl.mapChunkPacket().getName()); techhiders.put(ChunkHider.impl.mapChunkPacket(), ChunkHider.impl.chunkHiderGenerator(this)); if(Core.getVersion() > 12 && Core.getVersion() < 19) { diff --git a/SpigotCore/SpigotCore_Main/src/plugin.yml b/SpigotCore/SpigotCore_Main/src/plugin.yml index a29249d2..cd807cd2 100644 --- a/SpigotCore/SpigotCore_Main/src/plugin.yml +++ b/SpigotCore/SpigotCore_Main/src/plugin.yml @@ -1,7 +1,7 @@ name: SpigotCore version: "2.0" author: Lixfel -api-version: "1.13" +api-version: "1.21" load: STARTUP softdepend: - WorldEdit diff --git a/settings.gradle.kts b/settings.gradle.kts index 8ab618ff..6665697f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -126,7 +126,7 @@ dependencyResolutionManagement { library("nms18", "de.steamwar:spigot:1.18") library("nms19", "de.steamwar:spigot:1.19") library("nms20", "de.steamwar:spigot:1.20") - library("nms21", "de.steamwar:spigot:1.21.5") + library("nms21", "de.steamwar:spigot:1.21.6") library("axiom", "de.steamwar:axiompaper:RELEASE") library("worldedit12", "de.steamwar:worldedit:1.12") From e7803dcf822a070734cffc0f134019c7e18326e8 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Thu, 31 Jul 2025 11:34:56 +0200 Subject: [PATCH 002/214] Enhance compatibility and feature support for Minecraft 1.21: Add ProtocolWrapper21, update gamerule management, streamline entity tracking, and refine chunk hider logic. --- .../features/techhider/TechHiderCommand.java | 4 +- .../utils/CraftbukkitWrapper10.java | 3 + .../utils/CraftbukkitWrapper12.java | 3 + .../utils/CraftbukkitWrapper14.java | 3 + .../utils/CraftbukkitWrapper15.java | 3 + .../utils/CraftbukkitWrapper18.java | 3 + FightSystem/FightSystem_21/build.gradle.kts | 1 + .../fightsystem/utils/BlockIdWrapper21.java | 36 ++++------ .../utils/CraftbukkitWrapper21.java | 7 ++ .../utils/CraftbukkitWrapper8.java | 3 + .../utils/CraftbukkitWrapper9.java | 3 + .../de/steamwar/fightsystem/FightSystem.java | 2 + .../fightsystem/utils/CraftbukkitWrapper.java | 2 + .../fightsystem/utils/TechHiderWrapper.java | 4 +- .../de/steamwar/core/ProtocolWrapper21.java | 66 +++++++++++++++++++ .../de/steamwar/techhider/ChunkHider21.java | 4 +- .../src/de/steamwar/Reflection.java | 11 +++- .../src/de/steamwar/techhider/ChunkHider.java | 12 ++-- 18 files changed, 135 insertions(+), 35 deletions(-) create mode 100644 SpigotCore/SpigotCore_21/src/de/steamwar/core/ProtocolWrapper21.java diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/techhider/TechHiderCommand.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/techhider/TechHiderCommand.java index 17d3563c..0c1d8af5 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/techhider/TechHiderCommand.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/techhider/TechHiderCommand.java @@ -87,8 +87,8 @@ public class TechHiderCommand extends SWCommand implements Listener, ScoreboardE Set hiddenBlockEntities = Collections.unmodifiableSet(new HashSet<>(config.getStringList("Techhider.HiddenBlockEntities"))); TechHider current = new TechHider((TechHider.LocationEvaluator) (p, cX, cY) -> { - Chunk playerChunk = p.getLocation().getChunk(); - return playerChunk.getX() == cX && playerChunk.getZ() == cY; + if (rg.buildChunkOutside(cX, cY)) return true; + return !hidden.get(rg).contains(p); }, Material.valueOf(obfuscateWith.toUpperCase()), hiddenBlocks.stream().map(String::toUpperCase).map(Material::valueOf).collect(Collectors.toSet()), hiddenBlockEntities); current.enable(); diff --git a/FightSystem/FightSystem_10/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper10.java b/FightSystem/FightSystem_10/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper10.java index 78dd79a5..d5f654ae 100644 --- a/FightSystem/FightSystem_10/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper10.java +++ b/FightSystem/FightSystem_10/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper10.java @@ -55,4 +55,7 @@ public class CraftbukkitWrapper10 implements CraftbukkitWrapper { public Stream entityIterator() { return ((CraftWorld) Config.world).getHandle().entityList.stream(); } + + @Override + public void setupGamerule() { } } diff --git a/FightSystem/FightSystem_12/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper12.java b/FightSystem/FightSystem_12/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper12.java index f8e843bc..a134b9fe 100644 --- a/FightSystem/FightSystem_12/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper12.java +++ b/FightSystem/FightSystem_12/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper12.java @@ -55,4 +55,7 @@ public class CraftbukkitWrapper12 implements CraftbukkitWrapper { public Stream entityIterator() { return ((CraftWorld) Config.world).getHandle().entityList.stream(); } + + @Override + public void setupGamerule() { } } diff --git a/FightSystem/FightSystem_14/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper14.java b/FightSystem/FightSystem_14/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper14.java index 07c525d4..8e2f96ab 100644 --- a/FightSystem/FightSystem_14/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper14.java +++ b/FightSystem/FightSystem_14/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper14.java @@ -56,4 +56,7 @@ public class CraftbukkitWrapper14 implements CraftbukkitWrapper { public Stream entityIterator() { return ((CraftWorld) Config.world).getHandle().entitiesById.values().stream(); } + + @Override + public void setupGamerule() { } } diff --git a/FightSystem/FightSystem_15/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper15.java b/FightSystem/FightSystem_15/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper15.java index 70d9e8c5..64a0f9e1 100644 --- a/FightSystem/FightSystem_15/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper15.java +++ b/FightSystem/FightSystem_15/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper15.java @@ -56,4 +56,7 @@ public class CraftbukkitWrapper15 implements CraftbukkitWrapper { public Stream entityIterator() { return ((CraftWorld) Config.world).getHandle().entitiesById.values().stream(); } + + @Override + public void setupGamerule() { } } diff --git a/FightSystem/FightSystem_18/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper18.java b/FightSystem/FightSystem_18/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper18.java index 8fa8e7de..aafd5c08 100644 --- a/FightSystem/FightSystem_18/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper18.java +++ b/FightSystem/FightSystem_18/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper18.java @@ -62,4 +62,7 @@ public class CraftbukkitWrapper18 implements CraftbukkitWrapper { public Stream entityIterator() { return StreamSupport.stream(((Iterable) getIterable.invoke(getWorldEntities.invoke(getWorld.invoke(Config.world)))).spliterator(), false); } + + @Override + public void setupGamerule() { } } diff --git a/FightSystem/FightSystem_21/build.gradle.kts b/FightSystem/FightSystem_21/build.gradle.kts index 3309134f..2da59fce 100644 --- a/FightSystem/FightSystem_21/build.gradle.kts +++ b/FightSystem/FightSystem_21/build.gradle.kts @@ -41,4 +41,5 @@ dependencies { } compileOnly(libs.fastutil) + compileOnly(libs.authlib) } diff --git a/FightSystem/FightSystem_21/src/de/steamwar/fightsystem/utils/BlockIdWrapper21.java b/FightSystem/FightSystem_21/src/de/steamwar/fightsystem/utils/BlockIdWrapper21.java index 32e2e6e4..105bbe36 100644 --- a/FightSystem/FightSystem_21/src/de/steamwar/fightsystem/utils/BlockIdWrapper21.java +++ b/FightSystem/FightSystem_21/src/de/steamwar/fightsystem/utils/BlockIdWrapper21.java @@ -19,34 +19,24 @@ package de.steamwar.fightsystem.utils; -import de.steamwar.Reflection; -import de.steamwar.fightsystem.Config; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import com.comphenix.tinyprotocol.TinyProtocol; +import com.mojang.authlib.GameProfile; +import de.steamwar.core.ProtocolWrapper; +import de.steamwar.fightsystem.FightSystem; import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ChunkMap; -import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.block.CraftBlockState; -import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; public class BlockIdWrapper21 implements BlockIdWrapper { - static Int2ObjectMap tracker; - - static Reflection.Field chunkMap = Reflection.getField(ServerChunkCache.class, "chunkMap", Object.class); - static { - ServerChunkCache chunkCache = ((CraftWorld) Config.world).getHandle().getChunkSource(); - Object map = chunkMap.get(chunkCache); - Reflection.Field eMapField = Reflection.getField(map.getClass(), "entityMap", Int2ObjectMap.class); - tracker = eMapField.get(map); - } @Override public Material idToMaterial(int blockState) { @@ -71,17 +61,17 @@ public class BlockIdWrapper21 implements BlockIdWrapper { @Override public void trackEntity(Player player, Entity entity) { - ChunkMap.TrackedEntity trackedEntity = tracker.get(entity.getEntityId()); - if (trackedEntity != null) { - trackedEntity.updatePlayer(((CraftPlayer) player).getHandle()); - } + if(entity instanceof Player) + TinyProtocol.instance.sendPacket(player, ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.REMOVE, new GameProfile(entity.getUniqueId(), entity.getName()), GameMode.CREATIVE)); + + player.showEntity(FightSystem.getPlugin(), entity); } @Override public void untrackEntity(Player player, Entity entity) { - ChunkMap.TrackedEntity trackedEntity = tracker.get(entity.getEntityId()); - if (trackedEntity != null) { - trackedEntity.removePlayer(((CraftPlayer) player).getHandle()); - } + player.hideEntity(FightSystem.getPlugin(), entity); + + if(entity instanceof Player) + TinyProtocol.instance.sendPacket(player, ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.ADD, new GameProfile(entity.getUniqueId(), entity.getName()), GameMode.CREATIVE)); } } diff --git a/FightSystem/FightSystem_21/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper21.java b/FightSystem/FightSystem_21/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper21.java index b5c920a7..68f35171 100644 --- a/FightSystem/FightSystem_21/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper21.java +++ b/FightSystem/FightSystem_21/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper21.java @@ -19,6 +19,8 @@ package de.steamwar.fightsystem.utils; +import de.steamwar.fightsystem.Config; +import org.bukkit.GameRule; import org.bukkit.entity.Entity; public class CraftbukkitWrapper21 extends CraftbukkitWrapper18 { @@ -27,4 +29,9 @@ public class CraftbukkitWrapper21 extends CraftbukkitWrapper18 { public float headRotation(Entity e) { return getEntity(e).getYHeadRot(); } + + @Override + public void setupGamerule() { + Config.world.setGameRule(GameRule.LOCATOR_BAR, false); + } } diff --git a/FightSystem/FightSystem_8/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper8.java b/FightSystem/FightSystem_8/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper8.java index 8d743ae7..e7597dd7 100644 --- a/FightSystem/FightSystem_8/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper8.java +++ b/FightSystem/FightSystem_8/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper8.java @@ -52,4 +52,7 @@ public class CraftbukkitWrapper8 implements CraftbukkitWrapper { public Stream entityIterator() { return ((CraftWorld) Config.world).getHandle().entityList.stream(); } + + @Override + public void setupGamerule() { } } diff --git a/FightSystem/FightSystem_9/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper9.java b/FightSystem/FightSystem_9/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper9.java index 54281ed3..c7f393b3 100644 --- a/FightSystem/FightSystem_9/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper9.java +++ b/FightSystem/FightSystem_9/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper9.java @@ -55,4 +55,7 @@ public class CraftbukkitWrapper9 implements CraftbukkitWrapper { public Stream entityIterator() { return ((CraftWorld) Config.world).getHandle().entityList.stream(); } + + @Override + public void setupGamerule() { } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java index 1ff85e23..a95670a0 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java @@ -188,6 +188,8 @@ public class FightSystem extends JavaPlugin { }else if(Config.mode == ArenaMode.PREPARE) { Fight.getUnrotated().setSchem(SchematicNode.getSchematicNode(Config.PrepareSchemID)); } + + CraftbukkitWrapper.impl.setupGamerule(); } @Override diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper.java index 242119f5..e008a3bd 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper.java @@ -33,4 +33,6 @@ public interface CraftbukkitWrapper { float headRotation(Entity e); Stream entityIterator(); + + void setupGamerule(); } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java index fde87959..bf890168 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java @@ -59,7 +59,7 @@ public class TechHiderWrapper extends StateDependent implements TechHider.Locati private final SecretKey key; public TechHiderWrapper() { - super(ENABLED, FightState.All); + super(ENABLED, FightState.Schem); techHider = new TechHider(this, Config.ObfuscateWith, Config.HiddenBlocks, Config.HiddenBlockEntities); try { @@ -68,7 +68,7 @@ public class TechHiderWrapper extends StateDependent implements TechHider.Locati throw new SecurityException(e); } - new StateDependentListener(ENABLED, FightState.All, this); + new StateDependentListener(ENABLED, FightState.Schem, this); register(); } diff --git a/SpigotCore/SpigotCore_21/src/de/steamwar/core/ProtocolWrapper21.java b/SpigotCore/SpigotCore_21/src/de/steamwar/core/ProtocolWrapper21.java new file mode 100644 index 00000000..7018aa64 --- /dev/null +++ b/SpigotCore/SpigotCore_21/src/de/steamwar/core/ProtocolWrapper21.java @@ -0,0 +1,66 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 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.core; + +import com.mojang.authlib.GameProfile; +import com.mojang.datafixers.util.Pair; +import de.steamwar.Reflection; +import net.minecraft.Util; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; +import net.minecraft.world.level.GameType; +import org.bukkit.GameMode; + +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; +import java.util.function.LongSupplier; + +public class ProtocolWrapper21 implements ProtocolWrapper { + + private static final Reflection.Field equipmentStack = Reflection.getField(equipmentPacket, List.class, 0); + @Override + public void setEquipmentPacketStack(Object packet, Object slot, Object stack) { + equipmentStack.set(packet, Collections.singletonList(new Pair<>(slot, stack))); + } + + private static final Reflection.Constructor removePacketConstructor = Reflection.getConstructor(ClientboundPlayerInfoRemovePacket.class, List.class); + + @Override + @SuppressWarnings("deprecation") + public Object playerInfoPacketConstructor(PlayerInfoAction action, GameProfile profile, GameMode mode) { + if(action == PlayerInfoAction.REMOVE) + return removePacketConstructor.invoke(Collections.singletonList(profile.getId())); + return switch (action) { + case ADD -> new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE), new ClientboundPlayerInfoUpdatePacket.Entry( + profile.getId(), profile, true, 0, GameType.byId(mode.getValue()), null, true, 0, null + )); + case GAMEMODE -> new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE), new ClientboundPlayerInfoUpdatePacket.Entry( + profile.getId(), profile, true, 0, GameType.byId(mode.getValue()), null, true, 0, null + )); + default -> null; + }; + } + + @Override + public void initTPSWarp(LongSupplier longSupplier) { + Util.timeSource = () -> System.nanoTime() + longSupplier.getAsLong(); + } +} diff --git a/SpigotCore/SpigotCore_21/src/de/steamwar/techhider/ChunkHider21.java b/SpigotCore/SpigotCore_21/src/de/steamwar/techhider/ChunkHider21.java index c31e5f8f..0d0cb782 100644 --- a/SpigotCore/SpigotCore_21/src/de/steamwar/techhider/ChunkHider21.java +++ b/SpigotCore/SpigotCore_21/src/de/steamwar/techhider/ChunkHider21.java @@ -123,7 +123,9 @@ public class ChunkHider21 implements ChunkHider { for (int x = 0; x < 16; x++) { int pos = (((y * 16) + z) * 16) + x; - switch (section.test(x, y, z)) { + TechHider.State test = section.test(x, y, z); + + switch (test) { case SKIP: break; case CHECK: diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/Reflection.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/Reflection.java index 7c34fca9..ff298c1a 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/Reflection.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/Reflection.java @@ -157,14 +157,21 @@ public final class Reflection { } else if(MAJOR_VERSION < 21 || MINOR_VERSION < 4) { return Class.forName(spigotClassnames.getOrDefault(name, name)); } else { - Class clazz = Class.forName(name); - if (clazz.getName().equals(name)) { + Class clazz = null; + try { + clazz = Class.forName(name); + } catch (ClassNotFoundException e) {} + if (clazz != null && clazz.getName().equals(name)) { return clazz; } try { return Core.class.getClassLoader().getParent().loadClass(name); } catch (ClassNotFoundException e) { + if (clazz == null) { + throw e; + } + return clazz; } } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java index fbd6e364..e1d2b5e9 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/ChunkHider.java @@ -147,8 +147,9 @@ public interface ChunkHider { return; } - int longs = (int) (((long) entries * bitsPerBlock + 63) >> 6); - out.writeBytes(in, longs * Long.BYTES); + char valuesPerLong = (char)(64 / bitsPerBlock); + int i1 = (entries + valuesPerLong - 1) / valuesPerLong; + out.writeBytes(in, i1 * Long.BYTES); } public long[] readDataArray() { @@ -164,9 +165,10 @@ public interface ChunkHider { return new long[entries]; } - int longs = (int) (((long) entries * bitsPerBlock + 63) >> 6); - long[] array = new long[longs]; - for(int i = 0; i < longs; i++) + char valuesPerLong = (char) (64 / bitsPerBlock); + int i1 = (entries + valuesPerLong - 1) / valuesPerLong; + long[] array = new long[i1]; + for(int i = 0; i < i1; i++) array[i] = in.readLong(); return array; From 6623e9d808fb29c4d84ba4fefa410bd6fefef271 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 1 Aug 2025 10:43:37 +0200 Subject: [PATCH 003/214] Add VacationCommand --- .../velocitycore/discord/DiscordBot.java | 10 +- .../velocitycore/discord/VacationCommand.java | 189 ++++++++++++++++++ 2 files changed, 197 insertions(+), 2 deletions(-) create mode 100644 VelocityCore/src/de/steamwar/velocitycore/discord/VacationCommand.java diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java index 28cd0c22..53714c52 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java @@ -54,8 +54,8 @@ import net.dv8tion.jda.api.utils.MemberCachePolicy; import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; import java.awt.*; -import java.util.List; import java.util.*; +import java.util.List; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; @@ -193,14 +193,20 @@ public class DiscordBot { VelocityCore.schedule(CouncilChannel::updateAll).repeat(1, TimeUnit.HOURS).schedule(); + VacationCommand vacationCommand = new VacationCommand(); jda.addEventListener( new DiscordTicketHandler(), new DiscordTeamEvent(), new ChannelListener(), - new DiscordSchemUpload() + new DiscordSchemUpload(), + vacationCommand ); commandSetup(jda.retrieveCommands().complete(), jda.updateCommands()); + + jda.getGuildById(1241489896909180998L) + .upsertCommand(vacationCommand.COMMAND) + .queue(); } private final OptionData commandArgument = new OptionData(OptionType.STRING, ARGUMENT_NAME, "Command arguments", false); diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/VacationCommand.java b/VelocityCore/src/de/steamwar/velocitycore/discord/VacationCommand.java new file mode 100644 index 00000000..ace8dcf6 --- /dev/null +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/VacationCommand.java @@ -0,0 +1,189 @@ +/* + * 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.velocitycore.discord; + +import it.unimi.dsi.fastutil.Pair; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.ScheduledEvent; +import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import net.dv8tion.jda.api.interactions.InteractionHook; +import net.dv8tion.jda.api.interactions.commands.Command; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; +import net.dv8tion.jda.internal.interactions.CommandDataImpl; +import org.jetbrains.annotations.NotNull; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class VacationCommand extends ListenerAdapter { + + private final Guild guild = Objects.requireNonNull(DiscordBot.getInstance().getJda().getGuildById(1241489896909180998L)); + + public final CommandDataImpl COMMAND = new CommandDataImpl("vacation", "Verwalte deinen Urlaub"); + + public VacationCommand() { + COMMAND.addSubcommands(new SubcommandData("create", "Erstelle deinen Urlaub") + .addOptions(new OptionData(OptionType.STRING, "from", "Datum (TT.MM.JJJJ)", true), + new OptionData(OptionType.STRING, "to", "Datum (TT.MM.JJJJ)", true))); + COMMAND.addSubcommands(new SubcommandData("delete", "Lösche deinen Urlaub") + .addOptions(new OptionData(OptionType.INTEGER, "vacation", "Dein Urlaub", true, true))); + } + + @Override + public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) { + if (!event.getName().equals("vacation")) return; + switch (event.getSubcommandName()) { + case "create": + createVacation(event); + break; + case "delete": + deleteVacation(event); + break; + default: + break; + } + } + + public static final DateTimeFormatter PARSER = DateTimeFormatter.ofPattern("dd.MM.uuuu"); + + private void createVacation(SlashCommandInteractionEvent event) { + InteractionHook interactionHook = event.deferReply(true).complete(); + String from = event.getOption("from").getAsString(); + String to = event.getOption("to").getAsString(); + + LocalDateTime fromDate; + try { + fromDate = LocalDate.parse(from, PARSER).atStartOfDay(); + } catch (DateTimeParseException e) { + interactionHook.editOriginal("Das Datumsformat ist falsch! Bitte verwenden Sie TT.MM.JJJJ für den ersten Tag deines Urlaubs").queue(); + return; + } + if (fromDate == null) { + interactionHook.editOriginal("Das Datumsformat ist falsch! Bitte verwenden Sie TT.MM.JJJJ für den ersten Tag deines Urlaubs").queue(); + return; + } + if (!fromDate.isAfter(LocalDateTime.now())) { + interactionHook.editOriginal("Bitte gib ein Datum in der Zukunft an!").queue(); + return; + } + + LocalDateTime toDate; + try { + toDate = LocalDate.parse(to, PARSER).atTime(23, 59, 59); + } catch (DateTimeParseException e) { + interactionHook.editOriginal("Das Datumsformat ist falsch! Bitte verwenden Sie TT.MM.JJJJ für den letzten Tag deines Urlaubs").queue(); + return; + } + if (toDate == null) { + interactionHook.editOriginal("Das Datumsformat ist falsch! Bitte verwenden Sie TT.MM.JJJJ für den letzten Tag deines Urlaubs").queue(); + return; + } + if (!toDate.isAfter(LocalDateTime.now())) { + interactionHook.editOriginal("Bitte gib ein Datum in der Zukunft an!").queue(); + return; + } + if (!toDate.isAfter(fromDate)) { + interactionHook.editOriginal("Bitte gib ein Datum nach dem ersten Urlaubstag an!").queue(); + return; + } + + guild.createScheduledEvent( + "Urlaub " + event.getMember().getEffectiveName(), + event.getMember().getId(), + OffsetDateTime.of(fromDate, ZoneId.of("Europe/Berlin").getRules().getOffset(fromDate)), + OffsetDateTime.of(toDate, ZoneId.of("Europe/Berlin").getRules().getOffset(toDate)) + ).onSuccess(scheduledEvent -> { + interactionHook.editOriginal("Urlaub erstellt!").queue(); + }) + .onErrorMap(throwable -> { + interactionHook.editOriginal("Urlaub konnte nicht erstellt werden!").queue(); + return null; + }) + .queue(); + } + + private void deleteVacation(SlashCommandInteractionEvent event) { + InteractionHook interactionHook = event.deferReply(true).complete(); + long eventId = event.getOption("vacation").getAsLong(); + ScheduledEvent scheduledEvent = guild.getScheduledEventById(eventId); + if (scheduledEvent == null) { + interactionHook.editOriginal("Konnte den Urlaub nicht finden!").queue(); + return; + } + scheduledEvent.delete() + .onSuccess(unused -> { + interactionHook.editOriginal("Urlaub gelöscht!").queue(); + }) + .onErrorMap(throwable -> { + interactionHook.editOriginal("Urlaub konnte nicht gelöscht werden!").queue(); + return null; + }) + .queue(); + } + + @Override + public void onCommandAutoCompleteInteraction(@NotNull CommandAutoCompleteInteractionEvent event) { + if (!event.getName().equals("vacation")) return; + switch (event.getFocusedOption().getName()) { + case "vacation": + listVacations(event); + break; + default: + break; + } + } + + private void listVacations(CommandAutoCompleteInteractionEvent event) { + String vacation = event.getOption("vacation").getAsString(); + List choices = guild.getScheduledEvents() + .stream() + .filter(scheduledEvent -> scheduledEvent.getLocation().equals(event.getMember().getId())) + .map(scheduledEvent -> { + StringBuilder st = new StringBuilder(); + st.append(String.format("%02d", scheduledEvent.getStartTime().getDayOfMonth())).append("."); + st.append(String.format("%02d", scheduledEvent.getStartTime().getMonth())).append("."); + st.append(scheduledEvent.getStartTime().getYear()); + st.append(" - "); + st.append(String.format("%02d", scheduledEvent.getEndTime().getDayOfMonth())).append("."); + st.append(String.format("%02d", scheduledEvent.getEndTime().getDayOfMonth())).append("."); + st.append(scheduledEvent.getEndTime().getYear()); + return Pair.of(scheduledEvent, st.toString()); + }) + .filter(pair -> pair.right().startsWith(vacation)) + .limit(25) + .map(pair -> { + return new Command.Choice(pair.right(), pair.left().getLocation()); + }) + .collect(Collectors.toList()); + event.replyChoices(choices) + .queue(); + } +} From d14022e69ef06648ffb4433719f019b3a93936c9 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 1 Aug 2025 10:46:54 +0200 Subject: [PATCH 004/214] Fix ChannelListener --- .../steamwar/velocitycore/discord/listeners/ChannelListener.java | 1 + 1 file changed, 1 insertion(+) diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/ChannelListener.java b/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/ChannelListener.java index bebf194c..bfecf313 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/ChannelListener.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/ChannelListener.java @@ -70,6 +70,7 @@ public class ChannelListener extends ListenerAdapter { @Override public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) { + if (event.getGuild().getIdLong() == 1241489896909180998L) return; InteractionReply.reply(event, sender -> { if(sender.user().getDiscordId() == null) return; From 9e629d09a80c90a5d36ea630f8a6597e353cd122 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 1 Aug 2025 10:48:17 +0200 Subject: [PATCH 005/214] Fix VacationCommand --- .../src/de/steamwar/velocitycore/discord/VacationCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/VacationCommand.java b/VelocityCore/src/de/steamwar/velocitycore/discord/VacationCommand.java index ace8dcf6..2c43356c 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/VacationCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/VacationCommand.java @@ -169,11 +169,11 @@ public class VacationCommand extends ListenerAdapter { .map(scheduledEvent -> { StringBuilder st = new StringBuilder(); st.append(String.format("%02d", scheduledEvent.getStartTime().getDayOfMonth())).append("."); - st.append(String.format("%02d", scheduledEvent.getStartTime().getMonth())).append("."); + st.append(String.format("%02d", scheduledEvent.getStartTime().getMonthValue())).append("."); st.append(scheduledEvent.getStartTime().getYear()); st.append(" - "); st.append(String.format("%02d", scheduledEvent.getEndTime().getDayOfMonth())).append("."); - st.append(String.format("%02d", scheduledEvent.getEndTime().getDayOfMonth())).append("."); + st.append(String.format("%02d", scheduledEvent.getEndTime().getMonthValue())).append("."); st.append(scheduledEvent.getEndTime().getYear()); return Pair.of(scheduledEvent, st.toString()); }) From d9681877509654f9730d8e0a3e92a138eb10eda4 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 1 Aug 2025 10:49:28 +0200 Subject: [PATCH 006/214] Fix VacationCommand --- .../src/de/steamwar/velocitycore/discord/VacationCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/VacationCommand.java b/VelocityCore/src/de/steamwar/velocitycore/discord/VacationCommand.java index 2c43356c..f4121468 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/VacationCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/VacationCommand.java @@ -180,7 +180,7 @@ public class VacationCommand extends ListenerAdapter { .filter(pair -> pair.right().startsWith(vacation)) .limit(25) .map(pair -> { - return new Command.Choice(pair.right(), pair.left().getLocation()); + return new Command.Choice(pair.right(), Long.parseLong(pair.left().getLocation())); }) .collect(Collectors.toList()); event.replyChoices(choices) From 01f55c43093f6641d387fafc6a189c99057470ed Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 1 Aug 2025 10:51:17 +0200 Subject: [PATCH 007/214] Fix VacationCommand --- .../de/steamwar/velocitycore/discord/VacationCommand.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/VacationCommand.java b/VelocityCore/src/de/steamwar/velocitycore/discord/VacationCommand.java index f4121468..5be79f9e 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/VacationCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/VacationCommand.java @@ -54,7 +54,7 @@ public class VacationCommand extends ListenerAdapter { .addOptions(new OptionData(OptionType.STRING, "from", "Datum (TT.MM.JJJJ)", true), new OptionData(OptionType.STRING, "to", "Datum (TT.MM.JJJJ)", true))); COMMAND.addSubcommands(new SubcommandData("delete", "Lösche deinen Urlaub") - .addOptions(new OptionData(OptionType.INTEGER, "vacation", "Dein Urlaub", true, true))); + .addOptions(new OptionData(OptionType.STRING, "vacation", "Dein Urlaub", true, true))); } @Override @@ -132,7 +132,7 @@ public class VacationCommand extends ListenerAdapter { private void deleteVacation(SlashCommandInteractionEvent event) { InteractionHook interactionHook = event.deferReply(true).complete(); - long eventId = event.getOption("vacation").getAsLong(); + String eventId = event.getOption("vacation").getAsString(); ScheduledEvent scheduledEvent = guild.getScheduledEventById(eventId); if (scheduledEvent == null) { interactionHook.editOriginal("Konnte den Urlaub nicht finden!").queue(); @@ -180,7 +180,7 @@ public class VacationCommand extends ListenerAdapter { .filter(pair -> pair.right().startsWith(vacation)) .limit(25) .map(pair -> { - return new Command.Choice(pair.right(), Long.parseLong(pair.left().getLocation())); + return new Command.Choice(pair.right(), pair.left().getId()); }) .collect(Collectors.toList()); event.replyChoices(choices) From 3a13fc7bb92e080a4cd6c388596c3b18d1d1ee9e Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 1 Aug 2025 17:51:19 +0200 Subject: [PATCH 008/214] Reduce MAX_BLOCKS of SelectAdjacent --- .../steamwar/bausystem/features/worldedit/SelectAdjacent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/SelectAdjacent.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/SelectAdjacent.java index 9afcd59e..c92b5aa2 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/SelectAdjacent.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/SelectAdjacent.java @@ -97,7 +97,7 @@ public class SelectAdjacent implements Listener { private class Selector { - private static final int MAX_BLOCKS = 1_000_000; + private static final int MAX_BLOCKS = 100_000; private int minX; private int minY; From 2166096ba55af0bc8c4773e48c680b1e980c076e Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 1 Aug 2025 21:17:58 +0200 Subject: [PATCH 009/214] Fix PistonCalculator --- .../steamwar/bausystem/features/util/PistonCalculator.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculator.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculator.java index 4479ff63..6bf9b0c9 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculator.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculator.java @@ -55,8 +55,9 @@ public class PistonCalculator implements Listener { public void onPlayerInteract(PlayerInteractEvent event) { if (!Permission.BUILD.hasPermission(event.getPlayer())) return; if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return; - if (event.hasItem() && event.getItem().getType() == Material.SLIME_BALL) { - } else if (event.hasItem()) return; + if (event.getItem() == null) {} + else if (event.getItem() != null && event.getItem().getType() == Material.SLIME_BALL) {} + else return; if (event.getClickedBlock() == null) return; Block clickedBlock = event.getClickedBlock(); Material blockType = clickedBlock.getType(); From 70d0f179ccd0851700e510d2ce9f57a8db64a70d Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 2 Aug 2025 11:34:41 +0200 Subject: [PATCH 010/214] Fix stuff in DiscordBot --- .../velocitycore/discord/DiscordBot.java | 49 ++++++------------- 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java index 53714c52..68d5d316 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java @@ -41,7 +41,6 @@ import net.dv8tion.jda.api.entities.Role; import net.dv8tion.jda.api.entities.emoji.Emoji; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.exceptions.ErrorResponseException; -import net.dv8tion.jda.api.interactions.commands.Command; import net.dv8tion.jda.api.interactions.commands.OptionType; import net.dv8tion.jda.api.interactions.commands.build.CommandData; import net.dv8tion.jda.api.interactions.commands.build.Commands; @@ -49,13 +48,14 @@ import net.dv8tion.jda.api.interactions.commands.build.OptionData; import net.dv8tion.jda.api.interactions.components.ActionRow; import net.dv8tion.jda.api.interactions.components.buttons.Button; import net.dv8tion.jda.api.requests.GatewayIntent; -import net.dv8tion.jda.api.requests.restaction.CommandListUpdateAction; import net.dv8tion.jda.api.utils.MemberCachePolicy; import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; import java.awt.*; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; @@ -67,9 +67,10 @@ public class DiscordBot { @Getter private static final Map commands = new HashMap<>(); + private final OptionData commandArgument = new OptionData(OptionType.STRING, ARGUMENT_NAME, "Command arguments", false); public static void withBot(Consumer consumer) { - if(instance != null) + if (instance != null) consumer.accept(instance); } @@ -141,7 +142,7 @@ public class DiscordBot { ActionRow.of(Button.link("https://steamwar.de", "Website"), Button.link("https://steamwar.de/youtube", "YouTube")), ActionRow.of(Button.primary("auth", Emoji.fromUnicode("U+2705")).withLabel("Minecraft verknüpfen")) ), event -> { - if(event.getComponentId().equals("auth")) + if (event.getComponentId().equals("auth")) event.reply("Gebe innerhalb der nächsten 10 Minuten ``/verify " + AuthManager.createDiscordAuthToken(event.getUser()) + "`` auf dem Minecraft Server ein").setEphemeral(true).queue(); }); List actionRows = new ArrayList<>(); @@ -202,42 +203,24 @@ public class DiscordBot { vacationCommand ); - commandSetup(jda.retrieveCommands().complete(), jda.updateCommands()); + jda.updateCommands() + .addCommands(commands.keySet() + .stream() + .filter(command -> command.matches("^[\\w-]+$")) + .map(command -> Commands.slash(command, command).addOptions(commandArgument)) + .toArray(CommandData[]::new)) + .queue(); + jda.getGuildById(690530484920385586L).updateCommands().queue(); jda.getGuildById(1241489896909180998L) .upsertCommand(vacationCommand.COMMAND) .queue(); } - private final OptionData commandArgument = new OptionData(OptionType.STRING, ARGUMENT_NAME, "Command arguments", false); - private void commandSetup(List existing, CommandListUpdateAction updateCommands) { - Set correctCommands = new HashSet<>(); - for(Command command : existing) { - if(!commands.containsKey(command.getName())) { - command.delete().complete(); - continue; - } - - List options = command.getOptions(); - if(options.size() != 1 || options.get(0).getType() != OptionType.STRING) - command.editCommand().clearOptions().addOptions(commandArgument).complete(); - - correctCommands.add(command.getName()); - } - - updateCommands - .addCommands(commands - .keySet().stream() - .filter(command -> !correctCommands.contains(command)) - .filter(command -> command.matches("^[\\w-]+$")) - .map(command -> Commands.slash(command, command).addOptions(commandArgument)) - .toArray(CommandData[]::new)) - .queue(); - } - private boolean activityToggle = false; + private void activity() { - if(activityToggle) { + if (activityToggle) { Event event = Event.get(); jda.getPresence().setActivity(event != null ? Activity.competing("dem Event " + event.getEventName()) : Activity.playing("auf SteamWar.de")); } else { From 018b9a971f62ea37b1755ec55087134bcf022460 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 2 Aug 2025 11:36:08 +0200 Subject: [PATCH 011/214] Fix stuff in DiscordBot --- .../src/de/steamwar/velocitycore/discord/DiscordBot.java | 1 - 1 file changed, 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java index 68d5d316..e2930bb6 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java @@ -210,7 +210,6 @@ public class DiscordBot { .map(command -> Commands.slash(command, command).addOptions(commandArgument)) .toArray(CommandData[]::new)) .queue(); - jda.getGuildById(690530484920385586L).updateCommands().queue(); jda.getGuildById(1241489896909180998L) .upsertCommand(vacationCommand.COMMAND) From 2e91a5a582b4e07f38dedc970e4ba90158cef3b1 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 2 Aug 2025 11:42:39 +0200 Subject: [PATCH 012/214] Trigger rebuild --- .../src/de/steamwar/velocitycore/discord/DiscordBot.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java index e2930bb6..ae9decbd 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java @@ -131,6 +131,7 @@ public class DiscordBot { reply.system("DC_ROLE_ADDED", role.getAsMention()); } })); + new StaticMessageChannel(config.channel("rules"), () -> new MessageCreateBuilder() .setEmbeds(new EmbedBuilder() .setDescription(String.join("\n", config.getRules())) @@ -145,6 +146,7 @@ public class DiscordBot { if (event.getComponentId().equals("auth")) event.reply("Gebe innerhalb der nächsten 10 Minuten ``/verify " + AuthManager.createDiscordAuthToken(event.getUser()) + "`` auf dem Minecraft Server ein").setEphemeral(true).queue(); }); + List actionRows = new ArrayList<>(); List