diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index f277ba1c..e9f4d842 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -129,8 +129,12 @@ jobs: ssh-keyscan -p "$port" "$DEPLOY_HOST" >> ~/.ssh/known_hosts ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "mkdir -p '$DEPLOY_PATH'" - ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "rm -f '$DEPLOY_PATH/*'" - scp -i ~/.ssh/deploy_key -P "$port" deploy/* "${DEPLOY_USER}@${DEPLOY_HOST}:$DEPLOY_PATH/" + ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "mkdir -p '$DEPLOY_PATH/upload'" + scp -i ~/.ssh/deploy_key -P "$port" deploy/* "${DEPLOY_USER}@${DEPLOY_HOST}:$DEPLOY_PATH/upload" + ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "rm -f '$DEPLOY_PATH'/*.jar '$DEPLOY_PATH'/*.zip" + ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "mv '$DEPLOY_PATH'/upload/* '$DEPLOY_PATH'" + ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "rm -r '$DEPLOY_PATH/upload'" + ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "chmod o-w '$DEPLOY_PATH'/*" - name: Restart Services shell: bash env: diff --git a/.idea/runConfigurations/Remote_JVM_Debugger.xml b/.idea/runConfigurations/Remote_JVM_Debugger.xml new file mode 100644 index 00000000..d7e6e149 --- /dev/null +++ b/.idea/runConfigurations/Remote_JVM_Debugger.xml @@ -0,0 +1,15 @@ + + + + \ No newline at end of file diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java index a59a0206..c557f95f 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java @@ -80,7 +80,7 @@ public class SimulatorCursor implements Listener { } public SimulatorCursor() { - BiFunction function = (player, object) -> { + BiFunction function = (player, object) -> { calcCursor(player); return object; }; diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/BlockBoundingBox.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/BlockBoundingBox.java index 12636ba9..0df055af 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/BlockBoundingBox.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/BlockBoundingBox.java @@ -21,7 +21,6 @@ package de.steamwar.bausystem.features.slaves.laufbau; import com.sk89q.worldedit.blocks.SkullBlock; import com.sk89q.worldedit.world.block.BaseBlock; -import de.steamwar.bausystem.utils.NMSWrapper; import de.steamwar.inventory.SWItem; import lombok.Getter; import lombok.ToString; @@ -99,7 +98,7 @@ public class BlockBoundingBox { // addPixel(Material.COBWEB.createBlockData(), 0, 0, 0, 0, 0, 0, createItem("LAUFBAU_BLOCK_COBWEB", Material.COBWEB)); addPixel(Material.END_STONE.createBlockData(), 0, 0, 0, 16, 16, 16, null); - addPixel(NMSWrapper.impl.pathMaterial().createBlockData(), 0, 0, 0, 16, 15, 16, createItem("LAUFBAU_BLOCK_GRASS_PATH", NMSWrapper.impl.pathMaterial())); + addPixel(Material.DIRT_PATH.createBlockData(), 0, 0, 0, 16, 15, 16, createItem("LAUFBAU_BLOCK_GRASS_PATH", Material.DIRT_PATH)); addPixel(Material.MUD.createBlockData(), 0, 0, 0, 16, 14, 16, createItem("LAUFBAU_BLOCK_SOUL_SAND", Material.SOUL_SAND)); Cocoa cocoaNorth = (Cocoa) Material.COCOA.createBlockData(); diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/NoClipCommand.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/NoClipCommand.java index 36829c3b..0b10e163 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/NoClipCommand.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/NoClipCommand.java @@ -21,17 +21,22 @@ package de.steamwar.bausystem.features.util; import com.comphenix.tinyprotocol.TinyProtocol; import com.mojang.authlib.GameProfile; +import de.steamwar.Reflection; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.features.tpslimit.TPSUtils; import de.steamwar.bausystem.utils.BauMemberUpdateEvent; -import de.steamwar.bausystem.utils.NMSWrapper; import de.steamwar.command.SWCommand; import de.steamwar.core.ProtocolWrapper; import de.steamwar.core.SWPlayer; import de.steamwar.linkage.Linked; import net.minecraft.network.protocol.game.*; +import net.minecraft.server.level.ServerPlayerGameMode; +import net.minecraft.world.entity.player.Abilities; +import net.minecraft.world.level.GameType; import org.bukkit.Bukkit; import org.bukkit.GameMode; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -57,11 +62,11 @@ public class NoClipCommand extends SWCommand implements Listener { public NoClipCommand() { super("noclip", "nc"); - BiFunction first = (player, o) -> { + BiFunction first = (player, o) -> { NoClipData noClipData = SWPlayer.of(player).getComponent(NoClipData.class).orElse(null); if (noClipData == null) return o; if (noClipData.lastTick == TPSUtils.currentTick.get()) return o; - NMSWrapper.impl.setInternalGameMode(player, GameMode.SPECTATOR); + setInternalGameMode(player, GameMode.SPECTATOR); noClipData.lastTick = TPSUtils.currentTick.get(); return o; }; @@ -71,7 +76,7 @@ public class NoClipCommand extends SWCommand implements Listener { BiFunction second = (player, o) -> { NoClipData noClipData = SWPlayer.of(player).getComponent(NoClipData.class).orElse(null); if (noClipData == null) return o; - NMSWrapper.impl.setInternalGameMode(player, GameMode.CREATIVE); + setInternalGameMode(player, GameMode.CREATIVE); noClipData.lastTick = TPSUtils.currentTick.get(); return o; }; @@ -79,15 +84,31 @@ public class NoClipCommand extends SWCommand implements Listener { TinyProtocol.instance.addFilter(ServerboundPlayerActionPacket.class, second); TinyProtocol.instance.addFilter(ServerboundContainerClickPacket.class, second); - BiFunction third = (player, o) -> { + BiFunction third = (player, o) -> { if (SWPlayer.of(player).hasComponent(NoClipData.class)) { - NMSWrapper.impl.setSlotToItemStack(player, o); + int index = o.slotNum(); + if (index >= 36 && index <= 44) { + index -= 36; + } else if (index > 44) { + index -= 5; + } else if (index <= 8) { + index = index - 8 + 36; + } + player.getInventory().setItem(index, CraftItemStack.asBukkitCopy(o.itemStack())); + if (index < 9) player.getInventory().setHeldItemSlot(index); + player.updateInventory(); } return o; }; TinyProtocol.instance.addFilter(ServerboundSetCreativeModeSlotPacket.class, third); } + private static final Reflection.Field playerGameMode = Reflection.getField(ServerPlayerGameMode.class, GameType.class, 0); + + private void setInternalGameMode(Player player, GameMode gameMode) { + playerGameMode.set(((CraftPlayer) player).getHandle().gameMode, GameType.byId(gameMode.getValue())); + } + @Register(help = true) public void genericCommand(@Validator Player player) { SWPlayer swPlayer = SWPlayer.of(player); @@ -95,7 +116,9 @@ public class NoClipCommand extends SWCommand implements Listener { swPlayer.removeComponent(NoClipData.class); } else { player.setGameMode(GameMode.SPECTATOR); - NMSWrapper.impl.setPlayerBuildAbilities(player); + Abilities abilities = (((CraftPlayer) player).getHandle()).getAbilities(); + abilities.mayBuild = true; + abilities.mayfly = true; swPlayer.setComponent(new NoClipData()); BauSystem.MESSAGE.send("OTHER_NOCLIP_SLOT_INFO", player); diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/world/InventoryListener.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/world/InventoryListener.java index edc9f9c2..964f50e6 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/world/InventoryListener.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/world/InventoryListener.java @@ -19,8 +19,9 @@ package de.steamwar.bausystem.features.world; -import de.steamwar.bausystem.utils.NMSWrapper; import de.steamwar.linkage.Linked; +import io.papermc.paper.datacomponent.DataComponentTypes; +import io.papermc.paper.datacomponent.item.ItemContainerContents; import org.bukkit.attribute.Attribute; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; @@ -32,6 +33,8 @@ import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import java.util.List; + @Linked public class InventoryListener implements Listener { @@ -57,7 +60,7 @@ public class InventoryListener implements Listener { } stack.setItemMeta(meta); } - if (NMSWrapper.impl.checkItemStack(stack)) { + if (checkItemStack(stack)) { e.setCurrentItem(null); e.setCancelled(true); return; @@ -73,7 +76,7 @@ public class InventoryListener implements Listener { for (int i = 0; i < content.length; i++) { if (content[i] == null) continue; int finalI = i; - if (NMSWrapper.impl.checkItemStack(content[finalI])) { + if (checkItemStack(content[finalI])) { p.getInventory().setItem(i, null); } } @@ -82,11 +85,44 @@ public class InventoryListener implements Listener { @EventHandler(ignoreCancelled = true) public void onBlockPlace(BlockPlaceEvent event) { Player p = event.getPlayer(); - if (NMSWrapper.impl.checkItemStack(event.getItemInHand())) { + if (checkItemStack(event.getItemInHand())) { event.setCancelled(true); event.setBuild(false); p.getInventory().setItemInMainHand(null); p.getInventory().setItemInOffHand(null); } } + + private static final int threshold = 2048; + + private boolean checkItemStack(ItemStack item) { + ItemContainerContents data = item.getData(DataComponentTypes.CONTAINER); + if (data == null) { + return false; + } + + return drillDown(data.contents(), 0, 0) > threshold; + } + + private int drillDown(List items, int layer, int start) { + if (layer > 2) return start + threshold; + int invalid = start; + for (int i = start; i < items.size(); i++) { + ItemStack item = items.get(i); + if (item.isEmpty()) continue; + + invalid += item.getAmount(); + + ItemContainerContents data = item.getData(DataComponentTypes.CONTAINER); + if (data == null) { + continue; + } + + List subItems = data.contents(); + if (subItems.size() > 1) { + invalid = drillDown(subItems, layer + 1, invalid); + } + } + return invalid; + } } diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/world/NoCreativeKnockback.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/world/NoCreativeKnockback.java index 2debf84e..55b7b0f4 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/world/NoCreativeKnockback.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/world/NoCreativeKnockback.java @@ -20,18 +20,24 @@ package de.steamwar.bausystem.features.world; import com.comphenix.tinyprotocol.TinyProtocol; -import de.steamwar.bausystem.utils.NMSWrapper; import de.steamwar.linkage.Linked; import net.minecraft.network.protocol.game.ClientboundExplodePacket; import org.bukkit.GameMode; +import java.util.Optional; + @Linked public class NoCreativeKnockback { public NoCreativeKnockback() { TinyProtocol.instance.addFilter(ClientboundExplodePacket.class, (player, o) -> { if (player.getGameMode() != GameMode.CREATIVE) return o; - return NMSWrapper.impl.resetExplosionKnockback(o); + return new ClientboundExplodePacket( + o.center(), + Optional.empty(), + o.explosionParticle(), + o.explosionSound() + ); }); } } diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEdit.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEdit.java index 95f0a337..5fcbcbf5 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEdit.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEdit.java @@ -101,7 +101,7 @@ public class SignEdit implements Listener { } { - TinyProtocol.instance.addTypedFilter(ServerboundSignUpdatePacket.class, (player, o) -> { + TinyProtocol.instance.addFilter(ServerboundSignUpdatePacket.class, (player, o) -> { Bukkit.getScheduler().runTask(BauSystem.getInstance(), () -> { ServerLevel serverLevel = ((CraftWorld) player.getWorld()).getHandle(); Block signLoc = CraftBlock.at(serverLevel, o.getPos()); diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/xray/XrayCommand.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/xray/XrayCommand.java index a5fae7cb..1ddfe6f7 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/xray/XrayCommand.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/xray/XrayCommand.java @@ -114,8 +114,8 @@ public class XrayCommand extends SWCommand implements Listener, ScoreboardElemen return packet; }; - TinyProtocol.instance.addTypedFilter(ServerboundMovePlayerPacket.Pos.class, positionSetter); - TinyProtocol.instance.addTypedFilter(ServerboundMovePlayerPacket.PosRot.class, positionSetter); + TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.Pos.class, positionSetter); + TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.PosRot.class, positionSetter); } @EventHandler diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/NMSWrapper.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/NMSWrapper.java deleted file mode 100644 index 7141ff96..00000000 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/NMSWrapper.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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.bausystem.utils; - -import de.steamwar.Reflection; -import io.papermc.paper.datacomponent.DataComponentTypes; -import io.papermc.paper.datacomponent.item.ItemContainerContents; -import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; -import net.minecraft.network.protocol.game.ClientboundExplodePacket; -import net.minecraft.server.level.ServerPlayerGameMode; -import net.minecraft.world.entity.player.Abilities; -import net.minecraft.world.level.GameType; -import org.bukkit.GameMode; -import org.bukkit.Material; -import org.bukkit.craftbukkit.entity.CraftPlayer; -import org.bukkit.craftbukkit.inventory.CraftItemStack; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import java.util.List; -import java.util.Optional; - -public class NMSWrapper { - public static final NMSWrapper impl = new NMSWrapper(); - - private static final Reflection.Field playerGameMode = Reflection.getField(ServerPlayerGameMode.class, GameType.class, 0); - - public void setInternalGameMode(Player player, GameMode gameMode) { - playerGameMode.set(((CraftPlayer) player).getHandle().gameMode, GameType.byId(gameMode.getValue())); - } - - public void setSlotToItemStack(Player player, Object o) { - ClientboundContainerSetSlotPacket packetPlayInSetCreativeSlot = (ClientboundContainerSetSlotPacket) o; - int index = packetPlayInSetCreativeSlot.getSlot(); - if (index >= 36 && index <= 44) { - index -= 36; - } else if (index > 44) { - index -= 5; - } else if (index <= 8) { - index = index - 8 + 36; - } - player.getInventory().setItem(index, CraftItemStack.asBukkitCopy(packetPlayInSetCreativeSlot.getItem())); - if (index < 9) player.getInventory().setHeldItemSlot(index); - player.updateInventory(); - } - - public void setPlayerBuildAbilities(Player player) { - Abilities abilities = (((CraftPlayer) player).getHandle()).getAbilities(); - abilities.mayBuild = true; - abilities.mayfly = true; - } - - public Material pathMaterial() { - return Material.DIRT_PATH; - } - - private static final int threshold = 2048; - - public boolean checkItemStack(ItemStack item) { - ItemContainerContents data = item.getData(DataComponentTypes.CONTAINER); - if (data == null) { - return false; - } - - return drillDown(data.contents(), 0, 0) > threshold; - } - - private int drillDown(List items, int layer, int start) { - if (layer > 2) return start + threshold; - int invalid = start; - for (int i = start; i < items.size(); i++) { - ItemStack item = items.get(i); - if (item.isEmpty()) continue; - - invalid += item.getAmount(); - - ItemContainerContents data = item.getData(DataComponentTypes.CONTAINER); - if (data == null) { - continue; - } - - List subItems = data.contents(); - if (subItems.size() > 1) { - invalid = drillDown(subItems, layer + 1, invalid); - } - } - return invalid; - } - - public Object resetExplosionKnockback(Object packet) { - ClientboundExplodePacket explosion = (ClientboundExplodePacket) packet; - - return new ClientboundExplodePacket( - explosion.center(), - Optional.empty(), - explosion.explosionParticle(), - explosion.explosionSound() - ); - } -} diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/TickManager.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/TickManager.java index 086999e3..59d12df2 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/TickManager.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/utils/TickManager.java @@ -42,7 +42,7 @@ public class TickManager implements Listener { TinyProtocol.instance.addFilter(ClientboundTickingStatePacket.class, this::blockPacket); } - private Object blockPacket(Player player, Object packet) { + private Object blockPacket(Player player, ClientboundTickingStatePacket packet) { if (blockTpsPacket) { return new ClientboundTickingStatePacket(20, manager.isFrozen()); } else { diff --git a/BauSystem/build.gradle.kts b/BauSystem/build.gradle.kts index 574ee012..de9fe1b8 100644 --- a/BauSystem/build.gradle.kts +++ b/BauSystem/build.gradle.kts @@ -31,15 +31,6 @@ dependencies { implementation(project(":BauSystem:BauSystem_Main")) } -tasks.register("DevBau20") { - group = "run" - description = "Run a 1.20 Dev Bau" - dependsOn(":SpigotCore:shadowJar") - dependsOn(":BauSystem:shadowJar") - dependsOn(":SchematicSystem:shadowJar") - template = "Bau20" -} - tasks.register("DevBau21") { group = "run" description = "Run a 1.21 Dev Bau" diff --git a/CommonCore/SQL/src/de/steamwar/sql/GameModeConfig.java b/CommonCore/SQL/src/de/steamwar/sql/GameModeConfig.java index e2106380..f8b27f59 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/GameModeConfig.java +++ b/CommonCore/SQL/src/de/steamwar/sql/GameModeConfig.java @@ -411,7 +411,7 @@ public final class GameModeConfig { } @ToString - public static final class ArenaConfig { + public static final class ArenaConfig { public final boolean loaded; @@ -461,11 +461,11 @@ public final class GameModeConfig { public final boolean DisableSnowMelt; /** - * Disable ice forming + * Disable the forming of certain blocks * - * @implSpec {@code false} by default + * @implSpec {@code empty} by default */ - public final boolean DisableIceForm; + public final Set DisabledBlockForms; /** * Allow leaving the arena area as spectator @@ -488,7 +488,7 @@ public final class GameModeConfig { */ public final boolean NoFloor; - private ArenaConfig(YMLWrapper loader, SchematicConfig.SizeConfig Size, List EnterStages) { + private ArenaConfig(YMLWrapper loader, SchematicConfig.SizeConfig Size, List EnterStages) { loaded = loader.canLoad(); WaterDepth = loader.getInt("WaterDepth", 0); WaterDamage = loader.getBoolean("WaterDamage", true); @@ -497,7 +497,11 @@ public final class GameModeConfig { BorderFromSchematic = loader.getInt("BorderFromSchematic", 21); GroundWalkable = loader.getBoolean("GroundWalkable", true); DisableSnowMelt = loader.getBoolean("DisableSnowMelt", false); - DisableIceForm = loader.getBoolean("DisableIceForm", false); + Set disabledBlockForms = new HashSet<>(loader.getMaterialList("DisabledBlockForms")); + if (loader.getBoolean("DisableIceForm", false)) { + disabledBlockForms.add(loader.materialMapper.apply("ICE")); + } + DisabledBlockForms = Collections.unmodifiableSet(disabledBlockForms); Leaveable = loader.getBoolean("Leaveable", false); AllowMissiles = loader.getBoolean("AllowMissiles", !EnterStages.isEmpty()); NoFloor = loader.getBoolean("NoFloor", false); diff --git a/CommonCore/SQL/src/de/steamwar/sql/SchematicNode.kt b/CommonCore/SQL/src/de/steamwar/sql/SchematicNode.kt index 0dde368b..860aeebd 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/SchematicNode.kt +++ b/CommonCore/SQL/src/de/steamwar/sql/SchematicNode.kt @@ -434,7 +434,7 @@ class SchematicNode(id: EntityID) : IntEntity(id) { private var nodeItem by SchematicNodeTable.item var item: String get() = nodeItem.ifEmpty { - if (isDir()) "CHEST" else "CAULDRON_ITEM" + if (isDir()) "CHEST" else "CAULDRON" } set(value) = useDb { nodeItem = value diff --git a/CommonCore/SQL/src/de/steamwar/sql/SteamwarUser.kt b/CommonCore/SQL/src/de/steamwar/sql/SteamwarUser.kt index a5572bcc..0d19c712 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/SteamwarUser.kt +++ b/CommonCore/SQL/src/de/steamwar/sql/SteamwarUser.kt @@ -25,6 +25,7 @@ import org.jetbrains.exposed.v1.core.dao.id.EntityID import org.jetbrains.exposed.v1.core.dao.id.IntIdTable import org.jetbrains.exposed.v1.core.eq import org.jetbrains.exposed.v1.core.inList +import org.jetbrains.exposed.v1.core.neq import org.jetbrains.exposed.v1.dao.IntEntity import org.jetbrains.exposed.v1.dao.IntEntityClass import org.jetbrains.exposed.v1.jdbc.insert @@ -136,6 +137,12 @@ class SteamwarUser(id: EntityID) : IntEntity(id) { .select(SteamwarUserTable.fields).where { UserPermTable.perm eq perm }.map { wrapRow(it) } } + @JvmStatic + fun getUsersWithDiscordId() = + useDb { + find { SteamwarUserTable.discordId neq null }.toList() + } + @JvmStatic fun getServerTeam() = useDb { @@ -175,6 +182,9 @@ class SteamwarUser(id: EntityID) : IntEntity(id) { leaderInternal = false } + fun hasTeam() = + team != 0 + private var leaderInternal by SteamwarUserTable.leader var leader: Boolean get() = leaderInternal diff --git a/CommonCore/SQL/src/de/steamwar/sql/UserPerm.kt b/CommonCore/SQL/src/de/steamwar/sql/UserPerm.kt index e22126a9..43ba0696 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/UserPerm.kt +++ b/CommonCore/SQL/src/de/steamwar/sql/UserPerm.kt @@ -63,11 +63,11 @@ enum class UserPerm { PREFIX_NONE to emptyPrefix, PREFIX_YOUTUBER to Prefix("§x§8§A§2§B§E§5", "CC"), // 8A2BE5 PREFIX_GUIDE to Prefix("§x§e§7§6§2§e§d", "Guide"), // E762ED - PREFIX_SUPPORTER to Prefix("§x§6§0§9§5§F§B", "Sup"), // 6095FB - PREFIX_MODERATOR to Prefix("§x§F§F§A§2§5§C", "Mod"), // FFA25C - PREFIX_BUILDER to Prefix("§x§6§0§F§F§6§A", "Arch"), // 60FF6A - PREFIX_DEVELOPER to Prefix("§x§0§B§B§C§B§3", "Dev"), // 0BBCB3 - PREFIX_ADMIN to Prefix("§x§F§F§2§B§2§4", "Admin"), // FF2B24 + PREFIX_SUPPORTER to Prefix("§x§6§0§9§5§F§B", "Sup", true), // 6095FB + PREFIX_MODERATOR to Prefix("§x§F§F§A§2§5§C", "Mod", true), // FFA25C + PREFIX_BUILDER to Prefix("§x§6§0§F§F§6§A", "Arch", true), // 60FF6A + PREFIX_DEVELOPER to Prefix("§x§0§B§B§C§B§3", "Dev", true), // 0BBCB3 + PREFIX_ADMIN to Prefix("§x§F§F§2§B§2§4", "Admin", true), // FF2B24 ) @JvmStatic @@ -94,5 +94,5 @@ enum class UserPerm { } } - data class Prefix(val colorCode: String, val chatPrefix: String) + data class Prefix(val colorCode: String, val chatPrefix: String, val teamPrefix: Boolean = false) } \ No newline at end of file diff --git a/FightSystem/FightSystem_Core/src/config.yml b/FightSystem/FightSystem_Core/src/config.yml index 46267a72..81620820 100644 --- a/FightSystem/FightSystem_Core/src/config.yml +++ b/FightSystem/FightSystem_Core/src/config.yml @@ -48,6 +48,16 @@ Arena: GroundWalkable: true # defaults to true if missing # Disable snow and ice melting DisableSnowMelt: false # defaults to false if missing + # Disabled blocks from forming + DisabledBlockForms: + # For Cobble Generators + # - COBBLESTONE + # - BASALT + # - STONE + # - OBSIDIAN + # Disable ice specifically from forming + # Deprecated, add ICE to DisabledBlockForms list instead + DisableIceForm: false # Allow leaving the arena area as spectator Leaveable: false # defaults to false if missing # Allow missiles to fly to the enemy and not stop at the schem border. diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java index 1c348b4b..be822c7c 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java @@ -41,6 +41,9 @@ import de.steamwar.sql.SchematicNode; import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.GameRule; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerPickupArrowEvent; import org.bukkit.plugin.java.JavaPlugin; public class FightSystem extends JavaPlugin { @@ -95,7 +98,12 @@ public class FightSystem extends JavaPlugin { getMessage().broadcast("PISTON_PUSHED_OUTSIDE"); shutdown(); }); - new StateDependentListener(ArenaMode.All, FightState.All, BountifulWrapper.impl.newDenyArrowPickupListener()); + new StateDependentListener(ArenaMode.All, FightState.All, new Listener() { + @EventHandler + public void onArrowPickup(PlayerPickupArrowEvent e) { + if (Fight.fighting(e.getPlayer())) e.setCancelled(true); + } + }); new OneShotStateDependent(ArenaMode.All, FightState.PreSchemSetup, () -> Fight.playSound(SWSound.BLOCK_NOTE_PLING.getSound(), 100.0f, 2.0f)); new OneShotStateDependent(ArenaMode.Test, FightState.All, WorldEditRendererCUIEditor::new); Config.world.setGameRule(GameRule.REDUCED_DEBUG_INFO, ArenaMode.AntiTest.contains(Config.mode)); @@ -121,7 +129,7 @@ public class FightSystem extends JavaPlugin { Fight.getUnrotated().setSchem(SchematicNode.getSchematicNode(Config.PrepareSchemID)); } - CraftbukkitWrapper.impl.setupGamerule(); + Config.world.setGameRule(GameRule.LOCATOR_BAR, false); } @Override diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/TPSWarpCommand.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/TPSWarpCommand.java index e6755bb9..6ec55acd 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/TPSWarpCommand.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/TPSWarpCommand.java @@ -21,8 +21,8 @@ import de.steamwar.fightsystem.ArenaMode; import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.StateDependentCommand; -import de.steamwar.fightsystem.utils.TpsWarper; import de.steamwar.linkage.Linked; +import net.minecraft.server.MinecraftServer; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -45,8 +45,7 @@ public class TPSWarpCommand implements CommandExecutor { return false; } - TpsWarper warper = TpsWarper.impl; - warper.warp(tps); + MinecraftServer.getServer().tickRateManager().setTickRate(tps); FightSystem.getMessage().broadcastActionbar("TPSWARP_SET", tps); return false; diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java index 78dff55b..a8cddb3a 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java @@ -44,6 +44,8 @@ import de.steamwar.sql.SteamwarUser; import lombok.Getter; import net.md_5.bungee.api.ChatMessageType; import org.bukkit.*; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeInstance; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.scoreboard.NameTagVisibility; @@ -151,8 +153,8 @@ public class FightTeam { new TeamArea(this); team = FightScoreboard.getBukkitTeam(name); - WorldOfColorWrapper.impl.setTeamColor(team, color); - BountifulWrapper.impl.setNametagVisibility(team); + team.setColor(color); + team.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.FOR_OWN_TEAM); team.setNameTagVisibility(NameTagVisibility.HIDE_FOR_OTHER_TEAMS); if (!Config.GameModeConfig.WinConditions.contains(Winconditions.AMONG_US)) { team.setAllowFriendlyFire(false); @@ -284,7 +286,8 @@ public class FightTeam { entity.teleport(spawn); fightPlayer.ifPlayer(player -> { - BountifulWrapper.impl.setAttackSpeed(player); + AttributeInstance attribute = player.getAttribute(Attribute.ATTACK_SPEED); + attribute.setBaseValue(16); player.setFoodLevel(20); player.getInventory().clear(); FightSystem.getHullHider().updatePlayer(player); diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightWorld.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightWorld.java index e978f038..5663fe33 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightWorld.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightWorld.java @@ -26,7 +26,6 @@ import de.steamwar.fightsystem.listener.Recording; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.StateDependent; import de.steamwar.fightsystem.utils.CraftbukkitWrapper; -import de.steamwar.fightsystem.utils.FlatteningWrapper; import de.steamwar.linkage.Linked; import lombok.Getter; import org.bukkit.Bukkit; @@ -64,7 +63,7 @@ public class FightWorld extends StateDependent { public static void forceLoad() { Config.ArenaRegion.forEachChunk((cX, cZ) -> { Config.world.loadChunk(cX, cZ); - FlatteningWrapper.impl.forceLoadChunk(Config.world, cX, cZ); + Config.world.setChunkForceLoaded(cX, cZ, true); }); } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FreezeWorld.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FreezeWorld.java index e120d234..71c579bd 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FreezeWorld.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FreezeWorld.java @@ -20,7 +20,6 @@ package de.steamwar.fightsystem.fight; import de.steamwar.fightsystem.FightSystem; -import de.steamwar.fightsystem.utils.BountifulWrapper; import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -30,19 +29,16 @@ import org.bukkit.event.block.*; import org.bukkit.event.entity.ItemSpawnEvent; import org.bukkit.event.inventory.InventoryMoveItemEvent; import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerSwapHandItemsEvent; public class FreezeWorld implements Listener { - private final Listener denyHandSwap = BountifulWrapper.impl.newDenyHandSwapListener(); - public FreezeWorld() { Bukkit.getPluginManager().registerEvents(this, FightSystem.getPlugin()); - Bukkit.getPluginManager().registerEvents(denyHandSwap, FightSystem.getPlugin()); } public void disable() { HandlerList.unregisterAll(this); - HandlerList.unregisterAll(denyHandSwap); } @EventHandler @@ -94,4 +90,9 @@ public class FreezeWorld implements Listener { public void handlePlayerInteract(PlayerInteractEvent event) { event.setCancelled(true); } + + @EventHandler + public void onSwapItems(PlayerSwapHandItemsEvent event) { + if (Fight.fighting(event.getPlayer())) event.setCancelled(true); + } } 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 672ab18c..a6844252 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/Kit.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/Kit.java @@ -24,12 +24,12 @@ 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.FlatteningWrapper; -import de.steamwar.fightsystem.utils.ReflectionWrapper; import de.steamwar.inventory.SWInventory; import de.steamwar.inventory.SWItem; import de.steamwar.sql.PersonalKit; import de.steamwar.sql.SteamwarUser; +import io.papermc.paper.datacomponent.DataComponentType; +import io.papermc.paper.datacomponent.DataComponentTypes; import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -39,6 +39,7 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BlockDataMeta; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.potion.PotionEffect; @@ -193,13 +194,13 @@ public class Kit { if (Config.GameModeConfig.Kits.ForbiddenItems.contains(stack.getType())) return true; //Check for attribute modifiers - if (FlatteningWrapper.impl.hasAttributeModifier(stack)) { + if (stack.hasItemMeta() && stack.getItemMeta() != null && stack.getItemMeta().hasAttributeModifiers()) { return true; } if (stack.hasItemMeta()) { ItemMeta meta = stack.getItemMeta(); - if (FlatteningWrapper.impl.containsBlockMeta(meta)) return true; //Blocks always upwards slabs etc. + if (meta instanceof BlockDataMeta && ((BlockDataMeta) meta).hasBlockData()) return true; //Blocks always upwards slabs etc. if (hasItems(stack)) return true; //Blocks prefilled inventories } @@ -208,8 +209,42 @@ public class Kit { return !normal.isEnchantmentInKit(stack) && !stack.getEnchantments().isEmpty(); } + private static final Set FORBIDDEN_TYPES = new HashSet<>(); + + static { + FORBIDDEN_TYPES.add(DataComponentTypes.CUSTOM_NAME); + FORBIDDEN_TYPES.add(DataComponentTypes.PROFILE); + FORBIDDEN_TYPES.add(DataComponentTypes.UNBREAKABLE); + FORBIDDEN_TYPES.add(DataComponentTypes.BLOCK_DATA); + FORBIDDEN_TYPES.add(DataComponentTypes.BLOCKS_ATTACKS); + FORBIDDEN_TYPES.add(DataComponentTypes.BUNDLE_CONTENTS); + FORBIDDEN_TYPES.add(DataComponentTypes.CUSTOM_MODEL_DATA); + + FORBIDDEN_TYPES.add(DataComponentTypes.ATTRIBUTE_MODIFIERS); + FORBIDDEN_TYPES.add(DataComponentTypes.TOOL); + FORBIDDEN_TYPES.add(DataComponentTypes.WEAPON); + FORBIDDEN_TYPES.add(DataComponentTypes.FOOD); + FORBIDDEN_TYPES.add(DataComponentTypes.CONSUMABLE); + FORBIDDEN_TYPES.add(DataComponentTypes.POTION_CONTENTS); + FORBIDDEN_TYPES.add(DataComponentTypes.STORED_ENCHANTMENTS); + FORBIDDEN_TYPES.add(DataComponentTypes.CAN_BREAK); + FORBIDDEN_TYPES.add(DataComponentTypes.CAN_PLACE_ON); + FORBIDDEN_TYPES.add(DataComponentTypes.MAX_DAMAGE); + FORBIDDEN_TYPES.add(DataComponentTypes.USE_REMAINDER); + FORBIDDEN_TYPES.add(DataComponentTypes.USE_COOLDOWN); + FORBIDDEN_TYPES.add(DataComponentTypes.SUSPICIOUS_STEW_EFFECTS); + FORBIDDEN_TYPES.add(DataComponentTypes.CHARGED_PROJECTILES); + FORBIDDEN_TYPES.add(DataComponentTypes.INTANGIBLE_PROJECTILE); + FORBIDDEN_TYPES.add(DataComponentTypes.FIREWORKS); + FORBIDDEN_TYPES.add(DataComponentTypes.FIREWORK_EXPLOSION); + FORBIDDEN_TYPES.add(DataComponentTypes.EQUIPPABLE); + FORBIDDEN_TYPES.add(DataComponentTypes.REPAIR_COST); + FORBIDDEN_TYPES.add(DataComponentTypes.ENCHANTABLE); + } + public static boolean hasItems(ItemStack stack) { - return ReflectionWrapper.impl.hasItems(stack); + FORBIDDEN_TYPES.forEach(stack::resetData); + return false; } private boolean isEnchantmentInKit(ItemStack stack) { diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/ArrowStopper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/ArrowStopper.java index 03e00bbf..e6b0c64e 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/ArrowStopper.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/ArrowStopper.java @@ -22,12 +22,12 @@ package de.steamwar.fightsystem.listener; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.StateDependentTask; -import de.steamwar.fightsystem.utils.WorldOfColorWrapper; import de.steamwar.linkage.Linked; import net.minecraft.world.entity.projectile.AbstractArrow; import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; +import org.bukkit.entity.Arrow; import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; import org.bukkit.projectiles.ProjectileSource; @@ -93,8 +93,12 @@ public class ArrowStopper { boolean teamFrom = entity.getVelocity().getZ() > 0; boolean overMid = location.getZ() > Config.SpecSpawn.getZ(); boolean otherSide = teamFrom == overMid; - return otherSide || !Config.ArenaRegion.inRegion(location) || - WorldOfColorWrapper.impl.isInBlock(entity) || + if (otherSide || !Config.ArenaRegion.inRegion(location)) return true; + boolean result = false; + if (entity instanceof Arrow arrow) { + result = arrow.isInBlock(); + } + return result || entity.getVelocity().equals(NULL_VECTOR); } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/BlockFormListener.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/BlockFormListener.java index 29c6be82..55d58adb 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/BlockFormListener.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/BlockFormListener.java @@ -32,12 +32,16 @@ import org.bukkit.event.block.BlockFormEvent; public class BlockFormListener implements Listener { public BlockFormListener() { - new StateDependentListener(Config.GameModeConfig.Arena.DisableIceForm, FightState.All, this); + boolean enabled = !Config.GameModeConfig.Arena.DisabledBlockForms.isEmpty(); + new StateDependentListener(enabled, FightState.All, this); } @EventHandler public void onBlockForm(BlockFormEvent event) { - if (Config.ArenaRegion.inRegion(event.getBlock()) && event.getNewState().getType() == Material.ICE) { + if (!Config.ArenaRegion.inRegion(event.getBlock())) return; + + Material material = event.getNewState().getType(); + if (Config.GameModeConfig.Arena.DisabledBlockForms.contains(material)) { event.setCancelled(true); } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/BlockPlaceCollision.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/BlockPlaceCollision.java index efce662e..97b49283 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/BlockPlaceCollision.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/BlockPlaceCollision.java @@ -22,11 +22,11 @@ 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 de.steamwar.linkage.Linked; import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.entity.Player; +import org.bukkit.entity.Pose; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.BlockPlaceEvent; @@ -46,7 +46,7 @@ public class BlockPlaceCollision implements Listener { // 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 max = player.getLocation().add(0.3, player.getPose() == Pose.SWIMMING ? 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); diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Border.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Border.java index 39fb1870..55864abd 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Border.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Border.java @@ -24,7 +24,6 @@ import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.StateDependentTask; -import de.steamwar.fightsystem.utils.FlatteningWrapper; import de.steamwar.fightsystem.utils.Region; import net.md_5.bungee.api.ChatMessageType; import org.bukkit.Bukkit; @@ -141,7 +140,7 @@ public class Border { private void sendChange(Player player, Block block, Material type) { if (block.getType() == Material.AIR) { - FlatteningWrapper.impl.sendBlockChange(player, block, type); + player.sendBlockChange(block.getLocation(), type.createBlockData()); } } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/DenyInventoryMovement.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/DenyInventoryMovement.java index e9c1d797..0452691c 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/DenyInventoryMovement.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/DenyInventoryMovement.java @@ -20,24 +20,22 @@ package de.steamwar.fightsystem.listener; import de.steamwar.fightsystem.ArenaMode; +import de.steamwar.fightsystem.fight.Fight; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.StateDependentListener; -import de.steamwar.fightsystem.utils.BountifulWrapper; import de.steamwar.linkage.Linked; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryDragEvent; import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.event.player.PlayerSwapHandItemsEvent; @Linked public class DenyInventoryMovement implements Listener { public DenyInventoryMovement() { new StateDependentListener(ArenaMode.AntiTest, FightState.AntiIngame, this); - - Listener listener = BountifulWrapper.impl.newDenyHandSwapListener(); - new StateDependentListener(ArenaMode.AntiTest, FightState.AntiIngame, listener); } @EventHandler @@ -54,4 +52,9 @@ public class DenyInventoryMovement implements Listener { public void onItemPickup(PlayerPickupItemEvent event) { event.setCancelled(true); } + + @EventHandler + public void onSwapItems(PlayerSwapHandItemsEvent event) { + if (Fight.fighting(event.getPlayer())) event.setCancelled(true); + } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java index 27ca0dc5..75340bd5 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java @@ -27,13 +27,12 @@ import de.steamwar.fightsystem.fight.FightPlayer; import de.steamwar.fightsystem.fight.FightTeam; 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 de.steamwar.linkage.Linked; import net.md_5.bungee.api.ChatMessageType; import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.block.data.type.Dispenser; import org.bukkit.entity.Player; import org.bukkit.entity.TNTPrimed; import org.bukkit.event.EventHandler; @@ -62,7 +61,7 @@ public class Permanent implements Listener { private static final Team spectatorTeam = FightScoreboard.getBukkitTeam("Spectator"); static { - BountifulWrapper.impl.setNametagVisibility(spectatorTeam); + spectatorTeam.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.FOR_OWN_TEAM); spectatorTeam.setNameTagVisibility(NameTagVisibility.NEVER); } @@ -234,7 +233,7 @@ public class Permanent implements Listener { return; } - if (e.getItem().getType() == Material.TNT || FlatteningWrapper.impl.isFacingWater(block)) { + if (e.getItem().getType() == Material.TNT || block.getRelative(((Dispenser) block.getBlockData()).getFacing()).isLiquid()) { e.setCancelled(true); } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/PrepareSchem.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/PrepareSchem.java index d8ac07a6..f83c4c21 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/PrepareSchem.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/PrepareSchem.java @@ -28,12 +28,12 @@ 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 de.steamwar.fightsystem.utils.FlatteningWrapper; import de.steamwar.fightsystem.utils.Region; import de.steamwar.fightsystem.utils.WorldeditWrapper; import de.steamwar.linkage.Linked; import de.steamwar.sql.SchematicNode; import org.bukkit.Bukkit; +import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -52,7 +52,7 @@ public class PrepareSchem implements Listener { new OneShotStateDependent(ArenaMode.Prepare, FightState.PostSchemSetup, () -> Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> { stationaryMovingPistons.clear(); Fight.getUnrotated().getSchemRegion().forEach((x, y, z) -> { - if (FlatteningWrapper.impl.checkPistonMoving(Config.world.getBlockAt(x, y, z))) { + if (Config.world.getBlockAt(x, y, z).getType() == Material.MOVING_PISTON) { stationaryMovingPistons.add(new Vector(x, y, z)); } }); @@ -76,7 +76,7 @@ public class PrepareSchem implements Listener { try { region.forEach((x, y, z) -> { - if (FlatteningWrapper.impl.checkPistonMoving(Config.world.getBlockAt(x, y, z)) && !stationaryMovingPistons.contains(new Vector(x, y, z))) { + if (Config.world.getBlockAt(x, y, z).getType() == Material.MOVING_PISTON && !stationaryMovingPistons.contains(new Vector(x, y, z))) { FightSystem.getMessage().broadcast("PREPARE_ACTIVE_PISTON"); Bukkit.shutdown(); throw new IllegalStateException(); diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Recording.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Recording.java index 0a506cbf..05bed604 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Recording.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Recording.java @@ -22,6 +22,7 @@ package de.steamwar.fightsystem.listener; import com.comphenix.tinyprotocol.TinyProtocol; import de.steamwar.Reflection; import de.steamwar.fightsystem.ArenaMode; +import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.events.TeamDeathEvent; import de.steamwar.fightsystem.events.TeamLeaveEvent; @@ -34,17 +35,16 @@ import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.StateDependent; import de.steamwar.fightsystem.states.StateDependentListener; import de.steamwar.fightsystem.states.StateDependentTask; -import de.steamwar.fightsystem.utils.BountifulWrapper; -import de.steamwar.fightsystem.utils.CraftbukkitWrapper; -import de.steamwar.fightsystem.utils.FlatteningWrapper; import de.steamwar.fightsystem.utils.SWSound; import de.steamwar.linkage.Linked; import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket; import net.minecraft.network.protocol.game.ServerboundUseItemPacket; +import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.item.PrimedTnt; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; @@ -63,6 +63,7 @@ import java.util.Random; import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Predicate; +import java.util.stream.StreamSupport; @Linked public class Recording implements Listener { @@ -83,12 +84,22 @@ public class Recording implements Listener { public static final Class primedTnt = PrimedTnt.class; public static void iterateOverEntities(Predicate filter, Consumer consumer) { - CraftbukkitWrapper.impl.entityIterator().filter(filter).map(net.minecraft.world.entity.Entity::getBukkitEntity).forEach(consumer); + StreamSupport.stream(((CraftWorld) Config.world).getHandle().getEntities().getAll().spliterator(), false).filter(filter).map(net.minecraft.world.entity.Entity::getBukkitEntity).forEach(consumer); } public Recording() { new StateDependentListener(ArenaMode.AntiReplay, FightState.All, this); - new StateDependentListener(ArenaMode.AntiReplay, FightState.All, BountifulWrapper.impl.newHandSwapRecorder()); + new StateDependentListener(ArenaMode.AntiReplay, FightState.All, new Listener() { + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onItemSwap(PlayerSwapHandItemsEvent e) { + if (isNotSent(e.getPlayer())) + return; + + Player player = e.getPlayer(); + GlobalRecorder.getInstance().item(player, disarmNull(e.getMainHandItem()), "MAINHAND"); + GlobalRecorder.getInstance().item(player, disarmNull(e.getOffHandItem()), "OFFHAND"); + } + }); new StateDependent(ArenaMode.AntiReplay, FightState.Ingame) { @Override public void enable() { @@ -102,12 +113,12 @@ public class Recording implements Listener { } }.register(); new StateDependent(ArenaMode.AntiReplay, FightState.Ingame) { - private final BiFunction place = Recording.this::blockPlace; + private final BiFunction place = Recording.this::blockPlace; private final BiFunction dig = Recording.this::blockDig; @Override public void enable() { - TinyProtocol.instance.addFilter(blockPlacePacket, place); + TinyProtocol.instance.addFilter(ServerboundUseItemPacket.class, place); TinyProtocol.instance.addFilter(blockDigPacket, dig); } @@ -145,9 +156,9 @@ public class Recording implements Listener { public static final Class blockPlacePacket = ServerboundUseItemPacket.class; - private Object blockPlace(Player p, Object packet) { - boolean mainHand = BountifulWrapper.impl.mainHand(packet); - if (!isNotSent(p) && BountifulWrapper.impl.bowInHand(mainHand, p)) { + private Object blockPlace(Player p, ServerboundUseItemPacket packet) { + boolean mainHand = packet.getHand() == InteractionHand.MAIN_HAND; + if (!isNotSent(p) && (mainHand ? p.getInventory().getItemInMainHand() : p.getInventory().getItemInOffHand()).getType() == Material.BOW) { GlobalRecorder.getInstance().bowSpan(p, true, !mainHand); } return packet; @@ -177,7 +188,7 @@ public class Recording implements Listener { @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onBlockPhysics(BlockPhysicsEvent e) { - if (FlatteningWrapper.impl.doRecord(e)) { + if (e.getBlock() == e.getSourceBlock() || e.getChangedType() == Material.AIR) { GlobalRecorder.getInstance().blockChange(e.getBlock()); } } @@ -285,7 +296,8 @@ public class Recording implements Listener { if (!fp.isLiving()) continue; fp.ifPlayer(player -> { - BountifulWrapper.impl.recordHandItems(player); + GlobalRecorder.getInstance().item(player, disarmNull(player.getInventory().getItemInMainHand()), "MAINHAND"); + GlobalRecorder.getInstance().item(player, disarmNull(player.getInventory().getItemInOffHand()), "OFFHAND"); GlobalRecorder.getInstance().item(player, disarmNull(player.getInventory().getHelmet()), "HEAD"); GlobalRecorder.getInstance().item(player, disarmNull(player.getInventory().getChestplate()), "CHEST"); GlobalRecorder.getInstance().item(player, disarmNull(player.getInventory().getLeggings()), "LEGS"); diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/WaterRemover.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/WaterRemover.java index 6ac8183a..c85da5ce 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/WaterRemover.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/WaterRemover.java @@ -25,11 +25,13 @@ 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.utils.FlatteningWrapper; import de.steamwar.linkage.Linked; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Waterlogged; import org.bukkit.entity.EntityType; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -101,7 +103,25 @@ public class WaterRemover implements Listener { if (!Config.BlueExtendRegion.inRegion(b) && !Config.RedExtendRegion.inRegion(b)) return; //checks for water and removes it, if present - if (!FlatteningWrapper.impl.removeWater(b)) return; + boolean result = true; + Material type = b.getType(); + if (type == Material.WATER || type == Material.LAVA) { + b.setType(Material.AIR); + } else { + BlockData data = b.getBlockData(); + if (!(data instanceof Waterlogged)) { + result = false; + } else { + Waterlogged waterlogged = (Waterlogged) data; + if (waterlogged.isWaterlogged()) { + b.setType(Material.AIR); + } else { + result = false; + } + } + } + + if (!result) return; if (b.getY() < MIN_Y) return; diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java index 3c010418..b62ef662 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/PacketProcessor.java @@ -42,11 +42,14 @@ 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 net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Pose; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Sound; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.*; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; @@ -72,7 +75,7 @@ public class PacketProcessor implements Listener { private static final org.bukkit.scoreboard.Team team = FightScoreboard.getBukkitTeam("Replay"); static { - BountifulWrapper.impl.setNametagVisibility(team); + team.setOption(org.bukkit.scoreboard.Team.Option.NAME_TAG_VISIBILITY, org.bukkit.scoreboard.Team.OptionStatus.FOR_OWN_TEAM); team.setNameTagVisibility(NameTagVisibility.NEVER); } @@ -460,8 +463,15 @@ public class PacketProcessor implements Listener { if (!Config.ArenaRegion.in2dRegion(x, z)) return; //Outside of the arena execSync(() -> { - BlockIdWrapper.impl.setBlock(Config.world, x, y, z, TechHiderWrapper.ENABLED && hiddenBlockIds.contains(blockState) ? obfuscateWith : blockState); - FightSystem.getHullHider().blockUpdate(Config.world.getBlockAt(x, y, z), BlockIdWrapper.impl.idToMaterial(blockState)); + int blockState1 = TechHiderWrapper.ENABLED && hiddenBlockIds.contains(blockState) ? obfuscateWith : blockState; + BlockState blockData = Block.stateById(blockState1); + ServerLevel level = ((CraftWorld) Config.world).getHandle(); + BlockPos pos = new BlockPos(x, y, z); + + level.removeBlockEntity(pos); + level.setBlock(pos, blockData, blockState1); + level.getChunkSource().blockChanged(pos); + FightSystem.getHullHider().blockUpdate(Config.world.getBlockAt(x, y, z), CraftMagicNumbers.getMaterial(Block.stateById(blockState)).getItemType()); }); } @@ -478,7 +488,7 @@ public class PacketProcessor implements Listener { double finalX = x; double finalZ = z; - execSync(() -> BountifulWrapper.impl.spawnParticle(Config.world, particleName, finalX + Config.ArenaRegion.getMinX(), y + Config.BluePasteRegion.getMinY(), finalZ + Config.ArenaRegion.getMinZ())); + execSync(() -> Config.world.spawnParticle(Particle.valueOf(particleName), finalX + Config.ArenaRegion.getMinX(), y + Config.BluePasteRegion.getMinY(), finalZ + Config.ArenaRegion.getMinZ(), 1)); } private void sound() throws IOException { @@ -502,7 +512,10 @@ public class PacketProcessor implements Listener { Sound sound = Sound.valueOf(soundName); - execSync(() -> WorldOfColorWrapper.impl.playSound(new Location(Config.world, x, y, z), sound, soundCategory, volume, pitch)); + execSync(() -> { + Location location = new Location(Config.world, x, y, z); + location.getWorld().playSound(location, sound, SoundCategory.valueOf(soundCategory), volume, pitch); + }); } private void soundAtPlayer() throws IOException { @@ -603,7 +616,7 @@ public class PacketProcessor implements Listener { Bukkit.getOnlinePlayers().forEach(p -> { p.resetTitle(); - WorldOfColorWrapper.impl.sendTitle(p, title, subtitle, 5, 40, 5); + p.sendTitle(title, subtitle, 5, 40, 5); }); } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/Recorder.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/Recorder.java index dec7160c..69f2bbcb 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/Recorder.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/record/Recorder.java @@ -25,7 +25,6 @@ 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.utils.BlockIdWrapper; import de.steamwar.fightsystem.utils.CraftbukkitWrapper; import de.steamwar.fightsystem.utils.Message; import de.steamwar.fightsystem.utils.SWSound; @@ -35,6 +34,7 @@ import de.steamwar.sql.SteamwarUser; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.block.Block; +import org.bukkit.craftbukkit.block.CraftBlockState; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; @@ -219,7 +219,7 @@ public interface Recorder { } default void blockChange(Block block) { - int blockState = BlockIdWrapper.impl.blockToId(block); + int blockState = net.minecraft.world.level.block.Block.getId(((CraftBlockState) block.getState()).getHandle()); int shortX = block.getX() - Config.ArenaRegion.getMinX(); int shortY = block.getY() - Config.BluePasteRegion.getMinY(); diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/BlockIdWrapper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/BlockIdWrapper.java deleted file mode 100644 index e6945ba5..00000000 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/BlockIdWrapper.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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 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.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.util.CraftMagicNumbers; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; - -public class BlockIdWrapper { - public static final BlockIdWrapper impl = new BlockIdWrapper(); - - public Material idToMaterial(int blockState) { - return CraftMagicNumbers.getMaterial(net.minecraft.world.level.block.Block.stateById(blockState)).getItemType(); - } - - public int blockToId(Block block) { - return net.minecraft.world.level.block.Block.getId(((CraftBlockState) block.getState()).getHandle()); - } - - 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); - } - - public void trackEntity(Player player, Entity entity) { - if (entity instanceof Player) { - TinyProtocol.instance.sendPacket(player, ProtocolWrapper.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.REMOVE, new GameProfile(entity.getUniqueId(), entity.getName()), GameMode.CREATIVE)); - } - - player.showEntity(FightSystem.getPlugin(), entity); - } - - public void untrackEntity(Player player, Entity entity) { - player.hideEntity(FightSystem.getPlugin(), entity); - - if (entity instanceof Player) { - TinyProtocol.instance.sendPacket(player, ProtocolWrapper.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.ADD, new GameProfile(entity.getUniqueId(), entity.getName()), GameMode.CREATIVE)); - } - } -} diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/BountifulWrapper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/BountifulWrapper.java deleted file mode 100644 index e1cefc9c..00000000 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/BountifulWrapper.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * 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.fight.Fight; -import de.steamwar.fightsystem.fight.FightTeam; -import de.steamwar.fightsystem.listener.Recording; -import de.steamwar.fightsystem.record.GlobalRecorder; -import net.minecraft.world.InteractionHand; -import org.bukkit.*; -import org.bukkit.attribute.Attribute; -import org.bukkit.attribute.AttributeInstance; -import org.bukkit.boss.BarColor; -import org.bukkit.boss.BarStyle; -import org.bukkit.boss.BossBar; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerPickupArrowEvent; -import org.bukkit.event.player.PlayerSwapHandItemsEvent; -import org.bukkit.scoreboard.Team; - -import java.util.HashMap; -import java.util.Map; - -public class BountifulWrapper { - public static final BountifulWrapper impl = new BountifulWrapper(); - - private static final Class enumHand = InteractionHand.class; - private static final Object mainHand = enumHand.getEnumConstants()[0]; - private static final Reflection.Field blockPlaceHand = Reflection.getField(Recording.blockPlacePacket, enumHand, 0); - - public boolean mainHand(Object packet) { - return blockPlaceHand.get(packet) == mainHand; - } - - public boolean bowInHand(boolean mainHand, Player p) { - return (mainHand ? p.getInventory().getItemInMainHand() : p.getInventory().getItemInOffHand()).getType() == Material.BOW; - } - - public void setAttackSpeed(Player player) { - AttributeInstance attribute = player.getAttribute(Attribute.ATTACK_SPEED); - attribute.setBaseValue(16); - } - - public void setNametagVisibility(Team team) { - team.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.FOR_OWN_TEAM); - } - - public Listener newDenyArrowPickupListener() { - return new Listener() { - @EventHandler - public void onArrowPickup(PlayerPickupArrowEvent e) { - if (Fight.fighting(e.getPlayer())) e.setCancelled(true); - } - }; - } - - public Listener newDenyHandSwapListener() { - return new Listener() { - @EventHandler - public void onSwapItems(PlayerSwapHandItemsEvent event) { - if (Fight.fighting(event.getPlayer())) event.setCancelled(true); - } - }; - } - - public void recordHandItems(Player player) { - GlobalRecorder.getInstance().item(player, Recording.disarmNull(player.getInventory().getItemInMainHand()), "MAINHAND"); - GlobalRecorder.getInstance().item(player, Recording.disarmNull(player.getInventory().getItemInOffHand()), "OFFHAND"); - } - - public Listener newHandSwapRecorder() { - return new Listener() { - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onItemSwap(PlayerSwapHandItemsEvent e) { - if (Recording.isNotSent(e.getPlayer())) - return; - - Player player = e.getPlayer(); - GlobalRecorder.getInstance().item(player, Recording.disarmNull(e.getMainHandItem()), "MAINHAND"); - GlobalRecorder.getInstance().item(player, Recording.disarmNull(e.getOffHandItem()), "OFFHAND"); - } - }; - } - - public void spawnParticle(World world, String particleName, double x, double y, double z) { - world.spawnParticle(Particle.valueOf(particleName), x, y, z, 1); - } - - private final Map barMap = new HashMap<>(); - - public void sendBar(Player player, FightTeam team, double progress, String text) { - barMap.keySet().removeIf(p -> !p.isOnline()); - - if (!barMap.containsKey(player)) { - BossBar bar = Bukkit.createBossBar(player.getName(), BarColor.WHITE, BarStyle.SOLID); - barMap.put(player, bar); - bar.addPlayer(player); - } - - BossBar bar = barMap.get(player); - BarColor color = chat2bar(team.getColor()); - if (bar.getColor() != color) bar.setColor(color); - - if (bar.getProgress() != progress) bar.setProgress(progress); - - if (!bar.getTitle().equals(text)) bar.setTitle(text); - } - - private BarColor chat2bar(ChatColor color) { - switch (color) { - case DARK_BLUE: - case DARK_AQUA: - case BLUE: - case AQUA: - return BarColor.BLUE; - case GREEN: - case DARK_GREEN: - return BarColor.GREEN; - case DARK_RED: - case RED: - return BarColor.RED; - case DARK_PURPLE: - return BarColor.PURPLE; - case GOLD: - case YELLOW: - return BarColor.YELLOW; - case LIGHT_PURPLE: - return BarColor.PINK; - case BLACK: - case WHITE: - case GRAY: - case DARK_GRAY: - default: - return BarColor.WHITE; - } - } -} 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 6a4518c8..031ac904 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/CraftbukkitWrapper.java @@ -19,11 +19,9 @@ package de.steamwar.fightsystem.utils; -import de.steamwar.fightsystem.Config; import net.minecraft.core.BlockPos; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; -import org.bukkit.GameRule; import org.bukkit.World; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.entity.CraftEntity; @@ -31,26 +29,12 @@ import org.bukkit.entity.Entity; import java.util.HashSet; import java.util.Set; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; public class CraftbukkitWrapper { public static final CraftbukkitWrapper impl = new CraftbukkitWrapper(); - protected net.minecraft.world.entity.Entity getEntity(Entity e) { - return ((CraftEntity) e).getHandle(); - } - public float headRotation(Entity e) { - return getEntity(e).getYHeadRot(); - } - - public Stream entityIterator() { - return StreamSupport.stream(((CraftWorld) Config.world).getHandle().getEntities().getAll().spliterator(), false); - } - - public void setupGamerule() { - Config.world.setGameRule(GameRule.LOCATOR_BAR, false); + return ((CraftEntity) e).getHandle().getYHeadRot(); } private LevelChunk getChunk(World world, int x, int z) { diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/FightUI.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/FightUI.java index ce6fa5d4..68103b76 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/FightUI.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/FightUI.java @@ -34,12 +34,12 @@ import de.steamwar.fightsystem.winconditions.Wincondition; import de.steamwar.linkage.Linked; import lombok.Getter; import org.bukkit.Bukkit; +import org.bukkit.boss.BarColor; +import org.bukkit.boss.BarStyle; +import org.bukkit.boss.BossBar; import org.bukkit.entity.Player; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; +import java.util.*; import java.util.logging.Level; import java.util.stream.Collectors; @@ -142,6 +142,7 @@ public class FightUI { BossBarType.RED_LEFT.text = leftRedText; } + private final Map barMap = new HashMap<>(); private void sendToPlayers() { Bukkit.getOnlinePlayers().forEach(player -> { BossBarType bar = BossBarType.byAngle(CraftbukkitWrapper.impl.headRotation(player)); @@ -154,7 +155,55 @@ public class FightUI { } } - BountifulWrapper.impl.sendBar(player, bar.team, bar.progress, FightSystem.getMessage().parse(bar.text.getMsg(), player, params)); + String text = FightSystem.getMessage().parse(bar.text.getMsg(), player, params); + barMap.keySet().removeIf(p -> !p.isOnline()); + + if (!barMap.containsKey(player)) { + BossBar bar1 = Bukkit.createBossBar(player.getName(), BarColor.WHITE, BarStyle.SOLID); + barMap.put(player, bar1); + bar1.addPlayer(player); + } + + BossBar bar1 = barMap.get(player); + BarColor color; + switch (bar.team.getColor()) { + case DARK_BLUE: + case DARK_AQUA: + case BLUE: + case AQUA: + color = BarColor.BLUE; + break; + case GREEN: + case DARK_GREEN: + color = BarColor.GREEN; + break; + case DARK_RED: + case RED: + color = BarColor.RED; + break; + case DARK_PURPLE: + color = BarColor.PURPLE; + break; + case GOLD: + case YELLOW: + color = BarColor.YELLOW; + break; + case LIGHT_PURPLE: + color = BarColor.PINK; + break; + case BLACK: + case WHITE: + case GRAY: + case DARK_GRAY: + default: + color = BarColor.WHITE; + break; + } + if (bar1.getColor() != color) bar1.setColor(color); + + if (bar1.getProgress() != bar.progress) bar1.setProgress(bar.progress); + + if (!bar1.getTitle().equals(text)) bar1.setTitle(text); }); } @@ -208,9 +257,17 @@ public class FightUI { Bukkit.getOnlinePlayers().forEach(Player::resetTitle); if (winner != null) { - Bukkit.getOnlinePlayers().forEach(p -> WorldOfColorWrapper.impl.sendTitle(p, FightSystem.getMessage().parse("UI_WIN", p, winner.getColor(), winner.getName()), FightSystem.getMessage().parse(subtitle, p, params), 5, 40, 5)); + Bukkit.getOnlinePlayers().forEach(p -> { + String title = FightSystem.getMessage().parse("UI_WIN", p, winner.getColor(), winner.getName()); + String subtitle1 = FightSystem.getMessage().parse(subtitle, p, params); + p.sendTitle(title, subtitle1, 5, 40, 5); + }); } else { - Bukkit.getOnlinePlayers().forEach(p -> WorldOfColorWrapper.impl.sendTitle(p, FightSystem.getMessage().parse("UI_DRAW", p), FightSystem.getMessage().parse(subtitle, p, params), 5, 40, 5)); + Bukkit.getOnlinePlayers().forEach(p -> { + String title = FightSystem.getMessage().parse("UI_DRAW", p); + String subtitle1 = FightSystem.getMessage().parse(subtitle, p, params); + p.sendTitle(title, subtitle1, 5, 40, 5); + }); } } @@ -232,7 +289,10 @@ public class FightUI { } Message message = queue.poll(); - Bukkit.getOnlinePlayers().forEach(p -> WorldOfColorWrapper.impl.sendTitle(p, " ", FightSystem.getMessage().parse(message.getMsg(), p, message.getParams()), 5, 40, 5)); + Bukkit.getOnlinePlayers().forEach(p -> { + String subtitle = FightSystem.getMessage().parse(message.getMsg(), p, message.getParams()); + p.sendTitle(" ", subtitle, 5, 40, 5); + }); Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), FightUI::printSubtitle, 50); subtitleScheduled = true; } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/FlatteningWrapper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/FlatteningWrapper.java deleted file mode 100644 index 099ed3ef..00000000 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/FlatteningWrapper.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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 org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.data.BlockData; -import org.bukkit.block.data.Waterlogged; -import org.bukkit.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; -import org.bukkit.inventory.meta.ItemMeta; - -public class FlatteningWrapper { - public static final FlatteningWrapper impl = new FlatteningWrapper(); - - public boolean isWater(Block block) { - if (block.getType() == Material.WATER) return true; - - BlockData data = block.getBlockData(); - if (!(data instanceof Waterlogged)) return false; - - return ((Waterlogged) data).isWaterlogged(); - } - - public boolean removeWater(Block block) { - Material type = block.getType(); - if (type == Material.WATER || type == Material.LAVA) { - block.setType(Material.AIR); - return true; - } - - BlockData data = block.getBlockData(); - if (!(data instanceof Waterlogged)) return false; - - Waterlogged waterlogged = (Waterlogged) data; - if (waterlogged.isWaterlogged()) { - block.setType(Material.AIR); - return true; - } - - return false; - } - - public boolean containsBlockMeta(ItemMeta meta) { - return meta instanceof BlockDataMeta && ((BlockDataMeta) meta).hasBlockData(); - } - - public boolean hasAttributeModifier(ItemStack stack) { - return stack.hasItemMeta() && stack.getItemMeta() != null && stack.getItemMeta().hasAttributeModifiers(); - } - - public boolean doRecord(BlockPhysicsEvent e) { - return e.getBlock() == e.getSourceBlock() || e.getChangedType() == Material.AIR; - } - - public void forceLoadChunk(World world, int cX, int cZ) { - world.setChunkForceLoaded(cX, cZ, true); - } - - public boolean checkPistonMoving(Block block) { - return block.getType() == Material.MOVING_PISTON; - } - - public boolean isFacingWater(Block dispenser) { - return dispenser.getRelative(((Dispenser) dispenser.getBlockData()).getFacing()).isLiquid(); - } - - public boolean isCrouching(Player player) { - return player.getPose() == Pose.SWIMMING; - } - - public void sendBlockChange(Player player, Block block, Material type) { - player.sendBlockChange(block.getLocation(), type.createBlockData()); - } -} diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java index 506e105d..72af266e 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java @@ -20,15 +20,25 @@ package de.steamwar.fightsystem.utils; import com.comphenix.tinyprotocol.TinyProtocol; +import com.mojang.authlib.GameProfile; +import de.steamwar.core.ProtocolWrapper; import de.steamwar.entity.REntity; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.fight.FightTeam; +import it.unimi.dsi.fastutil.shorts.Short2ObjectArrayMap; import lombok.AllArgsConstructor; import lombok.Getter; +import net.minecraft.core.BlockPos; +import net.minecraft.core.SectionPos; +import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket; +import net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; @@ -91,7 +101,7 @@ public class Hull { public void addPlayer(Player player) { if (players.add(player)) { for (Entity entity : entities) { - BlockIdWrapper.impl.untrackEntity(player, entity); + untrackEntity(player, entity); } } } @@ -99,7 +109,7 @@ public class Hull { public void removePlayer(Player player, boolean activeRemoval) { if (players.remove(player) && activeRemoval) { for (Entity entity : entities) { - BlockIdWrapper.impl.trackEntity(player, entity); + trackEntity(player, entity); } // techhider triggers block change sending } @@ -110,18 +120,34 @@ public class Hull { if (region.inRegion(location) && !visibility.get(new IntVector(location).toId(region))) { if (entities.add(entity)) { for (Player player : players) { - BlockIdWrapper.impl.untrackEntity(player, entity); + untrackEntity(player, entity); } } } else { if (entities.remove(entity)) { for (Player player : players) { - BlockIdWrapper.impl.trackEntity(player, entity); + trackEntity(player, entity); } } } } + public void trackEntity(Player player, Entity entity) { + if (entity instanceof Player) { + TinyProtocol.instance.sendPacket(player, ProtocolWrapper.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.REMOVE, new GameProfile(entity.getUniqueId(), entity.getName()), GameMode.CREATIVE)); + } + + player.showEntity(FightSystem.getPlugin(), entity); + } + + public void untrackEntity(Player player, Entity entity) { + player.hideEntity(FightSystem.getPlugin(), entity); + + if (entity instanceof Player) { + TinyProtocol.instance.sendPacket(player, ProtocolWrapper.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.ADD, new GameProfile(entity.getUniqueId(), entity.getName()), GameMode.CREATIVE)); + } + } + public void removeEntity(Entity entity) { entities.remove(entity); } @@ -189,7 +215,34 @@ public class Hull { uncoveredSurface.clear(); for (Map.Entry> entry : sectionWise.entrySet()) { - Object packet = HullHiderWrapper.impl.generateBlockChangePacket(entry.getValue()); + Object result; + List changes = entry.getValue(); + Object[] blockdata = new Object[changes.size()]; + for (int i = 0; i < blockdata.length; i++) { + IntVector change = changes.get(i); + blockdata[i] = ((CraftBlockData) Config.world.getBlockData(change.getX(), change.getY(), change.getZ())).getState(); + } + + if (changes.size() > 1) { + IntVector section = changes.get(0); + section = new IntVector(section.getX() >> 4, section.getY() >> 4, section.getZ() >> 4); + int xOffset = 16 * section.getX(); + int yOffset = 16 * section.getY(); + int zOffset = 16 * section.getZ(); + + short[] pos = new short[changes.size()]; + for (int i = 0; i < changes.size(); i++) { + IntVector change = changes.get(i); + + pos[i] = (short) (((change.getX() - xOffset) << 8) + ((change.getZ() - zOffset) << 4) + (change.getY() - yOffset)); + } + + result = new ClientboundSectionBlocksUpdatePacket(SectionPos.of(section.getX(), section.getY(), section.getZ()), new Short2ObjectArrayMap<>(pos, blockdata, blockdata.length)); + } else { + IntVector pos = changes.get(0); + result = new ClientboundBlockUpdatePacket(new BlockPos(pos.getX(), pos.getY(), pos.getZ()), (BlockState) blockdata[0]); + } + Object packet = result; players.forEach(player -> TinyProtocol.instance.sendPacket(player, packet)); } } 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 4d94b335..ea00c560 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHider.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHider.java @@ -117,7 +117,7 @@ public class HullHider implements Listener { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onBlockPhysic(BlockPhysicsEvent e) { - if (FlatteningWrapper.impl.doRecord(e)) { + if (e.getBlock() == e.getSourceBlock() || e.getChangedType() == Material.AIR) { blockUpdate(e.getBlock(), e.getChangedType()); } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHiderWrapper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHiderWrapper.java deleted file mode 100644 index 217b4e0b..00000000 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHiderWrapper.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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.fightsystem.Config; -import it.unimi.dsi.fastutil.shorts.Short2ObjectArrayMap; -import net.minecraft.core.BlockPos; -import net.minecraft.core.SectionPos; -import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket; -import net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket; -import net.minecraft.world.level.block.state.BlockState; -import org.bukkit.craftbukkit.block.data.CraftBlockData; - -import java.util.List; - -public class HullHiderWrapper { - public static final HullHiderWrapper impl = new HullHiderWrapper(); - - public Object generateBlockChangePacket(List changes) { - Object[] blockdata = new Object[changes.size()]; - for (int i = 0; i < blockdata.length; i++) { - Hull.IntVector change = changes.get(i); - blockdata[i] = ((CraftBlockData) Config.world.getBlockData(change.getX(), change.getY(), change.getZ())).getState(); - } - - return generateBlockChangePacket(changes, blockdata); - } - - private Object generateBlockChangePacket(List changes, Object[] blockdata) { - if (changes.size() > 1) { - Hull.IntVector section = changes.get(0); - section = new Hull.IntVector(section.getX() >> 4, section.getY() >> 4, section.getZ() >> 4); - int xOffset = 16 * section.getX(); - int yOffset = 16 * section.getY(); - int zOffset = 16 * section.getZ(); - - short[] pos = new short[changes.size()]; - for (int i = 0; i < changes.size(); i++) { - Hull.IntVector change = changes.get(i); - - pos[i] = (short) (((change.getX() - xOffset) << 8) + ((change.getZ() - zOffset) << 4) + (change.getY() - yOffset)); - } - - return constructMultiBlockChange(section, pos, blockdata); - } else { - Hull.IntVector pos = changes.get(0); - return new ClientboundBlockUpdatePacket(new BlockPos(pos.getX(), pos.getY(), pos.getZ()), (BlockState) blockdata[0]); - } - } - - protected Object constructMultiBlockChange(Hull.IntVector section, short[] pos, Object[] blockdata) { - return new ClientboundSectionBlocksUpdatePacket(SectionPos.of(section.getX(), section.getY(), section.getZ()), new Short2ObjectArrayMap<>(pos, blockdata, blockdata.length)); - } -} diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/ReflectionWrapper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/ReflectionWrapper.java deleted file mode 100644 index 9044f7d0..00000000 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/ReflectionWrapper.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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.DataComponentType; -import io.papermc.paper.datacomponent.DataComponentTypes; -import org.bukkit.Location; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import java.util.HashSet; -import java.util.Set; - -public class ReflectionWrapper { - public static final ReflectionWrapper impl = new ReflectionWrapper(); - - private static final Set FORBIDDEN_TYPES = new HashSet<>(); - - static { - FORBIDDEN_TYPES.add(DataComponentTypes.CUSTOM_NAME); - FORBIDDEN_TYPES.add(DataComponentTypes.PROFILE); - FORBIDDEN_TYPES.add(DataComponentTypes.UNBREAKABLE); - FORBIDDEN_TYPES.add(DataComponentTypes.BLOCK_DATA); - FORBIDDEN_TYPES.add(DataComponentTypes.BLOCKS_ATTACKS); - FORBIDDEN_TYPES.add(DataComponentTypes.BUNDLE_CONTENTS); - FORBIDDEN_TYPES.add(DataComponentTypes.CUSTOM_MODEL_DATA); - - FORBIDDEN_TYPES.add(DataComponentTypes.ATTRIBUTE_MODIFIERS); - FORBIDDEN_TYPES.add(DataComponentTypes.TOOL); - FORBIDDEN_TYPES.add(DataComponentTypes.WEAPON); - FORBIDDEN_TYPES.add(DataComponentTypes.FOOD); - FORBIDDEN_TYPES.add(DataComponentTypes.CONSUMABLE); - FORBIDDEN_TYPES.add(DataComponentTypes.POTION_CONTENTS); - FORBIDDEN_TYPES.add(DataComponentTypes.STORED_ENCHANTMENTS); - FORBIDDEN_TYPES.add(DataComponentTypes.CAN_BREAK); - FORBIDDEN_TYPES.add(DataComponentTypes.CAN_PLACE_ON); - FORBIDDEN_TYPES.add(DataComponentTypes.MAX_DAMAGE); - FORBIDDEN_TYPES.add(DataComponentTypes.USE_REMAINDER); - FORBIDDEN_TYPES.add(DataComponentTypes.USE_COOLDOWN); - FORBIDDEN_TYPES.add(DataComponentTypes.SUSPICIOUS_STEW_EFFECTS); - FORBIDDEN_TYPES.add(DataComponentTypes.CHARGED_PROJECTILES); - FORBIDDEN_TYPES.add(DataComponentTypes.INTANGIBLE_PROJECTILE); - FORBIDDEN_TYPES.add(DataComponentTypes.FIREWORKS); - FORBIDDEN_TYPES.add(DataComponentTypes.FIREWORK_EXPLOSION); - FORBIDDEN_TYPES.add(DataComponentTypes.EQUIPPABLE); - FORBIDDEN_TYPES.add(DataComponentTypes.REPAIR_COST); - FORBIDDEN_TYPES.add(DataComponentTypes.ENCHANTABLE); - } - - public Object explosionHider(Player player, Object packet, PacketHiderFunction packetHiderFunction) { - return packet; - } - - public boolean hasItems(ItemStack stack) { - FORBIDDEN_TYPES.forEach(stack::resetData); - return false; - } - - public interface PacketHiderFunction { - Object hide(Player player, Object packet, Location location); - } -} diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TpsWarper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TpsWarper.java deleted file mode 100644 index 7f45d87c..00000000 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TpsWarper.java +++ /dev/null @@ -1,11 +0,0 @@ -package de.steamwar.fightsystem.utils; - -import net.minecraft.server.MinecraftServer; - -public class TpsWarper { - public static final TpsWarper impl = new TpsWarper(); - - public void warp(float tps) { - MinecraftServer.getServer().tickRateManager().setTickRate(tps); - } -} diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/WorldOfColorWrapper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/WorldOfColorWrapper.java deleted file mode 100644 index 7075bce1..00000000 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/WorldOfColorWrapper.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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 org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.Sound; -import org.bukkit.SoundCategory; -import org.bukkit.entity.Arrow; -import org.bukkit.entity.Player; -import org.bukkit.entity.Projectile; -import org.bukkit.scoreboard.Team; - -public class WorldOfColorWrapper { - public static final WorldOfColorWrapper impl = new WorldOfColorWrapper(); - - public void setTeamColor(Team team, ChatColor color) { - team.setColor(color); - } - - public boolean isInBlock(Projectile e) { - if (e instanceof Arrow arrow) return arrow.isInBlock(); - return false; - } - - public void playSound(Location location, Sound sound, String soundCategory, float volume, float pitch) { - location.getWorld().playSound(location, sound, SoundCategory.valueOf(soundCategory), volume, pitch); - } - - public void sendTitle(Player player, String title, String subtitle, int start, int hold, int stop) { - player.sendTitle(title, subtitle, start, hold, stop); - } -} diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionWaterTechKO.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionWaterTechKO.java index 89b72b5e..b7897d77 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionWaterTechKO.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionWaterTechKO.java @@ -19,13 +19,22 @@ package de.steamwar.fightsystem.winconditions; -import de.steamwar.fightsystem.utils.FlatteningWrapper; import de.steamwar.linkage.Linked; +import org.bukkit.Material; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Waterlogged; @Linked public class WinconditionWaterTechKO extends WinconditionBlocks { public WinconditionWaterTechKO() { - super(Winconditions.WATER_TECH_KO, "WaterTechKO", "BAR_WATER", FlatteningWrapper.impl::isWater); + super(Winconditions.WATER_TECH_KO, "WaterTechKO", "BAR_WATER", block -> { + if (block.getType() == Material.WATER) return true; + + BlockData data = block.getBlockData(); + if (!(data instanceof Waterlogged)) return false; + + return ((Waterlogged) data).isWaterlogged(); + }); } } diff --git a/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java b/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java index ec599390..abcfbe26 100644 --- a/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java +++ b/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java @@ -2,6 +2,7 @@ package com.comphenix.tinyprotocol; import com.google.common.collect.MapMaker; import de.steamwar.Reflection; +import de.steamwar.core.CRIUWakeupEvent; import de.steamwar.core.Core; import io.netty.channel.*; import net.minecraft.network.Connection; @@ -164,6 +165,10 @@ public class TinyProtocol { } } + @EventHandler + public void onCRIUWakeup(CRIUWakeupEvent event) { + registerChannelHandler(); + } }; plugin.getServer().getPluginManager().registerEvents(listener, plugin); @@ -222,15 +227,10 @@ public class TinyProtocol { } } - public void addTypedFilter(Class packetType, BiFunction filter) { + public void addFilter(Class packetType, BiFunction filter) { packetFilters.computeIfAbsent(packetType, c -> new CopyOnWriteArrayList<>()).add((BiFunction) filter); } - @Deprecated - public void addFilter(Class packetType, BiFunction filter) { - packetFilters.computeIfAbsent(packetType, c -> new CopyOnWriteArrayList<>()).add(filter); - } - public void removeFilter(Class packetType, BiFunction filter) { packetFilters.getOrDefault(packetType, Collections.emptyList()).remove(filter); } @@ -342,6 +342,8 @@ public class TinyProtocol { // Lookup channel again if (channel == null) { + System.out.println(((CraftPlayer) player).getHandle()); + System.out.println(((CraftPlayer) player).getHandle().connection); Channel playerChannel = ((CraftPlayer) player).getHandle().connection.connection.channel; channelLookup.put(player.getName(), channel = playerChannel); } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/CheckpointUtilsJ9.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/CheckpointUtilsJ9.java index 176715ab..4ccbaaa7 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/CheckpointUtilsJ9.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/CheckpointUtilsJ9.java @@ -79,11 +79,14 @@ class CheckpointUtilsJ9 { return; } + e.printStackTrace(); + Bukkit.shutdown(); if (!message.contains("Can't dump ghost file") && !message.contains("Can't create link remap")) // File/Jar has been updated throw new SecurityException(e); } finally { + if (true) return; // Delete checkpoint try (Stream stream = Files.walk(path)) { stream.sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/WorldIdentifier.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/WorldIdentifier.java index d9edd2c7..2ca9d085 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/WorldIdentifier.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/WorldIdentifier.java @@ -43,9 +43,8 @@ public class WorldIdentifier { } public WorldIdentifier() { - TinyProtocol.instance.addFilter(ClientboundLoginPacket.class, (player, o) -> { - if (resourceKey == null) return o; - ClientboundLoginPacket packet = (ClientboundLoginPacket) o; + TinyProtocol.instance.addFilter(ClientboundLoginPacket.class, (player, packet) -> { + if (resourceKey == null) return packet; return new ClientboundLoginPacket(packet.playerId(), packet.hardcore(), diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/events/AntiNocom.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/events/AntiNocom.java index 67230149..2361be24 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/core/events/AntiNocom.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/core/events/AntiNocom.java @@ -46,7 +46,7 @@ public class AntiNocom implements Listener { private final Map flags = new ConcurrentHashMap<>(); public AntiNocom() { - TinyProtocol.instance.addTypedFilter(ServerboundPlayerActionPacket.class, this::onDig); + TinyProtocol.instance.addFilter(ServerboundPlayerActionPacket.class, this::onDig); registerUseItem(); } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java index 8c241d3a..8ac0c01b 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java @@ -343,9 +343,9 @@ public class REntity { } private Object getMoveLookPacket(double diffX, double diffY, double diffZ, boolean rotEq) { - short x = (short) (this.x * 4096); - short y = (short) (this.y * 4096); - short z = (short) (this.z * 4096); + short x = (short) (diffX * 4096); + short y = (short) (diffY * 4096); + short z = (short) (diffZ * 4096); byte yaw = (byte) (this.yaw * 256 / 360); byte pitch = (byte) (this.pitch * 256 / 360); diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java index 1a7532d8..1372ed17 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java @@ -78,7 +78,7 @@ public class REntityServer implements Listener { this.callback = callback; if (uninitialized) { - TinyProtocol.instance.addTypedFilter(ServerboundInteractPacket.class, filter); + TinyProtocol.instance.addFilter(ServerboundInteractPacket.class, filter); } } diff --git a/VelocityCore/Dependencies/build.gradle.kts b/VelocityCore/Dependencies/build.gradle.kts index 2b0beeb2..34b43f07 100644 --- a/VelocityCore/Dependencies/build.gradle.kts +++ b/VelocityCore/Dependencies/build.gradle.kts @@ -37,12 +37,7 @@ tasks.build { } kotlin { - jvmToolchain(17) -} - -java { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + jvmToolchain(21) } dependencies { diff --git a/VelocityCore/Persistent/build.gradle.kts b/VelocityCore/Persistent/build.gradle.kts index 462fccfd..34e0830d 100644 --- a/VelocityCore/Persistent/build.gradle.kts +++ b/VelocityCore/Persistent/build.gradle.kts @@ -21,11 +21,6 @@ plugins { steamwar.java } -java { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 -} - dependencies { compileOnly(libs.velocity) annotationProcessor(libs.velocityapi) diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties index 6f0c2054..0dd2a7d6 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties @@ -493,6 +493,16 @@ TEAM_INFO_TEAM = §7Team §e{0} §8[§{1}{2}§8] TEAM_INFO_LEADER = §7Leader ({0})§8: {1} TEAM_INFO_MEMBER = §7Member ({0})§8: {1} TEAM_INFO_EVENTS = §7Events ({0})§8: §e{1} +#Server Team +TEAM_INFO_SW_USAGE = §8/§7team info §8[§eSW§8|§eSteamWar§8] +TEAM_INFO_SW_HEADER = §7Server Team §eSteam§8War §8[§eS§8W] +TEAM_INFO_SW_RANK = {0} §7({1})§8: {2} + +#TEAM Prefix +TEAM_PREFIX_USAGE = §8/§7team prefix §8[§eteam§8|§eSW§8] +TEAM_PREFIX_CURRENT = §7Current chat prefix§8: §e{0} +TEAM_PREFIX_SET = §7Your chat prefix is now your §e{0} prefix§7. +TEAM_PREFIX_TEAM = Team #Team List TEAM_LIST_NOT_PAGE = §cNo page number entered @@ -586,8 +596,8 @@ JOIN_STREAMING = §5Streaming Mode§7 is still active§8.§7 Keep in mind that y EVENTMODE_KICK = §cYou are not an event participant. #TablistManager -TABLIST_PHASE_WEBSITE = §8Website: https://§eSteam§8War.de -TABLIST_PHASE_DISCORD = §8Discord: https://§eSteam§8War.de/discord +TABLIST_PHASE_WEBSITE = §7Website§8: §7https://§eSteam§8War§7.de +TABLIST_PHASE_DISCORD = §7Discord§8: §7https://§eSteam§8War§7.de/discord TABLIST_FOOTER = §e{0} {1}§8ms §ePlayers§8: §7{2} TABLIST_BAU = §7§lBuild LIST_COMMAND = §e{0}§8 [{1}]: §7{2} diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties index 860d311b..47b815ea 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties @@ -466,6 +466,11 @@ TEAM_INFO_LEADER = §7Leader ({0})§8: {1} TEAM_INFO_MEMBER = §7Member ({0})§8: {1} TEAM_INFO_EVENTS = §7Events ({0})§8: §e{1} +#Team Prefix +TEAM_PREFIX_USAGE = §8/§7team prefix §8[§eteam§8|§eSW§8] +TEAM_PREFIX_CURRENT = §7Aktueller Chatprefix§8: §e{0} +TEAM_PREFIX_SET = §7Dein Chatprefix ist jetzt dein §e{0}prefix§7. + #Team List TEAM_LIST_NOT_PAGE = §cKeine Seitenzahl angegeben TEAM_LIST_UNKNOWN_PAGE = §cUngültige Seitenzahl angegeben diff --git a/VelocityCore/src/de/steamwar/velocitycore/Config.java b/VelocityCore/src/de/steamwar/velocitycore/Config.java index 5c2a886f..6c8ec6d8 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/Config.java +++ b/VelocityCore/src/de/steamwar/velocitycore/Config.java @@ -21,6 +21,7 @@ package de.steamwar.velocitycore; import com.velocitypowered.api.proxy.server.RegisteredServer; import lombok.Getter; +import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.TypeDescription; import org.yaml.snakeyaml.Yaml; @@ -46,7 +47,7 @@ public class Config { Constructor constructor = new Constructor(clazz, new LoaderOptions()); constructor.addTypeDescription(typeDescription); - Representer representer = new Representer(); + Representer representer = new Representer(new DumperOptions()); representer.getPropertyUtils().setSkipMissingProperties(true); Yaml yaml = new Yaml(constructor, representer); diff --git a/VelocityCore/src/de/steamwar/velocitycore/VelocityCore.java b/VelocityCore/src/de/steamwar/velocitycore/VelocityCore.java index b658cb5c..31866c87 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/VelocityCore.java +++ b/VelocityCore/src/de/steamwar/velocitycore/VelocityCore.java @@ -45,6 +45,7 @@ import de.steamwar.velocitycore.commands.TeamCommand; import de.steamwar.velocitycore.discord.DiscordBot; import de.steamwar.velocitycore.discord.DiscordConfig; import de.steamwar.velocitycore.listeners.BasicListener; +import de.steamwar.velocitycore.util.SteamwarPrefix; import lombok.Getter; import lombok.NonNull; @@ -185,6 +186,7 @@ public class VelocityCore implements ReloadablePlugin { schedule(() -> { SteamwarUser.clear(); Team.clear(); + SteamwarPrefix.clearCache(); }).repeat(1, TimeUnit.HOURS).schedule(); DiscordConfig discordConfig = DiscordConfig.load(); diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/TeamCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/TeamCommand.java index c549eec3..c73b256c 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/TeamCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/TeamCommand.java @@ -27,14 +27,12 @@ import de.steamwar.linkage.Linked; import de.steamwar.messages.Chatter; import de.steamwar.messages.Message; import de.steamwar.messages.PlayerChatter; -import de.steamwar.sql.Event; -import de.steamwar.sql.SteamwarUser; -import de.steamwar.sql.Team; -import de.steamwar.sql.TeamTeilnahme; +import de.steamwar.sql.*; import de.steamwar.velocitycore.VelocityCore; import de.steamwar.velocitycore.discord.DiscordBot; import de.steamwar.velocitycore.inventory.SWItem; import de.steamwar.velocitycore.inventory.SWListInv; +import de.steamwar.velocitycore.util.SteamwarPrefix; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.HoverEvent; @@ -51,6 +49,9 @@ import static de.steamwar.persistent.Storage.teamInvitations; @Linked public class TeamCommand extends SWCommand { + public static final String STEAM_WAR = "SteamWar"; + public static final String SW = "SW"; + public TeamCommand() { super("team"); } @@ -324,26 +325,63 @@ public class TeamCommand extends SWCommand { } } + @Register(value = "info", description = "TEAM_INFO_SW_USAGE") + public void infoServerTeam(Chatter sender, @StaticValue({SW, STEAM_WAR}) String __) { + sender.system("TEAM_INFO_SW_HEADER"); + + UserPerm.prefixes.entrySet().stream() + .filter(entry -> entry.getValue().getTeamPrefix()) + .sorted(Map.Entry.comparingByKey().reversed()) + .map(entry -> Map.entry(SteamwarUser.getUsersWithPerm(entry.getKey()), entry.getValue())) + .filter(entry -> !entry.getKey().isEmpty()) + .forEach(entry -> { + UserPerm.Prefix prefix = entry.getValue(); + String memberList = getMemberList(entry.getKey().stream()); + sender.prefixless("TEAM_INFO_SW_RANK", + prefix.getColorCode() + prefix.getChatPrefix(), + entry.getKey().size(), memberList); + }); + } + private String getMemberList(List users, boolean leaders) { - return users.stream() - .filter(user -> user.isLeader() == leaders) - .map(user -> { - StringBuilder st = new StringBuilder(); - if (VelocityCore.getProxy().getPlayer(user.getUUID()).isPresent()) { - if (!StreamingCommand.isNotStreaming(user)) { - st.append("§5"); - } else { - st.append("§a"); - } - } else { - st.append("§e"); - } - st.append(user.getUserName()); - return st.toString(); - }) + return getMemberList(users.stream().filter(u -> u.isLeader() == leaders)); + } + + private String getMemberList(Stream users) { + return users.map(user -> getUserColor(user) + user.getUserName()) .collect(Collectors.joining("§8,§r ")); } + private String getUserColor(SteamwarUser user) { + if (VelocityCore.getProxy().getPlayer(user.getUUID()).isPresent()) { + return StreamingCommand.isNotStreaming(user) ? /* Not Streaming */ "§a" : /* Streaming */ "§5"; + } + return "§e"; // Offline + } + + @Register(value = "prefix", description = "TEAM_PREFIX_USAGE") + public void prefix(@Validator("canUseTeamPrefix") Chatter sender) { + boolean swPrefix = SteamwarPrefix.usesSWPrefix(sender.user()); + sender.system("TEAM_PREFIX_CURRENT", swPrefix ? STEAM_WAR : sender.parseToPlain("TEAM_PREFIX_TEAM")); + } + + @Register(value = "prefix", description = "TEAM_PREFIX_USAGE") + public void prefix(@Validator("canUseTeamPrefix") Chatter sender, @StaticValue(value = {SW, STEAM_WAR, "Team"}, falseValues = {2}, allowISE = true) boolean useSWTeamTag) { + SteamwarPrefix.setSWPrefix(sender.user(), useSWTeamTag); + sender.system("TEAM_PREFIX_SET", useSWTeamTag ? STEAM_WAR : sender.parseToPlain("TEAM_PREFIX_TEAM")); + } + + @Validator(value = "canUseTeamPrefix", local = true) + public TypeValidator canUseTeamPrefixValidator() { + return (sender, value, messageSender) -> { + SteamwarUser user = value.user(); + + return user.hasPerm(UserPerm.TEAM) + && user.getTeam() != 0 + && user.prefix() != UserPerm.emptyPrefix; + }; + } + @Register("list") public void list(Chatter sender, @Min(intValue = 1) @OptionalValue("1") @ErrorMessage("TEAM_LIST_NOT_PAGE") int page) { final int TEAMS_PER_PAGE = 10; @@ -532,6 +570,9 @@ public class TeamCommand extends SWCommand { return new TypeMapper() { @Override public Team map(Chatter sender, PreviousArguments previousArguments, String s) { + if ((s.equalsIgnoreCase(SW) || s.equalsIgnoreCase(STEAM_WAR))) { + return null; + } return Team.get(s); } diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java index cdcb8e51..9cbd4061 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java @@ -22,6 +22,7 @@ package de.steamwar.velocitycore.discord; import de.steamwar.command.SWCommand; import de.steamwar.messages.Chatter; import de.steamwar.sql.Event; +import de.steamwar.sql.SteamwarUser; import de.steamwar.velocitycore.VelocityCore; import de.steamwar.velocitycore.discord.channels.*; import de.steamwar.velocitycore.discord.listeners.ChannelListener; @@ -52,12 +53,12 @@ import net.dv8tion.jda.api.utils.MemberCachePolicy; import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; import java.awt.*; -import java.util.ArrayList; -import java.util.HashMap; +import java.util.*; import java.util.List; -import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; +import java.util.stream.Collectors; public class DiscordBot { public static final String ARGUMENT_NAME = "arguments"; @@ -169,7 +170,7 @@ public class DiscordBot { eventChannel = new StaticMessageChannel(config.channel("events"), EventChannel::get); checklistChannel = new ChecklistChannel(config.channel("checklist")); - config.getCouncilThread().forEach((roleId, threadId) -> new CouncilChannel(DiscordBot.getGuild().getRoleById(roleId), DiscordBot.getGuild().getThreadChannelById(threadId))); + CouncilChannel.initCouncilChannels(); announcementChannel = new DiscordChannel(config.channel("announcement"), 0) { @Override diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/CouncilChannel.java b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/CouncilChannel.java index 5a11bb7c..ac563005 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/CouncilChannel.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/CouncilChannel.java @@ -20,9 +20,7 @@ package de.steamwar.velocitycore.discord.channels; import de.steamwar.sql.SteamwarUser; -import de.steamwar.velocitycore.VelocityCore; import de.steamwar.velocitycore.discord.DiscordBot; -import it.unimi.dsi.fastutil.Pair; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Role; @@ -30,45 +28,88 @@ import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; public class CouncilChannel extends StaticMessageChannel { private static final Set channels = new HashSet<>(); + private static final Set roleSet = DiscordBot.getInstance() + .getConfig() + .getCouncilThread() + .keySet() + .stream() + .map(roleId -> DiscordBot.getGuild().getRoleById(roleId)) + .collect(Collectors.toSet()); + + private static final Map> membersByRole = new HashMap<>(); + + private static void initRolesAndMembers(Runnable loaded) { + List discordIds = SteamwarUser.getUsersWithDiscordId().stream() + .map(SteamwarUser::getDiscordId) + .collect(Collectors.toList()); + + membersByRole.clear(); + AtomicInteger countdown = new AtomicInteger(0); + for (int i = 0; i < discordIds.size(); i += 100) { + countdown.incrementAndGet(); + + List retrieveIds = discordIds.subList(i, Math.min(discordIds.size(), i + 100)); + + DiscordBot.getGuild().retrieveMembersByIds(retrieveIds) + .onSuccess(members -> { + members.forEach(member -> { + for (Role role : roleSet) { + if (member.getUnsortedRoles().contains(role)) { + membersByRole.computeIfAbsent(role, __ -> new ArrayList<>()).add(member); + } + } + }); + + if (countdown.decrementAndGet() == 0) { + loaded.run(); + } + }); + } + } + + public static void initCouncilChannels() { + initRolesAndMembers(() -> { + DiscordBot.getInstance() + .getConfig() + .getCouncilThread() + .forEach((roleId, threadId) -> { + new CouncilChannel(DiscordBot.getGuild().getRoleById(roleId), DiscordBot.getGuild().getThreadChannelById(threadId)); + }); + }); + } + public static void updateAll() { - channels.forEach(StaticMessageChannel::update); + initRolesAndMembers(() -> { + channels.forEach(StaticMessageChannel::update); + }); } public CouncilChannel(Role role, ThreadChannel threadChannel) { super(threadChannel, () -> { MessageCreateBuilder messageCreateBuilder = new MessageCreateBuilder(); messageCreateBuilder.setContent("# Ratsmitglieder"); - - List members; - try { - members = DiscordBot.getGuild().findMembersWithRoles(role).onError(throwable -> { - // Ignore - }).get(); - } catch (Exception e) { - VelocityCore.getLogger().warning("Could not get members for " + role.getName()); - return messageCreateBuilder; - } - - members.stream() + membersByRole.get(role) + .stream() .map(member -> { SteamwarUser steamwarUser = SteamwarUser.get(member.getIdLong()); String name = steamwarUser == null ? member.getEffectiveName() : steamwarUser.getUserName(); UUID uuid = steamwarUser == null ? null : steamwarUser.getUUID(); - return Pair.of(name, uuid); + return Map.entry(name, uuid); }) - .sorted(Comparator.comparing(Pair::key)) - .forEach(pair -> { + .sorted(Map.Entry.comparingByKey()) + .forEach(entry -> { messageCreateBuilder.addEmbeds(new EmbedBuilder() - .setTitle(pair.key()) - .setImage(pair.value() == null ? null : "https://api.steamwar.de/data/skin/" + pair.value().toString()) + .setTitle(entry.getKey()) + .setImage(entry.getValue() == null ? null : "https://api.steamwar.de/data/skin/" + entry.getValue()) .build()); }); - return messageCreateBuilder; }, event -> { }); diff --git a/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java b/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java index 2e083b4d..ad522fee 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java +++ b/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java @@ -42,6 +42,7 @@ import de.steamwar.velocitycore.VelocityCore; import de.steamwar.velocitycore.commands.PunishmentCommand; import de.steamwar.velocitycore.discord.DiscordBot; import de.steamwar.velocitycore.network.NetworkSender; +import de.steamwar.velocitycore.util.SteamwarPrefix; import java.util.Arrays; import java.util.List; @@ -176,19 +177,21 @@ public class ChatListener extends BasicListener { final String coloredMessage = user.hasPerm(UserPerm.COLOR_CHAT) ? message.replace('&', '§') : message; if (chatFilter(sender, coloredMessage)) return; + boolean useSwPrefix = useSwPrefix(user); + boolean noReceiver = true; for (Chatter player : receivers.getChatters()) { if (player.chatShown()) { - chatToReciever(player, msgReceiver, user, format, coloredMessage); + chatToReciever(player, msgReceiver, user, format, coloredMessage, useSwPrefix); if (sender.user().getId() != player.user().getId()) noReceiver = false; } } if (format.equals("CHAT_GLOBAL")) { - DiscordBot.withBot(bot -> chatToReciever(bot.getIngameChat(), msgReceiver, user, format, coloredMessage)); + DiscordBot.withBot(bot -> chatToReciever(bot.getIngameChat(), msgReceiver, user, format, coloredMessage, useSwPrefix)); } else if (format.equals("CHAT_SERVERTEAM")) { - DiscordBot.withBot(bot -> chatToReciever(bot.getServerTeamChat(), msgReceiver, user, "CHAT_GLOBAL", coloredMessage)); + DiscordBot.withBot(bot -> chatToReciever(bot.getServerTeamChat(), msgReceiver, user, "CHAT_GLOBAL", coloredMessage, useSwPrefix)); } else if (noReceiver) { sender.system("CHAT_NO_RECEIVER"); } @@ -239,20 +242,45 @@ public class ChatListener extends BasicListener { return false; } - private static void chatToReciever(Chatter receiver, Chatter msgReceiver, SteamwarUser sender, String format, String message) { + private static void chatToReciever(Chatter receiver, Chatter msgReceiver, SteamwarUser sender, String format, String message, boolean useSwPrefix) { UserPerm.Prefix prefix = sender.prefix(); + + String teamPrefix = ""; + if (sender.hasPerm(UserPerm.TEAM) && useSwPrefix) { + teamPrefix = "§eS§8W "; + } else if (sender.getTeam() != 0) { + Team team = Team.byId(sender.getTeam()); + teamPrefix = "§" + team.getTeamColor() + team.getTeamKuerzel() + " "; + } + String chatColorCode = sender.hasPerm(UserPerm.TEAM) ? "§f" : "§7"; receiver.prefixless(format, sender, msgReceiver == null ? receiver : msgReceiver, highlightMentions(message, chatColorCode, receiver), - sender.getTeam() == 0 ? "" : "§" + Team.byId(sender.getTeam()).getTeamColor() + Team.byId(sender.getTeam()).getTeamKuerzel() + " ", + teamPrefix, "", - prefix.getColorCode(), + prefix == UserPerm.emptyPrefix ? "§f" : prefix.getColorCode(), prefix.getChatPrefix().length() == 0 ? "§f" : prefix.getChatPrefix() + " ", chatColorCode); } + private static boolean useSwPrefix(SteamwarUser user) { + if (!user.hasPerm(UserPerm.TEAM)) { + return false; + } + + UserPerm.Prefix prefix = user.prefix(); + + boolean hasTeamPrefix = user.getTeam() != 0; + boolean hasSwPrefix = prefix != UserPerm.emptyPrefix; + + if (!hasSwPrefix) return false; + if (!hasTeamPrefix) return true; + + return SteamwarPrefix.usesSWPrefix(user); + } + private static boolean filteredCommand(Chatter sender, String message) { String command = message.split(" ", 2)[0]; if (command.startsWith("/") && command.contains(":")) { diff --git a/VelocityCore/src/de/steamwar/velocitycore/tablist/Tablist.java b/VelocityCore/src/de/steamwar/velocitycore/tablist/Tablist.java index 206626ca..0fb7b202 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/tablist/Tablist.java +++ b/VelocityCore/src/de/steamwar/velocitycore/tablist/Tablist.java @@ -51,7 +51,7 @@ public class Tablist extends ChannelInboundHandlerAdapter { private static final UUID[] swUuids = IntStream.range(0, 80).mapToObj(i -> UUID.randomUUID()).toArray(UUID[]::new); private static final String[] swNames = IntStream.range(0, 80).mapToObj(i -> " »SW« " + String.format("%02d", i)).toArray(String[]::new); - public static final UpdateTeamsPacket createTeamPacket = new UpdateTeamsPacket21("zzzzzsw-tab", UpdateTeamsPacket.Mode.CREATE, Component.empty(), Component.empty(), Component.empty(), UpdateTeamsPacket.NameTagVisibility.NEVER, UpdateTeamsPacket.CollisionRule.ALWAYS, 21, (byte) 0x00, Arrays.stream(Tablist.swNames).toList()); + public static final UpdateTeamsPacket createTeamPacket = new UpdateTeamsPacketImpl("zzzzzsw-tab", UpdateTeamsPacket.Mode.CREATE, Component.empty(), Component.empty(), Component.empty(), UpdateTeamsPacket.NameTagVisibility.NEVER, UpdateTeamsPacket.CollisionRule.ALWAYS, 21, (byte) 0x00, Arrays.stream(Tablist.swNames).toList()); private final Map directTabItems; private final List current = new ArrayList<>(); diff --git a/VelocityCore/src/de/steamwar/velocitycore/tablist/UpdateTeamsPacket21.java b/VelocityCore/src/de/steamwar/velocitycore/tablist/UpdateTeamsPacket21.java deleted file mode 100644 index 131bf413..00000000 --- a/VelocityCore/src/de/steamwar/velocitycore/tablist/UpdateTeamsPacket21.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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.velocitycore.tablist; - -import com.velocitypowered.api.network.ProtocolVersion; -import com.velocitypowered.proxy.protocol.ProtocolUtils; -import com.velocitypowered.proxy.protocol.packet.UpdateTeamsPacket; -import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder; -import io.netty.buffer.ByteBuf; -import net.kyori.adventure.text.Component; - -import java.util.List; - -public class UpdateTeamsPacket21 extends UpdateTeamsPacket { - - private String name; - private Mode mode; - private Component displayName; - private Component prefix; - private Component suffix; - private NameTagVisibility nameTagVisibility; - private CollisionRule collisionRule; - private int color; - private byte friendlyFlags; - private List players; - - public UpdateTeamsPacket21(String name, Mode mode, Component displayName, Component prefix, Component suffix, NameTagVisibility nameTagVisibility, CollisionRule collisionRule, int color, byte friendlyFlags, List players) { - super(name, mode, displayName, prefix, suffix, nameTagVisibility, collisionRule, color, friendlyFlags, players); - this.name = name; - this.mode = mode; - this.displayName = displayName; - this.prefix = prefix; - this.suffix = suffix; - this.nameTagVisibility = nameTagVisibility; - this.collisionRule = collisionRule; - this.color = color; - this.friendlyFlags = friendlyFlags; - this.players = players; - } - - @Override - public void encode(ByteBuf byteBuf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) { - ProtocolUtils.writeString(byteBuf, this.name); - byteBuf.writeByte(this.mode.ordinal()); - switch (this.mode) { - case CREATE: - case UPDATE: - (new ComponentHolder(protocolVersion, this.displayName)).write(byteBuf); - if (protocolVersion.lessThan(ProtocolVersion.MINECRAFT_1_13)) { - (new ComponentHolder(protocolVersion, this.prefix)).write(byteBuf); - (new ComponentHolder(protocolVersion, this.suffix)).write(byteBuf); - } - - byteBuf.writeByte(this.friendlyFlags); - if (protocolVersion.noLessThan(ProtocolVersion.MINECRAFT_1_21_5)) { - ProtocolUtils.writeVarInt(byteBuf, this.nameTagVisibility.ordinal()); - ProtocolUtils.writeVarInt(byteBuf, this.collisionRule.ordinal()); - } else { - ProtocolUtils.writeString(byteBuf, this.nameTagVisibility.getValue()); - ProtocolUtils.writeString(byteBuf, this.collisionRule.getValue()); - } - if (protocolVersion.greaterThan(ProtocolVersion.MINECRAFT_1_12_2)) { - ProtocolUtils.writeVarInt(byteBuf, this.color); - (new ComponentHolder(protocolVersion, this.prefix)).write(byteBuf); - (new ComponentHolder(protocolVersion, this.suffix)).write(byteBuf); - } else { - byteBuf.writeByte((byte) this.color); - } - - ProtocolUtils.writeVarInt(byteBuf, this.players.size()); - - for (String player : this.players) { - ProtocolUtils.writeString(byteBuf, player); - } - break; - case ADD_PLAYER: - case REMOVE_PLAYER: - ProtocolUtils.writeVarInt(byteBuf, this.players.size()); - - for (String player : this.players) { - ProtocolUtils.writeString(byteBuf, player); - } - case REMOVE: - } - } -} diff --git a/VelocityCore/src/de/steamwar/velocitycore/tablist/UpdateTeamsPacketImpl.java b/VelocityCore/src/de/steamwar/velocitycore/tablist/UpdateTeamsPacketImpl.java new file mode 100644 index 00000000..998658c5 --- /dev/null +++ b/VelocityCore/src/de/steamwar/velocitycore/tablist/UpdateTeamsPacketImpl.java @@ -0,0 +1,76 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2026 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.tablist; + +import com.velocitypowered.api.network.ProtocolVersion; +import com.velocitypowered.proxy.protocol.ProtocolUtils; +import com.velocitypowered.proxy.protocol.packet.UpdateTeamsPacket; +import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder; +import io.netty.buffer.ByteBuf; +import net.kyori.adventure.text.Component; + +import java.util.List; + +public class UpdateTeamsPacketImpl extends UpdateTeamsPacket { + + public UpdateTeamsPacketImpl(String name, Mode mode, Component displayName, Component prefix, Component suffix, NameTagVisibility nameTagVisibility, CollisionRule collisionRule, int color, byte friendlyFlags, List players) { + super(name, mode, displayName, prefix, suffix, nameTagVisibility, collisionRule, color, friendlyFlags, players); + } + + @Override + public void encode(ByteBuf byteBuf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) { + ProtocolUtils.writeString(byteBuf, name); + byteBuf.writeByte(mode.ordinal()); + + switch (mode) { + case CREATE, UPDATE: + new ComponentHolder(protocolVersion, displayName).write(byteBuf); + if (protocolVersion.lessThan(ProtocolVersion.MINECRAFT_1_13)) { + new ComponentHolder(protocolVersion, prefix).write(byteBuf); + new ComponentHolder(protocolVersion, suffix).write(byteBuf); + } + + byteBuf.writeByte(friendlyFlags); + if (protocolVersion.noLessThan(ProtocolVersion.MINECRAFT_1_21_5)) { + ProtocolUtils.writeVarInt(byteBuf, nameTagVisibility.ordinal()); + ProtocolUtils.writeVarInt(byteBuf, collisionRule.ordinal()); + } else { + ProtocolUtils.writeString(byteBuf, nameTagVisibility.getValue()); + ProtocolUtils.writeString(byteBuf, collisionRule.getValue()); + } + if (protocolVersion.greaterThan(ProtocolVersion.MINECRAFT_1_12_2)) { + ProtocolUtils.writeVarInt(byteBuf, color); + new ComponentHolder(protocolVersion, prefix).write(byteBuf); + new ComponentHolder(protocolVersion, suffix).write(byteBuf); + } else { + byteBuf.writeByte((byte) color); + } + // Fallthrough since players are at the end of the packet! + case ADD_PLAYER, REMOVE_PLAYER: + ProtocolUtils.writeVarInt(byteBuf, players.size()); + for (String player : players) { + ProtocolUtils.writeString(byteBuf, player); + } + break; + case REMOVE: + break; + } + } +} diff --git a/VelocityCore/src/de/steamwar/velocitycore/util/SteamwarPrefix.java b/VelocityCore/src/de/steamwar/velocitycore/util/SteamwarPrefix.java new file mode 100644 index 00000000..77596c5a --- /dev/null +++ b/VelocityCore/src/de/steamwar/velocitycore/util/SteamwarPrefix.java @@ -0,0 +1,48 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2026 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.util; + +import de.steamwar.sql.SteamwarUser; +import de.steamwar.sql.UserConfig; +import lombok.experimental.UtilityClass; + +import java.util.HashMap; +import java.util.Map; + +@UtilityClass +public class SteamwarPrefix { + private static final String PREFIX_MODE_CONFIG = "chatprefix"; + private static final String PREFIX_MODE_SW = "SW"; + + private static final Map usesSwPrefix = new HashMap<>(); + + public static boolean usesSWPrefix(SteamwarUser user) { + return usesSwPrefix.computeIfAbsent(user, u -> PREFIX_MODE_SW.equals(UserConfig.getConfig(u.getId(), PREFIX_MODE_CONFIG))); + } + + public static void setSWPrefix(SteamwarUser user, boolean preferSW) { + UserConfig.updatePlayerConfig(user.getId(), PREFIX_MODE_CONFIG, preferSW ? PREFIX_MODE_SW : null); + usesSwPrefix.put(user, preferSW); + } + + public static void clearCache() { + usesSwPrefix.clear(); + } +} diff --git a/buildSrc/src/steamwar.devserver.gradle b/buildSrc/src/steamwar.devserver.gradle index 19c2570d..618ed2a6 100644 --- a/buildSrc/src/steamwar.devserver.gradle +++ b/buildSrc/src/steamwar.devserver.gradle @@ -49,6 +49,10 @@ class DevServer extends DefaultTask { @Optional Map dParams = new HashMap<>() + @Input + @Optional + String jvmArgs = null + @Input @Optional String checkpointFolder = null @@ -82,6 +86,7 @@ class DevServer extends DefaultTask { if (worldName == null) worldName = properties.get("worldName") host = properties.get("host") + debugPort = new Random().nextInt(5001, 10000) if (host == null) { throw new GradleException("Please supply the 'host' in a 'steamwar.properties' files either in this project dir or any parent project!") @@ -90,6 +95,7 @@ class DevServer extends DefaultTask { doLast { setupTemplate(template) uploadDependencies() + startDebugPort() startDevServer() } finalizedBy(new Finalizer()) @@ -101,6 +107,9 @@ class DevServer extends DefaultTask { @Internal String host + @Internal + int debugPort + @Internal Boolean running = true @@ -209,6 +218,17 @@ class DevServer extends DefaultTask { } } + void startDebugPort() { + def process = new ProcessBuilder("ssh", host, "-L", "5005:localhost:$debugPort").start() + def processOutput = new BufferedReader(new InputStreamReader(process.inputStream)) + new Thread({ + while (running) { + } + processOutput.close() + process.errorStream.close() + }).start() + } + void startDevServer() { def devPy = new StringBuilder().append("dev.py") if (port != null) devPy.append(" --port $port") @@ -221,6 +241,8 @@ class DevServer extends DefaultTask { devPy.append(" -D${dParam.key}=${dParam.value}") } devPy.append(" $template") + devPy.append(" -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:$debugPort") + if (jvmArgs != null) devPy.append(" $jvmArgs") println("Starting $template with command ${devPy.toString()}") def process = new ProcessBuilder("ssh", host, "-T", devPy.toString()).start() diff --git a/settings.gradle.kts b/settings.gradle.kts index c9103d0a..b84535d4 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -122,7 +122,7 @@ dependencyResolutionManagement { library("fawe", "de.steamwar:fastasyncworldedit:1.21") library("velocity", "de.steamwar:velocity:RELEASE") - library("velocityapi", "com.velocitypowered:velocity-api:3.3.0-SNAPSHOT") + library("velocityapi", "com.velocitypowered:velocity-api:3.5.0-SNAPSHOT") library("viaapi", "com.viaversion:viaversion-api:4.3.1") library("viavelocity", "com.viaversion:viaversion-velocity:4.3.1") library("jda", "net.dv8tion:JDA:5.5.1")