From c799046f435451ad62d699db491808886cbf105a Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 28 Dec 2024 18:22:48 +0100 Subject: [PATCH 001/107] Add bigger coins and remove TNT from spawning --- .../tntleague/events/IngameListener.kt | 8 ++++--- .../steamwar/tntleague/game/TNTLeagueGame.kt | 23 +++++++++++-------- .../tntleague/inventory/DealerInventory.kt | 22 ++++++++++++++++-- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/TNTLeague/src/de/steamwar/tntleague/events/IngameListener.kt b/TNTLeague/src/de/steamwar/tntleague/events/IngameListener.kt index f3722c22..7ae0618f 100644 --- a/TNTLeague/src/de/steamwar/tntleague/events/IngameListener.kt +++ b/TNTLeague/src/de/steamwar/tntleague/events/IngameListener.kt @@ -35,6 +35,8 @@ import org.bukkit.event.player.PlayerAttemptPickupItemEvent import org.bukkit.event.player.PlayerInteractEntityEvent import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.event.player.PlayerMoveEvent +import org.bukkit.event.player.* +import org.bukkit.persistence.PersistentDataType object IngameListener : Listener { @@ -75,9 +77,9 @@ object IngameListener : Listener { @EventHandler fun onPickupCoins(e: PlayerAttemptPickupItemEvent) { - if (e.item.itemStack.isSimilar(DealerInventory.coins)) { - TNTLeagueGame.getTeam(e.player)?.coins = - e.item.itemStack.amount + (TNTLeagueGame.getTeam(e.player)?.coins ?: 0) + if (e.item.itemStack.persistentDataContainer.has(DealerInventory.coinKey)) { + val numberOfCoins = e.item.itemStack.persistentDataContainer[DealerInventory.coinKey, PersistentDataType.INTEGER] ?: 0 + TNTLeagueGame.getTeam(e.player)?.coins = (e.item.itemStack.amount * numberOfCoins) + (TNTLeagueGame.getTeam(e.player)?.coins ?: 0) e.item.itemStack.amount = 0 e.isCancelled = true diff --git a/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt b/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt index e064a350..fcc96bb2 100644 --- a/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt +++ b/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt @@ -24,8 +24,6 @@ import de.steamwar.message.SubMessage import de.steamwar.network.NetworkSender import de.steamwar.network.packets.common.FightInfoPacket import de.steamwar.scoreboard.SWScoreboard -import de.steamwar.sql.Fight -import de.steamwar.sql.FightPlayer import de.steamwar.sql.SteamwarUser import de.steamwar.tntleague.colorByTeam import de.steamwar.tntleague.config.TNTLeagueConfig @@ -37,10 +35,9 @@ import de.steamwar.tntleague.events.LobbyListener import de.steamwar.tntleague.inventory.DealerInventory import de.steamwar.tntleague.message import de.steamwar.tntleague.plugin -import de.steamwar.tntleague.util.* +import de.steamwar.tntleague.util.TNTLeagueScoreboard import org.bukkit.GameMode import org.bukkit.Location -import org.bukkit.Material import org.bukkit.Sound import org.bukkit.entity.Item import org.bukkit.entity.Player @@ -51,6 +48,7 @@ import org.bukkit.inventory.ItemStack import org.bukkit.scheduler.BukkitTask import java.sql.Timestamp import java.time.Instant +import kotlin.random.Random object TNTLeagueGame { var state: GameState = GameState.LOBBY @@ -87,18 +85,23 @@ object TNTLeagueGame { message.broadcast("GAME_STARTED") - val tnt = ItemStack(Material.TNT) - start = Timestamp.from(Instant.now()) + val random = Random(System.currentTimeMillis()) + spawnerTask = plugin.server.scheduler.runTaskTimer(plugin, bukkit { + var coinsToSpawn = DealerInventory.coins + if (random.nextDouble() < 0.33) { + coinsToSpawn = DealerInventory.big_coins + } else if (random.nextDouble() < 0.11) { + coinsToSpawn = DealerInventory.huge_coins + } + if (world.getNearbyEntitiesByType(Item::class.java, TNTLeagueWorldConfig.blueTeam.itemSpawn, 3.0).sumOf { it.itemStack.amount } <= 256) { - spawnItems(TNTLeagueWorldConfig.blueTeam.itemSpawn, tnt) - spawnItems(TNTLeagueWorldConfig.blueTeam.itemSpawn, DealerInventory.coins) + spawnItems(TNTLeagueWorldConfig.blueTeam.itemSpawn, coinsToSpawn) } if (world.getNearbyEntitiesByType(Item::class.java, TNTLeagueWorldConfig.redTeam.itemSpawn, 3.0).sumOf { it.itemStack.amount } <= 256) { - spawnItems(TNTLeagueWorldConfig.redTeam.itemSpawn, tnt) - spawnItems(TNTLeagueWorldConfig.redTeam.itemSpawn, DealerInventory.coins) + spawnItems(TNTLeagueWorldConfig.redTeam.itemSpawn, coinsToSpawn) } }, 5, 10) diff --git a/TNTLeague/src/de/steamwar/tntleague/inventory/DealerInventory.kt b/TNTLeague/src/de/steamwar/tntleague/inventory/DealerInventory.kt index 418c15fb..c9bbe635 100644 --- a/TNTLeague/src/de/steamwar/tntleague/inventory/DealerInventory.kt +++ b/TNTLeague/src/de/steamwar/tntleague/inventory/DealerInventory.kt @@ -59,13 +59,31 @@ class DealerInventory(player: Player): KotlinInventory(player) { companion object { private val priceKey = NamespacedKey(plugin, "price") private val amountKey = NamespacedKey(plugin, "amount") - private val coinKey = NamespacedKey(plugin, "coin") + val coinKey = NamespacedKey(plugin, "coin") val coins = ItemStack(Material.RAW_GOLD).apply { itemMeta = itemMeta.apply { displayName(Component.text("Coins").color(NamedTextColor.GOLD)) persistentDataContainer.apply { - set(coinKey, PersistentDataType.BOOLEAN, true) + set(coinKey, PersistentDataType.INTEGER, 1) + } + } + } + + val big_coins = ItemStack(Material.GOLD_INGOT).apply { + itemMeta = itemMeta.apply { + displayName(Component.text("Big Coins").color(NamedTextColor.GOLD)) + persistentDataContainer.apply { + set(coinKey, PersistentDataType.INTEGER, 3) + } + } + } + + val huge_coins = ItemStack(Material.GOLD_BLOCK).apply { + itemMeta = itemMeta.apply { + displayName(Component.text("Huge Coins").color(NamedTextColor.GOLD)) + persistentDataContainer.apply { + set(coinKey, PersistentDataType.INTEGER, 9) } } } From 20c90d9af5c03f063986e904918918012051c149 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 30 Jan 2025 13:18:01 +0100 Subject: [PATCH 002/107] Remove randomness --- .../de/steamwar/tntleague/game/TNTLeagueGame.kt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt b/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt index fcc96bb2..f32cfbe1 100644 --- a/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt +++ b/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt @@ -87,15 +87,16 @@ object TNTLeagueGame { start = Timestamp.from(Instant.now()) - val random = Random(System.currentTimeMillis()) - + var spawnCount = 0 spawnerTask = plugin.server.scheduler.runTaskTimer(plugin, bukkit { - var coinsToSpawn = DealerInventory.coins - if (random.nextDouble() < 0.33) { - coinsToSpawn = DealerInventory.big_coins - } else if (random.nextDouble() < 0.11) { - coinsToSpawn = DealerInventory.huge_coins + val coinsToSpawn = if (spawnCount % 28 == 0) { + DealerInventory.huge_coins + } else if (spawnCount % 7 == 0) { + DealerInventory.big_coins + } else { + DealerInventory.coins } + spawnCount++ if (world.getNearbyEntitiesByType(Item::class.java, TNTLeagueWorldConfig.blueTeam.itemSpawn, 3.0).sumOf { it.itemStack.amount } <= 256) { spawnItems(TNTLeagueWorldConfig.blueTeam.itemSpawn, coinsToSpawn) From 4c6ab2c1a0e71bac024c399bc49ff6a682f7f1a9 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Tue, 8 Apr 2025 20:52:54 +0200 Subject: [PATCH 003/107] Improve and fix the discord rate limit warnings --- .../velocitycore/discord/DiscordBot.java | 11 +++- .../discord/channels/DiscordChannel.java | 61 +++++++++++-------- .../discord/channels/DiscordChatRoom.java | 4 +- .../listeners/DiscordTicketHandler.java | 2 +- 4 files changed, 46 insertions(+), 32 deletions(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java index ecdc5a53..8b522342 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java @@ -167,14 +167,19 @@ public class DiscordBot { checklistChannel = new ChecklistChannel(config.channel("checklist")); config.getCouncilThread().forEach((roleId, threadId) -> new CouncilChannel(DiscordBot.getGuild().getRoleById(roleId), DiscordBot.getGuild().getThreadChannelById(threadId))); - announcementChannel = new DiscordChannel(config.channel("announcement")) { + announcementChannel = new DiscordChannel(config.channel("announcement"), 0) { @Override public void received(MessageReceivedEvent event) { Chatter.broadcast().system("ALERT", event.getMessage().getContentDisplay()); } }; - ingameChat = new DiscordChatRoom(config.channel("ingame"), "CHAT_DISCORD_GLOBAL", Chatter::broadcast); - serverTeamChat = new DiscordChatRoom(config.channel("serverteam"), "CHAT_SERVERTEAM", Chatter::serverteam); + + // There is a hard limit of 30 messages per minute to send as a webhook, thus with 5 webhooks we can send + // 180 messages per minute. Which means 3 every second. I looked at the WGS fights and there were around + // ~70 in a short burst and then rather long no new message. + ingameChat = new DiscordChatRoom(config.channel("ingame"), "CHAT_DISCORD_GLOBAL", Chatter::broadcast, 5); + // 30 messages per minute should be enough for the server team! + serverTeamChat = new DiscordChatRoom(config.channel("serverteam"), "CHAT_SERVERTEAM", Chatter::serverteam, 1); VelocityCore.schedule(() -> { try { diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java index 7092aeb4..08b2b3cd 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java @@ -26,17 +26,21 @@ import de.steamwar.velocitycore.discord.DiscordBot; import de.steamwar.velocitycore.discord.listeners.ChannelListener; import lombok.AllArgsConstructor; import lombok.Getter; -import net.dv8tion.jda.api.entities.Icon; import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.Webhook; +import net.dv8tion.jda.api.entities.WebhookClient; import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; import net.dv8tion.jda.api.events.interaction.component.GenericComponentInteractionCreateEvent; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; -import net.dv8tion.jda.api.utils.ImageProxy; import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; +import net.dv8tion.jda.internal.requests.IncomingWebhookClientImpl; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +import java.util.ArrayDeque; +import java.util.Queue; + @AllArgsConstructor public class DiscordChannel extends Chatter.PlayerlessChatter { @@ -46,31 +50,37 @@ public class DiscordChannel extends Chatter.PlayerlessChatter { return user != null ? user : SteamwarUser.get(0); } + private final Queue webhooks = new ArrayDeque<>(); + private final int maxNumberOfWebhooks; + private final SteamwarUser user; @Getter private final MessageChannel channel; public DiscordChannel(User user) { - this(userOrPublic(user), user.openPrivateChannel().complete()); + this(0, userOrPublic(user), user.openPrivateChannel().complete()); } - public DiscordChannel(String channel) { - this(DiscordBot.getGuild().getTextChannelById(channel)); + public DiscordChannel(String channel, int maxNumberOfWebhooks) { + this(DiscordBot.getGuild().getTextChannelById(channel), maxNumberOfWebhooks); } - public DiscordChannel(MessageChannel channel) { - this(SteamwarUser.get(-1), channel); + public DiscordChannel(MessageChannel channel, int maxNumberOfWebhooks) { + this(maxNumberOfWebhooks, SteamwarUser.get(-1), channel); ChannelListener.getChannels().put(this.channel, this); + if (channel instanceof TextChannel) { + webhooks.addAll(((TextChannel) channel).retrieveWebhooks().complete()); + } } - public void send(String message) { + public synchronized void send(String message) { message = message .replace("&", "") .replace("@everyone", "`@everyone`") .replace("@here", "`@here`") .replaceAll("<[@#]!?\\d+>", "`$0`"); - if (getChannel() instanceof TextChannel && message.contains("»")) { + if (maxNumberOfWebhooks > 0 && getChannel() instanceof TextChannel && message.contains("»")) { String[] strings = message.split("»", 2); String userName = strings[0]; String sendMessage = strings[1]; @@ -85,29 +95,28 @@ public class DiscordChannel extends Chatter.PlayerlessChatter { return; } - ImageProxy avatarUrl; + String avatarUrl; if (user.getDiscordId() != null) { - avatarUrl = DiscordBot.getGuild().retrieveMemberById(user.getDiscordId()).complete().getEffectiveAvatar(); + avatarUrl = DiscordBot.getGuild().retrieveMemberById(user.getDiscordId()).complete().getEffectiveAvatarUrl(); } else { - avatarUrl = DiscordBot.getInstance().getJda().getSelfUser().getAvatar(); + avatarUrl = DiscordBot.getInstance().getJda().getSelfUser().getAvatarUrl(); } TextChannel textChannel = (TextChannel) getChannel(); - try { - textChannel.createWebhook(userName) - .setAvatar(Icon.from(avatarUrl.download(128).get())) - .onSuccess(webhook -> { - webhook.sendMessage(sendMessage) - .onSuccess(__ -> { - webhook.delete().queue(); - }) - .queue(); - }) - .queue(); - return; - } catch (Exception e) { - // Ignore and send message as normal! + if (webhooks.size() < maxNumberOfWebhooks) { + webhooks.add(textChannel.createWebhook(DiscordBot.getInstance().getJda().getSelfUser().getName() + "_" + webhooks.size()).complete()); } + Webhook webhook = webhooks.poll(); + webhooks.add(webhook); + + // This works as per this documentation: https://discord.com/developers/docs/resources/webhook#execute-webhook + IncomingWebhookClientImpl webhookClient = (IncomingWebhookClientImpl) WebhookClient.createClient(DiscordBot.getInstance().getJda(), webhook.getUrl()); + webhookClient.sendRequest() + .setUsername(userName) + .setAvatarUrl(avatarUrl) + .setContent(sendMessage) + .queue(); + return; } send(new MessageCreateBuilder() diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChatRoom.java b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChatRoom.java index 7b05357c..2db981f1 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChatRoom.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChatRoom.java @@ -33,8 +33,8 @@ public class DiscordChatRoom extends DiscordChannel { private final String format; private final Supplier target; - public DiscordChatRoom(String channel, String format, Supplier target) { - super(channel); + public DiscordChatRoom(String channel, String format, Supplier target, int maxNumberOfWebhooks) { + super(channel, maxNumberOfWebhooks); this.format = format; this.target = target; } diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordTicketHandler.java b/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordTicketHandler.java index f32b4767..d58fc6a5 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordTicketHandler.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordTicketHandler.java @@ -70,7 +70,7 @@ public class DiscordTicketHandler extends ListenerAdapter { Permission.MESSAGE_HISTORY).complete(); ticketChannel.getManager().setTopic(event.getUser().getId()).complete(); - DiscordChannel channel = new DiscordChannel(DiscordChannel.userOrPublic(event.getUser()), ticketChannel); + DiscordChannel channel = new DiscordChannel(0, DiscordChannel.userOrPublic(event.getUser()), ticketChannel); channel.send(new MessageCreateBuilder() .setEmbeds(new EmbedBuilder() .setTitle(channel.parseToPlain("DC_TICKET_TITLE")) From 038f54c3b31d9dbab3e0d00d0340728d01297bd1 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 9 Apr 2025 09:03:07 +0200 Subject: [PATCH 004/107] Make it buildable and reduce complexity --- .../discord/channels/ChecklistChannel.java | 2 +- .../discord/channels/DiscordChannel.java | 14 +++++++++----- .../discord/channels/StaticMessageChannel.java | 4 ++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/ChecklistChannel.java b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/ChecklistChannel.java index 6f19f34e..18bbff4a 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/ChecklistChannel.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/ChecklistChannel.java @@ -32,7 +32,7 @@ public class ChecklistChannel extends DiscordChannel { private final List lastSchematics = new ArrayList<>(); public ChecklistChannel(String channel) { - super(channel); + super(channel, 0); } public void update() { diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java index 08b2b3cd..eab85cc1 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java @@ -68,8 +68,16 @@ public class DiscordChannel extends Chatter.PlayerlessChatter { public DiscordChannel(MessageChannel channel, int maxNumberOfWebhooks) { this(maxNumberOfWebhooks, SteamwarUser.get(-1), channel); ChannelListener.getChannels().put(this.channel, this); + if (channel instanceof TextChannel) { - webhooks.addAll(((TextChannel) channel).retrieveWebhooks().complete()); + TextChannel textChannel = (TextChannel) channel; + webhooks.addAll(textChannel.retrieveWebhooks().complete()); + while (webhooks.size() > maxNumberOfWebhooks) { + webhooks.remove().delete().queue(); + } + while (webhooks.size() < maxNumberOfWebhooks) { + webhooks.add(textChannel.createWebhook(DiscordBot.getInstance().getJda().getSelfUser().getName()).complete()); + } } } @@ -102,10 +110,6 @@ public class DiscordChannel extends Chatter.PlayerlessChatter { avatarUrl = DiscordBot.getInstance().getJda().getSelfUser().getAvatarUrl(); } - TextChannel textChannel = (TextChannel) getChannel(); - if (webhooks.size() < maxNumberOfWebhooks) { - webhooks.add(textChannel.createWebhook(DiscordBot.getInstance().getJda().getSelfUser().getName() + "_" + webhooks.size()).complete()); - } Webhook webhook = webhooks.poll(); webhooks.add(webhook); diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/StaticMessageChannel.java b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/StaticMessageChannel.java index 69549d38..9ab2920e 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/StaticMessageChannel.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/StaticMessageChannel.java @@ -46,14 +46,14 @@ public class StaticMessageChannel extends DiscordChannel { } public StaticMessageChannel(String channel, Supplier supplier, Consumer interaction) { - super(channel); + super(channel, 0); this.supplier = supplier; this.interaction = interaction; init(); } public StaticMessageChannel(MessageChannel channel, Supplier supplier, Consumer interaction) { - super(channel); + super(channel, 0); this.supplier = supplier; this.interaction = interaction; init(); From 4a816696ec27e60cf2b803158c3c5af3db9f0c8e Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 9 Apr 2025 09:10:30 +0200 Subject: [PATCH 005/107] Update the message limits --- .../src/de/steamwar/velocitycore/discord/DiscordBot.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java index 8b522342..6ea27e2f 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java @@ -175,11 +175,11 @@ public class DiscordBot { }; // There is a hard limit of 30 messages per minute to send as a webhook, thus with 5 webhooks we can send - // 180 messages per minute. Which means 3 every second. I looked at the WGS fights and there were around + // 240 messages per minute. Which means 4 every second. I looked at the WGS fights and there were around // ~70 in a short burst and then rather long no new message. - ingameChat = new DiscordChatRoom(config.channel("ingame"), "CHAT_DISCORD_GLOBAL", Chatter::broadcast, 5); - // 30 messages per minute should be enough for the server team! - serverTeamChat = new DiscordChatRoom(config.channel("serverteam"), "CHAT_SERVERTEAM", Chatter::serverteam, 1); + ingameChat = new DiscordChatRoom(config.channel("ingame"), "CHAT_DISCORD_GLOBAL", Chatter::broadcast, 8); + // 60 messages per minute should be enough for the server team! + serverTeamChat = new DiscordChatRoom(config.channel("serverteam"), "CHAT_SERVERTEAM", Chatter::serverteam, 2); VelocityCore.schedule(() -> { try { From e1bcdd59baf94934d283e17cfab50fbe7eaa50a5 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Mon, 14 Apr 2025 09:14:04 +0200 Subject: [PATCH 006/107] Move 'maxNumberOfWebhooks' constructor parameter to end of list --- .../velocitycore/discord/channels/DiscordChannel.java | 9 +++++---- .../discord/listeners/DiscordTicketHandler.java | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java index eab85cc1..5fcbcf6a 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java @@ -51,14 +51,15 @@ public class DiscordChannel extends Chatter.PlayerlessChatter { } private final Queue webhooks = new ArrayDeque<>(); - private final int maxNumberOfWebhooks; private final SteamwarUser user; @Getter private final MessageChannel channel; + private final int maxNumberOfWebhooks; + public DiscordChannel(User user) { - this(0, userOrPublic(user), user.openPrivateChannel().complete()); + this(userOrPublic(user), user.openPrivateChannel().complete(), 0); } public DiscordChannel(String channel, int maxNumberOfWebhooks) { @@ -66,7 +67,7 @@ public class DiscordChannel extends Chatter.PlayerlessChatter { } public DiscordChannel(MessageChannel channel, int maxNumberOfWebhooks) { - this(maxNumberOfWebhooks, SteamwarUser.get(-1), channel); + this(SteamwarUser.get(-1), channel, maxNumberOfWebhooks); ChannelListener.getChannels().put(this.channel, this); if (channel instanceof TextChannel) { @@ -81,7 +82,7 @@ public class DiscordChannel extends Chatter.PlayerlessChatter { } } - public synchronized void send(String message) { + public void send(String message) { message = message .replace("&", "") .replace("@everyone", "`@everyone`") diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordTicketHandler.java b/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordTicketHandler.java index d58fc6a5..5c5e708b 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordTicketHandler.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/listeners/DiscordTicketHandler.java @@ -70,7 +70,7 @@ public class DiscordTicketHandler extends ListenerAdapter { Permission.MESSAGE_HISTORY).complete(); ticketChannel.getManager().setTopic(event.getUser().getId()).complete(); - DiscordChannel channel = new DiscordChannel(0, DiscordChannel.userOrPublic(event.getUser()), ticketChannel); + DiscordChannel channel = new DiscordChannel(DiscordChannel.userOrPublic(event.getUser()), ticketChannel, 0); channel.send(new MessageCreateBuilder() .setEmbeds(new EmbedBuilder() .setTitle(channel.parseToPlain("DC_TICKET_TITLE")) From 5b3c3f36b47c07f414fcb376df5ef5d71754b7ca Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Mon, 14 Apr 2025 09:16:06 +0200 Subject: [PATCH 007/107] Fix comment --- .../src/de/steamwar/velocitycore/discord/DiscordBot.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java index 6ea27e2f..637b0c7e 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java @@ -174,7 +174,7 @@ public class DiscordBot { } }; - // There is a hard limit of 30 messages per minute to send as a webhook, thus with 5 webhooks we can send + // There is a hard limit of 30 messages per minute to send as a webhook, thus with 8 webhooks we can send // 240 messages per minute. Which means 4 every second. I looked at the WGS fights and there were around // ~70 in a short burst and then rather long no new message. ingameChat = new DiscordChatRoom(config.channel("ingame"), "CHAT_DISCORD_GLOBAL", Chatter::broadcast, 8); From df5c363fb757c1aa20bb46be461cd4c226cb67ef Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Mon, 14 Apr 2025 09:57:31 +0200 Subject: [PATCH 008/107] Fix FreezeListener --- .../de/steamwar/bausystem/features/region/FreezeListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeListener.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeListener.java index a284cfa8..eb712ab4 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeListener.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeListener.java @@ -113,8 +113,8 @@ public class FreezeListener implements Listener, ScoreboardElement { if (Core.getVersion() < 19) return; if (e.getPlayer().getInventory().getItemInMainHand().getType() == Material.DEBUG_STICK) return; if (Region.getRegion(e.getBlock().getLocation()).get(Flag.FREEZE) == FreezeMode.ACTIVE) { - if (e.isCancelled()) return; e.setCancelled(true); + e.getBlock().setType(Material.BARRIER, false); e.getBlock().setType(Material.AIR, false); } } From b2853b9dec45baebd534861c380d4e5bc5f98df3 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Mon, 14 Apr 2025 10:01:50 +0200 Subject: [PATCH 009/107] Fix RCommand being able to send offline players --- .../src/de/steamwar/velocitycore/commands/MsgCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/MsgCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/MsgCommand.java index 8341318f..b14a827a 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/MsgCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/MsgCommand.java @@ -41,7 +41,7 @@ public class MsgCommand extends SWCommand { } public static void msg(PlayerChatter sender, Player target, String[] args) { - if(target == null) { + if(target == null || target.getCurrentServer().isEmpty()) { sender.system("MSG_OFFLINE"); return; } From 0b14a216d96ff2f23b524655e2e078ef5fec9483 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Mon, 14 Apr 2025 10:04:57 +0200 Subject: [PATCH 010/107] Fix SmartPlaceListener updating block under repeater/comparator --- .../bausystem/features/smartplace/SmartPlaceListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java index 75b3f8b7..dd3c61c2 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java @@ -223,7 +223,7 @@ public class SmartPlaceListener implements Listener { Block block = event.getBlock().getRelative(BlockFace.DOWN); BlockState old = block.getState(); Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { - block.setType(Material.GLASS); + block.setType(Material.GLASS, false); old.update(true, false); }, 1); } From 866c376ee58692d7e726f5f5a53d767470219599 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 16 Apr 2025 10:20:10 +0200 Subject: [PATCH 011/107] Fix DevCommand not working when version switching without trying to connect in between when no server is running --- .../src/de/steamwar/velocitycore/commands/DevCommand.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/DevCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/DevCommand.java index 71b4427c..bf74e672 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/DevCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/DevCommand.java @@ -135,12 +135,12 @@ public class DevCommand extends SWCommand { }); devServerPorts.forEach((username, value) -> { - if (devServers.containsKey(username)) - return; - SteamwarUser user = SteamwarUser.get(username); String name = "Dev " + user.getUserName(); ((VelocityViaConfig) Via.getConfig()).getVelocityServerProtocols().put(name, ServerVersion.get(devServerVersions.get(username)).getProtocolVersion().getProtocol()); + + if (devServers.containsKey(username)) + return; devServers.put(user.getUserName().toLowerCase(), VelocityCore.getProxy().registerServer(new ServerInfo(name, new InetSocketAddress("127.0.0.1", value)))); }); } From 9da1de9b6c80b170f363cc3e363abd1c8c92f33b Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 16 Apr 2025 13:42:31 +0200 Subject: [PATCH 012/107] Fix MsgCommand being able to /r to offline players --- .../src/de/steamwar/velocitycore/commands/MsgCommand.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/MsgCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/MsgCommand.java index b14a827a..5300909d 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/MsgCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/MsgCommand.java @@ -20,6 +20,8 @@ package de.steamwar.velocitycore.commands; import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.proxy.Velocity; +import de.steamwar.velocitycore.VelocityCore; import de.steamwar.velocitycore.listeners.ChatListener; import de.steamwar.command.SWCommand; import de.steamwar.messages.Chatter; @@ -41,7 +43,7 @@ public class MsgCommand extends SWCommand { } public static void msg(PlayerChatter sender, Player target, String[] args) { - if(target == null || target.getCurrentServer().isEmpty()) { + if(target == null || VelocityCore.getProxy().getPlayer(target.getUniqueId()).orElse(null) == null) { sender.system("MSG_OFFLINE"); return; } From d04ffd5cf6ef61c90f3a9141124f5cf958ee47ca Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 16 Apr 2025 18:12:50 +0200 Subject: [PATCH 013/107] Fix some stuff for 1.21 BauSystem --- .../features/script/lua/libs/TpsLib.java | 2 +- .../features/tpslimit/TPSCommand.java | 12 ++++++------ .../bausystem/features/tpslimit/TPSSystem.java | 18 +++++++----------- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TpsLib.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TpsLib.java index 1435aa44..6b9435e1 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TpsLib.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TpsLib.java @@ -51,7 +51,7 @@ public class TpsLib implements LuaLib { tpsLib.set("fiveMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.FIVE_MINUTES))); tpsLib.set("tenMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES))); tpsLib.set("current", getter(TPSWatcher::getTPS)); - tpsLib.set("limit", getter(tpsSystem::getCurrentTPSLimit)); + tpsLib.set("limit", getter(TPSSystem::getCurrentTPSLimit)); return tpsLib; } } diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSCommand.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSCommand.java index 1b5b51eb..c1d09c63 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSCommand.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSCommand.java @@ -42,16 +42,16 @@ public class TPSCommand extends SWCommand { public void genericCommand(Player p, String... args) { BauSystem.MESSAGE.sendPrefixless("OTHER_TPS_HEAD", p); BauSystem.MESSAGE.sendPrefixless("OTHER_TPS_MESSAGE", p, - TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_SECOND), - TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_SECONDS), - TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_MINUTE), - TPSWatcher.getTPS(TPSWatcher.TPSType.FIVE_MINUTES), - TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES) + TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.ONE_SECOND), + TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.TEN_SECONDS), + TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.ONE_MINUTE), + TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.FIVE_MINUTES), + TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.TEN_MINUTES) ); } @Register public void genericCommand(Player p, TPSWatcher.TPSType type) { - BauSystem.MESSAGE.sendPrefixless("OTHER_TPS_SINGLE", p, tpsSystem.getTPS(type)); + BauSystem.MESSAGE.sendPrefixless("OTHER_TPS_SINGLE", p, TPSWatcher.getTPSUnlimited(type)); } } diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSSystem.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSSystem.java index 1e25ff18..ac393e57 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSSystem.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSSystem.java @@ -56,11 +56,7 @@ import java.util.Arrays; public class TPSSystem implements Listener { @Getter - private double currentTPSLimit = 20; - - public double getTPS(TPSWatcher.TPSType tpsType) { - return TPSWatcher.getTPSUnlimited(tpsType); - } + private static double currentTPSLimit = 20; public TPSSystem() { if (TPSFreezeUtils.isCanFreeze()) { @@ -338,26 +334,26 @@ public class TPSSystem implements Listener { } else if (TPSFreezeUtils.frozen()) { return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8: " + BauSystem.MESSAGE.parse("SCOREBOARD_TPS_FROZEN", p); } else { - return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8: " + tpsColor() + tpsSystem.getTPS(TPSWatcher.TPSType.ONE_SECOND) + tpsLimit(); + return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8: " + tpsColor() + TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.ONE_SECOND) + tpsLimit(); } } private String tpsColor() { - double tps = tpsSystem.getTPS(TPSWatcher.TPSType.ONE_SECOND); - if (tps > tpsSystem.getCurrentTPSLimit() * 0.9) { + double tps = TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.ONE_SECOND); + if (tps > TPSSystem.getCurrentTPSLimit() * 0.9) { return "§a"; } - if (tps > tpsSystem.getCurrentTPSLimit() * 0.5) { + if (tps > TPSSystem.getCurrentTPSLimit() * 0.5) { return "§e"; } return "§c"; } private String tpsLimit() { - if (tpsSystem.getCurrentTPSLimit() == 20) { + if (TPSSystem.getCurrentTPSLimit() == 20) { return ""; } - return "§8/§7" + tpsSystem.getCurrentTPSLimit(); + return "§8/§7" + TPSSystem.getCurrentTPSLimit(); } } From e24dada43535f56a2e02e7d2f1fd27ac7f87731d Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 16 Apr 2025 18:13:58 +0200 Subject: [PATCH 014/107] Trigger rebuild --- settings.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 9fdaa60e..dc94bc0c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -27,7 +27,6 @@ private val isInCi by lazy { Os.isFamily(Os.FAMILY_UNIX) && ProcessBuilder("host dependencyResolutionManagement { repositories { - maven { url = URI("https://m2.dv8tion.net/releases") content { From 29dff8dce62248b8fb8b38d343e0019190e88b03 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 16 Apr 2025 21:07:05 +0200 Subject: [PATCH 015/107] Fix PunishmentCommand sending double prefix --- .../de/steamwar/messages/BungeeCore.properties | 18 +++++++++--------- .../steamwar/messages/BungeeCore_de.properties | 18 +++++++++--------- .../commands/PunishmentCommand.java | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties index 863d1099..e7ed6194 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties @@ -154,7 +154,7 @@ UNPUNISHMENT_USAGE=§8/§7{0} §8[§eplayer§8] PUNISHMENT_UNTIL=until {0} PUNISHMENT_PERMA=permanent -BAN_TEAM={0} §e{1} §7was §e§lbanned§7 by §e{2} {3}§8: §f{4} +BAN_TEAM=§e{0} §7was §e§lbanned§7 by §e{1} {2}§8: §f{3} BAN_PERMA=§7You are §e§lbanned §epermanently§8: §e{0} BAN_UNTIL=§7You are §e§lbanned §euntil {0}§8: §e{1} UNBAN_ERROR=§cThe player isn't banned. @@ -164,49 +164,49 @@ BAN_AVOIDING_ALERT=§cPotential ban bypass by §r{0}§c: {1} BAN_AVOIDING_LIST=§c{0} §e{1} BAN_AVOIDING_BAN_HOVER=§cBan player because of bann bypass. -MUTE_TEAM={0} §e{1} §7was §e§lmuted§7 by §e{2} {3}§8: §f{4} +MUTE_TEAM=§e{0} §7was §e§lmuted§7 by §e{1} {2}§8: §f{3} MUTE_PERMA=§7You are §epermanently §e§lmuted§8: §e{0} MUTE_UNTIL=§7You are §e§lmuted §euntil {0}§8: §e{1} UNMUTE_ERROR=§cThe player isn't muted. UNMUTE=§7You have §e§lunmuted §e{0}. -NOSCHEMRECEIVING_TEAM={0} §e{1} §7was excluded from §e{2} {3} §7from §e§lrecieving schematics§8: §f{4} +NOSCHEMRECEIVING_TEAM=§e{0} §7was excluded from §e{1} {2} §7from §e§lrecieving schematics§8: §f{3} NOSCHEMRECEIVING_PERMA=§7You are §epermanently§7 excluded from receiving §e§lschematics§8: §e{0} NOSCHEMRECEIVING_UNTIL=§7You are excluded from receiving §e§lschematics §euntil {0}§8: §e{1} UNNOSCHEMRECEIVING_ERROR=§cThe player is not excluded from receiving schematics. UNNOSCHEMRECEIVING=§e{0} §7may now receive §e§lschematics§7 again§8. -NOSCHEMSHARING_TEAM={0} §e{1} §7was excluded from §e{2} {3} §7from §e§lsharing schematics§8: §f{4} +NOSCHEMSHARING_TEAM=§e{0} §7was excluded from §e{1} {2} §7from §e§lsharing schematics§8: §f{3} NOSCHEMSHARING_PERMA=§7You are §epermanently§7 excluded from sharing §e§lschematics§8: §e{0} NOSCHEMSHARING_UNTIL=§7You are excluded from sharing §e§lschematics §euntil {0}§8: §e{1} UNNOSCHEMSHARING_ERROR=§cThe player is not excluded from sharing schematics. UNNOSCHEMSHARING=§e{0} §7may now share §e§lschematics§7 again§8. -NOSCHEMSUBMITTING_TEAM={0} §e{1} §7was excluded from §e{2} {3} §7from §e§lsubmitting schematics§8: §f{4} +NOSCHEMSUBMITTING_TEAM=§e{0} §7was excluded from §e{1} {2} §7from §e§lsubmitting schematics§8: §f{3} NOSCHEMSUBMITTING_PERMA=§7You are §epermanently§7 excluded from submitting §e§lschematics§8: §e{0} NOSCHEMSUBMITTING_UNTIL=§7You are excluded from submitting §e§lschematics §euntil {0}§8: §e{1} UNNOSCHEMSUBMITTING_ERROR=§cThe player is not excluded from submitting schematics. UNNOSCHEMSUBMITTING=§e{0} §7may now submit §e§lschematics§7 again§8. -NODEVSERVER_TEAM={0} §e{1} §7has annoyed §e{2} §7with reason §f{4}§7 and therefore has received §e§ldev server prohibition§7§8, §f{3} +NODEVSERVER_TEAM=§e{0} §7has annoyed §e{1} §7with reason §f{3}§7 and therefore has received §e§ldev server prohibition§7§8, §f{2} NODEVSERVER_PERMA=§7You are §epermanently§7 excluded from §e§ldev servers§8: §e{0} NODEVSERVER_UNTIL=§7You are excluded from §e§ldev servers§7 §euntil {0}§8: §e{1} UNNODEVSERVER_ERROR=§cThe player is not excluded from dev servers. UNNODEVSERVER=§e{0} §7may now join §e§ldev servers§7 again§8. -NOFIGHTSERVER_TEAM={0} §e{1} §7was excluded from §e{2} {3} §7from §e§lfighting§8: §f{4} +NOFIGHTSERVER_TEAM=§e{0} §7was excluded from §e{1} {2} §7from §e§lfighting§8: §f{3} NOFIGHTSERVER_PERMA=§7You are §epermanently§7 excluded from §e§lfighting§8: §e{0} NOFIGHTSERVER_UNTIL=§7You are excluded from §e§lfighting§7 §euntil {0}§8: §e{1} UNNOFIGHTSERVER_ERROR=§cThe player is not excluded from fighting. UNNOFIGHTSERVER=§e{0} §7may now join §e§lfights§7 again§8. -NOTEAMSERVER_TEAM={0} §e{1} §7was excluded from §e{2} {3} §7from §e§lteam servers§8: §f{4} +NOTEAMSERVER_TEAM=§e{0} §7was excluded from §e{1} {2} §7from §e§lteam servers§8: §f{3} NOTEAMSERVER_PERMA=§7You are §epermanently§7 excluded from §e§lteam servers§8: §e{0} NOTEAMSERVER_UNTIL=§7You are excluded from §e§lteam servers§7 §euntil {0}§8: §e{1} UNNOTEAMSERVER_ERROR=§cThe player is not excluded from team servers. UNNOTEAMSERVER=§e{0} §7may now set §e§lteam servers§7 again§8. -NOTE_TEAM={0} §e{1} §7received a §e§lnote§7 from §e{2} {3}: §f{4} +NOTE_TEAM=§e{0} §7received a §e§lnote§7 from §e{1} {2}: §f{3} #BugCommand BUG_MESSAGE=§7Please describe the issue in a Discord ticket with the bug ID §e{0} §7further§8. diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties index b758353c..d575eed4 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties @@ -138,7 +138,7 @@ UNPUNISHMENT_USAGE=§8/§7{0} §8[§eSpieler§8] PUNISHMENT_UNTIL=bis zum {0} PUNISHMENT_PERMA=permanent -BAN_TEAM={0} §e{1} §7wurde von §e{2} {3} §e§lgebannt§8. §7Grund§8: §f{4} +BAN_TEAM=§e{1} §7wurde von §e{2} {3} §e§lgebannt§8. §7Grund§8: §f{4} BAN_PERMA=§7Du bist §epermanent §e§lgebannt§8. §7Grund§8: §e{0} BAN_UNTIL=§7Du bist §ebis zum {0} §e§lgebannt§8. §7Grund§8: §e{1} UNBAN_ERROR=§cDer Spieler ist nicht gebannt. @@ -148,49 +148,49 @@ BAN_AVOIDING_ALERT=§cMögliche Bannumgehung durch §r{0}§c: {1} BAN_AVOIDING_LIST=§c{0} §e{1} BAN_AVOIDING_BAN_HOVER=§cBanne Spieler wegen Bannumgehung -MUTE_TEAM={0} §e{1} §7wurde von §e{2} {3} §e§lgemuted§8. §7Grund§8: §f{4} +MUTE_TEAM=§e{0} §7wurde von §e{1} {2} §e§lgemuted§8. §7Grund§8: §f{3} MUTE_PERMA=§7Du bist §epermanent §e§lgemuted§8. §7Grund§8: §e{0} MUTE_UNTIL=§7Du bist §ebis zum {0} §e§lgemuted§8. §7Grund§8: §e{1} UNMUTE_ERROR=§cDer Spieler ist nicht gemuted. UNMUTE=§7Du hast §e{0} §e§lentmuted. -NOSCHEMRECEIVING_TEAM={0} §e{1} §7wurde von §e{2} {3} §7vom §e§lSchematicerhalten§7 ausgeschlossen§8: §f{4} +NOSCHEMRECEIVING_TEAM=§e{0} §7wurde von §e{1} {2} §7vom §e§lSchematicerhalten§7 ausgeschlossen§8: §f{3} NOSCHEMRECEIVING_PERMA=§7Du bist §epermanent §7vom Erhalten von §e§lSchematics§7 ausgeschlossen§8: §e{0} NOSCHEMRECEIVING_UNTIL=§7Du bist §ebis zum {0} §7vom Erhalten von §e§lSchematics§7 ausgeschlossen§8: §e{1} UNNOSCHEMRECEIVING_ERROR=§cDer Spieler ist nicht vom Erhalten von Schematics ausgeschlossen. UNNOSCHEMRECEIVING=§e{0} §7darf nun wieder §e§lSchematics§7 erhalten§8. -NOSCHEMSHARING_TEAM={0} §e{1} §7wurde von §e{2} {3} §7vom §e§lSchematicverteilen§7 ausgeschlossen§8: §f{4} +NOSCHEMSHARING_TEAM=§e{0} §7wurde von §e{1} {2} §7vom §e§lSchematicverteilen§7 ausgeschlossen§8: §f{3} NOSCHEMSHARING_PERMA=§7Du bist §epermanent §7vom §e§lVerteilen von Schematics§7 ausgeschlossen§8: §e{0} NOSCHEMSHARING_UNTIL=§7Du bist §ebis zum {0} §7vom §e§lVerteilen von Schematics§7 ausgeschlossen§8: §e{1} UNNOSCHEMSHARING_ERROR=§cDer Spieler ist nicht vom Verteilen von Schematics ausgeschlossen. UNNOSCHEMSHARING=§e{0} §7darf nun wieder §e§lSchematics§7 verteilen§8. -NOSCHEMSUBMITTING_TEAM={0} §e{1} §7wurde von §e{2} {3} §7vom §e§lSchematiceinsenden§7 ausgeschlossen§8: §f{4} +NOSCHEMSUBMITTING_TEAM=§e{0} §7wurde von §e{1} {2} §7vom §e§lSchematiceinsenden§7 ausgeschlossen§8: §f{3} NOSCHEMSUBMITTING_PERMA=§7Du bist §epermanent §7vom §e§lEinsenden von Schematics§7 ausgeschlossen§8: §e{0} NOSCHEMSUBMITTING_UNTIL=§7Du bist §ebis zum {0} §7vom §e§lEinsenden von Schematics§7 ausgeschlossen§8: §e{1} UNNOSCHEMSUBMITTING_ERROR=§cDer Spieler ist nicht vom Einsenden von Schematics ausgeschlossen. UNNOSCHEMSUBMITTING=§e{0} §7darf nun wieder §e§lSchematis§7 einsenden§8. -NODEVSERVER_TEAM={0} §e{1} §7hat §e{2} §7mit Grund §f{4}§7 zu genervt und hat daher §e§lDevserververbot§7 erhalten§8, §f{3} +NODEVSERVER_TEAM=§e{0} §7hat §e{1} §7mit Grund §f{3}§7 zu genervt und hat daher §e§lDevserververbot§7 erhalten§8, §f{2} NODEVSERVER_PERMA=§7Du bist §epermanent §7vom §e§lDevserver§7 ausgeschlossen§8: §e{0} NODEVSERVER_UNTIL=§7Du bist §ebis zum {0} §7vom §e§lDevserver§7 ausgeschlossen§8: §e{1} UNNODEVSERVER_ERROR=§cDer Spieler ist nicht vom Devserver ausgeschlossen. UNNODEVSERVER=§e{0} §7darf nun wieder dem §e§lDevserver§7 beitreten§8. -NOFIGHTSERVER_TEAM={0} §e{1} §7wurde von §e{2} {3} §7vom §e§lKämpfen§7 ausgeschlossen§8: §f{4} +NOFIGHTSERVER_TEAM=§e{0} §7wurde von §e{1} {2} §7vom §e§lKämpfen§7 ausgeschlossen§8: §f{3} NOFIGHTSERVER_PERMA=§7Du bist §epermanent §7vom §e§lKämpfen§7 ausgeschlossen§8: §e{0} NOFIGHTSERVER_UNTIL=§7Du bist §ebis zum {0} §7vom §e§lKämpfen§7 ausgeschlossen§8: §e{1} UNNOFIGHTSERVER_ERROR=§cDer Spieler ist nicht vom Kämpfen ausgeschlossen. UNNOFIGHTSERVER=§e{0} §7darf nun wieder §e§lKämpfen§7 beitreten§8. -NOTEAMSERVER_TEAM={0} §e{1} §7wurde von §e{2} {3} §7vom §e§lTeamserver§7 setzen ausgeschlossen§8: §f{4} +NOTEAMSERVER_TEAM=§e{0} §7wurde von §e{1} {2} §7vom §e§lTeamserver§7 setzen ausgeschlossen§8: §f{3} NOTEAMSERVER_PERMA=§7Du bist §epermanent §7vom §e§lTeamserver§7 setzen ausgeschlossen§8: §e{0} NOTEAMSERVER_UNTIL=§7Du bist §ebis zum {0} §7vom §e§lTeamserver§7 setzen ausgeschlossen§8: §e{1} UNNOTEAMSERVER_ERROR=§cDer Spieler ist nicht vom Teamserver setzten ausgeschlossen. UNNOTEAMSERVER=§e{0} §7darf nun wieder §e§lTeamserver§7 setzen§8. -NOTE_TEAM={0} §e{1} §7erhielt von §e{2} {3} §7die §e§lNotiz§7§8: §f{4} +NOTE_TEAM=§e{0} §7erhielt von §e{1} {2} §7die §e§lNotiz§7§8: §f{3} #BugCommand BUG_MESSAGE=§7Bitte beschreibe das Problem in einem Discordticket genauer und gebe dabei die Bug-ID §e{0} §7an§8. diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/PunishmentCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/PunishmentCommand.java index 1dc8ebde..4932de02 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/PunishmentCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/PunishmentCommand.java @@ -210,7 +210,7 @@ public class PunishmentCommand { target.punish(punishmentType, banTime, msg, punisher.getId(), isPerma); if(punishmentType == Punishment.PunishmentType.Ban) ban(target, banTime, msg, punisher, isPerma); - Chatter.serverteam().system(punishmentType.getTeamMessage(), new Message("PREFIX"), target, sender, new Message((isPerma ? "PUNISHMENT_PERMA" : "PUNISHMENT_UNTIL"), banTime), msg); + Chatter.serverteam().system(punishmentType.getTeamMessage(), target, sender, new Message((isPerma ? "PUNISHMENT_PERMA" : "PUNISHMENT_UNTIL"), banTime), msg); } @Register From 306444356cbcb2255389f5d0a3b308f8981354d9 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Thu, 17 Apr 2025 01:28:06 +0200 Subject: [PATCH 016/107] Update & Fix Spelling on Chaos Messages --- .../src/de/steamwar/messages/BungeeCore_de.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties index d575eed4..d334a02a 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties @@ -536,9 +536,9 @@ CHAT_YOYONOW_3=Vielen Dank. CHAT_YOYONOW_4=Ich wünsche dir noch weiterhin ein reibungsloses Spielerlebnis. CHAT_CHAOSCAOT_1=Du hast mich gerufen! CHAT_CHAOSCAOT_2=Wenn etwas nicht funktioniert, dann nen es einfach ein Feature. -CHAT_CHAOSCAOT_3=Und wenn es ein Feature ist, dann kann es nicht kaputt. -CHAT_CHAOSCAOT_4=Kaputt ist nur eine Definition. Wenn du es als Feature definiert, dann kann es nicht kaputt sein. -CHAT_CHAOSCAOT_5=Und wenn du es als kaputt definiert, dann sag uns bescheid mit dem Befehl "/bug ". +CHAT_CHAOSCAOT_3=Und wenn es ein Feature ist, dann kann es nicht kaputt sein. +CHAT_CHAOSCAOT_4=Kaputt ist nur eine Definition. Wenn du alles als Feature definierst, dann kann es auch keine Bugs geben. +CHAT_CHAOSCAOT_5=Solltest du es aber doch als Bug definieren, dann sag uns bescheid mit dem Befehl "/bug ". CHAT_CHAOSCAOT_6=Vielen Dank. CHAT_RECEIVE=§cUm Chatnachrichten versenden zu können, musst du auch welche empfangen! CHAT_NO_LINKS=§cDu darfst keine Links versenden. From ae7d394ae2bb90b4bd5ad0a811a9a87a4f9b1eb3 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 17 Apr 2025 15:45:25 +0200 Subject: [PATCH 017/107] Enable clicking 'Ready' in inventory --- .../steamwar/fightsystem/fight/HotbarKit.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java index 5bc1d844..6567fe87 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java @@ -34,6 +34,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; +import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; @@ -117,5 +118,22 @@ public class HotbarKit extends Kit { ((HotbarKit)activeKit).onClicks[slot].accept(player); } + + @EventHandler + public void onInventoryClick(InventoryClickEvent event) { + int slot = event.getSlot(); + if (slot < 0 || slot >= HOTBAR_SIZE) return; + + Player player = (Player) event.getWhoClicked(); + Kit activeKit = activeKits.get(player); + if(!(activeKit instanceof HotbarKit) || PersonalKitCreator.inKitCreator(player) || activeKit.getInventory()[slot] == null) + return; + + event.setCancelled(true); + if(!clicked.add(player)) + return; + + ((HotbarKit)activeKit).onClicks[slot].accept(player); + } } } From 424c80ec81201f7dc1bbe5059d79bca1ee90361b Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 17 Apr 2025 16:09:29 +0200 Subject: [PATCH 018/107] Add general Melting of Blocks --- .../de/steamwar/towerrun/config/WorldConfig.java | 16 ++++------------ .../towerrun/listener/IngameListener.java | 13 +++++++------ 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/TowerRun/src/de/steamwar/towerrun/config/WorldConfig.java b/TowerRun/src/de/steamwar/towerrun/config/WorldConfig.java index fafdd453..56e90034 100644 --- a/TowerRun/src/de/steamwar/towerrun/config/WorldConfig.java +++ b/TowerRun/src/de/steamwar/towerrun/config/WorldConfig.java @@ -35,7 +35,8 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.util.Vector; import java.io.File; -import java.util.*; +import java.util.ArrayList; +import java.util.List; @UtilityClass public class WorldConfig { @@ -54,7 +55,7 @@ public class WorldConfig { public static final int MAP_MIN_Z; public static final int MAP_MAX_X; public static final int MAP_MAX_Z; - public static final Map MELTING_TIMES; + public static final boolean MELTING; public static final TowerGeneratorConfig TOWER_GENERATOR_CONFIG; public static final List WINCONDITIONS = new ArrayList<>(); @@ -161,16 +162,7 @@ public class WorldConfig { MAP_MAX_X = config.getInt("maxX"); MAP_MAX_Z = config.getInt("maxZ"); - ConfigurationSection meltingBlocksSection = tower.getConfigurationSection("meltingBlocks"); - if (meltingBlocksSection != null) { - Map meltingTimes = new HashMap<>(); - meltingBlocksSection.getKeys(false).forEach(s -> { - meltingTimes.put(Material.valueOf(s), meltingBlocksSection.getInt(s)); - }); - MELTING_TIMES = Collections.unmodifiableMap(meltingTimes); - } else { - MELTING_TIMES = Collections.emptyMap(); - } + MELTING = tower.getBoolean("melting") || tower.contains("meltingBlocks"); // Backwards compatibility with meltingBlocks key! ACTIVE_WINCONDITIONS = config.getStringList("winconditions"); WINCONDITIONS.stream().filter(winCondition -> ACTIVE_WINCONDITIONS.contains(winCondition.getName())).forEach(winCondition -> winCondition.setActive(true)); diff --git a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java index befc7d47..f3170215 100644 --- a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java +++ b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java @@ -68,7 +68,7 @@ public class IngameListener extends GameStateBukkitListener { return; } blocks.forEach(block -> { - if (!WorldConfig.MELTING_TIMES.containsKey(block.getType())) return; + if (block.getType() == Material.AIR || block.getType() == Material.LAVA) return; block.setType(Material.AIR); block.getWorld().playSound(block.getLocation(), Sound.BLOCK_FIRE_EXTINGUISH, 0.1F, 1); }); @@ -189,6 +189,9 @@ public class IngameListener extends GameStateBukkitListener { @EventHandler public void onBlockPhysics(BlockPhysicsEvent event) { + if (!WorldConfig.MELTING) { + return; + } if (event.getSourceBlock().getType() != Material.LAVA) { return; } @@ -202,11 +205,9 @@ public class IngameListener extends GameStateBukkitListener { } private void shouldMelt(Block block) { - int meltingTime = WorldConfig.MELTING_TIMES.getOrDefault(block.getType(), -1); - if (meltingTime == -1) { - return; - } - blocksToMelt.computeIfAbsent(time + meltingTime * 20, integer -> new ArrayList<>()).add(block); + if (block.getType().isBurnable()) return; + int meltingTime = (int) (block.getType().getHardness() * 48 * 20); + blocksToMelt.computeIfAbsent(time + meltingTime, integer -> new ArrayList<>()).add(block); } @EventHandler From f74780d3956edc9a3a8cc8edeabd8bdfe32f5a8c Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 17 Apr 2025 16:47:23 +0200 Subject: [PATCH 019/107] Hotfix IngameListener --- TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java index f3170215..bbb332bf 100644 --- a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java +++ b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java @@ -62,7 +62,7 @@ public class IngameListener extends GameStateBukkitListener { blocksToMeltRunnable = new BukkitRunnable() { @Override public void run() { - List blocks = blocksToMelt.get(time); + List blocks = blocksToMelt.remove(time); time++; if (blocks == null) { return; From 7fb3d3d137585c0c279f0b29c2df74df93160506 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 17 Apr 2025 21:38:35 +0200 Subject: [PATCH 020/107] Hotfix DiscordBot.ingameChat going to broadcast instead of globalChat --- .../src/de/steamwar/velocitycore/discord/DiscordBot.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java index 637b0c7e..7ec1cbb4 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java @@ -177,7 +177,7 @@ public class DiscordBot { // There is a hard limit of 30 messages per minute to send as a webhook, thus with 8 webhooks we can send // 240 messages per minute. Which means 4 every second. I looked at the WGS fights and there were around // ~70 in a short burst and then rather long no new message. - ingameChat = new DiscordChatRoom(config.channel("ingame"), "CHAT_DISCORD_GLOBAL", Chatter::broadcast, 8); + ingameChat = new DiscordChatRoom(config.channel("ingame"), "CHAT_DISCORD_GLOBAL", Chatter::globalChat, 8); // 60 messages per minute should be enough for the server team! serverTeamChat = new DiscordChatRoom(config.channel("serverteam"), "CHAT_SERVERTEAM", Chatter::serverteam, 2); From 7802fdd7d9fabdabc474166d19ba46cee9f6eb8a Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 18 Apr 2025 09:13:23 +0200 Subject: [PATCH 021/107] Add ActiveMonths to ArenaMode for rotating modes --- .../src/de/steamwar/velocitycore/ArenaMode.java | 12 +++++++++--- .../steamwar/velocitycore/commands/FightCommand.java | 2 +- .../steamwar/velocitycore/commands/TypeMappers.java | 5 ++++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/ArenaMode.java b/VelocityCore/src/de/steamwar/velocitycore/ArenaMode.java index 5595d9d9..035263f4 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/ArenaMode.java +++ b/VelocityCore/src/de/steamwar/velocitycore/ArenaMode.java @@ -22,6 +22,7 @@ package de.steamwar.velocitycore; import de.steamwar.sql.SchematicType; import lombok.Getter; +import java.time.LocalDateTime; import java.util.*; public class ArenaMode extends GameModeConfig { @@ -76,7 +77,7 @@ public class ArenaMode extends GameModeConfig { public static List getAllChatNames(boolean historic) { List chatNames = new LinkedList<>(); for(ArenaMode mode : byInternal.values()){ - if(historic == mode.isHistoric()) + if(!mode.isNotActive() && historic == mode.isHistoric()) chatNames.addAll(mode.getServer().getChatNames()); } return chatNames; @@ -94,6 +95,9 @@ public class ArenaMode extends GameModeConfig { @Getter private String config; + @Getter + private List ActiveMonths = Collections.emptyList(); + public String hasMap(String map){ for(String m : getMaps()) { if(m.equalsIgnoreCase(map)) @@ -114,8 +118,10 @@ public class ArenaMode extends GameModeConfig { return getServer().getChatNames().get(0); } - public boolean withoutChatName(){ - return getServer().getChatNames().isEmpty(); + public boolean isNotActive() { + if (getServer().getChatNames().isEmpty()) return true; + if (ActiveMonths.isEmpty()) return false; + return !ActiveMonths.contains(LocalDateTime.now().getMonth().getValue()); } public String getSchemTypeOrInternalName() { diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/FightCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/FightCommand.java index 6c320758..2e8405cc 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/FightCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/FightCommand.java @@ -45,7 +45,7 @@ public class FightCommand extends SWCommand { private static void getModes(Chatter sender, String precommand, boolean historic){ Component start = Component.empty(); for(ArenaMode mode : ArenaMode.getAllModes()){ - if(mode.withoutChatName() || mode.isHistoric() != historic) + if (mode.isNotActive() || mode.isHistoric() != historic) continue; String command = precommand + mode.getChatName(); diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/TypeMappers.java b/VelocityCore/src/de/steamwar/velocitycore/commands/TypeMappers.java index 8036272f..af160323 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/TypeMappers.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/TypeMappers.java @@ -49,7 +49,10 @@ public class TypeMappers { return new TypeMapper<>() { @Override public ArenaMode map(Chatter sender, PreviousArguments previousArguments, String s) { - return ArenaMode.getByChat(s); + ArenaMode arenaMode = ArenaMode.getByChat(s); + if (arenaMode.isHistoric() != historic) return null; + if (arenaMode.isNotActive()) return null; + return arenaMode; } @Override From e143268caa717e30b9826f7e036f4e1d498f49a3 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 18 Apr 2025 09:30:26 +0200 Subject: [PATCH 022/107] Fix DiscordBot.serverTeamChat sending to discord if received from discord! --- VelocityCore/src/de/steamwar/messages/BungeeCore.properties | 1 + VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties | 1 + .../src/de/steamwar/velocitycore/discord/DiscordBot.java | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties index e7ed6194..7b536bb7 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties @@ -572,6 +572,7 @@ CHAT_NO_RECEIVER=§cNobody receives your message CHAT_EMPTY=§cDon\'t write meaningless empty messages. CHAT_SERVERTEAM=§8STC §e{0}§8» §f{2} +CHAT_DISCORD_SERVERTEAM=§8Dc §8STC §e{0}§8» §f{2} CHAT_GLOBAL={3}{4}{5}{6}{0}§8» {7}{2} CHAT_DISCORD_GLOBAL=§8Dc {5}{6}{0}§8» {7}{2} CHAT_TEAM=§8TC §e{0}§8» §f{2} diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties index d334a02a..9d5a76bc 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties @@ -547,6 +547,7 @@ CHAT_NO_RECEIVER=§cNiemand empfängt deine Nachricht CHAT_EMPTY=§cSchreibe keine inhaltslosen Nachrichten. CHAT_SERVERTEAM=§8STC §e{0}§8» §f{2} +CHAT_DISCORD_SERVERTEAM=§8Dc §8STC §e{0}§8» §f{2} CHAT_GLOBAL={3}{4}{5}{6}{0}§8» {7}{2} CHAT_DISCORD_GLOBAL=§8Dc {5}{6}{0}§8» {7}{2} CHAT_TEAM=§8TC §e{0}§8» §f{2} diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java index 7ec1cbb4..28cd0c22 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/DiscordBot.java @@ -179,7 +179,7 @@ public class DiscordBot { // ~70 in a short burst and then rather long no new message. ingameChat = new DiscordChatRoom(config.channel("ingame"), "CHAT_DISCORD_GLOBAL", Chatter::globalChat, 8); // 60 messages per minute should be enough for the server team! - serverTeamChat = new DiscordChatRoom(config.channel("serverteam"), "CHAT_SERVERTEAM", Chatter::serverteam, 2); + serverTeamChat = new DiscordChatRoom(config.channel("serverteam"), "CHAT_DISCORD_SERVERTEAM", Chatter::serverteam, 2); VelocityCore.schedule(() -> { try { From 2094120150393f5f027e13e131bd384731aef386 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 18 Apr 2025 09:32:35 +0200 Subject: [PATCH 023/107] Remove prefix. Cannot merge them together because of 'ChatListener.sendChat' --- VelocityCore/src/de/steamwar/messages/BungeeCore.properties | 2 +- VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties index 7b536bb7..c46cd317 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties @@ -572,7 +572,7 @@ CHAT_NO_RECEIVER=§cNobody receives your message CHAT_EMPTY=§cDon\'t write meaningless empty messages. CHAT_SERVERTEAM=§8STC §e{0}§8» §f{2} -CHAT_DISCORD_SERVERTEAM=§8Dc §8STC §e{0}§8» §f{2} +CHAT_DISCORD_SERVERTEAM=§8STC §e{0}§8» §f{2} CHAT_GLOBAL={3}{4}{5}{6}{0}§8» {7}{2} CHAT_DISCORD_GLOBAL=§8Dc {5}{6}{0}§8» {7}{2} CHAT_TEAM=§8TC §e{0}§8» §f{2} diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties index 9d5a76bc..51a47cc3 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties @@ -547,7 +547,7 @@ CHAT_NO_RECEIVER=§cNiemand empfängt deine Nachricht CHAT_EMPTY=§cSchreibe keine inhaltslosen Nachrichten. CHAT_SERVERTEAM=§8STC §e{0}§8» §f{2} -CHAT_DISCORD_SERVERTEAM=§8Dc §8STC §e{0}§8» §f{2} +CHAT_DISCORD_SERVERTEAM=§8STC §e{0}§8» §f{2} CHAT_GLOBAL={3}{4}{5}{6}{0}§8» {7}{2} CHAT_DISCORD_GLOBAL=§8Dc {5}{6}{0}§8» {7}{2} CHAT_TEAM=§8TC §e{0}§8» §f{2} From ace567ba3333ec518cb13c19c4e68991e9f7ec13 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 18 Apr 2025 10:07:42 +0200 Subject: [PATCH 024/107] Add chat system to TowerRun --- TowerRun/src/TowerRun.properties | 33 ++++++++++--------- TowerRun/src/TowerRun_de.properties | 26 +++++++-------- .../steamwar/towerrun/game/TowerRunGame.java | 4 +++ .../towerrun/listener/GlobalListener.java | 30 ++++++++++++++--- 4 files changed, 60 insertions(+), 33 deletions(-) diff --git a/TowerRun/src/TowerRun.properties b/TowerRun/src/TowerRun.properties index 88c2ecd9..2a6c0e04 100644 --- a/TowerRun/src/TowerRun.properties +++ b/TowerRun/src/TowerRun.properties @@ -17,20 +17,23 @@ # along with this program. If not, see . # -PREFIX=eTowerRun8r +PREFIX=§eTowerRun§8§§r -PLAYER_DIED=c{0} 7died8! -PLAYER_ESCAPE=a{0} 7escaped8! -GAME_START=aThe game has started8! -GAME_WIN=a{0} 7has won the game8! -GAME_STARTING=7Starting: e{0}s8! -GAME_WAITING=7Waiting for players8... -SERVER_STOPPING=cThe server stops in e{0}s8! -SERVER_RESET=cThe server will be reset in e{0}s8! -KEY_NAME=eKey -KEY_FOUND=a{0} 7found a key8! -GAME_TIE=aThe game ended in a tie8! -GAME_TIME=a{0}:{1} -CATCH_UP_WARNING=4!! cYou should catch up 4!! +PLAYER_DIED=§c{0} §7died§8! +PLAYER_ESCAPE=§a{0} §7escaped§8! +GAME_START=§aThe game has started§8! +GAME_WIN=§a{0} §7has won the game§8! +GAME_STARTING=§7Starting: §e{0}s§8! +GAME_WAITING=§7Waiting for players§8... +SERVER_STOPPING=§cThe server stops in §e{0}s§8! +SERVER_RESET=§cThe server will be reset in §e{0}s§8! +KEY_NAME=§eKey +KEY_FOUND=§a{0} §7found a key§8! +GAME_TIE=§aThe game ended in a tie§8! +GAME_TIME=§a{0}:{1} +CATCH_UP_WARNING=§4!! §cYou should catch up §4!! -COMMAND_START=aThe game will start soon8! \ No newline at end of file +COMMAND_START=§aThe game will start soon§8! + +PARTICIPANT_CHAT={0} {1}§8» §7{2} +SPECTATOR_CHAT=§7{0}§8» §7{1} \ No newline at end of file diff --git a/TowerRun/src/TowerRun_de.properties b/TowerRun/src/TowerRun_de.properties index 2c88c3b6..82fd014b 100644 --- a/TowerRun/src/TowerRun_de.properties +++ b/TowerRun/src/TowerRun_de.properties @@ -17,19 +17,19 @@ # along with this program. If not, see . # -PLAYER_DIED=c{0} 7ist gestorben8! -PLAYER_ESCAPE=a{0} 7ist entkommen8! -GAME_START=aDas Spiel beginnt8! -GAME_WIN=a{0} 7hat das Spiel gewonnen8! -GAME_STARTING=7Das Spiel startet in e{0}s8! -GAME_WAITING=7Warte auf weitere Spieler8... -SERVER_STOPPING=cDer Server stoppt in e{0}s8! -SERVER_RESET=cDer Server wird in e{0}s czurckgesetzt8! -GAME_TIE=7Keiner hat gewonnen8! +PLAYER_DIED=§c{0} §7ist gestorben§8! +PLAYER_ESCAPE=§a{0} §7ist entkommen§8! +GAME_START=§aDas Spiel beginnt§8! +GAME_WIN=§a{0} §7hat das Spiel gewonnen§8! +GAME_STARTING=§7Das Spiel startet in §e{0}s§8! +GAME_WAITING=§7Warte auf weitere Spieler§8... +SERVER_STOPPING=§cDer Server stoppt in §e{0}s§8! +SERVER_RESET=§cDer Server wird in §e{0}s §czur§ckgesetzt§8! +GAME_TIE=§7Keiner hat gewonnen§8! -KEY_NAME=eSchlssel -KEY_FOUND=a{0} 7hat einen Schlssel gefunden8! +KEY_NAME=§eSchl§ssel +KEY_FOUND=§a{0} §7hat einen Schl§ssel gefunden§8! -CATCH_UP_WARNING=4!! cDu solltest aufholen 4!! +CATCH_UP_WARNING=§4!! §cDu solltest aufholen §4!! -COMMAND_START=7Das Spiel startet bald8! \ No newline at end of file +COMMAND_START=§7Das Spiel startet bald§8! \ No newline at end of file diff --git a/TowerRun/src/de/steamwar/towerrun/game/TowerRunGame.java b/TowerRun/src/de/steamwar/towerrun/game/TowerRunGame.java index 2c014cb5..3c846247 100644 --- a/TowerRun/src/de/steamwar/towerrun/game/TowerRunGame.java +++ b/TowerRun/src/de/steamwar/towerrun/game/TowerRunGame.java @@ -46,6 +46,10 @@ public class TowerRunGame { public static final List PLAYERS_ESCAPED = new ArrayList<>(); private static final World world = Bukkit.getWorlds().get(0); + public static boolean isEscaped(TowerRunPlayer player) { + return PLAYERS_ESCAPED.contains(player); + } + public static boolean isAlive(TowerRunPlayer player) { return PLAYERS_ALIVE.contains(player); } diff --git a/TowerRun/src/de/steamwar/towerrun/listener/GlobalListener.java b/TowerRun/src/de/steamwar/towerrun/listener/GlobalListener.java index 5c2956b2..8d1c6004 100644 --- a/TowerRun/src/de/steamwar/towerrun/listener/GlobalListener.java +++ b/TowerRun/src/de/steamwar/towerrun/listener/GlobalListener.java @@ -19,20 +19,19 @@ package de.steamwar.towerrun.listener; +import de.steamwar.towerrun.TowerRun; import de.steamwar.towerrun.config.WorldConfig; import de.steamwar.towerrun.game.TowerRunGame; import de.steamwar.towerrun.game.TowerRunPlayer; import de.steamwar.towerrun.state.GameStateBukkitListener; import de.steamwar.towerrun.state.GameStates; +import lombok.val; import org.bukkit.Bukkit; +import org.bukkit.GameMode; import org.bukkit.Location; -import org.bukkit.World; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerMoveEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.event.player.*; import java.util.EnumSet; @@ -67,4 +66,25 @@ public class GlobalListener extends GameStateBukkitListener implements Listener public void onPlayerRespawn(PlayerRespawnEvent event) { event.setRespawnLocation(WorldConfig.SPAWN); } + + @EventHandler + public void onAsyncPlayerChat(AsyncPlayerChatEvent event) { + TowerRunPlayer player = TowerRunPlayer.get(event.getPlayer()); + if (TowerRunGame.isAlive(player) || TowerRunGame.isEscaped(player)) { + String prefix; + if (TowerRunGame.isAlive(player)) { + if (event.getPlayer().getGameMode() == GameMode.SPECTATOR) { + prefix = "§c☠"; + } else { + prefix = "§6❤"; + } + } else { + prefix = "§a✔"; + } + TowerRun.getMessage().broadcastPrefixless("PARTICIPANT_CHAT", prefix, event.getPlayer().getName(), event.getMessage()); + } else { + TowerRun.getMessage().broadcastPrefixless("SPECTATOR_CHAT", event.getPlayer().getName(), event.getMessage()); + } + event.setCancelled(true); + } } From c9cfb48c4eb208d790f73a39ac372d5255067f9f Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 18 Apr 2025 10:14:08 +0200 Subject: [PATCH 025/107] Final fix for GlobalListener --- TowerRun/src/de/steamwar/towerrun/listener/GlobalListener.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/TowerRun/src/de/steamwar/towerrun/listener/GlobalListener.java b/TowerRun/src/de/steamwar/towerrun/listener/GlobalListener.java index 8d1c6004..c20dd391 100644 --- a/TowerRun/src/de/steamwar/towerrun/listener/GlobalListener.java +++ b/TowerRun/src/de/steamwar/towerrun/listener/GlobalListener.java @@ -23,6 +23,7 @@ import de.steamwar.towerrun.TowerRun; import de.steamwar.towerrun.config.WorldConfig; import de.steamwar.towerrun.game.TowerRunGame; import de.steamwar.towerrun.game.TowerRunPlayer; +import de.steamwar.towerrun.state.GameState; import de.steamwar.towerrun.state.GameStateBukkitListener; import de.steamwar.towerrun.state.GameStates; import lombok.val; @@ -70,7 +71,7 @@ public class GlobalListener extends GameStateBukkitListener implements Listener @EventHandler public void onAsyncPlayerChat(AsyncPlayerChatEvent event) { TowerRunPlayer player = TowerRunPlayer.get(event.getPlayer()); - if (TowerRunGame.isAlive(player) || TowerRunGame.isEscaped(player)) { + if (GameState.getCurrentState() == GameStates.RUNNING && (TowerRunGame.isAlive(player) || TowerRunGame.isEscaped(player))) { String prefix; if (TowerRunGame.isAlive(player)) { if (event.getPlayer().getGameMode() == GameMode.SPECTATOR) { From 1f58b51af614a5fe474fe2ba2577dd0d8934ac1f Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 18 Apr 2025 12:07:31 +0200 Subject: [PATCH 026/107] Fix NoteBlock turning off on redstone destroy under or up to 2 blocks beside it --- .../features/region/FreezeListener.java | 120 +++++++++++++++++- 1 file changed, 119 insertions(+), 1 deletion(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeListener.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeListener.java index eb712ab4..a78ff18a 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeListener.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeListener.java @@ -11,8 +11,9 @@ import de.steamwar.linkage.Linked; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.data.type.NoteBlock; import org.bukkit.block.data.type.Switch; -import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -60,6 +61,24 @@ public class FreezeListener implements Listener, ScoreboardElement { @EventHandler public void onPhysicsEvent(BlockPhysicsEvent e) { if (Region.getRegion(e.getBlock().getLocation()).get(Flag.FREEZE) == FreezeMode.ACTIVE) { + if (e.getSourceBlock().getType() == Material.NOTE_BLOCK) { + BlockState state = e.getSourceBlock().getState(); + NoteBlock noteBlock = (NoteBlock) state.getBlockData(); + if (noteBlock.isPowered()) { + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + state.update(true, false); + }, 1); + } + } + if (e.getBlock().getType() == Material.NOTE_BLOCK) { + BlockState state = e.getBlock().getState(); + NoteBlock noteBlock = (NoteBlock) state.getBlockData(); + if (noteBlock.isPowered()) { + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + state.update(true, false); + }, 1); + } + } e.setCancelled(true); } } @@ -71,6 +90,105 @@ public class FreezeListener implements Listener, ScoreboardElement { } } + @EventHandler + public void onNotePlay(NotePlayEvent event) { + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=45, z=98},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=44, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=45, z=97},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=45, z=99},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=custom_head,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=custom_head,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=custom_head,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=custom_head,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=custom_head,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=custom_head,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=45, z=97},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=96},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=45, z=99},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-108, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=45, z=98},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-104, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} + + + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=46, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=46, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=45, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=100},type=STONE_SLAB,data=Block{minecraft:stone_slab}[type=bottom,waterlogged=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=100},type=STONE_SLAB,data=Block{minecraft:stone_slab}[type=bottom,waterlogged=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=49, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + ////[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=100},type=STONE_SLAB,data=Block{minecraft:stone_slab}[type=bottom,waterlogged=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=100},type=STONE_SLAB,data=Block{minecraft:stone_slab}[type=bottom,waterlogged=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=102},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-108, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=100},type=STONE_SLAB,data=Block{minecraft:stone_slab}[type=bottom,waterlogged=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=46, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=100},type=STONE_SLAB,data=Block{minecraft:stone_slab}[type=bottom,waterlogged=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-104, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=46, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + //[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} + } + + @EventHandler public void onPistonRetract(BlockPistonRetractEvent e) { if (Region.getRegion(e.getBlock().getLocation()).get(Flag.FREEZE) == FreezeMode.ACTIVE) { From 684a74b60d0fd3567423c8a3b09f250e1ce5afc5 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 18 Apr 2025 12:14:43 +0200 Subject: [PATCH 027/107] Fix SmartPlaceListener not updating Comparator or Repeater --- .../bausystem/features/smartplace/SmartPlaceListener.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java index dd3c61c2..17e0d9f3 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java @@ -19,8 +19,8 @@ package de.steamwar.bausystem.features.smartplace; -import de.steamwar.Reflection; import com.comphenix.tinyprotocol.TinyProtocol; +import de.steamwar.Reflection; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.configplayer.Config; @@ -223,7 +223,7 @@ public class SmartPlaceListener implements Listener { Block block = event.getBlock().getRelative(BlockFace.DOWN); BlockState old = block.getState(); Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { - block.setType(Material.GLASS, false); + block.setType(Material.GLASS, true); old.update(true, false); }, 1); } From 8204e2ad215de402f6849bdb07b5ddd4d5b34e32 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 18 Apr 2025 12:30:22 +0200 Subject: [PATCH 028/107] Fix MWTeam.leave not distributing items correctly --- MissileWars/src/de/steamwar/misslewars/MWTeam.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MissileWars/src/de/steamwar/misslewars/MWTeam.java b/MissileWars/src/de/steamwar/misslewars/MWTeam.java index 8abc5bc9..b5ee7c51 100644 --- a/MissileWars/src/de/steamwar/misslewars/MWTeam.java +++ b/MissileWars/src/de/steamwar/misslewars/MWTeam.java @@ -184,6 +184,7 @@ public class MWTeam { public void leave(Player p) { if (!players.contains(p)) return; + players.remove(p); for (ItemStack stack : p.getInventory().getContents()) { if (stack == null) continue; @@ -198,7 +199,6 @@ public class MWTeam { if (players.isEmpty() && MissileWars.getFightState() == FightState.FIGHTING) MissileWars.end(WinReasons.NO_ENEMY, enemy()); - players.remove(p); sbteam.removePlayer(p); } From fd738f539a8c16dce763be064a4988a21894d10c Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 18 Apr 2025 14:17:59 +0200 Subject: [PATCH 029/107] Add 3 new PluginMessage channel --- .../src/de/steamwar/velocitycore/listeners/PluginMessage.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/listeners/PluginMessage.java b/VelocityCore/src/de/steamwar/velocitycore/listeners/PluginMessage.java index af208aed..7ef0be27 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/listeners/PluginMessage.java +++ b/VelocityCore/src/de/steamwar/velocitycore/listeners/PluginMessage.java @@ -377,7 +377,8 @@ public class PluginMessage extends BasicListener { "axiom:hello", "axiom:set_gamemode", "axiom:set_fly_speed", "axiom:set_world_time", "axiom:set_world_property", "axiom:set_block", "axiom:set_hotbar_slot", "axiom:switch_active_hotbar", "axiom:teleport", "axiom:request_chunk_data", "axiom:spawn_entity", "axiom:response_entity_data", - "axiom:manipulate_entity", "axiom:delete_entity", "axiom:marker_nbt_request", "axiom:set_buffer" + "axiom:manipulate_entity", "axiom:delete_entity", "axiom:marker_nbt_request", "axiom:set_buffer", + "axiom:allowed_gamemodes", "axiom:ignore_display_entities", "axiom:add_server_heightmap" )) { channelRegisterHandlers.put(channel, player -> {}); registerPassthroughToServer(channel); From e5bdbac3c73031e94bef0d4ed12e813a9fae26fc Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 18 Apr 2025 16:50:16 +0200 Subject: [PATCH 030/107] Change isNotActive to isActive --- .../src/de/steamwar/velocitycore/ArenaMode.java | 10 +++++----- .../steamwar/velocitycore/commands/FightCommand.java | 2 +- .../de/steamwar/velocitycore/commands/TypeMappers.java | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/ArenaMode.java b/VelocityCore/src/de/steamwar/velocitycore/ArenaMode.java index 035263f4..4490c172 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/ArenaMode.java +++ b/VelocityCore/src/de/steamwar/velocitycore/ArenaMode.java @@ -77,7 +77,7 @@ public class ArenaMode extends GameModeConfig { public static List getAllChatNames(boolean historic) { List chatNames = new LinkedList<>(); for(ArenaMode mode : byInternal.values()){ - if(!mode.isNotActive() && historic == mode.isHistoric()) + if(mode.isActive() && historic == mode.isHistoric()) chatNames.addAll(mode.getServer().getChatNames()); } return chatNames; @@ -118,10 +118,10 @@ public class ArenaMode extends GameModeConfig { return getServer().getChatNames().get(0); } - public boolean isNotActive() { - if (getServer().getChatNames().isEmpty()) return true; - if (ActiveMonths.isEmpty()) return false; - return !ActiveMonths.contains(LocalDateTime.now().getMonth().getValue()); + public boolean isActive() { + if (getServer().getChatNames().isEmpty()) return false; + if (ActiveMonths.isEmpty()) return true; + return ActiveMonths.contains(LocalDateTime.now().getMonth().getValue()); } public String getSchemTypeOrInternalName() { diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/FightCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/FightCommand.java index 2e8405cc..ee82988c 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/FightCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/FightCommand.java @@ -45,7 +45,7 @@ public class FightCommand extends SWCommand { private static void getModes(Chatter sender, String precommand, boolean historic){ Component start = Component.empty(); for(ArenaMode mode : ArenaMode.getAllModes()){ - if (mode.isNotActive() || mode.isHistoric() != historic) + if (!mode.isActive() || mode.isHistoric() != historic) continue; String command = precommand + mode.getChatName(); diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/TypeMappers.java b/VelocityCore/src/de/steamwar/velocitycore/commands/TypeMappers.java index af160323..a9b8e37b 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/TypeMappers.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/TypeMappers.java @@ -51,7 +51,7 @@ public class TypeMappers { public ArenaMode map(Chatter sender, PreviousArguments previousArguments, String s) { ArenaMode arenaMode = ArenaMode.getByChat(s); if (arenaMode.isHistoric() != historic) return null; - if (arenaMode.isNotActive()) return null; + if (!arenaMode.isActive()) return null; return arenaMode; } From 43621b18b435eb012141bed725227160f3fae626 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 18 Apr 2025 16:57:35 +0200 Subject: [PATCH 031/107] Fix TypeMappers.arenaMapTypeMapper --- .../src/de/steamwar/velocitycore/commands/TypeMappers.java | 1 + 1 file changed, 1 insertion(+) diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/TypeMappers.java b/VelocityCore/src/de/steamwar/velocitycore/commands/TypeMappers.java index a9b8e37b..e2c1176a 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/TypeMappers.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/TypeMappers.java @@ -50,6 +50,7 @@ public class TypeMappers { @Override public ArenaMode map(Chatter sender, PreviousArguments previousArguments, String s) { ArenaMode arenaMode = ArenaMode.getByChat(s); + if (arenaMode == null) return null; if (arenaMode.isHistoric() != historic) return null; if (!arenaMode.isActive()) return null; return arenaMode; From ae9166528d62067826d2243de83ba6c738e78450 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 18 Apr 2025 21:49:59 +0200 Subject: [PATCH 032/107] Add TNTClickListener.TNT_CLICK_DETAILS as a toggle --- .../BauSystem_Main/src/BauSystem.properties | 3 +++ .../src/BauSystem_de.properties | 3 +++ .../tracer/rendering/TraceEntity.java | 5 ++++ .../features/util/TNTClickListener.java | 26 ++++++++++++++++++- 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/BauSystem/BauSystem_Main/src/BauSystem.properties b/BauSystem/BauSystem_Main/src/BauSystem.properties index e4dc1b27..90f1d4cf 100644 --- a/BauSystem/BauSystem_Main/src/BauSystem.properties +++ b/BauSystem/BauSystem_Main/src/BauSystem.properties @@ -947,6 +947,9 @@ SPEED_TAB_NAME=Input speed WORLDEDIT_WAND=WorldEdit Wand WORLDEDIT_LEFTCLICK=Left click: select pos #1 WORLDEDIT_RIGHTCLICK=Right click: select pos #2 +TNT_DETAILS_COMMAND=§8/§etntdetails §8-§7 Toggle information printed after clicking on a TNT +TNT_DETAILS_ON = §eTNTDetails §aactivated +TNT_DETAILS_OFF = §eTNTDetails §cdeactivated TNT_CLICK_HEADER=§8---=== §eTNT §8===--- TNT_CLICK_ORDER=§eEntity Order§8: §e{0} TNT_CLICK_FUSE_TIME=§eFuseTime§8: §e{0} diff --git a/BauSystem/BauSystem_Main/src/BauSystem_de.properties b/BauSystem/BauSystem_Main/src/BauSystem_de.properties index ea6826ed..fca76eb9 100644 --- a/BauSystem/BauSystem_Main/src/BauSystem_de.properties +++ b/BauSystem/BauSystem_Main/src/BauSystem_de.properties @@ -889,6 +889,9 @@ SPEED_TAB_NAME=Geschwindigkeit eingeben WORLDEDIT_WAND=WorldEdit Wand WORLDEDIT_LEFTCLICK=Left click: select pos #1 WORLDEDIT_RIGHTCLICK=Right click: select pos #2 +TNT_DETAILS_COMMAND=§8/§etntdetails §8-§7 Aktiviert/Deaktiviert das senden von Details beim Klick auf TNT +TNT_DETAILS_ON = §eTNTDetails §aaktiviert +TNT_DETAILS_OFF = §eTNTDetails §cdeaktiviert TNT_CLICK_HEADER=§8---=== §eTNT §8===--- TNT_CLICK_ORDER=§eEntity Order§8: §e{0} TNT_CLICK_FUSE_TIME=§eFuseTime§8: §e{0} diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/TraceEntity.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/TraceEntity.java index 0f785468..75b893ab 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/TraceEntity.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/rendering/TraceEntity.java @@ -20,6 +20,7 @@ package de.steamwar.bausystem.features.tracer.rendering; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.configplayer.Config; import de.steamwar.bausystem.features.tracer.TNTPoint; import de.steamwar.bausystem.features.tracer.Trace; import de.steamwar.bausystem.features.tracer.TraceManager; @@ -30,10 +31,13 @@ import net.md_5.bungee.api.chat.ClickEvent; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Player; +import yapion.hierarchy.types.YAPIONValue; import java.util.List; import java.util.stream.Collectors; +import static de.steamwar.bausystem.features.util.TNTClickListener.TNT_CLICK_DETAILS; + /** * Wrapper for the rendering of a record bundle */ @@ -66,6 +70,7 @@ public class TraceEntity extends RFallingBlockEntity { * @param player the player the message should be printed for */ public void printIntoChat(Player player) { + if (!Config.getInstance().get(player).getOrSetDefault(TNT_CLICK_DETAILS, new YAPIONValue<>(true)).asBoolean().orElse(true)) return; TNTPoint representative = records.get(0); BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_HEADER", player); diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/TNTClickListener.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/TNTClickListener.java index 3284876a..a0d91aaa 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/TNTClickListener.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/TNTClickListener.java @@ -21,22 +21,46 @@ package de.steamwar.bausystem.features.util; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.configplayer.Config; +import de.steamwar.command.SWCommand; import de.steamwar.linkage.Linked; import org.bukkit.Bukkit; import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; import org.bukkit.entity.TNTPrimed; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.inventory.EquipmentSlot; +import yapion.hierarchy.types.YAPIONObject; +import yapion.hierarchy.types.YAPIONValue; @Linked -public class TNTClickListener implements Listener { +public class TNTClickListener extends SWCommand implements Listener { + + public static final String TNT_CLICK_DETAILS = "tnt_click_details"; + + public TNTClickListener() { + super("tntdetails"); + } + + @Register("TNT_DETAILS_COMMAND") + public void toggle(Player player) { + YAPIONObject yapionObject = Config.getInstance().get(player); + if (yapionObject.getOrSetDefault(TNT_CLICK_DETAILS, new YAPIONValue<>(true)).asBoolean().orElse(true)) { + yapionObject.put(TNT_CLICK_DETAILS, false); + BauSystem.MESSAGE.send("TNT_DETAILS_OFF", player); + } else { + yapionObject.put(TNT_CLICK_DETAILS, true); + BauSystem.MESSAGE.send("TNT_DETAILS_ON", player); + } + } @EventHandler public void onPlayerInteractEntity(PlayerInteractEntityEvent event) { if (!Permission.BUILD.hasPermission(event.getPlayer())) return; if (event.getHand() != EquipmentSlot.HAND) return; + if (!Config.getInstance().get(event.getPlayer()).getOrSetDefault(TNT_CLICK_DETAILS, new YAPIONValue<>(true)).asBoolean().orElse(true)) return; Entity entity = event.getRightClicked(); if (event.getRightClicked() instanceof TNTPrimed) { From 17704487c9d5418391f932f2ac5f5c0242e3d25f Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 19 Apr 2025 17:58:40 +0200 Subject: [PATCH 033/107] Add SimulatorStabGenerator --- .../features/cannon/depth/Depth.java | 19 +- .../features/simulator/SimulatorCommand.java | 2 +- .../features/simulator/SimulatorCursor.java | 16 +- .../features/simulator/data/Simulator.java | 3 +- .../simulator/execute/SimulatorExecutor.java | 8 +- .../execute/SimulatorStabGenerator.java | 365 ++++++++++++++++++ .../simulator/gui/SimulatorTNTGui.java | 11 + .../simulator/gui/base/SimulatorAnvilGui.java | 2 +- .../simulator/gui/base/SimulatorBaseGui.java | 20 +- .../features/tracer/TraceRecorder.java | 7 +- 10 files changed, 436 insertions(+), 17 deletions(-) create mode 100644 BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/Depth.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/Depth.java index 22ce7fde..3a48d136 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/Depth.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/Depth.java @@ -32,13 +32,22 @@ import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; +import java.util.function.BiConsumer; import java.util.stream.Collectors; public class Depth { + private static final Map>> callbacks = new HashMap<>(); + + public static void addCallback(Region region, BiConsumer callback) { + callbacks.computeIfAbsent(region, k -> new ArrayList<>()).add(callback); + } + + public static void removeCallback(Region region, BiConsumer callback) { + callbacks.computeIfAbsent(region, k -> new ArrayList<>()).remove(callback); + } + private Region region; private Vector minVector = null; private Vector maxVector = null; @@ -70,6 +79,10 @@ public class Depth { player.spigot().sendMessage(getMessage(player, dimensions.getBlockX() + 1, dimensions.getBlockY() + 1, dimensions.getBlockZ() + 1, tntCount)); } }); + + new ArrayList<>(callbacks.getOrDefault(region, Collections.emptyList())).forEach(consumer -> { + consumer.accept(dimensions, tntCount); + }); } private void internalUpdate(Block block) { diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java index de0c4b74..bf329b3b 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java @@ -76,7 +76,7 @@ public class SimulatorCommand extends SWCommand { @Register(value = "start", description = "SIMULATOR_START_HELP") public void start(@Validator Player p, @ErrorMessage("SIMULATOR_NOT_EXISTS") Simulator simulator) { - SimulatorExecutor.run(simulator); + SimulatorExecutor.run(simulator, () -> {}); } @Register(value = "rename", description = "SIMULATOR_RENAME_HELP") 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 de9dae3f..f9629c3d 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 @@ -168,9 +168,19 @@ public class SimulatorCursor implements Listener { } return; } - Simulator simulator = SimulatorStorage.getSimulator(player); - SimulatorWatcher.show(simulator, player); + Simulator simulator = SimulatorStorage.getSimulator(player); + if (simulator != null && simulator.getStabGenerator() != null) { + removeCursor(player); + SimulatorWatcher.show(null, player); + SWUtils.sendToActionbar(player, "§cGenerating Stab"); + synchronized (calculating) { + calculating.remove(player); + } + return; + } + + SimulatorWatcher.show(simulator, player); List entities = SimulatorWatcher.getEntitiesOfSimulator(simulator); RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), entities); if (rayTraceResult == null) { @@ -357,7 +367,7 @@ public class SimulatorCursor implements Listener { if (simulator == null) { return; } - SimulatorExecutor.run(simulator); + SimulatorExecutor.run(simulator, () -> {}); return; } diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/Simulator.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/Simulator.java index 91b7a8e1..8dcb8321 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/Simulator.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/Simulator.java @@ -20,6 +20,7 @@ package de.steamwar.bausystem.features.simulator.data; import de.steamwar.bausystem.features.simulator.execute.SimulatorAction; +import de.steamwar.bausystem.features.simulator.execute.SimulatorStabGenerator; import de.steamwar.inventory.InvCallback; import de.steamwar.inventory.SWItem; import lombok.Getter; @@ -30,13 +31,13 @@ import org.bukkit.entity.Player; import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.function.BiConsumer; @Getter @Setter @RequiredArgsConstructor public final class Simulator { + private SimulatorStabGenerator stabGenerator = null; private Material material = Material.BARREL; private final String name; private boolean autoTrace = false; diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorExecutor.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorExecutor.java index 5c3d30e0..b052e4c8 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorExecutor.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorExecutor.java @@ -46,7 +46,7 @@ public class SimulatorExecutor implements Listener { private static Map>> tickStartActions = new HashMap<>(); private static Map> tickEndActions = new HashMap<>(); - public static boolean run(Simulator simulator) { + public static boolean run(Simulator simulator, Runnable onEnd) { if (currentlyRunning.contains(simulator)) return false; currentlyRunning.add(simulator); @@ -69,7 +69,7 @@ public class SimulatorExecutor implements Listener { public void accept(World world) { currentlyRunning.remove(simulator); - if (simulator.isAutoTrace()) { + if (simulator.isAutoTrace() && onEnd == null) { simulator.getGroups() .stream() .map(SimulatorGroup::getElements) @@ -82,10 +82,12 @@ public class SimulatorExecutor implements Listener { TraceRecorder.instance.stopRecording(region); }); } + + onEnd.run(); } }); - if (simulator.isAutoTrace()) { + if (simulator.isAutoTrace() && onEnd == null) { simulator.getGroups() .stream() .map(SimulatorGroup::getElements) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java new file mode 100644 index 00000000..5d700ddd --- /dev/null +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java @@ -0,0 +1,365 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.simulator.execute; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bukkit.BukkitWorld; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.world.block.BlockTypes; +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.features.cannon.depth.Depth; +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; +import de.steamwar.bausystem.features.simulator.data.SimulatorPhase; +import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement; +import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase; +import de.steamwar.bausystem.features.tracer.TNTPoint; +import de.steamwar.bausystem.features.tracer.Trace; +import de.steamwar.bausystem.features.tracer.TraceManager; +import de.steamwar.bausystem.features.tracer.TraceRecorder; +import de.steamwar.bausystem.region.Point; +import de.steamwar.bausystem.region.Region; +import de.steamwar.bausystem.region.flags.Flag; +import de.steamwar.bausystem.region.flags.flagvalues.ColorMode; +import de.steamwar.bausystem.region.utils.RegionExtensionType; +import de.steamwar.bausystem.region.utils.RegionType; +import de.steamwar.bausystem.utils.FlatteningWrapper; +import de.steamwar.bausystem.utils.PasteBuilder; +import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar; +import de.steamwar.bausystem.utils.bossbar.BossBarService; +import lombok.AllArgsConstructor; +import org.bukkit.Bukkit; +import org.bukkit.boss.BarColor; +import org.bukkit.boss.BarStyle; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.*; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.logging.Level; + +public class SimulatorStabGenerator { + + private static final int MAX_RECORDINGS = 10; + + private final Region region; + private final Simulator simulator; + private final TNTElement tntElement; + private final List phases; + private final int depthLimit; + private Clipboard clipboard; + private boolean cancel = false; + + public SimulatorStabGenerator(Region region, Simulator simulator, TNTElement tntElement, int depthLimit) { + this.region = region; + this.simulator = simulator; + this.tntElement = tntElement; + this.phases = tntElement.getPhases(); + this.depthLimit = depthLimit; + + setup(); + } + + private void setup() { + TNTPhase tntPhase = simulator.getGroups().stream() + .map(SimulatorGroup::getElements) + .flatMap(List::stream) + .filter(TNTElement.class::isInstance) + .map(TNTElement.class::cast) + .filter(tntElement -> this.tntElement != tntElement) + .map(tntElement -> tntElement.getPhases().stream().max(Comparator.comparingInt(TNTPhase::getTickOffset))) + .filter(Optional::isPresent) + .map(Optional::get) + .filter(phase -> phase != phases.get(0)) + .max(Comparator.comparingInt(TNTPhase::getTickOffset)) + .orElse(null); + if (tntPhase == null) { + throw new SecurityException(""); + } + + TNTPhase phase = phases.get(0); + phases.clear(); + phases.add(phase); + phase.setCount(1); + phase.setTickOffset(tntPhase.getTickOffset()); + phase.setOrder(100); + + TraceRecorder.instance.stopRecording(region); + if (TraceRecorder.instance.isAutoTraceEnabledInRegion(region)) { + TraceRecorder.instance.removeAutoTraceRegion(region); + } + clipboard = FlatteningWrapper.impl.copy(region.getMinPointTestblockExtension(), region.getMaxPointTestblockExtension(), region.getTestBlockPoint()); + run(); + } + + private BlockVector3 toBlockVector3(Point point) { + return BlockVector3.at(point.getX(), point.getY(), point.getZ()); + } + + private Direction direction = null; + + private void removeTestblock() { + try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1)) { + e.setBlocks((com.sk89q.worldedit.regions.Region) new CuboidRegion(toBlockVector3(region.getMinPointTestblockExtension()), toBlockVector3(region.getMaxPointTestblockExtension())), Objects.requireNonNull(BlockTypes.AIR).getDefaultState().toBaseBlock()); + } + } + + private void setTestblock() { + try { + PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(clipboard); + PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider) + .color(region.getPlain(Flag.COLOR, ColorMode.class).getColor()); + region.reset(pasteBuilder, RegionType.TESTBLOCK, RegionExtensionType.EXTENSION); + } catch (SecurityException e) { + stop(); + throw e; + } + } + + private void run() { + if (cancel) return; + showBossbar(false); + + Trace trace; + if (direction == null) { + removeTestblock(); + trace = TraceRecorder.instance.startRecording(region); + } else { + setTestblock(); + trace = null; + } + + if (trace == null && currentDepth > 0) { + TNTPhase lastPhase = phases.getLast(); + TNTPhase nextPhase = new TNTPhase(); + nextPhase.setCount(1); + nextPhase.setTickOffset(lastPhase.getTickOffset()); + nextPhase.setOrder(100); + nextPhase.setXJump(lastPhase.isXJump()); + nextPhase.setYJump(lastPhase.isYJump()); + nextPhase.setZJump(lastPhase.isZJump()); + phases.add(nextPhase); + } + + SimulatorExecutor.run(simulator, () -> { + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + if (trace != null) TraceRecorder.instance.stopRecording(region); + if (trace == null && currentDepth > 0) phases.removeLast(); + next(trace); + }, 20); + }); + } + + @AllArgsConstructor + private enum Direction { + X(Vector::getBlockX), + Y(Vector::getBlockY), + Z(Vector::getBlockZ); + + private final Function extractVelocity; + } + + private void calcDirection(Trace trace) { + long tickSinceStart = -1; + List points = null; + for (List current : trace.getHistories()) { + long ticks = current.get(0).getTicksSinceStart(); + if (points == null || ticks > tickSinceStart) { + tickSinceStart = ticks; + points = current; + } else if (ticks == tickSinceStart && points.get(0).getTntId() < current.get(0).getTntId()) { + points = current; + } + } + if (points == null) { + stop(); + return; + } + + TNTPoint current = points.getLast(); + Vector velocity = current.getVelocity(); + if (velocity.getX() < 0) velocity.setX(-velocity.getX()); + if (velocity.getY() < 0) velocity.setY(-velocity.getY()); + if (velocity.getZ() < 0) velocity.setZ(-velocity.getZ()); + if (velocity.getX() > velocity.getY() && velocity.getX() > velocity.getZ()) { + direction = Direction.X; + } else if (velocity.getY() > velocity.getX() && velocity.getY() > velocity.getZ()) { + direction = Direction.Y; + } else if (velocity.getZ() > velocity.getX() && velocity.getZ() > velocity.getY()) { + direction = Direction.Z; + } else { + stop(); + return; + } + + Bukkit.getLogger().log(Level.FINEST, "Direction: {}", direction); + TraceManager.instance.remove(trace); + phases.getFirst().setOrder(SimulatorPhase.ORDER_LIMIT); + phases.getFirst().setCount(10); + Depth.addCallback(region, callback); + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::run, 20); + } + + private int recordings = 0; + private List depths = new ArrayList<>(); + private int lastDepth = 0; + private int currentDepth = 0; + + private void next(Trace trace) { + if (direction == null) { + calcDirection(trace); + return; + } + + List depths = new ArrayList<>(); + for (Vector vector : this.depths) { + depths.add(direction.extractVelocity.apply(vector)); + } + // System.out.println(depths); + + int depth = depths.stream().max(Integer::compareTo).orElse(0); + currentDepth = depth; + + int countWithoutLast = 0; + for (int i = 0; i < phases.size() - 1; i++) { + countWithoutLast += phases.get(i).getCount(); + } + + TNTPhase lastPhase = phases.getLast(); + boolean moreTNTNeeded = depth - countWithoutLast >= lastPhase.getCount() - 5; + if (!depths.isEmpty() && moreTNTNeeded) { + Bukkit.getLogger().log(Level.FINEST, "Increasing tnt count by 10"); + lastPhase.setCount(lastPhase.getCount() + 10); + recordings = 0; + depths.clear(); + + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::run, 20); + return; + } + + if (recordings++ < MAX_RECORDINGS) { + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::run, 20); + return; + } + + recordings = 0; + if (depths.isEmpty()) { + Bukkit.getLogger().log(Level.FINEST, "No dimension - Increasing tickOffset to: {}", phases.getFirst().getTickOffset() + 1); + phases.getFirst().setTickOffset(phases.getFirst().getTickOffset() + 1); + phases.getFirst().setOrder(0); + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::run, 20); + return; + } + + depths.clear(); + + Bukkit.getLogger().log(Level.FINEST, "No more TNT needed on phase adjusting - {} new depth; {} current count", new Object[]{depth - countWithoutLast, lastPhase.getCount()}); + lastPhase.setCount(depth - countWithoutLast); + if (lastPhase.getCount() <= 0) { + Bukkit.getLogger().log(Level.FINEST, "Count was 0 or negative - removing last phase"); + phases.removeLast(); + } + + if (depth > depthLimit) { + Bukkit.getLogger().log(Level.FINEST, "Depth is greater than {} - finished", depthLimit); + stop(); + return; + } + if (depth <= lastDepth) { + Bukkit.getLogger().log(Level.FINEST, "Depth is equal to last depth recorded {} - finished", depth); + stop(); + return; + } + lastDepth = depth; + + Bukkit.getLogger().log(Level.FINEST, "Adding new phase in next tick"); + TNTPhase nextPhase = new TNTPhase(); + nextPhase.setCount(10); + nextPhase.setTickOffset(lastPhase.getTickOffset() + 1); + nextPhase.setXJump(lastPhase.isXJump()); + nextPhase.setYJump(lastPhase.isYJump()); + nextPhase.setZJump(lastPhase.isZJump()); + phases.add(nextPhase); + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::run, 20); + } + + private void showBossbar(boolean finished) { + for (Player player : Bukkit.getOnlinePlayers()) { + BauSystemBossbar bossbar = BossBarService.instance.get(player, region, "simulator_stab_generator"); + bossbar.setColor(BarColor.GREEN); + bossbar.setStyle(BarStyle.SEGMENTED_10); + bossbar.setProgress(Math.min(currentDepth / (double) depthLimit, 1.0)); + StringBuilder st = new StringBuilder(); + + if (finished) { + st.append("§eFinished ").append(currentDepth).append("§8/§7").append(depthLimit); + } else if (direction == null) { + st.append("§eCalculating Stab Direction"); + } else { + st.append("§7Direction§7 §e" + direction); + st.append(" §e").append(currentDepth).append("§8/§7").append(depthLimit); + if (recordings > 0) { + st.append(" §7Retries§8:§e ").append(recordings).append("§8/§7").append(MAX_RECORDINGS); + } + } + + bossbar.setTitle(st.toString()); + } + } + + private void stop() { + simulator.setStabGenerator(null); + Depth.removeCallback(region, callback); + SimulatorWatcher.update(simulator); + + showBossbar(true); + new Thread(() -> { + try { + Thread.sleep(4000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } finally { + for (Player player : Bukkit.getOnlinePlayers()) { + BossBarService.instance.remove(player, region, "simulator_stab_generator"); + } + } + }).start(); + } + + private BiConsumer callback = this::depth; + + private void depth(Vector dimension, int tntCount) { + depths.add(dimension.clone().add(new Vector(1, 1, 1))); + } + + public void cancel() { + cancel = true; + simulator.setStabGenerator(null); + Depth.removeCallback(region, callback); + for (Player player : Bukkit.getOnlinePlayers()) { + BossBarService.instance.remove(player, region, "simulator_stab_generator"); + } + } +} diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTGui.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTGui.java index a9c178ce..3520720e 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTGui.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTGui.java @@ -24,8 +24,11 @@ import de.steamwar.bausystem.features.simulator.data.Simulator; import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement; import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase; +import de.steamwar.bausystem.features.simulator.execute.SimulatorStabGenerator; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui; import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; import de.steamwar.bausystem.features.simulator.gui.base.SimulatorScrollGui; +import de.steamwar.bausystem.region.Region; import de.steamwar.inventory.SWItem; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -97,6 +100,14 @@ public class SimulatorTNTGui extends SimulatorScrollGui { tnt.setDisabled(!tnt.isDisabled()); SimulatorWatcher.update(simulator); })); + inventory.setItem(49, new SWItem(Material.CALIBRATED_SCULK_SENSOR, "§eCreate Stab", click -> { + new SimulatorAnvilGui<>(player, "Depth Limit", "", Integer::parseInt, depthLimit -> { + if (depthLimit <= 0) return false; + simulator.setStabGenerator(new SimulatorStabGenerator(Region.getRegion(player.getLocation()), simulator, tnt, depthLimit)); + SimulatorWatcher.update(simulator); + return true; + }, null).open(); + })); inventory.setItem(50, new SWItem(Material.CHEST, parent.getElements().size() == 1 ? "§eMake Group" : "§eAdd another TNT to Group", clickType -> { TNTElement tntElement = new TNTElement(tnt.getPosition().clone()); tntElement.add(new TNTPhase()); diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorAnvilGui.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorAnvilGui.java index 380dc618..e22c807a 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorAnvilGui.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorAnvilGui.java @@ -44,7 +44,7 @@ public class SimulatorAnvilGui { if (error.get()) { anvilInv.open(); } else { - back.open(); + if (back != null) back.open(); } error.set(false); }, 0); diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorBaseGui.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorBaseGui.java index 6fa35d4c..aeb4da13 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorBaseGui.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorBaseGui.java @@ -22,7 +22,6 @@ package de.steamwar.bausystem.features.simulator.gui.base; import de.steamwar.bausystem.features.simulator.SimulatorWatcher; import de.steamwar.bausystem.features.simulator.data.Simulator; import de.steamwar.core.Core; -import de.steamwar.core.TrickyTrialsWrapper; import de.steamwar.inventory.SWInventory; import de.steamwar.inventory.SWItem; import org.bukkit.Bukkit; @@ -64,7 +63,11 @@ public abstract class SimulatorBaseGui { if (Core.getVersion() > 19) { player.getOpenInventory().setTitle(title()); } - populate(); + if (simulator != null && simulator.getStabGenerator() != null) { + populateStabGenerator(); + } else { + populate(); + } if (player.getOpenInventory().getTopInventory() == inv) { inventory.open(); SimulatorWatcher.watch(player, simulator, this::open); @@ -84,10 +87,21 @@ public abstract class SimulatorBaseGui { }); SimulatorWatcher.watch(player, simulator, this::open); - populate(); + if (simulator != null && simulator.getStabGenerator() != null) { + populateStabGenerator(); + } else { + populate(); + } inventory.open(); } + private void populateStabGenerator() { + inventory.setItem(22, new SWItem(Material.BARRIER, "§cCancel Stab Generator", click -> { + simulator.getStabGenerator().cancel(); + SimulatorWatcher.update(simulator); + })); + } + public boolean shouldOpen() { return true; } diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRecorder.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRecorder.java index 6a0a2314..208b49e8 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRecorder.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRecorder.java @@ -102,11 +102,14 @@ public class TraceRecorder implements Listener { * * @param region region to be recorded */ - public void startRecording(Region region) { - if (activeTraces.containsKey(region)) return; + public Trace startRecording(Region region) { + if (activeTraces.containsKey(region)) { + return activeTraces.get(region).getTrace(); + } TraceRecordingWrapper wrappedTrace = new TraceRecordingWrapper(region); activeTraces.put(region, wrappedTrace); + return wrappedTrace.getTrace(); } /** From 05dc42355df752d88e7fc3140f6b47f8f12b5015 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 19 Apr 2025 23:04:19 +0200 Subject: [PATCH 034/107] Update and improve SimulatorStabGenerator --- .../features/cannon/depth/Depth.java | 19 +- .../execute/SimulatorStabGenerator.java | 227 ++++++++++-------- 2 files changed, 127 insertions(+), 119 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/Depth.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/Depth.java index 3a48d136..22ce7fde 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/Depth.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/Depth.java @@ -32,22 +32,13 @@ import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import java.util.*; -import java.util.function.BiConsumer; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.stream.Collectors; public class Depth { - private static final Map>> callbacks = new HashMap<>(); - - public static void addCallback(Region region, BiConsumer callback) { - callbacks.computeIfAbsent(region, k -> new ArrayList<>()).add(callback); - } - - public static void removeCallback(Region region, BiConsumer callback) { - callbacks.computeIfAbsent(region, k -> new ArrayList<>()).remove(callback); - } - private Region region; private Vector minVector = null; private Vector maxVector = null; @@ -79,10 +70,6 @@ public class Depth { player.spigot().sendMessage(getMessage(player, dimensions.getBlockX() + 1, dimensions.getBlockY() + 1, dimensions.getBlockZ() + 1, tntCount)); } }); - - new ArrayList<>(callbacks.getOrDefault(region, Collections.emptyList())).forEach(consumer -> { - consumer.accept(dimensions, tntCount); - }); } private void internalUpdate(Block block) { diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java index 5d700ddd..b874280f 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java @@ -27,7 +27,6 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.world.block.BlockTypes; import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.features.cannon.depth.Depth; import de.steamwar.bausystem.features.simulator.SimulatorWatcher; import de.steamwar.bausystem.features.simulator.data.Simulator; import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; @@ -50,28 +49,57 @@ import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar; import de.steamwar.bausystem.utils.bossbar.BossBarService; import lombok.AllArgsConstructor; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.boss.BarColor; import org.bukkit.boss.BarStyle; import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.util.Vector; import java.util.*; -import java.util.function.BiConsumer; import java.util.function.Function; import java.util.logging.Level; +import java.util.stream.Collectors; -public class SimulatorStabGenerator { +public class SimulatorStabGenerator implements Listener { - private static final int MAX_RECORDINGS = 10; + // Lupfstichs sind noch nicht perfekt + // Schwenkstichs sidn noch nicht perfekt + + private static final int MAX_RECORDINGS = 5; + private static final Level LEVEL = Level.INFO; + private static final int TNT_INCREASE = 10; + private static final int MIN_BLOCK_TO_COUNT_AS_DEPTH = 20; + + private final Map> destroyedBlocksPerSlice = new HashMap<>(); + + @EventHandler + public void onEntityExplode(EntityExplodeEvent event) { + if (direction == null) return; + if (Region.getRegion(event.getEntity().getLocation()) == region) { + event.blockList().forEach(block -> { + if (!region.inRegion(block.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.EXTENSION)) return; + int component = direction.component.apply(block.getLocation().toVector()); + destroyedBlocksPerSlice.computeIfAbsent(component, __ -> new HashSet<>()) + .add(block.getLocation()); + }); + } + } private final Region region; private final Simulator simulator; private final TNTElement tntElement; private final List phases; private final int depthLimit; + private Clipboard clipboard; private boolean cancel = false; + private Direction direction = null; + public SimulatorStabGenerator(Region region, Simulator simulator, TNTElement tntElement, int depthLimit) { this.region = region; this.simulator = simulator; @@ -111,77 +139,31 @@ public class SimulatorStabGenerator { TraceRecorder.instance.removeAutoTraceRegion(region); } clipboard = FlatteningWrapper.impl.copy(region.getMinPointTestblockExtension(), region.getMaxPointTestblockExtension(), region.getTestBlockPoint()); - run(); + + getDirection(); } private BlockVector3 toBlockVector3(Point point) { return BlockVector3.at(point.getX(), point.getY(), point.getZ()); } - private Direction direction = null; - - private void removeTestblock() { + private void getDirection() { try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1)) { e.setBlocks((com.sk89q.worldedit.regions.Region) new CuboidRegion(toBlockVector3(region.getMinPointTestblockExtension()), toBlockVector3(region.getMaxPointTestblockExtension())), Objects.requireNonNull(BlockTypes.AIR).getDefaultState().toBaseBlock()); } - } - private void setTestblock() { - try { - PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(clipboard); - PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider) - .color(region.getPlain(Flag.COLOR, ColorMode.class).getColor()); - region.reset(pasteBuilder, RegionType.TESTBLOCK, RegionExtensionType.EXTENSION); - } catch (SecurityException e) { - stop(); - throw e; - } - } - - private void run() { - if (cancel) return; showBossbar(false); - Trace trace; - if (direction == null) { - removeTestblock(); - trace = TraceRecorder.instance.startRecording(region); - } else { - setTestblock(); - trace = null; - } - - if (trace == null && currentDepth > 0) { - TNTPhase lastPhase = phases.getLast(); - TNTPhase nextPhase = new TNTPhase(); - nextPhase.setCount(1); - nextPhase.setTickOffset(lastPhase.getTickOffset()); - nextPhase.setOrder(100); - nextPhase.setXJump(lastPhase.isXJump()); - nextPhase.setYJump(lastPhase.isYJump()); - nextPhase.setZJump(lastPhase.isZJump()); - phases.add(nextPhase); - } - + Trace trace = TraceRecorder.instance.startRecording(region); SimulatorExecutor.run(simulator, () -> { Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { - if (trace != null) TraceRecorder.instance.stopRecording(region); - if (trace == null && currentDepth > 0) phases.removeLast(); - next(trace); + TraceRecorder.instance.stopRecording(region); + calculateDirection(trace); }, 20); }); } - @AllArgsConstructor - private enum Direction { - X(Vector::getBlockX), - Y(Vector::getBlockY), - Z(Vector::getBlockZ); - - private final Function extractVelocity; - } - - private void calcDirection(Trace trace) { + private void calculateDirection(Trace trace) { long tickSinceStart = -1; List points = null; for (List current : trace.getHistories()) { @@ -193,6 +175,7 @@ public class SimulatorStabGenerator { points = current; } } + TraceManager.instance.remove(trace); if (points == null) { stop(); return; @@ -214,33 +197,64 @@ public class SimulatorStabGenerator { return; } - Bukkit.getLogger().log(Level.FINEST, "Direction: {}", direction); - TraceManager.instance.remove(trace); + Bukkit.getLogger().log(LEVEL, "Direction: {0}", direction); phases.getFirst().setOrder(SimulatorPhase.ORDER_LIMIT); - phases.getFirst().setCount(10); - Depth.addCallback(region, callback); - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::run, 20); + phases.getFirst().setCount(TNT_INCREASE); + destroyedBlocksPerSlice.clear(); + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance()); + getStab(); + }, 20); + } + + private void getStab() { + try { + PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(clipboard); + PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider) + .color(region.getPlain(Flag.COLOR, ColorMode.class).getColor()); + region.reset(pasteBuilder, RegionType.TESTBLOCK, RegionExtensionType.EXTENSION); + } catch (SecurityException e) { + stop(); + throw e; + } + if (cancel) return; + + showBossbar(false); + + SimulatorExecutor.run(simulator, () -> { + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::calculateStep, 20); + }); } private int recordings = 0; - private List depths = new ArrayList<>(); + private List currentDepths = new ArrayList<>(); private int lastDepth = 0; private int currentDepth = 0; - private void next(Trace trace) { - if (direction == null) { - calcDirection(trace); - return; + private void calculateStep() { + List>> locations = destroyedBlocksPerSlice.entrySet() + .stream() + .sorted(Comparator.comparingInt(Map.Entry::getKey)) + .collect(Collectors.toList()); + int depth = 0; + for (int i = 0; i < locations.size(); i++) { + if (i == 0 || i == locations.size() - 1) { + if (locations.get(i).getValue().size() > MIN_BLOCK_TO_COUNT_AS_DEPTH) { + depth++; + } + } else { + depth++; + } } - List depths = new ArrayList<>(); - for (Vector vector : this.depths) { - depths.add(direction.extractVelocity.apply(vector)); + if (depth > 0) { + Bukkit.getLogger().log(LEVEL, "{0} {1} {2}", new Object[]{depth, destroyedBlocksPerSlice.size(), destroyedBlocksPerSlice.values().stream().map(Set::size).collect(Collectors.toList())}); + currentDepths.add(depth); } - // System.out.println(depths); + destroyedBlocksPerSlice.clear(); - int depth = depths.stream().max(Integer::compareTo).orElse(0); - currentDepth = depth; + int maxDepth = currentDepths.stream().max(Integer::compareTo).orElse(0); + currentDepth = maxDepth; int countWithoutLast = 0; for (int i = 0; i < phases.size() - 1; i++) { @@ -248,61 +262,74 @@ public class SimulatorStabGenerator { } TNTPhase lastPhase = phases.getLast(); - boolean moreTNTNeeded = depth - countWithoutLast >= lastPhase.getCount() - 5; - if (!depths.isEmpty() && moreTNTNeeded) { - Bukkit.getLogger().log(Level.FINEST, "Increasing tnt count by 10"); - lastPhase.setCount(lastPhase.getCount() + 10); + boolean moreTNTNeeded = maxDepth - countWithoutLast >= lastPhase.getCount() - 5; + if (!currentDepths.isEmpty() && moreTNTNeeded) { + Bukkit.getLogger().log(LEVEL, "Increasing tnt count by {0}", TNT_INCREASE); + lastPhase.setCount(lastPhase.getCount() + TNT_INCREASE); recordings = 0; - depths.clear(); + currentDepths.clear(); - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::run, 20); + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::getStab, 20); return; } if (recordings++ < MAX_RECORDINGS) { - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::run, 20); + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::getStab, 20); return; } recordings = 0; - if (depths.isEmpty()) { - Bukkit.getLogger().log(Level.FINEST, "No dimension - Increasing tickOffset to: {}", phases.getFirst().getTickOffset() + 1); + if (currentDepths.isEmpty()) { + Bukkit.getLogger().log(LEVEL, "No dimension - Increasing tickOffset to: {0}", phases.getFirst().getTickOffset() + 1); phases.getFirst().setTickOffset(phases.getFirst().getTickOffset() + 1); phases.getFirst().setOrder(0); - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::run, 20); + if (phases.getFirst().getTickOffset() > 80) { + stop(); + } else { + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::getStab, 20); + } return; } - depths.clear(); + currentDepths.clear(); - Bukkit.getLogger().log(Level.FINEST, "No more TNT needed on phase adjusting - {} new depth; {} current count", new Object[]{depth - countWithoutLast, lastPhase.getCount()}); - lastPhase.setCount(depth - countWithoutLast); + Bukkit.getLogger().log(LEVEL, "No more TNT needed on phase adjusting - {0} new depth; {1} current count", new Object[]{maxDepth - countWithoutLast, lastPhase.getCount()}); + lastPhase.setCount(maxDepth - countWithoutLast); if (lastPhase.getCount() <= 0) { - Bukkit.getLogger().log(Level.FINEST, "Count was 0 or negative - removing last phase"); + Bukkit.getLogger().log(LEVEL, "Count was 0 or negative - removing last phase"); phases.removeLast(); } - if (depth > depthLimit) { - Bukkit.getLogger().log(Level.FINEST, "Depth is greater than {} - finished", depthLimit); + if (maxDepth > depthLimit) { + Bukkit.getLogger().log(LEVEL, "Depth is greater than {0} - finished", depthLimit); stop(); return; } - if (depth <= lastDepth) { - Bukkit.getLogger().log(Level.FINEST, "Depth is equal to last depth recorded {} - finished", depth); + if (maxDepth <= lastDepth) { + Bukkit.getLogger().log(LEVEL, "Depth is equal to last depth recorded {0} - finished", maxDepth); stop(); return; } - lastDepth = depth; + lastDepth = maxDepth; - Bukkit.getLogger().log(Level.FINEST, "Adding new phase in next tick"); + Bukkit.getLogger().log(LEVEL, "Adding new phase in next tick"); TNTPhase nextPhase = new TNTPhase(); - nextPhase.setCount(10); + nextPhase.setCount(TNT_INCREASE); nextPhase.setTickOffset(lastPhase.getTickOffset() + 1); nextPhase.setXJump(lastPhase.isXJump()); nextPhase.setYJump(lastPhase.isYJump()); nextPhase.setZJump(lastPhase.isZJump()); phases.add(nextPhase); - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::run, 20); + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::getStab, 20); + } + + @AllArgsConstructor + private enum Direction { + X(Vector::getBlockX), + Y(Vector::getBlockY), + Z(Vector::getBlockZ); + + private final Function component; } private void showBossbar(boolean finished) { @@ -331,8 +358,8 @@ public class SimulatorStabGenerator { private void stop() { simulator.setStabGenerator(null); - Depth.removeCallback(region, callback); SimulatorWatcher.update(simulator); + HandlerList.unregisterAll(this); showBossbar(true); new Thread(() -> { @@ -348,18 +375,12 @@ public class SimulatorStabGenerator { }).start(); } - private BiConsumer callback = this::depth; - - private void depth(Vector dimension, int tntCount) { - depths.add(dimension.clone().add(new Vector(1, 1, 1))); - } - public void cancel() { cancel = true; simulator.setStabGenerator(null); - Depth.removeCallback(region, callback); for (Player player : Bukkit.getOnlinePlayers()) { BossBarService.instance.remove(player, region, "simulator_stab_generator"); } + HandlerList.unregisterAll(this); } } From 230ac09b61a8a7b63e238d21bf22bc8b7de319d8 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 20 Apr 2025 08:12:22 +0200 Subject: [PATCH 035/107] Hotfix for disabled things --- .../features/simulator/execute/SimulatorStabGenerator.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java index b874280f..0cbd2eeb 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java @@ -112,10 +112,12 @@ public class SimulatorStabGenerator implements Listener { private void setup() { TNTPhase tntPhase = simulator.getGroups().stream() + .filter(simulatorGroup -> !simulatorGroup.isDisabled()) .map(SimulatorGroup::getElements) .flatMap(List::stream) .filter(TNTElement.class::isInstance) .map(TNTElement.class::cast) + .filter(tntElement -> !tntElement.isDisabled()) .filter(tntElement -> this.tntElement != tntElement) .map(tntElement -> tntElement.getPhases().stream().max(Comparator.comparingInt(TNTPhase::getTickOffset))) .filter(Optional::isPresent) From 50543ddd4e6ef50de6d5b906df4e8c5d8a530fff Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 17 Apr 2025 09:56:41 +0200 Subject: [PATCH 036/107] Improve Server starter 'steamwar.devserver.gradle' See build.gradle.kts of BauSystem --- BauSystem/build.gradle.kts | 21 +++++ buildSrc/src/steamwar.devserver.gradle | 111 +++++++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 buildSrc/src/steamwar.devserver.gradle diff --git a/BauSystem/build.gradle.kts b/BauSystem/build.gradle.kts index 712238c8..423a8e98 100644 --- a/BauSystem/build.gradle.kts +++ b/BauSystem/build.gradle.kts @@ -1,3 +1,5 @@ +import DevServer + /* * This file is a part of the SteamWar software. * @@ -20,6 +22,7 @@ plugins { `java-library` alias(libs.plugins.shadow) + steamwar.devserver } tasks.build { @@ -34,3 +37,21 @@ dependencies { implementation(project(":BauSystem:BauSystem_20")) implementation(project(":BauSystem:BauSystem_21")) } + +tasks.register("DevBau20") { + group = "run" + description = "Run a 1.20 Dev Bau" + dependsOn(":SpigotCore:shadowJar") + dependsOn(":BauSystem:shadowJar") + worldName = "245" + template = "Bau20" +} + +tasks.register("DevBau21") { + group = "run" + description = "Run a 1.21 Dev Bau" + dependsOn(":SpigotCore:shadowJar") + dependsOn(":BauSystem:shadowJar") + worldName = "245" + template = "Bau21" +} diff --git a/buildSrc/src/steamwar.devserver.gradle b/buildSrc/src/steamwar.devserver.gradle new file mode 100644 index 00000000..22993d27 --- /dev/null +++ b/buildSrc/src/steamwar.devserver.gradle @@ -0,0 +1,111 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import org.gradle.api.DefaultTask +import org.gradle.api.GradleException +import org.gradle.api.Project +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.bundling.AbstractArchiveTask + +plugins { +} + +class DevServer extends DefaultTask { + + @Input + worldName = "" + + @Input + template = "" + + DevServer() { + super() + doLast { + uploadDependencies() + startDevServer() + } + finalizedBy(new Finalizer()) + } + + @Internal + def BufferedWriter processInput; + + class Finalizer extends DefaultTask { + + Finalizer() { + super() + doLast { + if (processInput != null) { + processInput.write("stop\n") + processInput.flush() + } + } + } + } + + void uploadDependencies() { + this.dependsOn.forEach { + Project resolved; + if (it instanceof Project) { + resolved = (Project) it; + } else if (it instanceof String) { + resolved = project.findProject(it.substring(0, it.lastIndexOf(':'))) + } else { + throw new GradleException("Illegal argument for uploading dependencies") + } + + def archive = ((AbstractArchiveTask) resolved.tasks.findByName("shadowJar")).archiveFile.get().asFile + println("Uploading $archive to ~/plugins/${template}") + new ProcessBuilder("scp", archive.absolutePath, "sw:~/plugins/$template/${archive.name.replace("-all", "")}").start().waitFor() + println("Uploaded $archive to ~/plugins/${template}") + } + } + + void startDevServer() { + println("Starting $template with world $worldName and plugins in ~/plugins/${template}") + + def process = new ProcessBuilder("ssh", "sw", "-T", "dev.py -w $worldName -p plugins/$template $template").start(); + def running = true; + def processOutput = new BufferedReader(new InputStreamReader(process.inputStream)) + new Thread({ + while (running) { + if (processOutput.ready()) { + println(processOutput.readLine()) + } + } + }).start() + + processInput = new BufferedWriter(new OutputStreamWriter(process.outputStream)) + def input = new BufferedReader(new InputStreamReader(System.in)) + new Thread({ + while (running) { + def text = input.readLine() + if (text == null) break + processInput.write(text) + processInput.newLine() + processInput.flush() + } + }).start() + + process.waitFor() + processInput = null + running = false + } +} \ No newline at end of file From e393aad25ff0edba0305ea87636a1b0add6f238b Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 17 Apr 2025 10:07:50 +0200 Subject: [PATCH 037/107] Add all parameters that dev.py has --- buildSrc/src/steamwar.devserver.gradle | 43 ++++++++++++++++++-------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/buildSrc/src/steamwar.devserver.gradle b/buildSrc/src/steamwar.devserver.gradle index 22993d27..35bfcab1 100644 --- a/buildSrc/src/steamwar.devserver.gradle +++ b/buildSrc/src/steamwar.devserver.gradle @@ -16,24 +16,33 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ - -import org.gradle.api.DefaultTask -import org.gradle.api.GradleException -import org.gradle.api.Project -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.Internal -import org.gradle.api.tasks.bundling.AbstractArchiveTask - plugins { } class DevServer extends DefaultTask { @Input - worldName = "" + @Optional + String worldName = null @Input - template = "" + String template = null + + @Input + @Optional + Integer port = null + + @Input + @Optional + Boolean profile = false + + @Input + @Optional + Boolean forceUpgrade = false + + @Input + @Optional + String jar = null DevServer() { super() @@ -45,7 +54,7 @@ class DevServer extends DefaultTask { } @Internal - def BufferedWriter processInput; + BufferedWriter processInput; class Finalizer extends DefaultTask { @@ -79,9 +88,17 @@ class DevServer extends DefaultTask { } void startDevServer() { - println("Starting $template with world $worldName and plugins in ~/plugins/${template}") + def devPy = new StringBuilder().append("dev.py") + if (port != null) devPy.append(" --port $port") + if (worldName != null) devPy.append(" -w $worldName") + devPy.append(" -p plugins/$template") + if (profile) devPy.append(" --profile") + if (forceUpgrade) devPy.append(" --forceUpgrade") + if (jar != null) devPy.append(" --jar $jar") + println("Starting $template with command ${devPy.toString()}") + devPy.append(" $template") - def process = new ProcessBuilder("ssh", "sw", "-T", "dev.py -w $worldName -p plugins/$template $template").start(); + def process = new ProcessBuilder("ssh", "sw", "-T", devPy.toString()).start(); def running = true; def processOutput = new BufferedReader(new InputStreamReader(process.inputStream)) new Thread({ From 32703c6659e024954ca1c87281702698df664d21 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 17 Apr 2025 10:40:50 +0200 Subject: [PATCH 038/107] Enable Velocity, prio Setup needed for that --- VelocityCore/build.gradle.kts | 10 +++++++- buildSrc/src/steamwar.devserver.gradle | 34 +++++++++++++++----------- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/VelocityCore/build.gradle.kts b/VelocityCore/build.gradle.kts index 844e9f21..90d43d36 100644 --- a/VelocityCore/build.gradle.kts +++ b/VelocityCore/build.gradle.kts @@ -66,4 +66,12 @@ dependencies { implementation(libs.apolloprotos) implementation(libs.nbt) -} \ No newline at end of file +} + +tasks.register("DevVelocity") { + group = "run" + description = "Run a Dev Velocity" + dependsOn(":VelocityCore:shadowJar") + dependsOn(":VelocityCore:Persistent:jar") + template = "Velocity" +} diff --git a/buildSrc/src/steamwar.devserver.gradle b/buildSrc/src/steamwar.devserver.gradle index 35bfcab1..eb1dec46 100644 --- a/buildSrc/src/steamwar.devserver.gradle +++ b/buildSrc/src/steamwar.devserver.gradle @@ -71,16 +71,16 @@ class DevServer extends DefaultTask { void uploadDependencies() { this.dependsOn.forEach { - Project resolved; - if (it instanceof Project) { - resolved = (Project) it; - } else if (it instanceof String) { + Project resolved + AbstractArchiveTask archiveTask + if (it instanceof String) { resolved = project.findProject(it.substring(0, it.lastIndexOf(':'))) + archiveTask = (AbstractArchiveTask) resolved.tasks.findByName(it.substring(it.lastIndexOf(':') + 1)) } else { throw new GradleException("Illegal argument for uploading dependencies") } - def archive = ((AbstractArchiveTask) resolved.tasks.findByName("shadowJar")).archiveFile.get().asFile + def archive = archiveTask.archiveFile.get().asFile println("Uploading $archive to ~/plugins/${template}") new ProcessBuilder("scp", archive.absolutePath, "sw:~/plugins/$template/${archive.name.replace("-all", "")}").start().waitFor() println("Uploaded $archive to ~/plugins/${template}") @@ -88,15 +88,21 @@ class DevServer extends DefaultTask { } void startDevServer() { - def devPy = new StringBuilder().append("dev.py") - if (port != null) devPy.append(" --port $port") - if (worldName != null) devPy.append(" -w $worldName") - devPy.append(" -p plugins/$template") - if (profile) devPy.append(" --profile") - if (forceUpgrade) devPy.append(" --forceUpgrade") - if (jar != null) devPy.append(" --jar $jar") - println("Starting $template with command ${devPy.toString()}") - devPy.append(" $template") + def devPy = new StringBuilder() + if (template.endsWith("Velocity")) { + devPy.append("cd DevVelocity") + devPy.append("; java -jar Velocity.jar --port 25566") + } else { + devPy.append("dev.py") + if (port != null) devPy.append(" --port $port") + if (worldName != null) devPy.append(" -w $worldName") + devPy.append(" -p plugins/$template") + if (profile) devPy.append(" --profile") + if (forceUpgrade) devPy.append(" --forceUpgrade") + if (jar != null) devPy.append(" --jar $jar") + println("Starting $template with command ${devPy.toString()}") + devPy.append(" $template") + } def process = new ProcessBuilder("ssh", "sw", "-T", devPy.toString()).start(); def running = true; From 9001e83321575f3b5fa186bc3e8079e66350563e Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 17 Apr 2025 15:24:12 +0200 Subject: [PATCH 039/107] Add steamwar.properties 'worldName' and 'host' Remove some options --- BauSystem/build.gradle.kts | 5 ---- buildSrc/src/steamwar.devserver.gradle | 39 +++++++++++++++++--------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/BauSystem/build.gradle.kts b/BauSystem/build.gradle.kts index 423a8e98..fd9dca11 100644 --- a/BauSystem/build.gradle.kts +++ b/BauSystem/build.gradle.kts @@ -1,5 +1,3 @@ -import DevServer - /* * This file is a part of the SteamWar software. * @@ -22,7 +20,6 @@ import DevServer plugins { `java-library` alias(libs.plugins.shadow) - steamwar.devserver } tasks.build { @@ -43,7 +40,6 @@ tasks.register("DevBau20") { description = "Run a 1.20 Dev Bau" dependsOn(":SpigotCore:shadowJar") dependsOn(":BauSystem:shadowJar") - worldName = "245" template = "Bau20" } @@ -52,6 +48,5 @@ tasks.register("DevBau21") { description = "Run a 1.21 Dev Bau" dependsOn(":SpigotCore:shadowJar") dependsOn(":BauSystem:shadowJar") - worldName = "245" template = "Bau21" } diff --git a/buildSrc/src/steamwar.devserver.gradle b/buildSrc/src/steamwar.devserver.gradle index eb1dec46..734bc88d 100644 --- a/buildSrc/src/steamwar.devserver.gradle +++ b/buildSrc/src/steamwar.devserver.gradle @@ -32,20 +32,30 @@ class DevServer extends DefaultTask { @Optional Integer port = null - @Input - @Optional - Boolean profile = false - - @Input - @Optional - Boolean forceUpgrade = false - @Input @Optional String jar = null DevServer() { super() + doFirst { + List projects = [] + projects.add(project) + while (projects.first.parent != null) { + projects.add(0, projects.first.parent) + } + + def properties = new Properties() + projects.forEach { + def file = new File(it.projectDir, "steamwar.properties") + if (file.exists()) { + properties.load(new FileInputStream(file)) + } + } + + if (worldName == null) worldName = properties.get("worldName") + host = properties.get("host") + } doLast { uploadDependencies() startDevServer() @@ -54,7 +64,10 @@ class DevServer extends DefaultTask { } @Internal - BufferedWriter processInput; + BufferedWriter processInput + + @Internal + String host class Finalizer extends DefaultTask { @@ -82,14 +95,14 @@ class DevServer extends DefaultTask { def archive = archiveTask.archiveFile.get().asFile println("Uploading $archive to ~/plugins/${template}") - new ProcessBuilder("scp", archive.absolutePath, "sw:~/plugins/$template/${archive.name.replace("-all", "")}").start().waitFor() + new ProcessBuilder("scp", archive.absolutePath, "$host:~/plugins/$template/${archive.name.replace("-all", "")}").start().waitFor() println("Uploaded $archive to ~/plugins/${template}") } } void startDevServer() { def devPy = new StringBuilder() - if (template.endsWith("Velocity")) { + if (template.endsWith("Velocity")) { // TODO Add this to the dev.py! devPy.append("cd DevVelocity") devPy.append("; java -jar Velocity.jar --port 25566") } else { @@ -97,14 +110,12 @@ class DevServer extends DefaultTask { if (port != null) devPy.append(" --port $port") if (worldName != null) devPy.append(" -w $worldName") devPy.append(" -p plugins/$template") - if (profile) devPy.append(" --profile") - if (forceUpgrade) devPy.append(" --forceUpgrade") if (jar != null) devPy.append(" --jar $jar") println("Starting $template with command ${devPy.toString()}") devPy.append(" $template") } - def process = new ProcessBuilder("ssh", "sw", "-T", devPy.toString()).start(); + def process = new ProcessBuilder("ssh", host, "-T", devPy.toString()).start(); def running = true; def processOutput = new BufferedReader(new InputStreamReader(process.inputStream)) new Thread({ From 335649fa873dd02d385a888be473e466efb03691 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 17 Apr 2025 20:36:16 +0200 Subject: [PATCH 040/107] Fix steamwar.devserver.gradle --- VelocityCore/build.gradle.kts | 2 +- buildSrc/src/steamwar.devserver.gradle | 37 +++++++++++++------------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/VelocityCore/build.gradle.kts b/VelocityCore/build.gradle.kts index 90d43d36..f81416a3 100644 --- a/VelocityCore/build.gradle.kts +++ b/VelocityCore/build.gradle.kts @@ -73,5 +73,5 @@ tasks.register("DevVelocity") { description = "Run a Dev Velocity" dependsOn(":VelocityCore:shadowJar") dependsOn(":VelocityCore:Persistent:jar") - template = "Velocity" + template = "DevVelocity" } diff --git a/buildSrc/src/steamwar.devserver.gradle b/buildSrc/src/steamwar.devserver.gradle index 734bc88d..d38f465a 100644 --- a/buildSrc/src/steamwar.devserver.gradle +++ b/buildSrc/src/steamwar.devserver.gradle @@ -55,6 +55,13 @@ class DevServer extends DefaultTask { if (worldName == null) worldName = properties.get("worldName") host = properties.get("host") + + if (worldName == null) { + throw new GradleException("Please supply the 'worldName' in a 'steamwar.properties' files either in this project dir or any parent project!") + } + if (host == null) { + throw new GradleException("Please supply the 'host' in a 'steamwar.properties' files either in this project dir or any parent project!") + } } doLast { uploadDependencies() @@ -75,7 +82,7 @@ class DevServer extends DefaultTask { super() doLast { if (processInput != null) { - processInput.write("stop\n") + processInput.write(template.endsWith("Velocity") ? "end\n" : "stop\n") processInput.flush() } } @@ -94,28 +101,22 @@ class DevServer extends DefaultTask { } def archive = archiveTask.archiveFile.get().asFile - println("Uploading $archive to ~/plugins/${template}") - new ProcessBuilder("scp", archive.absolutePath, "$host:~/plugins/$template/${archive.name.replace("-all", "")}").start().waitFor() - println("Uploaded $archive to ~/plugins/${template}") + println("Uploading $archive to ~/$template/plugins") + new ProcessBuilder("scp", archive.absolutePath, "$host:~/$template/plugins/${archive.name.replace("-all", "")}").start().waitFor() + println("Uploaded $archive to ~/$template/plugins") } } void startDevServer() { - def devPy = new StringBuilder() - if (template.endsWith("Velocity")) { // TODO Add this to the dev.py! - devPy.append("cd DevVelocity") - devPy.append("; java -jar Velocity.jar --port 25566") - } else { - devPy.append("dev.py") - if (port != null) devPy.append(" --port $port") - if (worldName != null) devPy.append(" -w $worldName") - devPy.append(" -p plugins/$template") - if (jar != null) devPy.append(" --jar $jar") - println("Starting $template with command ${devPy.toString()}") - devPy.append(" $template") - } + def devPy = new StringBuilder().append("./dev.py") + if (port != null) devPy.append(" --port $port") + if (worldName != null) devPy.append(" -w $template/$worldName") + devPy.append(" -p $template/plugins") + if (jar != null) devPy.append(" --jar $jar") + println("Starting $template with command ${devPy.toString()}") + devPy.append(" $template") - def process = new ProcessBuilder("ssh", host, "-T", devPy.toString()).start(); + def process = new ProcessBuilder("ssh", host, "-T", devPy.toString()).start() def running = true; def processOutput = new BufferedReader(new InputStreamReader(process.inputStream)) new Thread({ From 5669725f9bb7e1d328ed53b9eb5ee6b11aa7d73e Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 17 Apr 2025 20:54:32 +0200 Subject: [PATCH 041/107] Fix dev.py path --- buildSrc/src/steamwar.devserver.gradle | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/buildSrc/src/steamwar.devserver.gradle b/buildSrc/src/steamwar.devserver.gradle index d38f465a..847fe64f 100644 --- a/buildSrc/src/steamwar.devserver.gradle +++ b/buildSrc/src/steamwar.devserver.gradle @@ -36,6 +36,8 @@ class DevServer extends DefaultTask { @Optional String jar = null + // Add Configs for FightServer! + DevServer() { super() doFirst { @@ -108,7 +110,7 @@ class DevServer extends DefaultTask { } void startDevServer() { - def devPy = new StringBuilder().append("./dev.py") + def devPy = new StringBuilder().append("dev.py") if (port != null) devPy.append(" --port $port") if (worldName != null) devPy.append(" -w $template/$worldName") devPy.append(" -p $template/plugins") From 4edfd32ff50599f83a8680925257a071d9b09ed5 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 18 Apr 2025 07:53:46 +0200 Subject: [PATCH 042/107] Add a check if the template exists in the user.home directory --- buildSrc/src/steamwar.devserver.gradle | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/buildSrc/src/steamwar.devserver.gradle b/buildSrc/src/steamwar.devserver.gradle index 847fe64f..410b8c9c 100644 --- a/buildSrc/src/steamwar.devserver.gradle +++ b/buildSrc/src/steamwar.devserver.gradle @@ -66,6 +66,7 @@ class DevServer extends DefaultTask { } } doLast { + checkHasTemplate() uploadDependencies() startDevServer() } @@ -91,6 +92,14 @@ class DevServer extends DefaultTask { } } + void checkHasTemplate() { + def process = new ProcessBuilder("ssh", host, "-T", "ls $template").start() + process.waitFor() + if (new BufferedReader(new InputStreamReader(process.inputStream)).lines().count() < 4) { + throw new GradleException("Used template is not in your user.home directory of the given host $host") + } + } + void uploadDependencies() { this.dependsOn.forEach { Project resolved @@ -104,6 +113,7 @@ class DevServer extends DefaultTask { def archive = archiveTask.archiveFile.get().asFile println("Uploading $archive to ~/$template/plugins") + new ProcessBuilder("ssh", host, "-T", "rm $template/plugins/${archive.name.replace("-all", "")}").start().waitFor() new ProcessBuilder("scp", archive.absolutePath, "$host:~/$template/plugins/${archive.name.replace("-all", "")}").start().waitFor() println("Uploaded $archive to ~/$template/plugins") } From 76e00b07db1b8f2a1edcd83eff65120c132be0e9 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 18 Apr 2025 08:00:55 +0200 Subject: [PATCH 043/107] Add plugins option to DevServer Task --- buildSrc/src/steamwar.devserver.gradle | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/buildSrc/src/steamwar.devserver.gradle b/buildSrc/src/steamwar.devserver.gradle index 410b8c9c..339193cd 100644 --- a/buildSrc/src/steamwar.devserver.gradle +++ b/buildSrc/src/steamwar.devserver.gradle @@ -28,6 +28,10 @@ class DevServer extends DefaultTask { @Input String template = null + @Input + @Optional + String plugins = null + @Input @Optional Integer port = null @@ -101,6 +105,8 @@ class DevServer extends DefaultTask { } void uploadDependencies() { + def base = plugins == null ? "$template/plugins" : plugins + println("Uploading to ~/$base") this.dependsOn.forEach { Project resolved AbstractArchiveTask archiveTask @@ -112,10 +118,10 @@ class DevServer extends DefaultTask { } def archive = archiveTask.archiveFile.get().asFile - println("Uploading $archive to ~/$template/plugins") - new ProcessBuilder("ssh", host, "-T", "rm $template/plugins/${archive.name.replace("-all", "")}").start().waitFor() - new ProcessBuilder("scp", archive.absolutePath, "$host:~/$template/plugins/${archive.name.replace("-all", "")}").start().waitFor() - println("Uploaded $archive to ~/$template/plugins") + println("Uploading $archive") + new ProcessBuilder("ssh", host, "-T", "rm $base/${archive.name.replace("-all", "")}").start().waitFor() + new ProcessBuilder("scp", archive.absolutePath, "$host:~/$base/${archive.name.replace("-all", "")}").start().waitFor() + println("Uploaded $archive") } } @@ -123,7 +129,7 @@ class DevServer extends DefaultTask { def devPy = new StringBuilder().append("dev.py") if (port != null) devPy.append(" --port $port") if (worldName != null) devPy.append(" -w $template/$worldName") - devPy.append(" -p $template/plugins") + if (plugins != null) devPy.append(" -p $plugins") if (jar != null) devPy.append(" --jar $jar") println("Starting $template with command ${devPy.toString()}") devPy.append(" $template") From 86ff619548de30c97e430b911e433d066146f155 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 18 Apr 2025 08:20:59 +0200 Subject: [PATCH 044/107] Add FightServer to configure those --- buildSrc/src/steamwar.devserver.gradle | 65 +++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/buildSrc/src/steamwar.devserver.gradle b/buildSrc/src/steamwar.devserver.gradle index 339193cd..f40eefb1 100644 --- a/buildSrc/src/steamwar.devserver.gradle +++ b/buildSrc/src/steamwar.devserver.gradle @@ -40,7 +40,9 @@ class DevServer extends DefaultTask { @Optional String jar = null - // Add Configs for FightServer! + @Input + @Optional + Map dParams = {} DevServer() { super() @@ -131,6 +133,9 @@ class DevServer extends DefaultTask { if (worldName != null) devPy.append(" -w $template/$worldName") if (plugins != null) devPy.append(" -p $plugins") if (jar != null) devPy.append(" --jar $jar") + for (Map.Entry dParam : dParams.entrySet()) { + devPy.append("-D${dParam.key}=${dParam.value}") + } println("Starting $template with command ${devPy.toString()}") devPy.append(" $template") @@ -161,4 +166,62 @@ class DevServer extends DefaultTask { processInput = null running = false } +} + +class FightServer extends DevServer { + + @Input + @Optional + int checkSchemID = 0 + + @Input + @Optional + int prepareSchemID = 0 + + @Input + @Optional + int replay = 0 + + @Input + @Optional + String config = null + + @Input + @Optional + // Property: fightID + int eventKampfID = 0 + + @Input + @Optional + UUID blueLeader = null + + @Input + @Optional + UUID redLeader = null + + FightServer() { + super() + doFirst { + { + int count = 0 + if (checkSchemID != 0) count++ + if (prepareSchemID != 0) count++ + if (replay != 0) count++ + if (eventKampfID != 0) count++ + if (count > 1) { + throw new GradleException("You can only set one of 'checkSchemID', 'prepareSchemID', 'replay' and 'eventKampfID'") + } + if (checkSchemID != 0) dParams.put("checkSchemID", "$checkSchemID") + if (prepareSchemID != 0) dParams.put("prepareSchemID", "$prepareSchemID") + if (replay != 0) dParams.put("replay", "$replay") + if (eventKampfID != 0) dParams.put("fightID", "$eventKampfID") + } + if (blueLeader != null && redLeader == null || blueLeader == null && redLeader != null) { + logger.log(LogLevel.WARN, "Please provide both a blue and a red leader. If this is intended ignore this message!") + } + if (blueLeader != null) dParams.put("blueLeader", blueLeader.toString()) + if (redLeader != null) dParams.put("redLeader", redLeader.toString()) + if (config != null) dParams.put("config", config) + } + } } \ No newline at end of file From 059dd314d18284730add43a56613b5ec8b430863 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 18 Apr 2025 10:07:23 +0200 Subject: [PATCH 045/107] Fix building of DevServer --- buildSrc/src/steamwar.devserver.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/steamwar.devserver.gradle b/buildSrc/src/steamwar.devserver.gradle index f40eefb1..feeadce2 100644 --- a/buildSrc/src/steamwar.devserver.gradle +++ b/buildSrc/src/steamwar.devserver.gradle @@ -42,7 +42,7 @@ class DevServer extends DefaultTask { @Input @Optional - Map dParams = {} + Map dParams = new HashMap<>() DevServer() { super() From 925901e40e2093fc97a32cd5444746596c25d031 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 18 Apr 2025 14:15:39 +0200 Subject: [PATCH 046/107] Fix steamwar.devserver.gradle --- buildSrc/src/steamwar.devserver.gradle | 3 --- 1 file changed, 3 deletions(-) diff --git a/buildSrc/src/steamwar.devserver.gradle b/buildSrc/src/steamwar.devserver.gradle index feeadce2..664ee95e 100644 --- a/buildSrc/src/steamwar.devserver.gradle +++ b/buildSrc/src/steamwar.devserver.gradle @@ -64,9 +64,6 @@ class DevServer extends DefaultTask { if (worldName == null) worldName = properties.get("worldName") host = properties.get("host") - if (worldName == null) { - throw new GradleException("Please supply the 'worldName' in a 'steamwar.properties' files either in this project dir or any parent project!") - } if (host == null) { throw new GradleException("Please supply the 'host' in a 'steamwar.properties' files either in this project dir or any parent project!") } From 83c20729fa980488e3d0709087ed06da5a322cea Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 18 Apr 2025 14:52:27 +0200 Subject: [PATCH 047/107] Fix RAM usage on multiple usages --- buildSrc/src/steamwar.devserver.gradle | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/buildSrc/src/steamwar.devserver.gradle b/buildSrc/src/steamwar.devserver.gradle index 664ee95e..72f14168 100644 --- a/buildSrc/src/steamwar.devserver.gradle +++ b/buildSrc/src/steamwar.devserver.gradle @@ -82,11 +82,15 @@ class DevServer extends DefaultTask { @Internal String host + @Internal + Boolean running = true + class Finalizer extends DefaultTask { Finalizer() { super() doLast { + running = false if (processInput != null) { processInput.write(template.endsWith("Velocity") ? "end\n" : "stop\n") processInput.flush() @@ -137,7 +141,6 @@ class DevServer extends DefaultTask { devPy.append(" $template") def process = new ProcessBuilder("ssh", host, "-T", devPy.toString()).start() - def running = true; def processOutput = new BufferedReader(new InputStreamReader(process.inputStream)) new Thread({ while (running) { From 313b22cb4461dbc85a833172c93b441414bf01f1 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 20 Apr 2025 18:30:30 +0200 Subject: [PATCH 048/107] Optimize SimulatorStabGenerator --- .../bausystem/utils/FlatteningWrapper15.java | 14 +- .../features/simulator/data/tnt/TNTPhase.java | 1 + .../features/simulator/execute/Direction.java | 34 ++ .../execute/SimulatorStabGenerator.java | 357 +----------------- .../features/simulator/execute/StabData.java | 52 +++ .../simulator/execute/StabDirection.java | 103 +++++ .../simulator/execute/StabFinalizer.java | 61 +++ .../simulator/execute/StabGenerator.java | 250 ++++++++++++ .../features/simulator/execute/StabSetup.java | 85 +++++ .../features/simulator/execute/StabStep.java | 95 +++++ .../de/steamwar/bausystem/region/Point.java | 4 + 11 files changed, 697 insertions(+), 359 deletions(-) create mode 100644 BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/Direction.java create mode 100644 BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabData.java create mode 100644 BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabDirection.java create mode 100644 BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabFinalizer.java create mode 100644 BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabGenerator.java create mode 100644 BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabSetup.java create mode 100644 BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabStep.java diff --git a/BauSystem/BauSystem_15/src/de/steamwar/bausystem/utils/FlatteningWrapper15.java b/BauSystem/BauSystem_15/src/de/steamwar/bausystem/utils/FlatteningWrapper15.java index 9407f542..266326e0 100644 --- a/BauSystem/BauSystem_15/src/de/steamwar/bausystem/utils/FlatteningWrapper15.java +++ b/BauSystem/BauSystem_15/src/de/steamwar/bausystem/utils/FlatteningWrapper15.java @@ -109,7 +109,7 @@ public class FlatteningWrapper15 implements FlatteningWrapper { @Override public void setSelection(Player p, Point minPoint, Point maxPoint) { - WORLDEDIT_PLUGIN.getSession(p).setRegionSelector(BUKKITWORLD, new CuboidRegionSelector(BUKKITWORLD, toBlockVector3(minPoint), toBlockVector3(maxPoint))); + WORLDEDIT_PLUGIN.getSession(p).setRegionSelector(BUKKITWORLD, new CuboidRegionSelector(BUKKITWORLD, minPoint.toBlockVector3(), maxPoint.toBlockVector3())); } @Override @@ -178,9 +178,9 @@ public class FlatteningWrapper15 implements FlatteningWrapper { pastePoint.set(v); if (pasteBuilder.isReset()) { - e.setBlocks(new CuboidRegion(toBlockVector3(pasteBuilder.getMinPoint()), toBlockVector3(pasteBuilder.getMaxPoint())), Objects.requireNonNull(BlockTypes.AIR).getDefaultState().toBaseBlock()); + e.setBlocks(new CuboidRegion(pasteBuilder.getMinPoint().toBlockVector3(), pasteBuilder.getMaxPoint().toBlockVector3()), Objects.requireNonNull(BlockTypes.AIR).getDefaultState().toBaseBlock()); if (pasteBuilder.getWaterLevel() != 0) { - e.setBlocks(new CuboidRegion(toBlockVector3(pasteBuilder.getMinPoint()), toBlockVector3(pasteBuilder.getMaxPoint()).withY(pasteBuilder.getWaterLevel())), Objects.requireNonNull(BlockTypes.WATER).getDefaultState().toBaseBlock()); + e.setBlocks(new CuboidRegion(pasteBuilder.getMinPoint().toBlockVector3(), pasteBuilder.getMaxPoint().toBlockVector3().withY(pasteBuilder.getWaterLevel())), Objects.requireNonNull(BlockTypes.WATER).getDefaultState().toBaseBlock()); } } Operations.completeBlindly(ch.createPaste(e).to(v).ignoreAirBlocks(pasteBuilder.isIgnoreAir()).build()); @@ -193,7 +193,7 @@ public class FlatteningWrapper15 implements FlatteningWrapper { @Override public Clipboard copy(Point minPoint, Point maxPoint, Point copyPoint) { BukkitWorld bukkitWorld = new BukkitWorld(Bukkit.getWorlds().get(0)); - CuboidRegion region = new CuboidRegion(bukkitWorld, toBlockVector3(minPoint), toBlockVector3(maxPoint)); + CuboidRegion region = new CuboidRegion(bukkitWorld, minPoint.toBlockVector3(), maxPoint.toBlockVector3()); BlockArrayClipboard clipboard = new BlockArrayClipboard(region); try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(bukkitWorld, -1)) { ForwardExtentCopy copy = new ForwardExtentCopy( @@ -204,7 +204,7 @@ public class FlatteningWrapper15 implements FlatteningWrapper { copy.setCopyingBiomes(false); Operations.complete(copy); - clipboard.setOrigin(toBlockVector3(copyPoint)); + clipboard.setOrigin(copyPoint.toBlockVector3()); return clipboard; } catch (WorldEditException e) { Bukkit.getLogger().log(Level.SEVERE, e.getMessage(), e); @@ -224,10 +224,6 @@ public class FlatteningWrapper15 implements FlatteningWrapper { } } - private BlockVector3 toBlockVector3(Point point) { - return BlockVector3.at(point.getX(), point.getY(), point.getZ()); - } - @Override public boolean inWater(org.bukkit.World world, Vector tntPosition) { Block block = world.getBlockAt(tntPosition.getBlockX(), tntPosition.getBlockY(), tntPosition.getBlockZ()); diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTPhase.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTPhase.java index 4c03ac9b..29f59d93 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTPhase.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTPhase.java @@ -60,6 +60,7 @@ public final class TNTPhase extends SimulatorPhase { @Override public void toSimulatorActions(Vector position, BiConsumer tickStart, BiConsumer tickEnd) { + if (count <= 0) return; tickStart.accept(tickOffset, new SimulatorAction(order, count) { @Override public void accept(World world) { diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/Direction.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/Direction.java new file mode 100644 index 00000000..31737266 --- /dev/null +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/Direction.java @@ -0,0 +1,34 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.simulator.execute; + +import lombok.AllArgsConstructor; +import org.bukkit.util.Vector; + +import java.util.function.Function; + +@AllArgsConstructor +public enum Direction { + X(Vector::getBlockX), + Y(Vector::getBlockY), + Z(Vector::getBlockZ); + + public final Function component; +} diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java index 0cbd2eeb..37ca8bf3 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorStabGenerator.java @@ -19,370 +19,27 @@ package de.steamwar.bausystem.features.simulator.execute; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.WorldEdit; -import com.sk89q.worldedit.bukkit.BukkitWorld; -import com.sk89q.worldedit.extent.clipboard.Clipboard; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.regions.CuboidRegion; -import com.sk89q.worldedit.world.block.BlockTypes; -import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.features.simulator.SimulatorWatcher; import de.steamwar.bausystem.features.simulator.data.Simulator; -import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; -import de.steamwar.bausystem.features.simulator.data.SimulatorPhase; import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement; -import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase; -import de.steamwar.bausystem.features.tracer.TNTPoint; -import de.steamwar.bausystem.features.tracer.Trace; -import de.steamwar.bausystem.features.tracer.TraceManager; -import de.steamwar.bausystem.features.tracer.TraceRecorder; -import de.steamwar.bausystem.region.Point; import de.steamwar.bausystem.region.Region; -import de.steamwar.bausystem.region.flags.Flag; -import de.steamwar.bausystem.region.flags.flagvalues.ColorMode; -import de.steamwar.bausystem.region.utils.RegionExtensionType; -import de.steamwar.bausystem.region.utils.RegionType; -import de.steamwar.bausystem.utils.FlatteningWrapper; -import de.steamwar.bausystem.utils.PasteBuilder; -import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar; import de.steamwar.bausystem.utils.bossbar.BossBarService; -import lombok.AllArgsConstructor; import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.boss.BarColor; -import org.bukkit.boss.BarStyle; import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.HandlerList; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityExplodeEvent; -import org.bukkit.util.Vector; -import java.util.*; -import java.util.function.Function; -import java.util.logging.Level; -import java.util.stream.Collectors; +public class SimulatorStabGenerator { -public class SimulatorStabGenerator implements Listener { - - // Lupfstichs sind noch nicht perfekt - // Schwenkstichs sidn noch nicht perfekt - - private static final int MAX_RECORDINGS = 5; - private static final Level LEVEL = Level.INFO; - private static final int TNT_INCREASE = 10; - private static final int MIN_BLOCK_TO_COUNT_AS_DEPTH = 20; - - private final Map> destroyedBlocksPerSlice = new HashMap<>(); - - @EventHandler - public void onEntityExplode(EntityExplodeEvent event) { - if (direction == null) return; - if (Region.getRegion(event.getEntity().getLocation()) == region) { - event.blockList().forEach(block -> { - if (!region.inRegion(block.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.EXTENSION)) return; - int component = direction.component.apply(block.getLocation().toVector()); - destroyedBlocksPerSlice.computeIfAbsent(component, __ -> new HashSet<>()) - .add(block.getLocation()); - }); - } - } - - private final Region region; - private final Simulator simulator; - private final TNTElement tntElement; - private final List phases; - private final int depthLimit; - - private Clipboard clipboard; - private boolean cancel = false; - - private Direction direction = null; + private final StabData stabData; public SimulatorStabGenerator(Region region, Simulator simulator, TNTElement tntElement, int depthLimit) { - this.region = region; - this.simulator = simulator; - this.tntElement = tntElement; - this.phases = tntElement.getPhases(); - this.depthLimit = depthLimit; - - setup(); - } - - private void setup() { - TNTPhase tntPhase = simulator.getGroups().stream() - .filter(simulatorGroup -> !simulatorGroup.isDisabled()) - .map(SimulatorGroup::getElements) - .flatMap(List::stream) - .filter(TNTElement.class::isInstance) - .map(TNTElement.class::cast) - .filter(tntElement -> !tntElement.isDisabled()) - .filter(tntElement -> this.tntElement != tntElement) - .map(tntElement -> tntElement.getPhases().stream().max(Comparator.comparingInt(TNTPhase::getTickOffset))) - .filter(Optional::isPresent) - .map(Optional::get) - .filter(phase -> phase != phases.get(0)) - .max(Comparator.comparingInt(TNTPhase::getTickOffset)) - .orElse(null); - if (tntPhase == null) { - throw new SecurityException(""); - } - - TNTPhase phase = phases.get(0); - phases.clear(); - phases.add(phase); - phase.setCount(1); - phase.setTickOffset(tntPhase.getTickOffset()); - phase.setOrder(100); - - TraceRecorder.instance.stopRecording(region); - if (TraceRecorder.instance.isAutoTraceEnabledInRegion(region)) { - TraceRecorder.instance.removeAutoTraceRegion(region); - } - clipboard = FlatteningWrapper.impl.copy(region.getMinPointTestblockExtension(), region.getMaxPointTestblockExtension(), region.getTestBlockPoint()); - - getDirection(); - } - - private BlockVector3 toBlockVector3(Point point) { - return BlockVector3.at(point.getX(), point.getY(), point.getZ()); - } - - private void getDirection() { - try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1)) { - e.setBlocks((com.sk89q.worldedit.regions.Region) new CuboidRegion(toBlockVector3(region.getMinPointTestblockExtension()), toBlockVector3(region.getMaxPointTestblockExtension())), Objects.requireNonNull(BlockTypes.AIR).getDefaultState().toBaseBlock()); - } - - showBossbar(false); - - Trace trace = TraceRecorder.instance.startRecording(region); - SimulatorExecutor.run(simulator, () -> { - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { - TraceRecorder.instance.stopRecording(region); - calculateDirection(trace); - }, 20); - }); - } - - private void calculateDirection(Trace trace) { - long tickSinceStart = -1; - List points = null; - for (List current : trace.getHistories()) { - long ticks = current.get(0).getTicksSinceStart(); - if (points == null || ticks > tickSinceStart) { - tickSinceStart = ticks; - points = current; - } else if (ticks == tickSinceStart && points.get(0).getTntId() < current.get(0).getTntId()) { - points = current; - } - } - TraceManager.instance.remove(trace); - if (points == null) { - stop(); - return; - } - - TNTPoint current = points.getLast(); - Vector velocity = current.getVelocity(); - if (velocity.getX() < 0) velocity.setX(-velocity.getX()); - if (velocity.getY() < 0) velocity.setY(-velocity.getY()); - if (velocity.getZ() < 0) velocity.setZ(-velocity.getZ()); - if (velocity.getX() > velocity.getY() && velocity.getX() > velocity.getZ()) { - direction = Direction.X; - } else if (velocity.getY() > velocity.getX() && velocity.getY() > velocity.getZ()) { - direction = Direction.Y; - } else if (velocity.getZ() > velocity.getX() && velocity.getZ() > velocity.getY()) { - direction = Direction.Z; - } else { - stop(); - return; - } - - Bukkit.getLogger().log(LEVEL, "Direction: {0}", direction); - phases.getFirst().setOrder(SimulatorPhase.ORDER_LIMIT); - phases.getFirst().setCount(TNT_INCREASE); - destroyedBlocksPerSlice.clear(); - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { - Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance()); - getStab(); - }, 20); - } - - private void getStab() { - try { - PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(clipboard); - PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider) - .color(region.getPlain(Flag.COLOR, ColorMode.class).getColor()); - region.reset(pasteBuilder, RegionType.TESTBLOCK, RegionExtensionType.EXTENSION); - } catch (SecurityException e) { - stop(); - throw e; - } - if (cancel) return; - - showBossbar(false); - - SimulatorExecutor.run(simulator, () -> { - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::calculateStep, 20); - }); - } - - private int recordings = 0; - private List currentDepths = new ArrayList<>(); - private int lastDepth = 0; - private int currentDepth = 0; - - private void calculateStep() { - List>> locations = destroyedBlocksPerSlice.entrySet() - .stream() - .sorted(Comparator.comparingInt(Map.Entry::getKey)) - .collect(Collectors.toList()); - int depth = 0; - for (int i = 0; i < locations.size(); i++) { - if (i == 0 || i == locations.size() - 1) { - if (locations.get(i).getValue().size() > MIN_BLOCK_TO_COUNT_AS_DEPTH) { - depth++; - } - } else { - depth++; - } - } - - if (depth > 0) { - Bukkit.getLogger().log(LEVEL, "{0} {1} {2}", new Object[]{depth, destroyedBlocksPerSlice.size(), destroyedBlocksPerSlice.values().stream().map(Set::size).collect(Collectors.toList())}); - currentDepths.add(depth); - } - destroyedBlocksPerSlice.clear(); - - int maxDepth = currentDepths.stream().max(Integer::compareTo).orElse(0); - currentDepth = maxDepth; - - int countWithoutLast = 0; - for (int i = 0; i < phases.size() - 1; i++) { - countWithoutLast += phases.get(i).getCount(); - } - - TNTPhase lastPhase = phases.getLast(); - boolean moreTNTNeeded = maxDepth - countWithoutLast >= lastPhase.getCount() - 5; - if (!currentDepths.isEmpty() && moreTNTNeeded) { - Bukkit.getLogger().log(LEVEL, "Increasing tnt count by {0}", TNT_INCREASE); - lastPhase.setCount(lastPhase.getCount() + TNT_INCREASE); - recordings = 0; - currentDepths.clear(); - - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::getStab, 20); - return; - } - - if (recordings++ < MAX_RECORDINGS) { - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::getStab, 20); - return; - } - - recordings = 0; - if (currentDepths.isEmpty()) { - Bukkit.getLogger().log(LEVEL, "No dimension - Increasing tickOffset to: {0}", phases.getFirst().getTickOffset() + 1); - phases.getFirst().setTickOffset(phases.getFirst().getTickOffset() + 1); - phases.getFirst().setOrder(0); - if (phases.getFirst().getTickOffset() > 80) { - stop(); - } else { - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::getStab, 20); - } - return; - } - - currentDepths.clear(); - - Bukkit.getLogger().log(LEVEL, "No more TNT needed on phase adjusting - {0} new depth; {1} current count", new Object[]{maxDepth - countWithoutLast, lastPhase.getCount()}); - lastPhase.setCount(maxDepth - countWithoutLast); - if (lastPhase.getCount() <= 0) { - Bukkit.getLogger().log(LEVEL, "Count was 0 or negative - removing last phase"); - phases.removeLast(); - } - - if (maxDepth > depthLimit) { - Bukkit.getLogger().log(LEVEL, "Depth is greater than {0} - finished", depthLimit); - stop(); - return; - } - if (maxDepth <= lastDepth) { - Bukkit.getLogger().log(LEVEL, "Depth is equal to last depth recorded {0} - finished", maxDepth); - stop(); - return; - } - lastDepth = maxDepth; - - Bukkit.getLogger().log(LEVEL, "Adding new phase in next tick"); - TNTPhase nextPhase = new TNTPhase(); - nextPhase.setCount(TNT_INCREASE); - nextPhase.setTickOffset(lastPhase.getTickOffset() + 1); - nextPhase.setXJump(lastPhase.isXJump()); - nextPhase.setYJump(lastPhase.isYJump()); - nextPhase.setZJump(lastPhase.isZJump()); - phases.add(nextPhase); - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::getStab, 20); - } - - @AllArgsConstructor - private enum Direction { - X(Vector::getBlockX), - Y(Vector::getBlockY), - Z(Vector::getBlockZ); - - private final Function component; - } - - private void showBossbar(boolean finished) { - for (Player player : Bukkit.getOnlinePlayers()) { - BauSystemBossbar bossbar = BossBarService.instance.get(player, region, "simulator_stab_generator"); - bossbar.setColor(BarColor.GREEN); - bossbar.setStyle(BarStyle.SEGMENTED_10); - bossbar.setProgress(Math.min(currentDepth / (double) depthLimit, 1.0)); - StringBuilder st = new StringBuilder(); - - if (finished) { - st.append("§eFinished ").append(currentDepth).append("§8/§7").append(depthLimit); - } else if (direction == null) { - st.append("§eCalculating Stab Direction"); - } else { - st.append("§7Direction§7 §e" + direction); - st.append(" §e").append(currentDepth).append("§8/§7").append(depthLimit); - if (recordings > 0) { - st.append(" §7Retries§8:§e ").append(recordings).append("§8/§7").append(MAX_RECORDINGS); - } - } - - bossbar.setTitle(st.toString()); - } - } - - private void stop() { - simulator.setStabGenerator(null); - SimulatorWatcher.update(simulator); - HandlerList.unregisterAll(this); - - showBossbar(true); - new Thread(() -> { - try { - Thread.sleep(4000); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } finally { - for (Player player : Bukkit.getOnlinePlayers()) { - BossBarService.instance.remove(player, region, "simulator_stab_generator"); - } - } - }).start(); + stabData = new StabData(region, simulator, tntElement, tntElement.getPhases(), depthLimit); + new StabSetup(stabData); } public void cancel() { - cancel = true; - simulator.setStabGenerator(null); + stabData.cancel = true; + stabData.simulator.setStabGenerator(null); for (Player player : Bukkit.getOnlinePlayers()) { - BossBarService.instance.remove(player, region, "simulator_stab_generator"); + BossBarService.instance.remove(player, stabData.region, "simulator_stab_generator"); } - HandlerList.unregisterAll(this); } } diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabData.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabData.java new file mode 100644 index 00000000..dc1a6e0e --- /dev/null +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabData.java @@ -0,0 +1,52 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.simulator.execute; + +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement; +import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase; +import de.steamwar.bausystem.region.Region; +import lombok.RequiredArgsConstructor; + +import java.util.List; +import java.util.logging.Level; + +@RequiredArgsConstructor +public class StabData { + + protected static final int MAX_RECORDINGS = 5; + protected static final int MAX_TICK_DIFFERENCE = 3; + protected static final Level LEVEL = Level.INFO; + protected static final int TNT_INCREASE = 10; + protected static final int MIN_BLOCK_TO_COUNT_AS_DEPTH = 20; + + protected final Region region; + protected final Simulator simulator; + protected final TNTElement tntElement; + protected final List phases; + protected final int depthLimit; + + protected Clipboard clipboard; + protected boolean cancel = false; + + protected Direction direction = null; + protected int currentDepth = 0; +} diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabDirection.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabDirection.java new file mode 100644 index 00000000..4be5284b --- /dev/null +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabDirection.java @@ -0,0 +1,103 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.simulator.execute; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bukkit.BukkitWorld; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.world.block.BlockTypes; +import de.steamwar.bausystem.features.simulator.data.SimulatorPhase; +import de.steamwar.bausystem.features.tracer.TNTPoint; +import de.steamwar.bausystem.features.tracer.Trace; +import de.steamwar.bausystem.features.tracer.TraceManager; +import de.steamwar.bausystem.features.tracer.TraceRecorder; +import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar; +import org.bukkit.Bukkit; +import org.bukkit.util.Vector; + +import java.util.List; +import java.util.Objects; + +public class StabDirection extends StabStep { + + public StabDirection(StabData data) { + super(data); + } + + @Override + protected void start() { + try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1)) { + e.setBlocks((com.sk89q.worldedit.regions.Region) new CuboidRegion(data.region.getMinPointTestblockExtension().toBlockVector3(), data.region.getMaxPointTestblockExtension().toBlockVector3()), Objects.requireNonNull(BlockTypes.AIR).getDefaultState().toBaseBlock()); + } + + Trace trace = TraceRecorder.instance.startRecording(data.region); + runSimulator(() -> { + TraceRecorder.instance.stopRecording(data.region); + calculateDirection(trace); + }); + } + + private void calculateDirection(Trace trace) { + long tickSinceStart = -1; + List points = null; + for (List current : trace.getHistories()) { + long ticks = current.get(0).getTicksSinceStart(); + if (points == null || ticks > tickSinceStart) { + tickSinceStart = ticks; + points = current; + } else if (ticks == tickSinceStart && points.get(0).getTntId() < current.get(0).getTntId()) { + points = current; + } + } + TraceManager.instance.remove(trace); + if (points == null) { + stop(); + return; + } + + TNTPoint current = points.getLast(); + Vector velocity = current.getVelocity(); + if (velocity.getX() < 0) velocity.setX(-velocity.getX()); + if (velocity.getY() < 0) velocity.setY(-velocity.getY()); + if (velocity.getZ() < 0) velocity.setZ(-velocity.getZ()); + if (velocity.getX() > velocity.getY() && velocity.getX() > velocity.getZ()) { + data.direction = Direction.X; + } else if (velocity.getY() > velocity.getX() && velocity.getY() > velocity.getZ()) { + data.direction = Direction.Y; + } else if (velocity.getZ() > velocity.getX() && velocity.getZ() > velocity.getY()) { + data.direction = Direction.Z; + } else { + stop(); + return; + } + + Bukkit.getLogger().log(StabData.LEVEL, "Direction: {0}", data.direction); + data.phases.getFirst().setOrder(SimulatorPhase.ORDER_LIMIT); + data.phases.getFirst().setCount(StabData.TNT_INCREASE); + new StabGenerator(data); + } + + @Override + protected void bossbar(BauSystemBossbar bossbar, boolean finished) { + bossbar.setProgress(0); + bossbar.setTitle("§eCalculating Stab Direction"); + } +} diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabFinalizer.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabFinalizer.java new file mode 100644 index 00000000..5c0d77aa --- /dev/null +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabFinalizer.java @@ -0,0 +1,61 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.simulator.execute; + +import de.steamwar.bausystem.features.tracer.Trace; +import de.steamwar.bausystem.features.tracer.TraceRecorder; +import de.steamwar.bausystem.region.flags.Flag; +import de.steamwar.bausystem.region.flags.flagvalues.ColorMode; +import de.steamwar.bausystem.region.utils.RegionExtensionType; +import de.steamwar.bausystem.region.utils.RegionType; +import de.steamwar.bausystem.utils.PasteBuilder; +import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar; + +public class StabFinalizer extends StabStep { + + public StabFinalizer(StabData data) { + super(data); + } + + @Override + protected void start() { + try { + PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(data.clipboard); + PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider) + .color(data.region.getPlain(Flag.COLOR, ColorMode.class).getColor()); + data.region.reset(pasteBuilder, RegionType.TESTBLOCK, RegionExtensionType.EXTENSION); + } catch (SecurityException e) { + stop(); + throw e; + } + + TraceRecorder.instance.startRecording(data.region); + runSimulator(() -> { + TraceRecorder.instance.stopRecording(data.region); + stop(); + }); + } + + @Override + protected void bossbar(BauSystemBossbar bossbar, boolean stopped) { + bossbar.setProgress(Math.min(data.currentDepth / (double) data.depthLimit, 1.0)); + bossbar.setTitle("§e" + data.currentDepth + "§8/§7" + data.depthLimit); + } +} diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabGenerator.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabGenerator.java new file mode 100644 index 00000000..4a15ebcb --- /dev/null +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabGenerator.java @@ -0,0 +1,250 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.simulator.execute; + +import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase; +import de.steamwar.bausystem.region.Region; +import de.steamwar.bausystem.region.flags.Flag; +import de.steamwar.bausystem.region.flags.flagvalues.ColorMode; +import de.steamwar.bausystem.region.utils.RegionExtensionType; +import de.steamwar.bausystem.region.utils.RegionType; +import de.steamwar.bausystem.utils.PasteBuilder; +import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityExplodeEvent; + +import java.util.*; +import java.util.stream.Collectors; + +import static de.steamwar.bausystem.features.simulator.execute.Direction.Y; + +public class StabGenerator extends StabStep implements Listener { + + private int recordings = 0; + private List currentDepths = new ArrayList<>(); + private int lastDepth = 0; + + private int retries = 0; + + private final Map> destroyedBlocksPerSlice = new HashMap<>(); + + private Set gabStart = new HashSet<>(); + private Set failedAtLeastOnce = new HashSet<>(); + + @EventHandler + public void onEntityExplode(EntityExplodeEvent event) { + if (Region.getRegion(event.getEntity().getLocation()) == data.region) { + event.blockList().forEach(block -> { + if (!data.region.inRegion(block.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.EXTENSION)) return; + int component = data.direction.component.apply(block.getLocation().toVector()); + destroyedBlocksPerSlice.computeIfAbsent(component, __ -> new HashSet<>()) + .add(block.getLocation()); + }); + } + } + + public StabGenerator(StabData data) { + super(data); + } + + @Override + protected void start() { + try { + PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(data.clipboard); + PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider) + .color(data.region.getPlain(Flag.COLOR, ColorMode.class).getColor()); + data.region.reset(pasteBuilder, RegionType.TESTBLOCK, RegionExtensionType.EXTENSION); + } catch (SecurityException e) { + stop(); + throw e; + } + + if (data.cancel) { + HandlerList.unregisterAll(this); + return; + } + + runSimulator(this::calculateStab); + } + + private void calculateStab() { + TNTPhase lastPhase = data.phases.getLast(); + + List>> locations = destroyedBlocksPerSlice.entrySet() + .stream() + .sorted(Comparator.comparingInt(Map.Entry::getKey)) + .collect(Collectors.toList()); + int depth = 0; + for (int i = 0; i < locations.size(); i++) { + if (data.direction != Y && i > 0 && Math.abs(locations.get(i - 1).getKey() - locations.get(i).getKey()) > 3) { + if (gabStart.add(locations.get(i).getKey())) { + Bukkit.getLogger().log(StabData.LEVEL, "Increasing tnt count by {0} because of gap", StabData.TNT_INCREASE); + lastPhase.setCount(lastPhase.getCount() + StabData.TNT_INCREASE); + recordings = 0; + currentDepths.clear(); + + run(); + return; + } + } + if (i == 0 || i == locations.size() - 1) { + if (locations.get(i).getValue().size() > StabData.MIN_BLOCK_TO_COUNT_AS_DEPTH) { + depth++; + } + } else { + depth++; + } + } + + if (depth > 0) { + Bukkit.getLogger().log(StabData.LEVEL, "{0} {1} {2}", new Object[]{depth, destroyedBlocksPerSlice.size(), destroyedBlocksPerSlice.values().stream().map(Set::size).collect(Collectors.toList())}); + destroyedBlocksPerSlice.clear(); + currentDepths.add(depth); + } else { + destroyedBlocksPerSlice.clear(); + lastPhase.setTickOffset(lastPhase.getTickOffset() + 1); + Bukkit.getLogger().log(StabData.LEVEL, "No dimension - Increasing tickOffset to: {0}", lastPhase.getTickOffset()); + lastPhase.setOrder(0); + if (lastPhase.getTickOffset() > 80) { + stop(); + } else { + run(); + } + return; + } + + int minDepth = currentDepths.stream().min(Integer::compareTo).orElse(0); + int maxDepth = currentDepths.stream().max(Integer::compareTo).orElse(0); + data.currentDepth = maxDepth; + + int countWithoutLast = 0; + for (int i = 0; i < data.phases.size() - 1; i++) { + countWithoutLast += data.phases.get(i).getCount(); + } + countWithoutLast -= gabStart.size(); + + boolean moreTNTNeeded = maxDepth - countWithoutLast >= lastPhase.getCount() - 5; + if (moreTNTNeeded) { + Bukkit.getLogger().log(StabData.LEVEL, "Increasing tnt count by {0}", StabData.TNT_INCREASE); + lastPhase.setCount(lastPhase.getCount() + StabData.TNT_INCREASE); + recordings = 0; + currentDepths.clear(); + + run(); + return; + } + + if (recordings++ < StabData.MAX_RECORDINGS) { + run(); + return; + } + + recordings = 0; + currentDepths.clear(); + + if (maxDepth - minDepth > lastPhase.getCount()) { + Bukkit.getLogger().log(StabData.LEVEL, "Stab failed at least once. Adding one tnt to {0}", minDepth - 3); + int current = 0; + TNTPhase last = null; + for (TNTPhase phase : data.phases) { + if (current < minDepth - 3) { + current += phase.getCount(); + last = phase; + continue; + } + + if (failedAtLeastOnce.add(last)) { + last = null; + break; + } + + if (last != null) { + last.setCount(last.getCount() + 1); + Bukkit.getLogger().log(StabData.LEVEL, "Added to phase {0} now has {1} tnt", new Object[]{data.phases.indexOf(last), last.getCount()}); + } + break; + } + + if (last != null) { + run(); + return; + } + } + + Bukkit.getLogger().log(StabData.LEVEL, "No more TNT needed on phase adjusting - {0} new count; {1} current count", new Object[]{maxDepth - countWithoutLast, lastPhase.getCount()}); + lastPhase.setCount(maxDepth - countWithoutLast); + if (lastPhase.getCount() <= 0) { + Bukkit.getLogger().log(StabData.LEVEL, "Count was 0 or negative - removing last phase"); + data.phases.removeLast(); + } + + if (maxDepth > data.depthLimit) { + Bukkit.getLogger().log(StabData.LEVEL, "Depth is greater than {0} - finished", data.depthLimit); + new StabFinalizer(data); + return; + } + if (maxDepth <= lastDepth) { + if (lastPhase.getCount() <= 0) { + retries++; + } + if (lastPhase.getCount() > 0 || retries > StabData.MAX_TICK_DIFFERENCE) { + Bukkit.getLogger().log(StabData.LEVEL, "Depth is equal to last depth recorded {0} - finished", maxDepth); + new StabFinalizer(data); + return; + } + } + lastDepth = maxDepth; + + newPhase(data, lastPhase); + run(); + } + + public static void newPhase(StabData data, TNTPhase lastPhase) { + Bukkit.getLogger().log(StabData.LEVEL, "Adding new phase in next tick"); + TNTPhase nextPhase = new TNTPhase(); + nextPhase.setCount(StabData.TNT_INCREASE); + nextPhase.setTickOffset(lastPhase.getTickOffset() + 1); + nextPhase.setXJump(lastPhase.isXJump()); + nextPhase.setYJump(lastPhase.isYJump()); + nextPhase.setZJump(lastPhase.isZJump()); + data.phases.add(nextPhase); + } + + @Override + protected void bossbar(BauSystemBossbar bossbar, boolean finished) { + bossbar.setProgress(Math.min(data.currentDepth / (double) data.depthLimit, 1.0)); + if (finished) { + bossbar.setTitle("§e" + data.currentDepth + "§8/§7" + data.depthLimit); + return; + } + + StringBuilder st = new StringBuilder(); + st.append("§7Direction §e").append(data.direction); + st.append(" §e").append(data.currentDepth).append("§8/§7").append(data.depthLimit); + if (recordings > 0) { + st.append(" §7Retries§8:§e ").append(recordings).append("§8/§7").append(StabData.MAX_RECORDINGS); + } + bossbar.setTitle(st.toString()); + } +} diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabSetup.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabSetup.java new file mode 100644 index 00000000..9662a638 --- /dev/null +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabSetup.java @@ -0,0 +1,85 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.simulator.execute; + +import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; +import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement; +import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase; +import de.steamwar.bausystem.features.tracer.TraceRecorder; +import de.steamwar.bausystem.utils.FlatteningWrapper; +import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar; + +import java.util.Comparator; +import java.util.List; +import java.util.Optional; + +public class StabSetup extends StabStep { + + public StabSetup(StabData data) { + super(data); + } + + @Override + protected void start() { + TNTPhase tntPhase = data.simulator.getGroups().stream() + .filter(simulatorGroup -> !simulatorGroup.isDisabled()) + .map(SimulatorGroup::getElements) + .flatMap(List::stream) + .filter(TNTElement.class::isInstance) + .map(TNTElement.class::cast) + .filter(tntElement -> !tntElement.isDisabled()) + .filter(tntElement -> data.tntElement != tntElement) + .map(tntElement -> tntElement.getPhases().stream().max(Comparator.comparingInt(TNTPhase::getTickOffset))) + .filter(Optional::isPresent) + .map(Optional::get) + .peek(phase -> { + if (phase.getOrder() > TNTPhase.ORDER_LIMIT) { + phase.setOrder(TNTPhase.ORDER_LIMIT); + } + }) + .filter(phase -> phase != data.phases.get(0)) + .max(Comparator.comparingInt(TNTPhase::getTickOffset)) + .orElse(null); + if (tntPhase == null) { + throw new SecurityException(""); + } + + TNTPhase phase = data.phases.get(0); + data.phases.clear(); + data.phases.add(phase); + phase.setCount(1); + phase.setTickOffset(tntPhase.getTickOffset()); + phase.setOrder(100); + + TraceRecorder.instance.stopRecording(data.region); + if (TraceRecorder.instance.isAutoTraceEnabledInRegion(data.region)) { + TraceRecorder.instance.removeAutoTraceRegion(data.region); + } + data.clipboard = FlatteningWrapper.impl.copy(data.region.getMinPointTestblockExtension(), data.region.getMaxPointTestblockExtension(), data.region.getTestBlockPoint()); + + new StabDirection(data); + } + + @Override + protected void bossbar(BauSystemBossbar bossbar, boolean finished) { + bossbar.setProgress(0); + bossbar.setTitle("§eSetting up Simulator"); + } +} diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabStep.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabStep.java new file mode 100644 index 00000000..ad0d05ee --- /dev/null +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/StabStep.java @@ -0,0 +1,95 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.simulator.execute; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar; +import de.steamwar.bausystem.utils.bossbar.BossBarService; +import org.bukkit.Bukkit; +import org.bukkit.boss.BarColor; +import org.bukkit.boss.BarStyle; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; + +public abstract class StabStep { + + protected final StabData data; + + protected StabStep(StabData data) { + this.data = data; + run(); + } + + protected final void run() { + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + for (Player player : Bukkit.getOnlinePlayers()) { + BauSystemBossbar bossbar = BossBarService.instance.get(player, data.region, "simulator_stab_generator"); + bossbar.setColor(BarColor.GREEN); + bossbar.setStyle(BarStyle.SEGMENTED_10); + bossbar(bossbar, false); + } + }, 1); + + if (this instanceof Listener) { + Bukkit.getPluginManager().registerEvents((Listener) this, BauSystem.getInstance()); + } + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::start, 20); + } + + protected abstract void start(); + + protected final void runSimulator(Runnable onFinish) { + SimulatorExecutor.run(data.simulator, () -> { + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + if (this instanceof Listener) { + HandlerList.unregisterAll((Listener) this); + } + onFinish.run(); + }, 20); + }); + } + + protected abstract void bossbar(BauSystemBossbar bossbar, boolean stopped); + + protected final void stop() { + data.simulator.setStabGenerator(null); + SimulatorWatcher.update(data.simulator); + + for (Player player : Bukkit.getOnlinePlayers()) { + BauSystemBossbar bossbar = BossBarService.instance.get(player, data.region, "simulator_stab_generator"); + bossbar.setColor(BarColor.GREEN); + bossbar.setStyle(BarStyle.SEGMENTED_10); + bossbar(bossbar, true); + } + new Thread(() -> { + try { + Thread.sleep(4000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } finally { + for (Player player : Bukkit.getOnlinePlayers()) { + BossBarService.instance.remove(player, data.region, "simulator_stab_generator"); + } + } + }).start(); + } +} diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/region/Point.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/region/Point.java index 0fa5496e..6f8c5929 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/region/Point.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/region/Point.java @@ -73,4 +73,8 @@ public class Point { public Location toLocation(Player player, double dx, double dy, double dz) { return new Location(player.getWorld(), x + dx, y + dy, z + dz, player.getLocation().getYaw(), player.getLocation().getPitch()); } + + public BlockVector3 toBlockVector3() { + return BlockVector3.at(this.x, this.y, this.z); + } } \ No newline at end of file From 3df84a7dadab125eb19a1df9fe4d7c926fec28b3 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 20 Apr 2025 20:40:19 +0200 Subject: [PATCH 049/107] Update from PR --- buildSrc/src/steamwar.devserver.gradle | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/buildSrc/src/steamwar.devserver.gradle b/buildSrc/src/steamwar.devserver.gradle index 72f14168..1879bf87 100644 --- a/buildSrc/src/steamwar.devserver.gradle +++ b/buildSrc/src/steamwar.devserver.gradle @@ -202,23 +202,10 @@ class FightServer extends DevServer { FightServer() { super() doFirst { - { - int count = 0 - if (checkSchemID != 0) count++ - if (prepareSchemID != 0) count++ - if (replay != 0) count++ - if (eventKampfID != 0) count++ - if (count > 1) { - throw new GradleException("You can only set one of 'checkSchemID', 'prepareSchemID', 'replay' and 'eventKampfID'") - } - if (checkSchemID != 0) dParams.put("checkSchemID", "$checkSchemID") - if (prepareSchemID != 0) dParams.put("prepareSchemID", "$prepareSchemID") - if (replay != 0) dParams.put("replay", "$replay") - if (eventKampfID != 0) dParams.put("fightID", "$eventKampfID") - } - if (blueLeader != null && redLeader == null || blueLeader == null && redLeader != null) { - logger.log(LogLevel.WARN, "Please provide both a blue and a red leader. If this is intended ignore this message!") - } + if (checkSchemID != 0) dParams.put("checkSchemID", "$checkSchemID") + if (prepareSchemID != 0) dParams.put("prepareSchemID", "$prepareSchemID") + if (replay != 0) dParams.put("replay", "$replay") + if (eventKampfID != 0) dParams.put("fightID", "$eventKampfID") if (blueLeader != null) dParams.put("blueLeader", blueLeader.toString()) if (redLeader != null) dParams.put("redLeader", redLeader.toString()) if (config != null) dParams.put("config", config) From ca35ab92340befab77261285d9d1eb3bbac16978 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 20 Apr 2025 20:41:47 +0200 Subject: [PATCH 050/107] Remove code Duplication HotbarKit --- .../de/steamwar/fightsystem/fight/HotbarKit.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java index 6567fe87..193d14ea 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java @@ -31,6 +31,7 @@ import de.steamwar.fightsystem.states.StateDependentTask; import de.steamwar.fightsystem.utils.ItemBuilder; import org.bukkit.Material; import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; @@ -108,15 +109,7 @@ public class HotbarKit extends Kit { Player player = event.getPlayer(); int slot = player.getInventory().getHeldItemSlot(); - Kit activeKit = activeKits.get(player); - if(!(activeKit instanceof HotbarKit) || PersonalKitCreator.inKitCreator(player) || activeKit.getInventory()[slot] == null) - return; - - event.setCancelled(true); - if(!clicked.add(player)) - return; - - ((HotbarKit)activeKit).onClicks[slot].accept(player); + click(player, slot, event); } @EventHandler @@ -125,6 +118,10 @@ public class HotbarKit extends Kit { if (slot < 0 || slot >= HOTBAR_SIZE) return; Player player = (Player) event.getWhoClicked(); + click(player, slot, event); + } + + private void click(Player player, int slot, Cancellable event) { Kit activeKit = activeKits.get(player); if(!(activeKit instanceof HotbarKit) || PersonalKitCreator.inKitCreator(player) || activeKit.getInventory()[slot] == null) return; From 147e34c0d612d3d2b6be913bc5d25fc804cba3de Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Mon, 21 Apr 2025 11:47:00 +0200 Subject: [PATCH 051/107] Fix TNTClickListener --- .../de/steamwar/bausystem/features/util/TNTClickListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/TNTClickListener.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/TNTClickListener.java index a0d91aaa..f412b8ad 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/TNTClickListener.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/TNTClickListener.java @@ -44,7 +44,7 @@ public class TNTClickListener extends SWCommand implements Listener { super("tntdetails"); } - @Register("TNT_DETAILS_COMMAND") + @Register(description = "TNT_DETAILS_COMMAND") public void toggle(Player player) { YAPIONObject yapionObject = Config.getInstance().get(player); if (yapionObject.getOrSetDefault(TNT_CLICK_DETAILS, new YAPIONValue<>(true)).asBoolean().orElse(true)) { From ef66b8c1f1fd1ecf0e7807fdbc6294539b8ee8d8 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 23 Apr 2025 18:28:58 +0200 Subject: [PATCH 052/107] Fix HotbarKit.onInventoryClick not resetting the cursor item --- .../src/de/steamwar/fightsystem/fight/HotbarKit.java | 1 + 1 file changed, 1 insertion(+) diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java index 193d14ea..50144651 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java @@ -119,6 +119,7 @@ public class HotbarKit extends Kit { Player player = (Player) event.getWhoClicked(); click(player, slot, event); + player.setItemOnCursor(null); } private void click(Player player, int slot, Cancellable event) { From 3d7dedd3ade66de7245fff3ae4ea6805e0303050 Mon Sep 17 00:00:00 2001 From: D4rkr34lm Date: Wed, 23 Apr 2025 19:13:07 +0200 Subject: [PATCH 053/107] Fix jukeboxes in panzer sklave --- .../de/steamwar/bausystem/features/slaves/panzern/Panzern.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/Panzern.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/Panzern.java index 3eca97f4..fc27ff49 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/Panzern.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/Panzern.java @@ -25,6 +25,7 @@ import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypes; import de.steamwar.bausystem.utils.WorldEditUtils; +import de.steamwar.core.Core; import lombok.Getter; import lombok.SneakyThrows; import org.bukkit.Location; @@ -56,7 +57,7 @@ public class Panzern { private BaseBlock blockType; private BaseBlock slabType; - private static final BaseBlock jukeboxType = BlockTypes.JUKEBOX.getDefaultState().toBaseBlock(); + private static final BaseBlock jukeboxType = Core.getVersion() > 19 ? BlockTypes.get("lodestone").getDefaultState().toBaseBlock() : BlockTypes.get("jukebox").getDefaultState().toBaseBlock(); private static final BaseBlock cobwebType = BlockTypes.COBWEB.getDefaultState().toBaseBlock(); private static final BaseBlock airType = BlockTypes.AIR.getDefaultState().toBaseBlock(); From 239ba3f21335a2e0258cee6a473aff7abb1d4bbf Mon Sep 17 00:00:00 2001 From: D4rkr34lm Date: Wed, 23 Apr 2025 19:14:44 +0200 Subject: [PATCH 054/107] made more readable --- .../de/steamwar/bausystem/features/slaves/panzern/Panzern.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/Panzern.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/Panzern.java index fc27ff49..2823beb0 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/Panzern.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/Panzern.java @@ -57,7 +57,7 @@ public class Panzern { private BaseBlock blockType; private BaseBlock slabType; - private static final BaseBlock jukeboxType = Core.getVersion() > 19 ? BlockTypes.get("lodestone").getDefaultState().toBaseBlock() : BlockTypes.get("jukebox").getDefaultState().toBaseBlock(); + private static final BaseBlock jukeboxType = (Core.getVersion() > 19 ? BlockTypes.get("lodestone"): BlockTypes.get("jukebox")).getDefaultState().toBaseBlock(); private static final BaseBlock cobwebType = BlockTypes.COBWEB.getDefaultState().toBaseBlock(); private static final BaseBlock airType = BlockTypes.AIR.getDefaultState().toBaseBlock(); From 5ee9d3e1670ef5ce31e0ad116a9737d8b1222316 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 23 Apr 2025 20:55:26 +0200 Subject: [PATCH 055/107] Hotfix HotbarKit --- .../src/de/steamwar/fightsystem/fight/HotbarKit.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java index 50144651..ec4d5439 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java @@ -29,6 +29,7 @@ import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.StateDependentListener; import de.steamwar.fightsystem.states.StateDependentTask; import de.steamwar.fightsystem.utils.ItemBuilder; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; @@ -119,7 +120,9 @@ public class HotbarKit extends Kit { Player player = (Player) event.getWhoClicked(); click(player, slot, event); - player.setItemOnCursor(null); + Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> { + player.setItemOnCursor(null); + }, 1); } private void click(Player player, int slot, Cancellable event) { From 7d45680fcbd9a1db50537dc868c1a4d3f38b655f Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 23 Apr 2025 21:52:27 +0200 Subject: [PATCH 056/107] Enable a Dirt Block (Schem owner -1 and Name like GameMode) to be selected for any ServerTeam member --- .../fightsystem/FightSystem.properties | 1 + .../fightsystem/FightSystem_de.properties | 1 + .../de/steamwar/fightsystem/commands/GUI.java | 41 ++++++++++++++----- .../steamwar/fightsystem/fight/FightTeam.java | 7 +++- .../winconditions/WinconditionBlocks.java | 2 +- .../WinconditionCaptainDead.java | 2 + .../winconditions/WinconditionPercent.java | 2 + 7 files changed, 43 insertions(+), 13 deletions(-) diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties index dde4e266..455e0444 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties @@ -76,6 +76,7 @@ KITSEARCH_TITLE=Search for kit SCHEM_NO_ENEMY=§cNo schematic selection without an opponent SCHEM_TITLE={0} selection +SCHEM_DIRT=§eDirt Block SCHEM_PUBLIC=§ePublic {0} SCHEM_UNCHECKED=§eUnchecked {0} SCHEM_PRIVATE=§ePrivate {0} diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties index 470226a8..cd294425 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties @@ -70,6 +70,7 @@ KITSEARCH_TITLE=Nach Kit suchen SCHEM_NO_ENEMY=§cKeine Schematicwahl ohne Gegner SCHEM_TITLE={0}-Auswahl +SCHEM_DIRT=§eErdblock SCHEM_PUBLIC=§eÖffentliches {0} SCHEM_UNCHECKED=§eUngeprüftes {0} SCHEM_PRIVATE=§ePrivates {0} diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java index 2ca6849c..87e72c08 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java @@ -24,15 +24,14 @@ import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.ai.AIManager; import de.steamwar.fightsystem.fight.*; +import de.steamwar.fightsystem.fight.Fight; +import de.steamwar.fightsystem.fight.FightPlayer; import de.steamwar.fightsystem.listener.PersonalKitCreator; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.utils.ColorConverter; import de.steamwar.inventory.*; import de.steamwar.message.Message; -import de.steamwar.sql.PersonalKit; -import de.steamwar.sql.SchematicNode; -import de.steamwar.sql.SchematicType; -import de.steamwar.sql.SteamwarUser; +import de.steamwar.sql.*; import net.md_5.bungee.api.ChatMessageType; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -40,7 +39,10 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.function.Consumer; import java.util.stream.Collectors; public class GUI { @@ -206,6 +208,16 @@ public class GUI { for (int i = 0; i < Config.SubTypes.size(); i++) { setupSchemTypeRow(p, inv, Config.SubTypes.get(i), i + 1); } + if (!Config.test() && SteamwarUser.get(p.getUniqueId()).hasPerm(UserPerm.TEAM)) { + SchematicNode node = SchematicNode.getSchematicNode(-1, Config.GameName, (Integer) null); + if (node != null) { + inv.setItem(2, new SWItem(SWItem.getMaterial(node.getItem()), msg.parse("SCHEM_DIRT", p), click -> { + schemSelect(p, node, fightTeam -> { + fightTeam.setIgnoreWinconditions(true); + }); + })); + } + } inv.setCallback(-999, (ClickType click) -> p.closeInventory()); inv.open(); } @@ -241,14 +253,21 @@ public class GUI { private static void schemDialog(Player p, SchematicType type, boolean publicSchems, boolean unchecked){ SchematicSelector selector = new SchematicSelector(p, Config.test() ? SchematicSelector.selectSchematic() : SchematicSelector.selectSchematicType(unchecked ? type.checkType() : type), node -> { - FightTeam fightTeam = Fight.getPlayerTeam(p); - if(fightTeam == null) - return; - if(Config.test() || FightState.getFightState() != FightState.POST_SCHEM_SETUP) - fightTeam.pasteSchem(node); - p.closeInventory(); + schemSelect(p, node, fightTeam -> { + fightTeam.setIgnoreWinconditions(false); + }); }); selector.setPublicMode(publicSchems?SchematicSelector.PublicMode.PUBLIC_ONLY:SchematicSelector.PublicMode.PRIVATE_ONLY); selector.open(); } + + private static void schemSelect(Player p, SchematicNode node, Consumer fightTeamConsumer) { + FightTeam fightTeam = Fight.getPlayerTeam(p); + if(fightTeam == null) + return; + fightTeamConsumer.accept(fightTeam); + if(Config.test() || FightState.getFightState() != FightState.POST_SCHEM_SETUP) + fightTeam.pasteSchem(node); + p.closeInventory(); + } } 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 0cb68f71..19d45690 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java @@ -42,6 +42,7 @@ import de.steamwar.inventory.SWItem; import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SteamwarUser; import lombok.Getter; +import lombok.Setter; import net.md_5.bungee.api.ChatMessageType; import org.bukkit.*; import org.bukkit.entity.LivingEntity; @@ -100,6 +101,10 @@ public class FightTeam { @Getter private boolean publicsOnly; + @Getter + @Setter + private boolean ignoreWinconditions; + private final Map players = new HashMap<>(); @Getter @@ -385,7 +390,7 @@ public class FightTeam { } public void pasteSchem(SchematicNode schematic){ - if(schematic.getSchemtype().check()) { + if(schematic.getSchemtype().check() || schematic.getSchemtype().writeable()) { FightStatistics.unrank(); FightSystem.getMessage().broadcast("SCHEMATIC_UNCHECKED", getColoredName()); } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionBlocks.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionBlocks.java index b9b0c9f7..4bbaa241 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionBlocks.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionBlocks.java @@ -85,7 +85,7 @@ public class WinconditionBlocks extends Wincondition implements PrintableWincond private void check() { blocks.removeIf(block -> !isOfType.test(block)); - if(blocks.isEmpty()) + if(blocks.isEmpty() && !team.isIgnoreWinconditions()) win(Fight.getOpposite(team), "WIN_TECHKO", team.getColoredName()); } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionCaptainDead.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionCaptainDead.java index de0205ab..df7651ee 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionCaptainDead.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionCaptainDead.java @@ -42,6 +42,8 @@ public class WinconditionCaptainDead extends Wincondition implements Listener { return; FightTeam team = leader.getTeam(); + if (team.isIgnoreWinconditions()) + return; win(Fight.getOpposite(team), "WIN_LEADER_DEAD", team.getPrefix() + leader.getEntity().getName()); } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercent.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercent.java index 37d3fafa..5a2cbe4f 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercent.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercent.java @@ -40,6 +40,8 @@ public class WinconditionPercent extends Wincondition implements PrintableWincon private final Map teamMap = new HashMap<>(); protected Consumer checkWin = team -> { + if (team.isIgnoreWinconditions()) + return; if (getPercent(team) >= Config.PercentWin) { win(Fight.getOpposite(team), "WIN_PERCENT", team.getColoredName()); } From f89c4e88f91b5eefa0f7af6ec67a696e02b304f2 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 25 Apr 2025 18:07:14 +0200 Subject: [PATCH 057/107] Fix HotbarKit Fix steamwar.devserver.gradle Add WarGear20 to build.gradle.kts --- .../src/de/steamwar/fightsystem/fight/HotbarKit.java | 4 +--- FightSystem/build.gradle.kts | 10 ++++++++++ buildSrc/src/steamwar.devserver.gradle | 12 ++++++------ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java index ec4d5439..6b3df110 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java @@ -37,6 +37,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; @@ -120,9 +121,6 @@ public class HotbarKit extends Kit { Player player = (Player) event.getWhoClicked(); click(player, slot, event); - Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> { - player.setItemOnCursor(null); - }, 1); } private void click(Player player, int slot, Cancellable event) { diff --git a/FightSystem/build.gradle.kts b/FightSystem/build.gradle.kts index 0cd412bc..87849826 100644 --- a/FightSystem/build.gradle.kts +++ b/FightSystem/build.gradle.kts @@ -39,3 +39,13 @@ dependencies { implementation(project(":FightSystem:FightSystem_20")) implementation(project(":FightSystem:FightSystem_21")) } + +tasks.register("WarGear20") { + group = "run" + description = "Run a WarGear 1.20 Fight Server" + dependsOn(":SpigotCore:shadowJar") + dependsOn(":FightSystem:shadowJar") + template = "WarGear20" + worldName = "arenas/Pentraki" + config = "WarGear20.yml" +} diff --git a/buildSrc/src/steamwar.devserver.gradle b/buildSrc/src/steamwar.devserver.gradle index 1879bf87..53f8be3d 100644 --- a/buildSrc/src/steamwar.devserver.gradle +++ b/buildSrc/src/steamwar.devserver.gradle @@ -135,10 +135,10 @@ class DevServer extends DefaultTask { if (plugins != null) devPy.append(" -p $plugins") if (jar != null) devPy.append(" --jar $jar") for (Map.Entry dParam : dParams.entrySet()) { - devPy.append("-D${dParam.key}=${dParam.value}") + devPy.append(" -D${dParam.key}=${dParam.value}") } - println("Starting $template with command ${devPy.toString()}") devPy.append(" $template") + println("Starting $template with command ${devPy.toString()}") def process = new ProcessBuilder("ssh", host, "-T", devPy.toString()).start() def processOutput = new BufferedReader(new InputStreamReader(process.inputStream)) @@ -172,15 +172,15 @@ class FightServer extends DevServer { @Input @Optional - int checkSchemID = 0 + Integer checkSchemID = 0 @Input @Optional - int prepareSchemID = 0 + Integer prepareSchemID = 0 @Input @Optional - int replay = 0 + Integer replay = 0 @Input @Optional @@ -189,7 +189,7 @@ class FightServer extends DevServer { @Input @Optional // Property: fightID - int eventKampfID = 0 + Integer eventKampfID = 0 @Input @Optional From 84cc292df4fd8c821d3ef82dc3aabf01207c7411 Mon Sep 17 00:00:00 2001 From: D4rkr34lm Date: Sat, 26 Apr 2025 13:08:13 +0200 Subject: [PATCH 058/107] Fixed meterstock --- .../de/steamwar/bausystem/features/region/FreezeListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeListener.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeListener.java index a78ff18a..673867e7 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeListener.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeListener.java @@ -226,7 +226,7 @@ public class FreezeListener implements Listener, ScoreboardElement { } } - @EventHandler(priority = EventPriority.MONITOR) + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onBlockBreak(BlockBreakEvent e) { if (Core.getVersion() < 19) return; if (e.getPlayer().getInventory().getItemInMainHand().getType() == Material.DEBUG_STICK) return; From e72ae3cf9477238200161e2b315ec5bd10b6e14c Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sat, 26 Apr 2025 22:13:31 +0200 Subject: [PATCH 059/107] LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java aktualisiert --- LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java b/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java index f8ce3338..324a7901 100644 --- a/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java +++ b/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java @@ -107,7 +107,7 @@ public class JumpAndRun extends BasicListener { if (location.getY() < point.getY()) { return; } - if (location.toVector().distanceSquared(point) >= 12.25) { + if (location.toVector().distanceSquared(point) >= 17) { return; } CURRENT_POS.put(event.getPlayer(), index); From 713275ba11826874a00a6b87c4063d67608e3fe1 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sat, 26 Apr 2025 22:17:43 +0200 Subject: [PATCH 060/107] Add ErrorLogging for Bugged Schematics --- .../src/de/steamwar/routes/Schematic.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/WebsiteBackend/src/de/steamwar/routes/Schematic.kt b/WebsiteBackend/src/de/steamwar/routes/Schematic.kt index 1beb0f29..b220db08 100644 --- a/WebsiteBackend/src/de/steamwar/routes/Schematic.kt +++ b/WebsiteBackend/src/de/steamwar/routes/Schematic.kt @@ -149,6 +149,22 @@ fun Route.configureSchematic() { return@let SchematicFormat.SPONGE_V2 } + if (version == SchematicFormat.SPONGE_V3) { + try { + val fawe = schem.getCompound("Metadata") + .getCompound("WorldEdit") + .getString("Version") + + if (fawe.equals("2.12.3-SNAPSHOT")) { + SWException.log("Schematic with Bugged Version Uploaded", """ + Schematic=$schemName + User=${user.userName} + Id=${user.id} + """.trimIndent()) + } + } catch (_: Exception) {} + } + val data = NodeData(node.id, version) data.saveFromStream(content.inputStream(), version) From b1bef4ced5ed8d3222ed95ada4841b536abb9b50 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sat, 26 Apr 2025 22:27:53 +0200 Subject: [PATCH 061/107] Add ErrorLogging for Bugged Schematics --- WebsiteBackend/src/de/steamwar/routes/Schematic.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/WebsiteBackend/src/de/steamwar/routes/Schematic.kt b/WebsiteBackend/src/de/steamwar/routes/Schematic.kt index b220db08..ec3b54fb 100644 --- a/WebsiteBackend/src/de/steamwar/routes/Schematic.kt +++ b/WebsiteBackend/src/de/steamwar/routes/Schematic.kt @@ -154,6 +154,7 @@ fun Route.configureSchematic() { val fawe = schem.getCompound("Metadata") .getCompound("WorldEdit") .getString("Version") + .value if (fawe.equals("2.12.3-SNAPSHOT")) { SWException.log("Schematic with Bugged Version Uploaded", """ From f93362a02344b83bd29515700b99c551d0ac76f3 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sat, 26 Apr 2025 23:48:33 +0200 Subject: [PATCH 062/107] LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java aktualisiert --- LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java b/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java index 324a7901..a783b05e 100644 --- a/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java +++ b/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java @@ -67,7 +67,7 @@ public class JumpAndRun extends BasicListener { int count = CLICKED_COUNT.getOrDefault(player, -1); if (count >= 0) { - if (count > 60) { + if (count > 20) { toReset.add(player); return; } From b5a95648088c07492ffe4feed54442b61c3d18e8 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 26 Apr 2025 23:56:59 +0200 Subject: [PATCH 063/107] Allow next next location in JumpAndRun --- .../de/steamwar/lobby/jumpandrun/JumpAndRun.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java b/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java index 324a7901..3b8a3ab4 100644 --- a/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java +++ b/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java @@ -104,12 +104,18 @@ public class JumpAndRun extends BasicListener { return; } Vector point = points.get(index); - if (location.getY() < point.getY()) { - return; - } - if (location.toVector().distanceSquared(point) >= 17) { + if (location.getY() < point.getY()) index = -2; + if (location.toVector().distanceSquared(point) >= 17) index = -2; + if (index > 0 && index < points.size() - 1) { + Vector nextPoint = points.get(index + 1); + if (location.getY() >= nextPoint.getY() && location.toVector().distanceSquared(nextPoint) < 17) { + index = index + 1; + } + } + if (index == -2) { return; } + CURRENT_POS.put(event.getPlayer(), index); event.getPlayer().playSound(event.getPlayer().getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 0.4F, 1); if (index < points.size() - 1) { From 5cdad8c2f4adc909eec1f62c3b1966ff23d1d752 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 27 Apr 2025 02:28:39 +0200 Subject: [PATCH 064/107] Add Dev 1.21.5 --- VelocityCore/src/de/steamwar/velocitycore/ServerVersion.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/VelocityCore/src/de/steamwar/velocitycore/ServerVersion.java b/VelocityCore/src/de/steamwar/velocitycore/ServerVersion.java index a5e08b55..d8952118 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/ServerVersion.java +++ b/VelocityCore/src/de/steamwar/velocitycore/ServerVersion.java @@ -44,6 +44,7 @@ public enum ServerVersion { PAPER_18("paper-1.18.2.jar", 15, ProtocolVersion.MINECRAFT_1_18_2), PAPER_19("paper-1.19.3.jar", 19, ProtocolVersion.MINECRAFT_1_19_3), PAPER_20("paper-1.20.1.jar", 20, ProtocolVersion.MINECRAFT_1_20), + DEVEL_21("paper-1.21.5.jar", 21, ProtocolVersion.MINECRAFT_1_21_5), PAPER_21("paper-1.21.3.jar", 21, ProtocolVersion.MINECRAFT_1_21_2); private static final Map chatMap = new HashMap<>(); @@ -94,6 +95,10 @@ public enum ServerVersion { } public static ServerVersion get(int version) { + if (version == 21) { + return DEVEL_21; + } + return versionMap.get(version); } From 66d18e316b229fae615e0688f0d6da0908e881d7 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Mon, 28 Apr 2025 16:47:43 +0200 Subject: [PATCH 065/107] =?UTF-8?q?Hotfix:=20Schematic=20Download=20geht?= =?UTF-8?q?=20f=C3=BCr=20nicht=20Supervisor=20Player?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bausystem/features/world/SpectatorListener.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/world/SpectatorListener.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/world/SpectatorListener.java index 3b3ea664..f1aed39f 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/world/SpectatorListener.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/world/SpectatorListener.java @@ -179,7 +179,12 @@ public class SpectatorListener implements Listener { @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) { - if (event.getMessage().startsWith("/schem save") || event.getMessage().startsWith("//schem save") || event.getMessage().startsWith("/schematic save") || event.getMessage().startsWith("//schematic save")) { + if (event.getMessage().startsWith("/schem save") || + event.getMessage().startsWith("//schem save") || + event.getMessage().startsWith("/schematic save") || + event.getMessage().startsWith("//schematic save") || + event.getMessage().startsWith("/download") || + event.getMessage().startsWith("//download")) { if (!Permission.SUPERVISOR.hasPermission(event.getPlayer())) { event.setCancelled(true); event.setMessage("/"); From d6a5caf95d48499776b40bcdd148e96cb2d0933f Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Tue, 29 Apr 2025 17:59:22 +0200 Subject: [PATCH 066/107] Add error handling and logging to Techhider and TinyProtocol --- .../commands/TechhiderbugCommand.java | 42 ++++++++++++------- .../comphenix/tinyprotocol/TinyProtocol.java | 15 +++++++ 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/TechhiderbugCommand.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/TechhiderbugCommand.java index 4a3bf47f..eb0c82f5 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/TechhiderbugCommand.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/TechhiderbugCommand.java @@ -34,6 +34,7 @@ import org.bukkit.command.CommandSender; import java.io.StringWriter; import java.util.Arrays; +import java.util.logging.Level; public class TechhiderbugCommand implements CommandExecutor { @@ -45,25 +46,36 @@ public class TechhiderbugCommand implements CommandExecutor { public boolean onCommand(CommandSender sender, Command cmd, String alias, String[] args) { StringWriter writer = new StringWriter(); - writer.append("ArenaMode: ").append(Config.mode.name()).append('\n'); - writer.append("FightState: ").append(FightState.getFightState().name()).append('\n'); - writer.append("TechHider enabled: ").append(FightState.getStateDependentFeatures().get(FightSystem.getTechHider()).toString()).append('\n'); + try { + writer.append("ArenaMode: ").append(Config.mode.name()).append('\n'); + writer.append("FightState: ").append(FightState.getFightState().name()).append('\n'); + writer.append("TechHider enabled: ").append(FightState.getStateDependentFeatures().get(FightSystem.getTechHider()).toString()).append('\n'); - writer.append("Arena region: ").append(Config.ArenaRegion.toString()).append('\n'); - writer.append("Team regions: "); - Fight.teams().forEach(t -> writer.append(t.getName()).append(':').append(t.getExtendRegion().toString()).append(' ')); - writer.append('\n'); + writer.append("Arena region: ").append(Config.ArenaRegion.toString()).append('\n'); + writer.append("Team regions: "); + Fight.teams().forEach(t -> writer.append(t.getName()).append(':').append(t.getExtendRegion().toString()).append(' ')); + writer.append('\n'); - writer.append("HullHider regions: "); - FightSystem.getHullHider().getHullMap().forEach((t, h) -> writer.append(t.getName()).append(':').append(h.getRegion().toString()).append(' ')); - writer.append('\n'); + writer.append("HullHider regions: "); + FightSystem.getHullHider().getHullMap().forEach((t, h) -> writer.append(t.getName()).append(':').append(h.getRegion().toString()).append(' ')); + writer.append('\n'); - writer.append("Hidden regions: "); - FightSystem.getTechHider().getHiddenRegion().forEach((p, r) -> writer.append(p.getName()).append(':').append(r.toString()).append(' ')); - writer.append('\n'); + writer.append("Hidden regions: "); + FightSystem.getTechHider().getHiddenRegion().forEach((p, r) -> writer.append(p.getName()).append(':').append(r.toString()).append(' ')); + writer.append('\n'); - writer.append('\n').append("Netty pipelines:\n"); - Bukkit.getOnlinePlayers().forEach(p -> writer.append(p.getName()).append(": ").append(String.join(" ", TinyProtocol.instance.getPlayerInterceptors().get(p).getChannel().pipeline().names())).append('\n')); + writer.append("TinyProtocol: "); + writer.append(TinyProtocol.instance.toString()).append('\n'); + + writer.append('\n').append("Netty pipelines:\n"); + Bukkit.getOnlinePlayers().forEach(p -> writer.append(p.getName()).append(": ").append(String.join(" ", TinyProtocol.instance.getPlayerInterceptors().get(p).getChannel().pipeline().names())).append('\n')); + } catch (Exception e) { + writer.append("Error while generating bug report: ").append(e.getMessage()).append('\n'); + writer.flush(); + Bukkit.getLogger().log(Level.SEVERE, "Error while generating bug report", e); + } finally { + writer.flush(); + } SWException.log("Techhider-Bug reported by " + sender.getName() + ": " + Arrays.toString(args), writer.toString()); return false; diff --git a/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java b/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java index af318d83..6a77e082 100644 --- a/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java +++ b/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java @@ -71,6 +71,17 @@ public class TinyProtocol implements Listener { @Getter private final Map playerInterceptors = new HashMap<>(); + @Override + public String toString() { + return "TinyProtocol{" + + "plugin=" + plugin + + ", connections=" + connections + + ", closed=" + closed + + ", packetFilters=" + packetFilters + + ", playerInterceptors=" + playerInterceptors + + '}'; + } + private TinyProtocol(final Plugin plugin) { this.plugin = plugin; this.connections = networkManagers.get(getServerConnection(plugin)); @@ -84,6 +95,7 @@ public class TinyProtocol implements Listener { @EventHandler(priority = EventPriority.LOWEST) public void onPlayerLogin(PlayerLoginEvent e) { + plugin.getLogger().info("Creating Techhider for: " + e.getPlayer().getName() + " (" + closed + ")"); if(closed) return; new PacketInterceptor(e.getPlayer()); @@ -118,6 +130,8 @@ public class TinyProtocol implements Listener { } public final void close() { + plugin.getLogger().log(Level.INFO, "Closing Techhider", new Exception("Stacktrace")); + if(closed) return; closed = true; @@ -155,6 +169,7 @@ public class TinyProtocol implements Listener { return; synchronized (playerInterceptors) { + plugin.getLogger().info("Adding Techhider for: " + player.getName()); playerInterceptors.put(player, this); } From 15bb92fbbac90601ebdc4d2819c7e338789753d8 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Tue, 29 Apr 2025 18:04:58 +0200 Subject: [PATCH 067/107] Improve error handling and logging in Techhider and TinyProtocol Refined logging messages for clarity by replacing "Techhider" with "PacketInterceptor" where appropriate. Adjusted error handling in `TechhiderbugCommand` by removing redundant `flush` calls and properly logging exceptions during bug report generation. These changes aim to enhance maintainability and debugging. --- .../steamwar/fightsystem/commands/TechhiderbugCommand.java | 3 --- .../src/com/comphenix/tinyprotocol/TinyProtocol.java | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/TechhiderbugCommand.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/TechhiderbugCommand.java index eb0c82f5..3080c13e 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/TechhiderbugCommand.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/TechhiderbugCommand.java @@ -71,10 +71,7 @@ public class TechhiderbugCommand implements CommandExecutor { Bukkit.getOnlinePlayers().forEach(p -> writer.append(p.getName()).append(": ").append(String.join(" ", TinyProtocol.instance.getPlayerInterceptors().get(p).getChannel().pipeline().names())).append('\n')); } catch (Exception e) { writer.append("Error while generating bug report: ").append(e.getMessage()).append('\n'); - writer.flush(); Bukkit.getLogger().log(Level.SEVERE, "Error while generating bug report", e); - } finally { - writer.flush(); } SWException.log("Techhider-Bug reported by " + sender.getName() + ": " + Arrays.toString(args), writer.toString()); diff --git a/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java b/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java index 6a77e082..c8070e46 100644 --- a/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java +++ b/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java @@ -95,7 +95,7 @@ public class TinyProtocol implements Listener { @EventHandler(priority = EventPriority.LOWEST) public void onPlayerLogin(PlayerLoginEvent e) { - plugin.getLogger().info("Creating Techhider for: " + e.getPlayer().getName() + " (" + closed + ")"); + plugin.getLogger().info("Creating PacketInterceptor for: " + e.getPlayer().getName() + " (" + closed + ")"); if(closed) return; new PacketInterceptor(e.getPlayer()); @@ -130,7 +130,7 @@ public class TinyProtocol implements Listener { } public final void close() { - plugin.getLogger().log(Level.INFO, "Closing Techhider", new Exception("Stacktrace")); + plugin.getLogger().log(Level.INFO, "Closing PacketInterceptor", new Exception("Stacktrace")); if(closed) return; @@ -169,9 +169,9 @@ public class TinyProtocol implements Listener { return; synchronized (playerInterceptors) { - plugin.getLogger().info("Adding Techhider for: " + player.getName()); playerInterceptors.put(player, this); } + plugin.getLogger().info("Adding Techhider for: " + player.getName()); try { channel.pipeline().addBefore("packet_handler", HANDLER_NAME, this); From 5015aca15905ac4f920f6d9291b7502d87cb4c8d Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Fri, 2 May 2025 10:13:47 +0200 Subject: [PATCH 068/107] =?UTF-8?q?Maybe=E2=84=A2=EF=B8=8F=20fix=20Techhid?= =?UTF-8?q?er?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/com/comphenix/tinyprotocol/TinyProtocol.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java b/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java index c8070e46..6f1dbf1a 100644 --- a/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java +++ b/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java @@ -160,10 +160,10 @@ public class TinyProtocol implements Listener { private PacketInterceptor(Player player) { this.player = player; - channel = getChannel.get(connections.stream().filter(connection -> player.getUniqueId().equals(getUUID.get(connection))).findAny().orElseThrow(() -> { + channel = connections.stream().filter(connection -> player.getUniqueId().equals(getUUID.get(connection))).map(getChannel::get).filter(Channel::isActive).findAny().orElseThrow(() -> { Bukkit.getScheduler().runTask(plugin, () -> player.kickPlayer("Connection failure.")); return new SecurityException("Could not find channel for player " + player.getName()); - })); + }); if(!channel.isActive()) return; @@ -175,11 +175,11 @@ public class TinyProtocol implements Listener { try { channel.pipeline().addBefore("packet_handler", HANDLER_NAME, this); - } catch (IllegalArgumentException e) { + } catch (IllegalArgumentException | NoSuchElementException e) { Bukkit.getScheduler().runTask(plugin, () -> player.kickPlayer("Connection failure.")); throw new SecurityException(e); } - } + } private void sendPacket(Object packet) { channel.pipeline().writeAndFlush(packet); From 6940c32b02945d4594f4cca24f7fd9a09f89886f Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Fri, 2 May 2025 14:13:33 +0200 Subject: [PATCH 069/107] Adjust OpenJ9 JVM arguments to include hprof option in dumps. --- VelocityCore/src/de/steamwar/velocitycore/Node.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/Node.java b/VelocityCore/src/de/steamwar/velocitycore/Node.java index 9c717886..f83d042f 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/Node.java +++ b/VelocityCore/src/de/steamwar/velocitycore/Node.java @@ -35,7 +35,7 @@ public abstract class Node { private static final List OPENJ9_ARGS = Arrays.asList( "-XX:+EnableCRIUSupport", "-XX:-CRIURestoreNonPortableMode", "-Xgc:excessiveGCratio=80", "-Xdisableexplicitgc", "-Xnoclassgc", "-Xmos128M", "-Xmns48M", "-XX:+ExitOnOutOfMemoryError", // initial heap half values of memory observed by 1.19 spectate server - "-Xsyslog:none", "-Xtrace:none", "-Xverify:none", "-Xdump:system:none", "-Xdump:jit:none", "-Xdump:snap:none", + "-Xsyslog:none", "-Xtrace:none", "-Xverify:none", "-Xdump:system:none", "-Xdump:jit:none", "-Xdump:snap:none,opts=hprof", "-XX:+EnableDynamicAgentLoading", "-Dlog4j.configurationFile=log4j2.xml" ); private static final Set JAVA_8 = new HashSet<>(); From 7f0fa09c5674dd5b9799a13c09220f9d12c14235 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Fri, 2 May 2025 14:14:27 +0200 Subject: [PATCH 070/107] Update OpenJ9 dump configuration to enable heap hprof. --- VelocityCore/src/de/steamwar/velocitycore/Node.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/Node.java b/VelocityCore/src/de/steamwar/velocitycore/Node.java index f83d042f..308d9938 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/Node.java +++ b/VelocityCore/src/de/steamwar/velocitycore/Node.java @@ -35,7 +35,7 @@ public abstract class Node { private static final List OPENJ9_ARGS = Arrays.asList( "-XX:+EnableCRIUSupport", "-XX:-CRIURestoreNonPortableMode", "-Xgc:excessiveGCratio=80", "-Xdisableexplicitgc", "-Xnoclassgc", "-Xmos128M", "-Xmns48M", "-XX:+ExitOnOutOfMemoryError", // initial heap half values of memory observed by 1.19 spectate server - "-Xsyslog:none", "-Xtrace:none", "-Xverify:none", "-Xdump:system:none", "-Xdump:jit:none", "-Xdump:snap:none,opts=hprof", + "-Xsyslog:none", "-Xtrace:none", "-Xverify:none", "-Xdump:system:none", "-Xdump:jit:none", "-Xdump:snap:none", "-Xdump:heap:opts=hprof", "-XX:+EnableDynamicAgentLoading", "-Dlog4j.configurationFile=log4j2.xml" ); private static final Set JAVA_8 = new HashSet<>(); From a4eea298d21b2c270fe16231f0b9f94527f77aae Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 7 May 2025 14:37:00 +0200 Subject: [PATCH 071/107] Hotfix PrepareSchem not copying allowReplay and replaceColor while creating a prepared schem --- .../src/de/steamwar/fightsystem/listener/PrepareSchem.java | 3 +++ 1 file changed, 3 insertions(+) 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 288eda76..29ccc434 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/PrepareSchem.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/PrepareSchem.java @@ -86,7 +86,10 @@ public class PrepareSchem implements Listener { if(schemExists(schem)) return; + SchematicNode old = schem; schem = SchematicNode.createSchematicNode(schem.getOwner(), preparedName(schem), schem.getParent(), Config.SchematicType.checkType().toDB(), schem.getItem()); + schem.setReplaceColor(old.replaceColor()); + schem.setAllowReplay(old.allowReplay()); try{ WorldeditWrapper.impl.saveSchem(schem, region, minY); From ac00245b0481fb52b6c421a76a93a63e4431290c Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 11 May 2025 18:50:21 +0200 Subject: [PATCH 072/107] Fix lag of IngameListener --- .../de/steamwar/towerrun/listener/IngameListener.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java index bbb332bf..26b8b045 100644 --- a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java +++ b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java @@ -67,11 +67,15 @@ public class IngameListener extends GameStateBukkitListener { if (blocks == null) { return; } - blocks.forEach(block -> { - if (block.getType() == Material.AIR || block.getType() == Material.LAVA) return; + int maxBlocks = 1_000; + while (maxBlocks > 0 && !blocks.isEmpty()) { + Block block = blocks.removeFirst(); + if (block.getType() == Material.AIR || block.getType() == Material.LAVA) continue; block.setType(Material.AIR); block.getWorld().playSound(block.getLocation(), Sound.BLOCK_FIRE_EXTINGUISH, 0.1F, 1); - }); + maxBlocks--; + } + blocksToMelt.computeIfAbsent(time, __ -> new ArrayList<>()).addAll(0, blocks); } }; blocksToMeltRunnable.runTaskTimer(TowerRun.getInstance(), 0, 1); From b229b0d0ae3d64d1dc03d94ecd75b02b719f357b Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 11 May 2025 19:02:02 +0200 Subject: [PATCH 073/107] Fix many simple things --- .../towerrun/generator/TowerGenerator.java | 6 +- .../towerrun/listener/IngameListener.java | 69 +++++++++++++++---- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/TowerRun/src/de/steamwar/towerrun/generator/TowerGenerator.java b/TowerRun/src/de/steamwar/towerrun/generator/TowerGenerator.java index 4f379547..63cd94ee 100644 --- a/TowerRun/src/de/steamwar/towerrun/generator/TowerGenerator.java +++ b/TowerRun/src/de/steamwar/towerrun/generator/TowerGenerator.java @@ -140,8 +140,10 @@ public class TowerGenerator { noKeyFloors--; if (!chestBlocks.isEmpty() && noKeyFloors < 0 && random.nextDouble() < config.keyChance) { noKeyFloors = random.nextInt(config.maxNoKeyFloors - config.minNoKeyFloors) + config.minNoKeyFloors; - Container container = chestBlocks.get(random.nextInt(chestBlocks.size())); - keys.add(container.getLocation()); + for (int i = 0; i < 2; i++) { + Container container = chestBlocks.get(random.nextInt(chestBlocks.size())); + keys.add(container.getLocation()); + } for (WorldConfig.TowerGeneratorDoorBlock doorBlock : config.doorBlocks) { int x = doorBlock.getX(); diff --git a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java index 26b8b045..eb7c3c1c 100644 --- a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java +++ b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java @@ -20,6 +20,7 @@ package de.steamwar.towerrun.listener; import de.steamwar.inventory.SWItem; +import de.steamwar.network.packets.server.BaumemberUpdatePacket; import de.steamwar.towerrun.TowerRun; import de.steamwar.towerrun.config.Config; import de.steamwar.towerrun.config.WorldConfig; @@ -84,16 +85,16 @@ public class IngameListener extends GameStateBukkitListener { @Override public void run() { double minY = TowerRunGame.PLAYERS_ALIVE.stream() - .map(p -> p.player().getLocation().getY()) - .min(Comparator.comparing(Function.identity())) + .mapToDouble(p -> p.player().getLocation().getY()) + .average() .orElse(0.0); List toDamage = new ArrayList<>(); TowerRunGame.PLAYERS_ALIVE.forEach(towerRunPlayer -> { - if (towerRunPlayer.player().getLocation().getY() - minY > 20) { - towerRunPlayer.player().sendTitle("§a", TowerRun.getMessage().parse("CATCH_UP_WARNING", towerRunPlayer.player()), 5, 30, 5); - } if (towerRunPlayer.player().getLocation().getY() - minY > 30) { + towerRunPlayer.player().sendTitle("", TowerRun.getMessage().parse("CATCH_UP_WARNING", towerRunPlayer.player()), 5, 30, 5); + } + if (towerRunPlayer.player().getLocation().getY() - minY > 50) { toDamage.add(towerRunPlayer.player()); } }); @@ -119,12 +120,12 @@ public class IngameListener extends GameStateBukkitListener { public void onPlayerDeath(PlayerDeathEvent event) { event.setDeathMessage(null); Bukkit.getScheduler().runTaskLater(TowerRun.getInstance(), () -> { - if (TowerRun.getTowerGenerator() != null) { - event.getEntity().teleport(TowerRun.getTowerGenerator().getSpawn()); - } else { - event.getEntity().teleport(WorldConfig.SPAWN); - } - }, 5 + if (TowerRun.getTowerGenerator() != null) { + event.getEntity().teleport(TowerRun.getTowerGenerator().getSpawn()); + } else { + event.getEntity().teleport(WorldConfig.SPAWN); + } + }, 5 ); event.getEntity().setGameMode(GameMode.SPECTATOR); Bukkit.getOnlinePlayers().forEach(player -> { @@ -185,10 +186,12 @@ public class IngameListener extends GameStateBukkitListener { } event.getPlayer().getInventory().addItem(new SWItem(Material.LEVER, TowerRun.getMessage().parse("KEY_NAME", event.getPlayer())).getItemStack()); - event.getClickedBlock().setType(Material.ENDER_CHEST); - event.getPlayer().playSound(event.getPlayer().getLocation(), Sound.BLOCK_ENDER_CHEST_OPEN, 1, 1); - TowerRun.getMessage().broadcast("KEY_FOUND", event.getPlayer().getName()); + + Bukkit.getOnlinePlayers().forEach(player -> { + player.playSound(event.getPlayer().getLocation(), Sound.BLOCK_ENDER_CHEST_OPEN, 1, 1); + player.sendTitle("", TowerRun.getMessage().parse("KEY_FOUND", player, event.getPlayer().getName()), 10, 70, 20); + }); } @EventHandler @@ -211,6 +214,44 @@ public class IngameListener extends GameStateBukkitListener { private void shouldMelt(Block block) { if (block.getType().isBurnable()) return; int meltingTime = (int) (block.getType().getHardness() * 48 * 20); + switch (block.getType()) { + case TINTED_GLASS: + case WHITE_STAINED_GLASS: + case ORANGE_STAINED_GLASS: + case MAGENTA_STAINED_GLASS: + case LIGHT_BLUE_STAINED_GLASS: + case YELLOW_STAINED_GLASS: + case LIME_STAINED_GLASS: + case PINK_STAINED_GLASS: + case GRAY_STAINED_GLASS: + case LIGHT_GRAY_STAINED_GLASS: + case CYAN_STAINED_GLASS: + case PURPLE_STAINED_GLASS: + case BLUE_STAINED_GLASS: + case BROWN_STAINED_GLASS: + case GREEN_STAINED_GLASS: + case RED_STAINED_GLASS: + case BLACK_STAINED_GLASS: + case WHITE_STAINED_GLASS_PANE: + case ORANGE_STAINED_GLASS_PANE: + case MAGENTA_STAINED_GLASS_PANE: + case LIGHT_BLUE_STAINED_GLASS_PANE: + case YELLOW_STAINED_GLASS_PANE: + case LIME_STAINED_GLASS_PANE: + case PINK_STAINED_GLASS_PANE: + case GRAY_STAINED_GLASS_PANE: + case LIGHT_GRAY_STAINED_GLASS_PANE: + case CYAN_STAINED_GLASS_PANE: + case PURPLE_STAINED_GLASS_PANE: + case BLUE_STAINED_GLASS_PANE: + case BROWN_STAINED_GLASS_PANE: + case GREEN_STAINED_GLASS_PANE: + case RED_STAINED_GLASS_PANE: + case BLACK_STAINED_GLASS_PANE: + meltingTime = meltingTime * 10; + default: + break; + } blocksToMelt.computeIfAbsent(time + meltingTime, integer -> new ArrayList<>()).add(block); } From d6fba9b0afbfad27cfe50175a97c212a8083e95e Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 11 May 2025 19:02:46 +0200 Subject: [PATCH 074/107] Fix many simple things --- TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java index eb7c3c1c..a4e2bec6 100644 --- a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java +++ b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java @@ -216,6 +216,8 @@ public class IngameListener extends GameStateBukkitListener { int meltingTime = (int) (block.getType().getHardness() * 48 * 20); switch (block.getType()) { case TINTED_GLASS: + meltingTime = meltingTime * 2; + break; case WHITE_STAINED_GLASS: case ORANGE_STAINED_GLASS: case MAGENTA_STAINED_GLASS: From d0665932f44396b2d6f3accbfa9103e8090533a2 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 11 May 2025 20:19:23 +0200 Subject: [PATCH 075/107] Fix TowerRunGame.reset --- TowerRun/src/de/steamwar/towerrun/game/TowerRunGame.java | 1 + 1 file changed, 1 insertion(+) diff --git a/TowerRun/src/de/steamwar/towerrun/game/TowerRunGame.java b/TowerRun/src/de/steamwar/towerrun/game/TowerRunGame.java index 3c846247..c1514db4 100644 --- a/TowerRun/src/de/steamwar/towerrun/game/TowerRunGame.java +++ b/TowerRun/src/de/steamwar/towerrun/game/TowerRunGame.java @@ -147,6 +147,7 @@ public class TowerRunGame { player.setGameMode(GameMode.SURVIVAL); } player.teleport(WorldConfig.SPAWN); + PLAYERS_ALIVE.add(TowerRunPlayer.get(player)); }); } From e893d7934aa121cc618125175a6f2fd2e28cbff7 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Wed, 14 May 2025 19:11:05 +0200 Subject: [PATCH 076/107] Fix TowerRun for events --- TowerRun/src/de/steamwar/towerrun/TowerRun.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/TowerRun/src/de/steamwar/towerrun/TowerRun.java b/TowerRun/src/de/steamwar/towerrun/TowerRun.java index 7e6df112..4503c5da 100644 --- a/TowerRun/src/de/steamwar/towerrun/TowerRun.java +++ b/TowerRun/src/de/steamwar/towerrun/TowerRun.java @@ -80,7 +80,5 @@ public class TowerRun extends JavaPlugin { gameCountdown = new GameCountdown(); Bukkit.getScheduler().runTaskTimer(this, new FightInfoPacketSender(), 20, 20); - - TowerRunGame.reset(); } } From 260656ad357748e4fcd2bc40cbea00beaf0dab04 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Wed, 14 May 2025 19:28:27 +0200 Subject: [PATCH 077/107] Fix for events --- .../de/steamwar/misslewars/countdowns/EndCountdown.java | 2 +- .../src/de/steamwar/towerrun/countdowns/EndCountdown.java | 7 ++++++- .../src/de/steamwar/towerrun/listener/LobbyListener.java | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/MissileWars/src/de/steamwar/misslewars/countdowns/EndCountdown.java b/MissileWars/src/de/steamwar/misslewars/countdowns/EndCountdown.java index 292071a6..f2d3183b 100644 --- a/MissileWars/src/de/steamwar/misslewars/countdowns/EndCountdown.java +++ b/MissileWars/src/de/steamwar/misslewars/countdowns/EndCountdown.java @@ -37,7 +37,7 @@ public class EndCountdown extends StateDependent { @Override public void enable() { if (Config.isEvent()) { - task = Bukkit.getScheduler().runTaskLater(MissileWars.getPlugin(), this::stop, 1200); + task = Bukkit.getScheduler().runTaskLater(MissileWars.getPlugin(), this::stop, 200); } else { task = Bukkit.getScheduler().runTaskLater(MissileWars.getPlugin(), this::restart, Config.EndTime); } diff --git a/TowerRun/src/de/steamwar/towerrun/countdowns/EndCountdown.java b/TowerRun/src/de/steamwar/towerrun/countdowns/EndCountdown.java index 0162ba53..6d631e02 100644 --- a/TowerRun/src/de/steamwar/towerrun/countdowns/EndCountdown.java +++ b/TowerRun/src/de/steamwar/towerrun/countdowns/EndCountdown.java @@ -20,6 +20,7 @@ package de.steamwar.towerrun.countdowns; import de.steamwar.towerrun.TowerRun; +import de.steamwar.towerrun.config.Config; import de.steamwar.towerrun.game.TowerRunGame; import de.steamwar.towerrun.state.GameStates; import org.bukkit.Bukkit; @@ -48,7 +49,11 @@ public class EndCountdown extends Countdown { void timerEnd() { Bukkit.getOnlinePlayers().forEach(player -> player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 1, 1)); if (RESETS) { - TowerRunGame.reset(); + if (Config.event()) { + Bukkit.shutdown(); + } else { + TowerRunGame.reset(); + } lobbyCountdown.setTime(lobbyCountdown.defaultTime()); } else { Bukkit.shutdown(); diff --git a/TowerRun/src/de/steamwar/towerrun/listener/LobbyListener.java b/TowerRun/src/de/steamwar/towerrun/listener/LobbyListener.java index c93bc4bb..78fe59c5 100644 --- a/TowerRun/src/de/steamwar/towerrun/listener/LobbyListener.java +++ b/TowerRun/src/de/steamwar/towerrun/listener/LobbyListener.java @@ -62,12 +62,13 @@ public class LobbyListener extends GameStateBukkitListener { int team = user.getTeam(); if (team != Config.EVENT_TEAM_BLUE_ID && team != Config.EVENT_TEAM_RED_ID) { - player.setGameMode(GameMode.SPECTATOR); return; } if (TowerRunGame.PLAYERS_ALIVE.stream().map(towerRunPlayer -> SteamwarUser.get(towerRunPlayer.player().getUniqueId()).getTeam()).filter(integer -> integer == team).count() < Config.EVENT_MAXIMUM_TEAM_MEMBERS) { TowerRunGame.PLAYERS_ALIVE.add(TowerRunPlayer.get(player)); + } else { + player.setGameMode(GameMode.SPECTATOR); } } else { TowerRunGame.PLAYERS_ALIVE.add(TowerRunPlayer.get(player)); From 717cfa8baf6483122bbb64dc6d60f30fe46c4187 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Fri, 16 May 2025 18:00:23 +0200 Subject: [PATCH 078/107] Prevent usage of Flashback channels for restricted players Added new channel handlers to block Flashback mod channels for users without appropriate permissions. Ensures restricted players using these channels are disconnected with a specific warning message. This enhances control over mod usage and maintains server integrity. --- .../velocitycore/listeners/PluginMessage.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/VelocityCore/src/de/steamwar/velocitycore/listeners/PluginMessage.java b/VelocityCore/src/de/steamwar/velocitycore/listeners/PluginMessage.java index 7ef0be27..33e431fb 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/listeners/PluginMessage.java +++ b/VelocityCore/src/de/steamwar/velocitycore/listeners/PluginMessage.java @@ -33,6 +33,8 @@ import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier; import com.velocitypowered.proxy.protocol.ProtocolUtils; import de.steamwar.messages.Chatter; import de.steamwar.network.packets.NetworkPacket; +import de.steamwar.sql.SteamwarUser; +import de.steamwar.sql.UserPerm; import de.steamwar.velocitycore.VelocityCore; import de.steamwar.velocitycore.commands.TeamCommand; import de.steamwar.velocitycore.mods.*; @@ -360,6 +362,23 @@ public class PluginMessage extends BasicListener { )) channelRegisterHandlers.put(channel, player -> Chatter.disconnect(player).prefixless("MOD_YELLOW_SING", "minimap")); + for(String channel : Arrays.asList( + "flashback:remote_food_data", + "flashback:remote_set_slot", + "flashback:force_client_tick", + "flashback:accurate_entity_position", + "flashback:instantly_lerp", + "flashback:remote_experience", + "flashback:clear_particles", + "flashback:remote_select_hotbar_slot", // https://github.com/Moulberry/Flashback/tree/master/src/main/java/com/moulberry/flashback/packet + "flashback:clear_entities" // https://github.com/Moulberry/Flashback + )) + channelRegisterHandlers.put(channel, player -> { + if (!SteamwarUser.get(player.getUniqueId()).hasPerm(UserPerm.RESTRICTED_MODS)) { + Chatter.disconnect(player).prefixless("MOD_YELLOW_SING", "flashback"); + } + }); + for(String channel : Arrays.asList("bedrockify:cauldron_particles", "bedrockify:eat-particles")) //https://github.com/juancarloscp52/BedrockIfy (Bedrock features on Java, banned for reach-around block placement) channelRegisterHandlers.put(channel, player -> Chatter.disconnect(player).prefixless("MOD_YELLOW_SING", "bedrockify")); From 69251f42a6e540d57d50d8bf6a8424f6dce593ef Mon Sep 17 00:00:00 2001 From: D4rkr34lm Date: Sat, 17 May 2025 23:40:48 +0200 Subject: [PATCH 079/107] Add music disks to autochecker --- .../SchematicSystem_19/build.gradle.kts | 32 +++ .../autocheck/AutoChecker19.java | 213 ++++++++++++++++++ .../schematiccommand/SchematicCommand19.java | 147 ++++++++++++ SchematicSystem/build.gradle.kts | 1 + settings.gradle.kts | 1 + 5 files changed, 394 insertions(+) create mode 100644 SchematicSystem/SchematicSystem_19/build.gradle.kts create mode 100644 SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoChecker19.java create mode 100644 SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommand19.java diff --git a/SchematicSystem/SchematicSystem_19/build.gradle.kts b/SchematicSystem/SchematicSystem_19/build.gradle.kts new file mode 100644 index 00000000..d1baf622 --- /dev/null +++ b/SchematicSystem/SchematicSystem_19/build.gradle.kts @@ -0,0 +1,32 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 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 . + */ + +plugins { + steamwar.java +} + +dependencies { + compileOnly(project(":SpigotCore", "default")) + compileOnly(project(":SchematicSystem:SchematicSystem_Core", "default")) + + compileOnly(libs.spigotapi) + + compileOnly(libs.nms19) + compileOnly(libs.fawe18) +} diff --git a/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoChecker19.java b/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoChecker19.java new file mode 100644 index 00000000..92b06c0d --- /dev/null +++ b/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoChecker19.java @@ -0,0 +1,213 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 SteamWar.de-Serverteam + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ + +package de.steamwar.schematicsystem.autocheck; + +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.world.block.BaseBlock; +import de.steamwar.schematicsystem.CheckSchemType; +import org.bukkit.Material; + +import java.util.*; +import java.util.stream.Collectors; + +public class AutoChecker19 implements AutoChecker.IAutoChecker { + private static final Set INVENTORY = EnumSet.of( + Material.BARREL, + Material.BLAST_FURNACE, + Material.BREWING_STAND, + Material.CAMPFIRE, + Material.CHEST, + Material.DISPENSER, + Material.DROPPER, + Material.FURNACE, + Material.HOPPER, + Material.JUKEBOX, + Material.SHULKER_BOX, + Material.WHITE_SHULKER_BOX, + Material.ORANGE_SHULKER_BOX, + Material.MAGENTA_SHULKER_BOX, + Material.LIGHT_BLUE_SHULKER_BOX, + Material.YELLOW_SHULKER_BOX, + Material.LIME_SHULKER_BOX, + Material.PINK_SHULKER_BOX, + Material.GRAY_SHULKER_BOX, + Material.LIGHT_GRAY_SHULKER_BOX, + Material.CYAN_SHULKER_BOX, + Material.PURPLE_SHULKER_BOX, + Material.BLUE_SHULKER_BOX, + Material.BROWN_SHULKER_BOX, + Material.GREEN_SHULKER_BOX, + Material.RED_SHULKER_BOX, + Material.BLACK_SHULKER_BOX, + Material.SMOKER, + Material.TRAPPED_CHEST); + + private static final Set FLOWERS = EnumSet.of( + // 64-stackable Items + Material.CORNFLOWER, + Material.POPPY, + Material.FERN, + Material.DANDELION, + Material.BLUE_ORCHID, + Material.ALLIUM, + Material.AZURE_BLUET, + Material.RED_TULIP, + Material.ORANGE_TULIP, + Material.WHITE_TULIP, + Material.PINK_TULIP, + Material.OXEYE_DAISY, + Material.LILY_OF_THE_VALLEY, + Material.WITHER_ROSE, + Material.SUNFLOWER, + // 16-stackable Items + Material.HONEY_BOTTLE, + // Non-stackable items + Material.DIAMOND_HORSE_ARMOR, + Material.IRON_HORSE_ARMOR, + Material.GOLDEN_HORSE_ARMOR, + // Disks + Material.MUSIC_DISC_11, + Material.MUSIC_DISC_13, + Material.MUSIC_DISC_CAT, + Material.MUSIC_DISC_BLOCKS, + Material.MUSIC_DISC_CHIRP, + Material.MUSIC_DISC_FAR, + Material.MUSIC_DISC_MALL, + Material.MUSIC_DISC_MELLOHI, + Material.MUSIC_DISC_STAL, + Material.MUSIC_DISC_STRAD, + Material.MUSIC_DISC_WAIT, + Material.MUSIC_DISC_WARD, + Material.MUSIC_DISC_OTHERSIDE, + Material.MUSIC_DISC_PIGSTEP, + Material.MUSIC_DISC_RELIC, + Material.MUSIC_DISC_5 + ); + + public AutoChecker.BlockScanResult scan(Clipboard clipboard) { + AutoChecker.BlockScanResult result = new AutoChecker.BlockScanResult(); + BlockVector3 min = clipboard.getMinimumPoint(); + BlockVector3 max = clipboard.getMaximumPoint(); + for(int x = min.getBlockX(); x <= max.getBlockX(); x++){ + for(int y = min.getBlockY(); y <= max.getBlockY(); y++) { + for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { + final BaseBlock block = clipboard.getFullBlock(BlockVector3.at(x, y, z)); + final Material material = Material.matchMaterial(block.getBlockType().getId()); + if(material == null) { + continue; + } + + result.getBlockCounts().merge(material, 1, Integer::sum); + + if(INVENTORY.contains(material)) { + checkInventory(result, block, material, new BlockPos(x, y, z)); + } + + if(x == 0 || x == max.getBlockX() - 1 || y == max.getBlockY() - 1 || z == 0 || z == max.getBlockZ() - 1) { + result.getDesignBlocks().computeIfAbsent(material, m -> new ArrayList<>()).add(new BlockPos(x, y, z)); + } + } + } + } + return result; + } + + private static final Map> itemsInInv = new EnumMap<>(Material.class); + + static { + itemsInInv.put(Material.BUCKET, EnumSet.of(Material.DISPENSER)); + itemsInInv.put(Material.TNT, EnumSet.of( + Material.CHEST, Material.BARREL, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, + Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, + Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, + Material.LIGHT_GRAY_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, + Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, + Material.RED_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX + )); + itemsInInv.put(Material.FIRE_CHARGE, EnumSet.of(Material.DISPENSER)); + itemsInInv.put(Material.ARROW, EnumSet.of(Material.DISPENSER)); + FLOWERS.forEach(material -> itemsInInv.put(material, INVENTORY)); + } + + private void checkInventory(AutoChecker.BlockScanResult result, BaseBlock block, Material material, BlockPos pos) { + CompoundTag nbt = block.getNbtData(); + if(nbt == null) { + result.getDefunctNbt().add(pos); + return; + } + + + if(material == Material.JUKEBOX && nbt.getValue().containsKey("RecordItem")){ + result.getRecords().add(pos); + return; + } + + List items = nbt.getList("Items", CompoundTag.class); + if(items.isEmpty()) + return; //Leeres Inventar + + int counter = 0; + for(CompoundTag item : items){ + if(!item.containsKey("id")){ + result.getDefunctNbt().add(pos); + continue; + } + + Material itemType = Material.matchMaterial(item.getString("id")); + if(itemType == null) //Leere Slots + continue; + + if (!itemsInInv.getOrDefault(itemType, EnumSet.noneOf(Material.class)).contains(material)) { + result.getForbiddenItems().computeIfAbsent(pos, blockVector3 -> new HashSet<>()).add(itemType); + } else if(material == Material.DISPENSER && (itemType == Material.ARROW || itemType == Material.FIRE_CHARGE)) { + counter += item.getByte("Count"); + } + if (item.containsKey("tag")) { + result.getForbiddenNbt().computeIfAbsent(pos, blockVector3 -> new HashSet<>()).add(itemType); + } + } + result.getDispenserItems().put(pos, counter); + } + + @Override + public AutoCheckerResult check(Clipboard clipboard, CheckSchemType type) { + return AutoCheckerResult.builder() + .type(type) + .height(clipboard.getDimensions().getBlockY()) + .width(clipboard.getDimensions().getBlockX()) + .depth(clipboard.getDimensions().getBlockZ()) + .blockScanResult(scan(clipboard)) + .entities(clipboard.getEntities().stream().map(Entity::getLocation).map(blockVector3 -> new BlockPos(blockVector3.getBlockX(), blockVector3.getBlockY(), blockVector3.getBlockZ())).collect(Collectors.toList())) + .build(); + } + + @Override + public AutoCheckerResult sizeCheck(Clipboard clipboard, CheckSchemType type) { + return AutoCheckerResult.builder() + .type(type) + .height(clipboard.getDimensions().getBlockY()) + .width(clipboard.getDimensions().getBlockX()) + .depth(clipboard.getDimensions().getBlockZ()) + .build(); + } +} diff --git a/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommand19.java b/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommand19.java new file mode 100644 index 00000000..2fecb87d --- /dev/null +++ b/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommand19.java @@ -0,0 +1,147 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2023 SteamWar.de-Serverteam + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ + +package de.steamwar.schematicsystem.commands.schematiccommand; + +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.CompoundTagBuilder; +import com.sk89q.jnbt.ListTag; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.function.operation.ForwardExtentCopy; +import com.sk89q.worldedit.function.operation.Operations; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockTypes; +import de.steamwar.schematicsystem.CheckSchemType; +import de.steamwar.schematicsystem.autocheck.AutoCheckerResult; +import de.steamwar.schematicsystem.autocheck.BlockPos; +import org.bukkit.Material; + +import java.util.*; +import java.util.stream.Collectors; + +public class SchematicCommand19 implements SchematicCommand.ISchematicCommand { + @Override + public Clipboard fixClipboard(Clipboard clipboard, AutoCheckerResult result, CheckSchemType type) throws Exception { + for (BlockPos blockPos : result.getBlockScanResult().getRecords()) { + BlockVector3 vector = BlockVector3.at(blockPos.getX(), blockPos.getY(), blockPos.getZ()); + clipboard.setBlock(vector, clipboard.getFullBlock(vector).toBaseBlock(new CompoundTag(Collections.emptyMap()))); + } + + Map> toBeCheckedInvs = new HashMap<>(); + + toBeCheckedInvs.putAll(result.getBlockScanResult().getForbiddenItems()); + toBeCheckedInvs.putAll(result.getBlockScanResult().getForbiddenNbt()); + + for (Map.Entry> entry: toBeCheckedInvs.entrySet()) { + BlockPos pos = entry.getKey(); + Set materials = entry.getValue(); + BlockVector3 vector = BlockVector3.at(pos.getX(), pos.getY(), pos.getZ()); + BaseBlock block = clipboard.getFullBlock(vector); + CompoundTag tag = block.getNbtData(); + CompoundTagBuilder builder = CompoundTagBuilder.create(); + List list = new ArrayList<>(); + for (CompoundTag items : tag.getList("Items", CompoundTag.class)) { + if(materials.contains(Material.matchMaterial(items.getString("id")))) { + continue; + } + + if(items.containsKey("tag")) { + continue; + } + + list.add(items); + } + builder.put("Items", new ListTag(CompoundTag.class, list)); + clipboard.setBlock(vector, block.toBaseBlock(builder.build())); + } + + if(type.getMaxDispenserItems() > 0 ) { + for (Map.Entry entry : result.getBlockScanResult().getDispenserItems().entrySet()) { + if(entry.getValue() <= type.getMaxDispenserItems()) { + continue; + } + + BlockPos pos = entry.getKey(); + BlockVector3 vector = BlockVector3.at(pos.getX(), pos.getY(), pos.getZ()); + BaseBlock block = clipboard.getFullBlock(vector); + CompoundTag tag = block.getNbtData(); + CompoundTagBuilder builder = tag.createBuilder(); + List items = tag.getList("Items", CompoundTag.class); + Collections.reverse(items); // To let the first item be in the Dispenser + List list = new ArrayList<>(); + int diff = entry.getValue() - type.getMaxDispenserItems(); + for (CompoundTag item : items) { + if(item == null) { + continue; + } + + if(diff == 0) { + list.add(item); + continue; + } + + if(diff > item.getByte("Count")) { + diff -= item.getByte("Count"); + continue; + } + + item = item.createBuilder().putByte("Count", (byte) (item.getByte("Count") - diff)).build(); + diff = 0; + list.add(item); + } + + builder.put("Items", new ListTag(CompoundTag.class, list)); + clipboard.setBlock(vector, block.toBaseBlock(builder.build())); + } + } + + if(!result.isLimitedBlocksOK()) { + Set toReplace = type.getLimits().entrySet().stream() + .filter(setIntegerEntry -> setIntegerEntry.getValue() == 0) + .flatMap(setIntegerEntry -> setIntegerEntry.getKey().stream()) + .map(Material::matchMaterial) + .collect(Collectors.toSet()); + BlockState replaceType = Objects.requireNonNull(toReplace.contains(Material.END_STONE) ? BlockTypes.IRON_BLOCK : BlockTypes.END_STONE).getDefaultState(); + BlockVector3 min = clipboard.getMinimumPoint(); + BlockVector3 max = clipboard.getMaximumPoint(); + for (int i = min.getBlockX(); i <= max.getBlockX(); i++) { + for (int j = min.getBlockY(); j <= max.getBlockY(); j++) { + for (int k = min.getBlockZ(); k <= max.getBlockZ(); k++) { + BlockVector3 vector = BlockVector3.at(i, j, k); + BaseBlock block = clipboard.getFullBlock(vector); + if(toReplace.contains(Material.matchMaterial(block.getBlockType().getId()))) { + clipboard.setBlock(vector, replaceType.toBaseBlock()); + } + } + } + } + } + + return clipboard; + } + + @Override + public void createCopy(EditSession editSession, Clipboard clipboard) throws WorldEditException { + Operations.complete(new ForwardExtentCopy(editSession, clipboard.getRegion(), clipboard, clipboard.getMinimumPoint())); + } +} diff --git a/SchematicSystem/build.gradle.kts b/SchematicSystem/build.gradle.kts index f9871adc..813550b2 100644 --- a/SchematicSystem/build.gradle.kts +++ b/SchematicSystem/build.gradle.kts @@ -30,4 +30,5 @@ dependencies { implementation(project(":SchematicSystem:SchematicSystem_Core")) implementation(project(":SchematicSystem:SchematicSystem_8")) implementation(project(":SchematicSystem:SchematicSystem_15")) + implementation(project(":SchematicSystem:SchematicSystem_19")) } diff --git a/settings.gradle.kts b/settings.gradle.kts index dc94bc0c..cd2550dd 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -218,6 +218,7 @@ include( "SchematicSystem", "SchematicSystem:SchematicSystem_8", "SchematicSystem:SchematicSystem_15", + "SchematicSystem:SchematicSystem_19", "SchematicSystem:SchematicSystem_Core" ) From bf5eef2ebd7bcb936ac5eea5268cedb5b1447050 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 18 May 2025 10:28:32 +0200 Subject: [PATCH 080/107] Fix copyright nit Remove SchematicCommand19 --- .../SchematicSystem_19/build.gradle.kts | 2 +- .../autocheck/AutoChecker19.java | 2 +- .../schematiccommand/SchematicCommand19.java | 147 ------------------ 3 files changed, 2 insertions(+), 149 deletions(-) delete mode 100644 SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommand19.java diff --git a/SchematicSystem/SchematicSystem_19/build.gradle.kts b/SchematicSystem/SchematicSystem_19/build.gradle.kts index d1baf622..99b982c8 100644 --- a/SchematicSystem/SchematicSystem_19/build.gradle.kts +++ b/SchematicSystem/SchematicSystem_19/build.gradle.kts @@ -1,7 +1,7 @@ /* * This file is a part of the SteamWar software. * - * Copyright (C) 2024 SteamWar.de-Serverteam + * 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 diff --git a/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoChecker19.java b/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoChecker19.java index 92b06c0d..0f456ee2 100644 --- a/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoChecker19.java +++ b/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoChecker19.java @@ -1,7 +1,7 @@ /* This file is a part of the SteamWar software. - Copyright (C) 2023 SteamWar.de-Serverteam + 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 diff --git a/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommand19.java b/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommand19.java deleted file mode 100644 index 2fecb87d..00000000 --- a/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/commands/schematiccommand/SchematicCommand19.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - This file is a part of the SteamWar software. - - Copyright (C) 2023 SteamWar.de-Serverteam - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - */ - -package de.steamwar.schematicsystem.commands.schematiccommand; - -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.CompoundTagBuilder; -import com.sk89q.jnbt.ListTag; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.extent.clipboard.Clipboard; -import com.sk89q.worldedit.function.operation.ForwardExtentCopy; -import com.sk89q.worldedit.function.operation.Operations; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.world.block.BaseBlock; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockTypes; -import de.steamwar.schematicsystem.CheckSchemType; -import de.steamwar.schematicsystem.autocheck.AutoCheckerResult; -import de.steamwar.schematicsystem.autocheck.BlockPos; -import org.bukkit.Material; - -import java.util.*; -import java.util.stream.Collectors; - -public class SchematicCommand19 implements SchematicCommand.ISchematicCommand { - @Override - public Clipboard fixClipboard(Clipboard clipboard, AutoCheckerResult result, CheckSchemType type) throws Exception { - for (BlockPos blockPos : result.getBlockScanResult().getRecords()) { - BlockVector3 vector = BlockVector3.at(blockPos.getX(), blockPos.getY(), blockPos.getZ()); - clipboard.setBlock(vector, clipboard.getFullBlock(vector).toBaseBlock(new CompoundTag(Collections.emptyMap()))); - } - - Map> toBeCheckedInvs = new HashMap<>(); - - toBeCheckedInvs.putAll(result.getBlockScanResult().getForbiddenItems()); - toBeCheckedInvs.putAll(result.getBlockScanResult().getForbiddenNbt()); - - for (Map.Entry> entry: toBeCheckedInvs.entrySet()) { - BlockPos pos = entry.getKey(); - Set materials = entry.getValue(); - BlockVector3 vector = BlockVector3.at(pos.getX(), pos.getY(), pos.getZ()); - BaseBlock block = clipboard.getFullBlock(vector); - CompoundTag tag = block.getNbtData(); - CompoundTagBuilder builder = CompoundTagBuilder.create(); - List list = new ArrayList<>(); - for (CompoundTag items : tag.getList("Items", CompoundTag.class)) { - if(materials.contains(Material.matchMaterial(items.getString("id")))) { - continue; - } - - if(items.containsKey("tag")) { - continue; - } - - list.add(items); - } - builder.put("Items", new ListTag(CompoundTag.class, list)); - clipboard.setBlock(vector, block.toBaseBlock(builder.build())); - } - - if(type.getMaxDispenserItems() > 0 ) { - for (Map.Entry entry : result.getBlockScanResult().getDispenserItems().entrySet()) { - if(entry.getValue() <= type.getMaxDispenserItems()) { - continue; - } - - BlockPos pos = entry.getKey(); - BlockVector3 vector = BlockVector3.at(pos.getX(), pos.getY(), pos.getZ()); - BaseBlock block = clipboard.getFullBlock(vector); - CompoundTag tag = block.getNbtData(); - CompoundTagBuilder builder = tag.createBuilder(); - List items = tag.getList("Items", CompoundTag.class); - Collections.reverse(items); // To let the first item be in the Dispenser - List list = new ArrayList<>(); - int diff = entry.getValue() - type.getMaxDispenserItems(); - for (CompoundTag item : items) { - if(item == null) { - continue; - } - - if(diff == 0) { - list.add(item); - continue; - } - - if(diff > item.getByte("Count")) { - diff -= item.getByte("Count"); - continue; - } - - item = item.createBuilder().putByte("Count", (byte) (item.getByte("Count") - diff)).build(); - diff = 0; - list.add(item); - } - - builder.put("Items", new ListTag(CompoundTag.class, list)); - clipboard.setBlock(vector, block.toBaseBlock(builder.build())); - } - } - - if(!result.isLimitedBlocksOK()) { - Set toReplace = type.getLimits().entrySet().stream() - .filter(setIntegerEntry -> setIntegerEntry.getValue() == 0) - .flatMap(setIntegerEntry -> setIntegerEntry.getKey().stream()) - .map(Material::matchMaterial) - .collect(Collectors.toSet()); - BlockState replaceType = Objects.requireNonNull(toReplace.contains(Material.END_STONE) ? BlockTypes.IRON_BLOCK : BlockTypes.END_STONE).getDefaultState(); - BlockVector3 min = clipboard.getMinimumPoint(); - BlockVector3 max = clipboard.getMaximumPoint(); - for (int i = min.getBlockX(); i <= max.getBlockX(); i++) { - for (int j = min.getBlockY(); j <= max.getBlockY(); j++) { - for (int k = min.getBlockZ(); k <= max.getBlockZ(); k++) { - BlockVector3 vector = BlockVector3.at(i, j, k); - BaseBlock block = clipboard.getFullBlock(vector); - if(toReplace.contains(Material.matchMaterial(block.getBlockType().getId()))) { - clipboard.setBlock(vector, replaceType.toBaseBlock()); - } - } - } - } - } - - return clipboard; - } - - @Override - public void createCopy(EditSession editSession, Clipboard clipboard) throws WorldEditException { - Operations.complete(new ForwardExtentCopy(editSession, clipboard.getRegion(), clipboard, clipboard.getMinimumPoint())); - } -} From 8132e4fca08b020795b43f453b21bf9d59cc990e Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 18 May 2025 10:34:41 +0200 Subject: [PATCH 081/107] Remove code duplication --- .../autocheck/AutoChecker15.java | 55 +---- .../autocheck/AutoCheckerItems15.java | 90 ++++++++ .../autocheck/AutoChecker19.java | 213 ------------------ .../autocheck/AutoCheckerItems19.java | 111 +++++++++ .../autocheck/AutoCheckerItems.java | 34 +++ 5 files changed, 237 insertions(+), 266 deletions(-) create mode 100644 SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/autocheck/AutoCheckerItems15.java delete mode 100644 SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoChecker19.java create mode 100644 SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoCheckerItems19.java create mode 100644 SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/autocheck/AutoCheckerItems.java diff --git a/SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/autocheck/AutoChecker15.java b/SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/autocheck/AutoChecker15.java index 9dd5e456..a97cb133 100644 --- a/SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/autocheck/AutoChecker15.java +++ b/SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/autocheck/AutoChecker15.java @@ -31,57 +31,6 @@ import java.util.*; import java.util.stream.Collectors; public class AutoChecker15 implements AutoChecker.IAutoChecker { - private static final Set INVENTORY = EnumSet.of( - Material.BARREL, - Material.BLAST_FURNACE, - Material.BREWING_STAND, - Material.CAMPFIRE, - Material.CHEST, - Material.DISPENSER, - Material.DROPPER, - Material.FURNACE, - Material.HOPPER, - Material.JUKEBOX, - Material.SHULKER_BOX, - Material.WHITE_SHULKER_BOX, - Material.ORANGE_SHULKER_BOX, - Material.MAGENTA_SHULKER_BOX, - Material.LIGHT_BLUE_SHULKER_BOX, - Material.YELLOW_SHULKER_BOX, - Material.LIME_SHULKER_BOX, - Material.PINK_SHULKER_BOX, - Material.GRAY_SHULKER_BOX, - Material.LIGHT_GRAY_SHULKER_BOX, - Material.CYAN_SHULKER_BOX, - Material.PURPLE_SHULKER_BOX, - Material.BLUE_SHULKER_BOX, - Material.BROWN_SHULKER_BOX, - Material.GREEN_SHULKER_BOX, - Material.RED_SHULKER_BOX, - Material.BLACK_SHULKER_BOX, - Material.SMOKER, - Material.TRAPPED_CHEST); - - private static final Set FLOWERS = EnumSet.of( - Material.CORNFLOWER, - Material.POPPY, - Material.FERN, - Material.DANDELION, - Material.BLUE_ORCHID, - Material.ALLIUM, - Material.AZURE_BLUET, - Material.RED_TULIP, - Material.ORANGE_TULIP, - Material.WHITE_TULIP, - Material.PINK_TULIP, - Material.OXEYE_DAISY, - Material.LILY_OF_THE_VALLEY, - Material.WITHER_ROSE, - Material.SUNFLOWER, - Material.DIAMOND_HORSE_ARMOR, - Material.IRON_HORSE_ARMOR, - Material.GOLDEN_HORSE_ARMOR, - Material.HONEY_BOTTLE); public AutoChecker.BlockScanResult scan(Clipboard clipboard) { AutoChecker.BlockScanResult result = new AutoChecker.BlockScanResult(); @@ -98,7 +47,7 @@ public class AutoChecker15 implements AutoChecker.IAutoChecker { result.getBlockCounts().merge(material, 1, Integer::sum); - if(INVENTORY.contains(material)) { + if(AutoCheckerItems.impl.getInventoryMaterials().contains(material)) { checkInventory(result, block, material, new BlockPos(x, y, z)); } @@ -125,7 +74,7 @@ public class AutoChecker15 implements AutoChecker.IAutoChecker { )); itemsInInv.put(Material.FIRE_CHARGE, EnumSet.of(Material.DISPENSER)); itemsInInv.put(Material.ARROW, EnumSet.of(Material.DISPENSER)); - FLOWERS.forEach(material -> itemsInInv.put(material, INVENTORY)); + AutoCheckerItems.impl.getAllowedMaterialsInInventory().forEach(material -> itemsInInv.put(material, AutoCheckerItems.impl.getInventoryMaterials())); } private void checkInventory(AutoChecker.BlockScanResult result, BaseBlock block, Material material, BlockPos pos) { diff --git a/SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/autocheck/AutoCheckerItems15.java b/SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/autocheck/AutoCheckerItems15.java new file mode 100644 index 00000000..0d853c16 --- /dev/null +++ b/SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/autocheck/AutoCheckerItems15.java @@ -0,0 +1,90 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.schematicsystem.autocheck; + +import org.bukkit.Material; + +import java.util.EnumSet; +import java.util.Set; + +public class AutoCheckerItems15 implements AutoCheckerItems { + + private static final Set INVENTORY = EnumSet.of( + Material.BARREL, + Material.BLAST_FURNACE, + Material.BREWING_STAND, + Material.CAMPFIRE, + Material.CHEST, + Material.DISPENSER, + Material.DROPPER, + Material.FURNACE, + Material.HOPPER, + Material.JUKEBOX, + Material.SHULKER_BOX, + Material.WHITE_SHULKER_BOX, + Material.ORANGE_SHULKER_BOX, + Material.MAGENTA_SHULKER_BOX, + Material.LIGHT_BLUE_SHULKER_BOX, + Material.YELLOW_SHULKER_BOX, + Material.LIME_SHULKER_BOX, + Material.PINK_SHULKER_BOX, + Material.GRAY_SHULKER_BOX, + Material.LIGHT_GRAY_SHULKER_BOX, + Material.CYAN_SHULKER_BOX, + Material.PURPLE_SHULKER_BOX, + Material.BLUE_SHULKER_BOX, + Material.BROWN_SHULKER_BOX, + Material.GREEN_SHULKER_BOX, + Material.RED_SHULKER_BOX, + Material.BLACK_SHULKER_BOX, + Material.SMOKER, + Material.TRAPPED_CHEST); + + private static final Set FLOWERS = EnumSet.of( + Material.CORNFLOWER, + Material.POPPY, + Material.FERN, + Material.DANDELION, + Material.BLUE_ORCHID, + Material.ALLIUM, + Material.AZURE_BLUET, + Material.RED_TULIP, + Material.ORANGE_TULIP, + Material.WHITE_TULIP, + Material.PINK_TULIP, + Material.OXEYE_DAISY, + Material.LILY_OF_THE_VALLEY, + Material.WITHER_ROSE, + Material.SUNFLOWER, + Material.DIAMOND_HORSE_ARMOR, + Material.IRON_HORSE_ARMOR, + Material.GOLDEN_HORSE_ARMOR, + Material.HONEY_BOTTLE); + + @Override + public Set getInventoryMaterials() { + return INVENTORY; + } + + @Override + public Set getAllowedMaterialsInInventory() { + return FLOWERS; + } +} diff --git a/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoChecker19.java b/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoChecker19.java deleted file mode 100644 index 0f456ee2..00000000 --- a/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoChecker19.java +++ /dev/null @@ -1,213 +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.schematicsystem.autocheck; - -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.entity.Entity; -import com.sk89q.worldedit.extent.clipboard.Clipboard; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.world.block.BaseBlock; -import de.steamwar.schematicsystem.CheckSchemType; -import org.bukkit.Material; - -import java.util.*; -import java.util.stream.Collectors; - -public class AutoChecker19 implements AutoChecker.IAutoChecker { - private static final Set INVENTORY = EnumSet.of( - Material.BARREL, - Material.BLAST_FURNACE, - Material.BREWING_STAND, - Material.CAMPFIRE, - Material.CHEST, - Material.DISPENSER, - Material.DROPPER, - Material.FURNACE, - Material.HOPPER, - Material.JUKEBOX, - Material.SHULKER_BOX, - Material.WHITE_SHULKER_BOX, - Material.ORANGE_SHULKER_BOX, - Material.MAGENTA_SHULKER_BOX, - Material.LIGHT_BLUE_SHULKER_BOX, - Material.YELLOW_SHULKER_BOX, - Material.LIME_SHULKER_BOX, - Material.PINK_SHULKER_BOX, - Material.GRAY_SHULKER_BOX, - Material.LIGHT_GRAY_SHULKER_BOX, - Material.CYAN_SHULKER_BOX, - Material.PURPLE_SHULKER_BOX, - Material.BLUE_SHULKER_BOX, - Material.BROWN_SHULKER_BOX, - Material.GREEN_SHULKER_BOX, - Material.RED_SHULKER_BOX, - Material.BLACK_SHULKER_BOX, - Material.SMOKER, - Material.TRAPPED_CHEST); - - private static final Set FLOWERS = EnumSet.of( - // 64-stackable Items - Material.CORNFLOWER, - Material.POPPY, - Material.FERN, - Material.DANDELION, - Material.BLUE_ORCHID, - Material.ALLIUM, - Material.AZURE_BLUET, - Material.RED_TULIP, - Material.ORANGE_TULIP, - Material.WHITE_TULIP, - Material.PINK_TULIP, - Material.OXEYE_DAISY, - Material.LILY_OF_THE_VALLEY, - Material.WITHER_ROSE, - Material.SUNFLOWER, - // 16-stackable Items - Material.HONEY_BOTTLE, - // Non-stackable items - Material.DIAMOND_HORSE_ARMOR, - Material.IRON_HORSE_ARMOR, - Material.GOLDEN_HORSE_ARMOR, - // Disks - Material.MUSIC_DISC_11, - Material.MUSIC_DISC_13, - Material.MUSIC_DISC_CAT, - Material.MUSIC_DISC_BLOCKS, - Material.MUSIC_DISC_CHIRP, - Material.MUSIC_DISC_FAR, - Material.MUSIC_DISC_MALL, - Material.MUSIC_DISC_MELLOHI, - Material.MUSIC_DISC_STAL, - Material.MUSIC_DISC_STRAD, - Material.MUSIC_DISC_WAIT, - Material.MUSIC_DISC_WARD, - Material.MUSIC_DISC_OTHERSIDE, - Material.MUSIC_DISC_PIGSTEP, - Material.MUSIC_DISC_RELIC, - Material.MUSIC_DISC_5 - ); - - public AutoChecker.BlockScanResult scan(Clipboard clipboard) { - AutoChecker.BlockScanResult result = new AutoChecker.BlockScanResult(); - BlockVector3 min = clipboard.getMinimumPoint(); - BlockVector3 max = clipboard.getMaximumPoint(); - for(int x = min.getBlockX(); x <= max.getBlockX(); x++){ - for(int y = min.getBlockY(); y <= max.getBlockY(); y++) { - for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { - final BaseBlock block = clipboard.getFullBlock(BlockVector3.at(x, y, z)); - final Material material = Material.matchMaterial(block.getBlockType().getId()); - if(material == null) { - continue; - } - - result.getBlockCounts().merge(material, 1, Integer::sum); - - if(INVENTORY.contains(material)) { - checkInventory(result, block, material, new BlockPos(x, y, z)); - } - - if(x == 0 || x == max.getBlockX() - 1 || y == max.getBlockY() - 1 || z == 0 || z == max.getBlockZ() - 1) { - result.getDesignBlocks().computeIfAbsent(material, m -> new ArrayList<>()).add(new BlockPos(x, y, z)); - } - } - } - } - return result; - } - - private static final Map> itemsInInv = new EnumMap<>(Material.class); - - static { - itemsInInv.put(Material.BUCKET, EnumSet.of(Material.DISPENSER)); - itemsInInv.put(Material.TNT, EnumSet.of( - Material.CHEST, Material.BARREL, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, - Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, - Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, - Material.LIGHT_GRAY_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, - Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, - Material.RED_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX - )); - itemsInInv.put(Material.FIRE_CHARGE, EnumSet.of(Material.DISPENSER)); - itemsInInv.put(Material.ARROW, EnumSet.of(Material.DISPENSER)); - FLOWERS.forEach(material -> itemsInInv.put(material, INVENTORY)); - } - - private void checkInventory(AutoChecker.BlockScanResult result, BaseBlock block, Material material, BlockPos pos) { - CompoundTag nbt = block.getNbtData(); - if(nbt == null) { - result.getDefunctNbt().add(pos); - return; - } - - - if(material == Material.JUKEBOX && nbt.getValue().containsKey("RecordItem")){ - result.getRecords().add(pos); - return; - } - - List items = nbt.getList("Items", CompoundTag.class); - if(items.isEmpty()) - return; //Leeres Inventar - - int counter = 0; - for(CompoundTag item : items){ - if(!item.containsKey("id")){ - result.getDefunctNbt().add(pos); - continue; - } - - Material itemType = Material.matchMaterial(item.getString("id")); - if(itemType == null) //Leere Slots - continue; - - if (!itemsInInv.getOrDefault(itemType, EnumSet.noneOf(Material.class)).contains(material)) { - result.getForbiddenItems().computeIfAbsent(pos, blockVector3 -> new HashSet<>()).add(itemType); - } else if(material == Material.DISPENSER && (itemType == Material.ARROW || itemType == Material.FIRE_CHARGE)) { - counter += item.getByte("Count"); - } - if (item.containsKey("tag")) { - result.getForbiddenNbt().computeIfAbsent(pos, blockVector3 -> new HashSet<>()).add(itemType); - } - } - result.getDispenserItems().put(pos, counter); - } - - @Override - public AutoCheckerResult check(Clipboard clipboard, CheckSchemType type) { - return AutoCheckerResult.builder() - .type(type) - .height(clipboard.getDimensions().getBlockY()) - .width(clipboard.getDimensions().getBlockX()) - .depth(clipboard.getDimensions().getBlockZ()) - .blockScanResult(scan(clipboard)) - .entities(clipboard.getEntities().stream().map(Entity::getLocation).map(blockVector3 -> new BlockPos(blockVector3.getBlockX(), blockVector3.getBlockY(), blockVector3.getBlockZ())).collect(Collectors.toList())) - .build(); - } - - @Override - public AutoCheckerResult sizeCheck(Clipboard clipboard, CheckSchemType type) { - return AutoCheckerResult.builder() - .type(type) - .height(clipboard.getDimensions().getBlockY()) - .width(clipboard.getDimensions().getBlockX()) - .depth(clipboard.getDimensions().getBlockZ()) - .build(); - } -} diff --git a/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoCheckerItems19.java b/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoCheckerItems19.java new file mode 100644 index 00000000..556d354f --- /dev/null +++ b/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoCheckerItems19.java @@ -0,0 +1,111 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.schematicsystem.autocheck; + +import org.bukkit.Material; + +import java.util.EnumSet; +import java.util.Set; + +public class AutoCheckerItems19 implements AutoCheckerItems { + + private static final Set INVENTORY = EnumSet.of( + Material.BARREL, + Material.BLAST_FURNACE, + Material.BREWING_STAND, + Material.CAMPFIRE, + Material.CHEST, + Material.DISPENSER, + Material.DROPPER, + Material.FURNACE, + Material.HOPPER, + Material.JUKEBOX, + Material.SHULKER_BOX, + Material.WHITE_SHULKER_BOX, + Material.ORANGE_SHULKER_BOX, + Material.MAGENTA_SHULKER_BOX, + Material.LIGHT_BLUE_SHULKER_BOX, + Material.YELLOW_SHULKER_BOX, + Material.LIME_SHULKER_BOX, + Material.PINK_SHULKER_BOX, + Material.GRAY_SHULKER_BOX, + Material.LIGHT_GRAY_SHULKER_BOX, + Material.CYAN_SHULKER_BOX, + Material.PURPLE_SHULKER_BOX, + Material.BLUE_SHULKER_BOX, + Material.BROWN_SHULKER_BOX, + Material.GREEN_SHULKER_BOX, + Material.RED_SHULKER_BOX, + Material.BLACK_SHULKER_BOX, + Material.SMOKER, + Material.TRAPPED_CHEST); + + private static final Set ALLOWED_ITEMS_IN_INVENTORY = EnumSet.of( + // 64-stackable Items + Material.CORNFLOWER, + Material.POPPY, + Material.FERN, + Material.DANDELION, + Material.BLUE_ORCHID, + Material.ALLIUM, + Material.AZURE_BLUET, + Material.RED_TULIP, + Material.ORANGE_TULIP, + Material.WHITE_TULIP, + Material.PINK_TULIP, + Material.OXEYE_DAISY, + Material.LILY_OF_THE_VALLEY, + Material.WITHER_ROSE, + Material.SUNFLOWER, + // 16-stackable Items + Material.HONEY_BOTTLE, + // Non-stackable items + Material.DIAMOND_HORSE_ARMOR, + Material.IRON_HORSE_ARMOR, + Material.GOLDEN_HORSE_ARMOR, + // Disks + Material.MUSIC_DISC_11, + Material.MUSIC_DISC_13, + Material.MUSIC_DISC_CAT, + Material.MUSIC_DISC_BLOCKS, + Material.MUSIC_DISC_CHIRP, + Material.MUSIC_DISC_FAR, + Material.MUSIC_DISC_MALL, + Material.MUSIC_DISC_MELLOHI, + Material.MUSIC_DISC_STAL, + Material.MUSIC_DISC_STRAD, + Material.MUSIC_DISC_WAIT, + Material.MUSIC_DISC_WARD, + Material.MUSIC_DISC_OTHERSIDE, + Material.MUSIC_DISC_PIGSTEP, + Material.MUSIC_DISC_RELIC, + Material.MUSIC_DISC_5 + ); + + @Override + public Set getInventoryMaterials() { + return INVENTORY; + } + + @Override + public Set getAllowedMaterialsInInventory() { + return ALLOWED_ITEMS_IN_INVENTORY; + } +} diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/autocheck/AutoCheckerItems.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/autocheck/AutoCheckerItems.java new file mode 100644 index 00000000..fb103f67 --- /dev/null +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/autocheck/AutoCheckerItems.java @@ -0,0 +1,34 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.schematicsystem.autocheck; + +import de.steamwar.core.VersionDependent; +import de.steamwar.schematicsystem.SchematicSystem; +import org.bukkit.Material; + +import java.util.Set; + +public interface AutoCheckerItems { + + AutoCheckerItems impl = VersionDependent.getVersionImpl(SchematicSystem.getInstance()); + + Set getInventoryMaterials(); + Set getAllowedMaterialsInInventory(); +} From 7f215b921ec427693dc67c985aec739a67150ab4 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 18 May 2025 13:32:09 +0200 Subject: [PATCH 082/107] Add "/event vote" command for SteamWarArcade Event To be removed after event --- .../steamwar/messages/BungeeCore.properties | 2 ++ .../steamwar/velocitycore/EventStarter.java | 32 +++++++++++++++++ .../velocitycore/commands/EventCommand.java | 34 +++++++++++++++++++ 3 files changed, 68 insertions(+) diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties index c46cd317..8531389b 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties @@ -755,3 +755,5 @@ DC_SCHEMUPLOAD_IGNORED=Skipping `{0}`, not a schematic file. DC_SCHEMUPLOAD_INVCHAR=`{0}` has invalid characters in its name. DC_SCHEMUPLOAD_SUCCESS=`{0}` was uploaded successfully. DC_SCHEMUPLOAD_ERROR=An error has occured during the upload of `{0}`. For more information ask a Developer. + +EVENT_VOTE_SUCCESS=§aYour teams vote was accepted! diff --git a/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java b/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java index 15c16b64..54d17747 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java +++ b/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java @@ -24,6 +24,7 @@ import de.steamwar.messages.Message; import de.steamwar.persistent.Subserver; import de.steamwar.sql.EventFight; import de.steamwar.sql.Team; +import de.steamwar.velocitycore.commands.EventCommand; import net.kyori.adventure.text.event.ClickEvent; import java.sql.Timestamp; @@ -42,6 +43,19 @@ public class EventStarter { spectatePorts.put(port, command); } + private static final Map VOTES = new HashMap<>(); + private static final Map VOTES_REVERSE = new HashMap<>(); + + static { + VOTES.put("MissileWars", 0); + VOTES.put("TowerRun", 1); + VOTES.put("TNTLeague", 2); + + VOTES_REVERSE.put(0, "MissileWars"); + VOTES_REVERSE.put(1, "TowerRun"); + VOTES_REVERSE.put(2, "TNTLeague"); + } + public EventStarter() { EventFight.loadAllComingFights(); VelocityCore.schedule(this::run).repeat(10, TimeUnit.SECONDS).schedule(); @@ -63,6 +77,24 @@ public class EventStarter { //Don't start EventServer if not the event bungee String command; if(VelocityCore.get().getConfig().isEventmode() || next.getSpectatePort() == null) { + ArenaMode blueVote = ArenaMode.getByChat(EventCommand.TEAM_VOTES.getOrDefault(blue.getTeamId(), "TowerRun")); + ArenaMode redVote = ArenaMode.getByChat(EventCommand.TEAM_VOTES.getOrDefault(red.getTeamId(), "TowerRun")); + + ArenaMode mode = blueVote; + + if (!blueVote.getInternalName().equals(redVote.getInternalName())) { + mode = ArenaMode.getByChat(VOTES_REVERSE.get(3 - VOTES.get(blueVote.getInternalName()) - VOTES.get(redVote.getInternalName()))); + } + + next.update( + next.getStartTime(), + mode.getInternalName(), + mode.getRandomMap(), + next.getTeamBlue(), + next.getTeamRed(), + next.getSpectatePort() + ); + ServerStarter starter = new ServerStarter().event(next); starter.callback(subserver -> { diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/EventCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/EventCommand.java index b57d6aad..d718073b 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/EventCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/EventCommand.java @@ -27,6 +27,7 @@ import de.steamwar.messages.Chatter; import de.steamwar.messages.PlayerChatter; import de.steamwar.persistent.Subserver; import de.steamwar.sql.*; +import de.steamwar.velocitycore.ArenaMode; import de.steamwar.velocitycore.EventStarter; import de.steamwar.velocitycore.SubserverSystem; @@ -48,6 +49,39 @@ public class EventCommand extends SWCommand { return (sender, value, messageSender) -> Event.get() == null; } + public static final Map TEAM_VOTES = new HashMap<>(); + + @Register("vote") + public void eventVote(@Validator(value = "noEvent", invert = true) PlayerChatter sender, ArenaMode gamemode) { + if (!TeamTeilnahme.nimmtTeil(sender.user().getTeam(), Event.get().getEventID())) { + return; + } + + TEAM_VOTES.put(sender.user().getTeam(), gamemode.getChatName()); + sender.system("EVENT_VOTE_SUCCESS"); + } + + @ClassMapper(value = ArenaMode.class, local = true) + public TypeMapper eventGamemode() { + return new TypeMapper<>() { + @Override + public ArenaMode map(Chatter sender, PreviousArguments previousArguments, String s) { + ArenaMode mode = ArenaMode.getByChat(s); + + if (tabCompletes(null, previousArguments, null).contains(mode.getChatName())) { + return mode; + } + + return null; + } + + @Override + public Collection tabCompletes(Chatter sender, PreviousArguments previousArguments, String s) { + return Arrays.asList("TowerRun", "MissileWars", "TNTLeague"); + } + }; + } + @Register public void noCurrentEvent(@Validator("noEvent") Chatter sender) { sender.system("EVENT_NO_CURRENT"); From f7e81f82047a59f256cd44f6de31dbedcbe94bac Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 18 May 2025 13:34:42 +0200 Subject: [PATCH 083/107] Hotfix OOM in IngameListener --- .../towerrun/listener/IngameListener.java | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java index a4e2bec6..a7dcd60a 100644 --- a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java +++ b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java @@ -20,13 +20,13 @@ package de.steamwar.towerrun.listener; import de.steamwar.inventory.SWItem; -import de.steamwar.network.packets.server.BaumemberUpdatePacket; import de.steamwar.towerrun.TowerRun; import de.steamwar.towerrun.config.Config; import de.steamwar.towerrun.config.WorldConfig; import de.steamwar.towerrun.game.TowerRunGame; import de.steamwar.towerrun.state.GameStateBukkitListener; import de.steamwar.towerrun.state.GameStates; +import lombok.AllArgsConstructor; import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.entity.EntityType; @@ -43,16 +43,22 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.scheduler.BukkitRunnable; import java.util.*; -import java.util.function.Function; import java.util.stream.Stream; public class IngameListener extends GameStateBukkitListener { private int time = 0; - private final Map> blocksToMelt = new HashMap<>(); + private final Map> blocksToMelt = new HashMap<>(); private BukkitRunnable blocksToMeltRunnable; private BukkitRunnable antiCampRunnable; + @AllArgsConstructor + private class Pos { + private final int x; + private final int y; + private final int z; + } + public IngameListener() { super(EnumSet.of(GameStates.RUNNING)); } @@ -63,20 +69,21 @@ public class IngameListener extends GameStateBukkitListener { blocksToMeltRunnable = new BukkitRunnable() { @Override public void run() { - List blocks = blocksToMelt.remove(time); + List posList = blocksToMelt.remove(time); time++; - if (blocks == null) { + if (posList == null) { return; } int maxBlocks = 1_000; - while (maxBlocks > 0 && !blocks.isEmpty()) { - Block block = blocks.removeFirst(); + while (maxBlocks > 0 && !posList.isEmpty()) { + Pos pos = posList.removeFirst(); + Block block = Bukkit.getWorlds().get(0).getBlockAt(pos.x, pos.y, pos.z); if (block.getType() == Material.AIR || block.getType() == Material.LAVA) continue; block.setType(Material.AIR); block.getWorld().playSound(block.getLocation(), Sound.BLOCK_FIRE_EXTINGUISH, 0.1F, 1); maxBlocks--; } - blocksToMelt.computeIfAbsent(time, __ -> new ArrayList<>()).addAll(0, blocks); + blocksToMelt.computeIfAbsent(time, __ -> new ArrayList<>()).addAll(0, posList); } }; blocksToMeltRunnable.runTaskTimer(TowerRun.getInstance(), 0, 1); @@ -213,6 +220,8 @@ public class IngameListener extends GameStateBukkitListener { private void shouldMelt(Block block) { if (block.getType().isBurnable()) return; + if (block.getType().isAir()) return; + if (block.isLiquid()) return; int meltingTime = (int) (block.getType().getHardness() * 48 * 20); switch (block.getType()) { case TINTED_GLASS: @@ -254,7 +263,7 @@ public class IngameListener extends GameStateBukkitListener { default: break; } - blocksToMelt.computeIfAbsent(time + meltingTime, integer -> new ArrayList<>()).add(block); + blocksToMelt.computeIfAbsent(time + meltingTime, integer -> new ArrayList<>()).add(new Pos(block.getLocation().getBlockX(), block.getLocation().getBlockY(), block.getLocation().getBlockZ())); } @EventHandler From 6ed639fbb3f9bbd05cae8a4883697512f253434f Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 18 May 2025 13:46:39 +0200 Subject: [PATCH 084/107] Add sout --- TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java | 1 + 1 file changed, 1 insertion(+) diff --git a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java index a7dcd60a..f3fc9809 100644 --- a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java +++ b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java @@ -70,6 +70,7 @@ public class IngameListener extends GameStateBukkitListener { @Override public void run() { List posList = blocksToMelt.remove(time); + System.out.println(blocksToMelt.size() + (posList != null ? 1 : 0) + " " + (posList != null ? posList.size() : "")); time++; if (posList == null) { return; From 2a314e703589ff90b1cf2c76f53890f044fca7d7 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 18 May 2025 15:31:48 +0200 Subject: [PATCH 085/107] Add sout --- TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java index f3fc9809..bd38466e 100644 --- a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java +++ b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java @@ -70,11 +70,11 @@ public class IngameListener extends GameStateBukkitListener { @Override public void run() { List posList = blocksToMelt.remove(time); - System.out.println(blocksToMelt.size() + (posList != null ? 1 : 0) + " " + (posList != null ? posList.size() : "")); time++; if (posList == null) { return; } + System.out.println(blocksToMelt.size() + " " + posList.size() + " " + blocksToMelt.values().stream().mapToInt(List::size).sum()); int maxBlocks = 1_000; while (maxBlocks > 0 && !posList.isEmpty()) { Pos pos = posList.removeFirst(); From 778d0282d35f9f408a13d2025a92c19d004e8655 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 18 May 2025 15:37:43 +0200 Subject: [PATCH 086/107] Fix IngameListener --- .../towerrun/listener/IngameListener.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java index bd38466e..cc3723ef 100644 --- a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java +++ b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java @@ -27,6 +27,7 @@ import de.steamwar.towerrun.game.TowerRunGame; import de.steamwar.towerrun.state.GameStateBukkitListener; import de.steamwar.towerrun.state.GameStates; import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.entity.EntityType; @@ -43,16 +44,18 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.scheduler.BukkitRunnable; import java.util.*; +import java.util.stream.Collectors; import java.util.stream.Stream; public class IngameListener extends GameStateBukkitListener { private int time = 0; - private final Map> blocksToMelt = new HashMap<>(); + private final Map blocksToMelt = new HashMap<>(); private BukkitRunnable blocksToMeltRunnable; private BukkitRunnable antiCampRunnable; @AllArgsConstructor + @EqualsAndHashCode private class Pos { private final int x; private final int y; @@ -69,22 +72,22 @@ public class IngameListener extends GameStateBukkitListener { blocksToMeltRunnable = new BukkitRunnable() { @Override public void run() { - List posList = blocksToMelt.remove(time); + List blocksToBreak = blocksToMelt.entrySet().stream() + .filter(entry -> entry.getValue() == time) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); time++; - if (posList == null) { + if (blocksToBreak.isEmpty()) { return; } - System.out.println(blocksToMelt.size() + " " + posList.size() + " " + blocksToMelt.values().stream().mapToInt(List::size).sum()); - int maxBlocks = 1_000; - while (maxBlocks > 0 && !posList.isEmpty()) { - Pos pos = posList.removeFirst(); + System.out.println(blocksToBreak.size() + "/" + blocksToMelt.size()); + for (Pos pos : blocksToBreak) { + blocksToMelt.remove(pos); Block block = Bukkit.getWorlds().get(0).getBlockAt(pos.x, pos.y, pos.z); if (block.getType() == Material.AIR || block.getType() == Material.LAVA) continue; block.setType(Material.AIR); block.getWorld().playSound(block.getLocation(), Sound.BLOCK_FIRE_EXTINGUISH, 0.1F, 1); - maxBlocks--; } - blocksToMelt.computeIfAbsent(time, __ -> new ArrayList<>()).addAll(0, posList); } }; blocksToMeltRunnable.runTaskTimer(TowerRun.getInstance(), 0, 1); @@ -264,7 +267,8 @@ public class IngameListener extends GameStateBukkitListener { default: break; } - blocksToMelt.computeIfAbsent(time + meltingTime, integer -> new ArrayList<>()).add(new Pos(block.getLocation().getBlockX(), block.getLocation().getBlockY(), block.getLocation().getBlockZ())); + Pos pos = new Pos(block.getLocation().getBlockX(), block.getLocation().getBlockY(), block.getLocation().getBlockZ()); + blocksToMelt.putIfAbsent(pos, time + meltingTime); } @EventHandler From 400c78447ad9ee9653dac349aae18577bd50e721 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 18 May 2025 15:41:43 +0200 Subject: [PATCH 087/107] Fix IngameListener --- .../src/de/steamwar/towerrun/listener/IngameListener.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java index cc3723ef..c732ff72 100644 --- a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java +++ b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java @@ -73,7 +73,7 @@ public class IngameListener extends GameStateBukkitListener { @Override public void run() { List blocksToBreak = blocksToMelt.entrySet().stream() - .filter(entry -> entry.getValue() == time) + .filter(entry -> entry.getValue() <= time) .map(Map.Entry::getKey) .collect(Collectors.toList()); time++; @@ -268,7 +268,7 @@ public class IngameListener extends GameStateBukkitListener { break; } Pos pos = new Pos(block.getLocation().getBlockX(), block.getLocation().getBlockY(), block.getLocation().getBlockZ()); - blocksToMelt.putIfAbsent(pos, time + meltingTime); + blocksToMelt.putIfAbsent(pos, time + meltingTime + 1); } @EventHandler From 297e6c9b599a6f05eba6daae37006524a14b5287 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 18 May 2025 15:58:31 +0200 Subject: [PATCH 088/107] Fix OOM? --- TowerRun/src/TowerRun.properties | 2 +- TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/TowerRun/src/TowerRun.properties b/TowerRun/src/TowerRun.properties index 2a6c0e04..0935bd83 100644 --- a/TowerRun/src/TowerRun.properties +++ b/TowerRun/src/TowerRun.properties @@ -17,7 +17,7 @@ # along with this program. If not, see . # -PREFIX=§eTowerRun§8§§r +PREFIX=§eTowerRun§8»§r PLAYER_DIED=§c{0} §7died§8! PLAYER_ESCAPE=§a{0} §7escaped§8! diff --git a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java index c732ff72..bc74e57f 100644 --- a/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java +++ b/TowerRun/src/de/steamwar/towerrun/listener/IngameListener.java @@ -80,7 +80,6 @@ public class IngameListener extends GameStateBukkitListener { if (blocksToBreak.isEmpty()) { return; } - System.out.println(blocksToBreak.size() + "/" + blocksToMelt.size()); for (Pos pos : blocksToBreak) { blocksToMelt.remove(pos); Block block = Bukkit.getWorlds().get(0).getBlockAt(pos.x, pos.y, pos.z); From a5b61fb0d6f1f299f9f439ed5a7e7bc1ead9af54 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 18 May 2025 16:22:50 +0200 Subject: [PATCH 089/107] Add "/event vote" command for SteamWarArcade Event To be removed after event --- VelocityCore/src/de/steamwar/velocitycore/EventStarter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java b/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java index 54d17747..c21a5e01 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java +++ b/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java @@ -83,7 +83,7 @@ public class EventStarter { ArenaMode mode = blueVote; if (!blueVote.getInternalName().equals(redVote.getInternalName())) { - mode = ArenaMode.getByChat(VOTES_REVERSE.get(3 - VOTES.get(blueVote.getInternalName()) - VOTES.get(redVote.getInternalName()))); + mode = ArenaMode.getByChat(VOTES_REVERSE.get(Math.abs(3 - VOTES.get(blueVote.getInternalName()) - VOTES.get(redVote.getInternalName())))); } next.update( From b0bbc09113976fda9775399728acf452cb0fd553 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 18 May 2025 16:28:26 +0200 Subject: [PATCH 090/107] Fix TowerRun event --- TowerRun/src/de/steamwar/towerrun/listener/LobbyListener.java | 1 + 1 file changed, 1 insertion(+) diff --git a/TowerRun/src/de/steamwar/towerrun/listener/LobbyListener.java b/TowerRun/src/de/steamwar/towerrun/listener/LobbyListener.java index 78fe59c5..0a4e4358 100644 --- a/TowerRun/src/de/steamwar/towerrun/listener/LobbyListener.java +++ b/TowerRun/src/de/steamwar/towerrun/listener/LobbyListener.java @@ -62,6 +62,7 @@ public class LobbyListener extends GameStateBukkitListener { int team = user.getTeam(); if (team != Config.EVENT_TEAM_BLUE_ID && team != Config.EVENT_TEAM_RED_ID) { + player.setGameMode(GameMode.SPECTATOR); return; } From 8cd088050d15e251a05e42c348e8942c5774a2cb Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 18 May 2025 16:32:01 +0200 Subject: [PATCH 091/107] Fix TowerRun event --- VelocityCore/src/de/steamwar/velocitycore/EventStarter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java b/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java index c21a5e01..467d4285 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java +++ b/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java @@ -83,7 +83,7 @@ public class EventStarter { ArenaMode mode = blueVote; if (!blueVote.getInternalName().equals(redVote.getInternalName())) { - mode = ArenaMode.getByChat(VOTES_REVERSE.get(Math.abs(3 - VOTES.get(blueVote.getInternalName()) - VOTES.get(redVote.getInternalName())))); + mode = ArenaMode.getByChat(VOTES_REVERSE.get(Math.abs(3 - VOTES.get(blueVote.getChatName()) - VOTES.get(redVote.getChatName())))); } next.update( From 7fa97ce36ca8adb5bb03d75ea0906590cfdae8d8 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 18 May 2025 19:44:28 +0200 Subject: [PATCH 092/107] Revert "Fix TowerRun event" This reverts commit 8cd088050d15e251a05e42c348e8942c5774a2cb. --- VelocityCore/src/de/steamwar/velocitycore/EventStarter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java b/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java index 467d4285..c21a5e01 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java +++ b/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java @@ -83,7 +83,7 @@ public class EventStarter { ArenaMode mode = blueVote; if (!blueVote.getInternalName().equals(redVote.getInternalName())) { - mode = ArenaMode.getByChat(VOTES_REVERSE.get(Math.abs(3 - VOTES.get(blueVote.getChatName()) - VOTES.get(redVote.getChatName())))); + mode = ArenaMode.getByChat(VOTES_REVERSE.get(Math.abs(3 - VOTES.get(blueVote.getInternalName()) - VOTES.get(redVote.getInternalName())))); } next.update( From 0d15bbc2664d50a5818ec7d97bf14b939df7e405 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 18 May 2025 19:44:28 +0200 Subject: [PATCH 093/107] Revert "Add "/event vote" command for SteamWarArcade Event" This reverts commit a5b61fb0d6f1f299f9f439ed5a7e7bc1ead9af54. --- VelocityCore/src/de/steamwar/velocitycore/EventStarter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java b/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java index c21a5e01..54d17747 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java +++ b/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java @@ -83,7 +83,7 @@ public class EventStarter { ArenaMode mode = blueVote; if (!blueVote.getInternalName().equals(redVote.getInternalName())) { - mode = ArenaMode.getByChat(VOTES_REVERSE.get(Math.abs(3 - VOTES.get(blueVote.getInternalName()) - VOTES.get(redVote.getInternalName())))); + mode = ArenaMode.getByChat(VOTES_REVERSE.get(3 - VOTES.get(blueVote.getInternalName()) - VOTES.get(redVote.getInternalName()))); } next.update( From 45a8aab321bb568e82286b84310ff0a9207228a7 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 18 May 2025 19:44:29 +0200 Subject: [PATCH 094/107] Revert "Add "/event vote" command for SteamWarArcade Event" This reverts commit 7f215b921ec427693dc67c985aec739a67150ab4. --- .../steamwar/messages/BungeeCore.properties | 2 -- .../steamwar/velocitycore/EventStarter.java | 32 ----------------- .../velocitycore/commands/EventCommand.java | 34 ------------------- 3 files changed, 68 deletions(-) diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties index 8531389b..c46cd317 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties @@ -755,5 +755,3 @@ DC_SCHEMUPLOAD_IGNORED=Skipping `{0}`, not a schematic file. DC_SCHEMUPLOAD_INVCHAR=`{0}` has invalid characters in its name. DC_SCHEMUPLOAD_SUCCESS=`{0}` was uploaded successfully. DC_SCHEMUPLOAD_ERROR=An error has occured during the upload of `{0}`. For more information ask a Developer. - -EVENT_VOTE_SUCCESS=§aYour teams vote was accepted! diff --git a/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java b/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java index 54d17747..15c16b64 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java +++ b/VelocityCore/src/de/steamwar/velocitycore/EventStarter.java @@ -24,7 +24,6 @@ import de.steamwar.messages.Message; import de.steamwar.persistent.Subserver; import de.steamwar.sql.EventFight; import de.steamwar.sql.Team; -import de.steamwar.velocitycore.commands.EventCommand; import net.kyori.adventure.text.event.ClickEvent; import java.sql.Timestamp; @@ -43,19 +42,6 @@ public class EventStarter { spectatePorts.put(port, command); } - private static final Map VOTES = new HashMap<>(); - private static final Map VOTES_REVERSE = new HashMap<>(); - - static { - VOTES.put("MissileWars", 0); - VOTES.put("TowerRun", 1); - VOTES.put("TNTLeague", 2); - - VOTES_REVERSE.put(0, "MissileWars"); - VOTES_REVERSE.put(1, "TowerRun"); - VOTES_REVERSE.put(2, "TNTLeague"); - } - public EventStarter() { EventFight.loadAllComingFights(); VelocityCore.schedule(this::run).repeat(10, TimeUnit.SECONDS).schedule(); @@ -77,24 +63,6 @@ public class EventStarter { //Don't start EventServer if not the event bungee String command; if(VelocityCore.get().getConfig().isEventmode() || next.getSpectatePort() == null) { - ArenaMode blueVote = ArenaMode.getByChat(EventCommand.TEAM_VOTES.getOrDefault(blue.getTeamId(), "TowerRun")); - ArenaMode redVote = ArenaMode.getByChat(EventCommand.TEAM_VOTES.getOrDefault(red.getTeamId(), "TowerRun")); - - ArenaMode mode = blueVote; - - if (!blueVote.getInternalName().equals(redVote.getInternalName())) { - mode = ArenaMode.getByChat(VOTES_REVERSE.get(3 - VOTES.get(blueVote.getInternalName()) - VOTES.get(redVote.getInternalName()))); - } - - next.update( - next.getStartTime(), - mode.getInternalName(), - mode.getRandomMap(), - next.getTeamBlue(), - next.getTeamRed(), - next.getSpectatePort() - ); - ServerStarter starter = new ServerStarter().event(next); starter.callback(subserver -> { diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/EventCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/EventCommand.java index d718073b..b57d6aad 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/EventCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/EventCommand.java @@ -27,7 +27,6 @@ import de.steamwar.messages.Chatter; import de.steamwar.messages.PlayerChatter; import de.steamwar.persistent.Subserver; import de.steamwar.sql.*; -import de.steamwar.velocitycore.ArenaMode; import de.steamwar.velocitycore.EventStarter; import de.steamwar.velocitycore.SubserverSystem; @@ -49,39 +48,6 @@ public class EventCommand extends SWCommand { return (sender, value, messageSender) -> Event.get() == null; } - public static final Map TEAM_VOTES = new HashMap<>(); - - @Register("vote") - public void eventVote(@Validator(value = "noEvent", invert = true) PlayerChatter sender, ArenaMode gamemode) { - if (!TeamTeilnahme.nimmtTeil(sender.user().getTeam(), Event.get().getEventID())) { - return; - } - - TEAM_VOTES.put(sender.user().getTeam(), gamemode.getChatName()); - sender.system("EVENT_VOTE_SUCCESS"); - } - - @ClassMapper(value = ArenaMode.class, local = true) - public TypeMapper eventGamemode() { - return new TypeMapper<>() { - @Override - public ArenaMode map(Chatter sender, PreviousArguments previousArguments, String s) { - ArenaMode mode = ArenaMode.getByChat(s); - - if (tabCompletes(null, previousArguments, null).contains(mode.getChatName())) { - return mode; - } - - return null; - } - - @Override - public Collection tabCompletes(Chatter sender, PreviousArguments previousArguments, String s) { - return Arrays.asList("TowerRun", "MissileWars", "TNTLeague"); - } - }; - } - @Register public void noCurrentEvent(@Validator("noEvent") Chatter sender) { sender.system("EVENT_NO_CURRENT"); From 374e314faa4d1859f99ae94fda94721634570a98 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Thu, 22 May 2025 18:19:31 +0200 Subject: [PATCH 095/107] Add new WATUT Channel --- .../src/de/steamwar/velocitycore/listeners/PluginMessage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/listeners/PluginMessage.java b/VelocityCore/src/de/steamwar/velocitycore/listeners/PluginMessage.java index 33e431fb..5d84eb17 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/listeners/PluginMessage.java +++ b/VelocityCore/src/de/steamwar/velocitycore/listeners/PluginMessage.java @@ -405,7 +405,7 @@ public class PluginMessage extends BasicListener { for(String channel : Arrays.asList( "floodgate:skin", - "watut:nbt", //https://github.com/Corosauce/WATUT + "watut:nbt", "watut:nbt_server", //https://github.com/Corosauce/WATUT "bclib:hello_server", "vivecraft:data", //https://github.com/Vivecraft/VivecraftMod https://github.com/jrbudda/Vivecraft_Spigot_Extensions https://github.com/Techjar/Vivecraft_BungeeCord_Extensions (VR support) "badpackets:channel_sync", //https://github.com/badasintended/badpackets (Forge fabric translation layer) From d410484e4c5ce540877f2c128a1b8e52c950fb83 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 22 May 2025 19:47:14 +0200 Subject: [PATCH 096/107] Update JDA to newest version --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index dc94bc0c..8f25cf52 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -138,7 +138,7 @@ dependencyResolutionManagement { library("velocityapi", "com.velocitypowered:velocity-api:3.3.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.2.0") + library("jda", "net.dv8tion:JDA:5.5.1") library("msgpack", "org.msgpack:msgpack-core:0.9.8") library("apolloprotos", "com.lunarclient:apollo-protos:1.0-SNAPSHOT") From 380506542f2df4db70769dbccfd13eb14ded37d1 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 23 May 2025 09:13:23 +0200 Subject: [PATCH 097/107] Remove some more duplicates --- .../SchematicSystem_19/build.gradle.kts | 1 + .../autocheck/AutoCheckerItems19.java | 38 +------------------ 2 files changed, 2 insertions(+), 37 deletions(-) diff --git a/SchematicSystem/SchematicSystem_19/build.gradle.kts b/SchematicSystem/SchematicSystem_19/build.gradle.kts index 99b982c8..38fcd471 100644 --- a/SchematicSystem/SchematicSystem_19/build.gradle.kts +++ b/SchematicSystem/SchematicSystem_19/build.gradle.kts @@ -24,6 +24,7 @@ plugins { dependencies { compileOnly(project(":SpigotCore", "default")) compileOnly(project(":SchematicSystem:SchematicSystem_Core", "default")) + compileOnly(project(":SchematicSystem:SchematicSystem_15", "default")) compileOnly(libs.spigotapi) diff --git a/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoCheckerItems19.java b/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoCheckerItems19.java index 556d354f..0c004cfe 100644 --- a/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoCheckerItems19.java +++ b/SchematicSystem/SchematicSystem_19/src/de/steamwar/schematicsystem/autocheck/AutoCheckerItems19.java @@ -24,38 +24,7 @@ import org.bukkit.Material; import java.util.EnumSet; import java.util.Set; -public class AutoCheckerItems19 implements AutoCheckerItems { - - private static final Set INVENTORY = EnumSet.of( - Material.BARREL, - Material.BLAST_FURNACE, - Material.BREWING_STAND, - Material.CAMPFIRE, - Material.CHEST, - Material.DISPENSER, - Material.DROPPER, - Material.FURNACE, - Material.HOPPER, - Material.JUKEBOX, - Material.SHULKER_BOX, - Material.WHITE_SHULKER_BOX, - Material.ORANGE_SHULKER_BOX, - Material.MAGENTA_SHULKER_BOX, - Material.LIGHT_BLUE_SHULKER_BOX, - Material.YELLOW_SHULKER_BOX, - Material.LIME_SHULKER_BOX, - Material.PINK_SHULKER_BOX, - Material.GRAY_SHULKER_BOX, - Material.LIGHT_GRAY_SHULKER_BOX, - Material.CYAN_SHULKER_BOX, - Material.PURPLE_SHULKER_BOX, - Material.BLUE_SHULKER_BOX, - Material.BROWN_SHULKER_BOX, - Material.GREEN_SHULKER_BOX, - Material.RED_SHULKER_BOX, - Material.BLACK_SHULKER_BOX, - Material.SMOKER, - Material.TRAPPED_CHEST); +public class AutoCheckerItems19 extends AutoCheckerItems15 { private static final Set ALLOWED_ITEMS_IN_INVENTORY = EnumSet.of( // 64-stackable Items @@ -99,11 +68,6 @@ public class AutoCheckerItems19 implements AutoCheckerItems { Material.MUSIC_DISC_5 ); - @Override - public Set getInventoryMaterials() { - return INVENTORY; - } - @Override public Set getAllowedMaterialsInInventory() { return ALLOWED_ITEMS_IN_INVENTORY; From 277e1f9f9b036103846be2f9c9f985cae093d4d3 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Tue, 27 May 2025 18:15:03 +0200 Subject: [PATCH 098/107] Add NoGravity --- .../de/steamwar/fightsystem/FightSystem.java | 6 +-- .../steamwar/fightsystem/event/NoGravity.java | 41 +++++++++++++++++++ .../winconditions/Winconditions.java | 3 +- 3 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/event/NoGravity.java diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java index b32a41b9..bff38170 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java @@ -23,10 +23,7 @@ import com.comphenix.tinyprotocol.TinyProtocol; import de.steamwar.core.Core; import de.steamwar.fightsystem.commands.*; import de.steamwar.fightsystem.countdown.*; -import de.steamwar.fightsystem.event.HellsBells; -import de.steamwar.fightsystem.event.Meteor; -import de.steamwar.fightsystem.event.PersistentDamage; -import de.steamwar.fightsystem.event.TNTDistributor; +import de.steamwar.fightsystem.event.*; import de.steamwar.fightsystem.fight.Fight; import de.steamwar.fightsystem.fight.FightTeam; import de.steamwar.fightsystem.fight.FightWorld; @@ -136,6 +133,7 @@ public class FightSystem extends JavaPlugin { new PersistentDamage(); new TNTDistributor(); new WinconditionAmongUs(); + new NoGravity(); new NoPlayersOnlineCountdown(); new PreSchemCountdown(); diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/event/NoGravity.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/event/NoGravity.java new file mode 100644 index 00000000..12246f8e --- /dev/null +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/event/NoGravity.java @@ -0,0 +1,41 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.fightsystem.event; + +import de.steamwar.fightsystem.states.FightState; +import de.steamwar.fightsystem.states.StateDependentListener; +import de.steamwar.fightsystem.winconditions.Winconditions; +import org.bukkit.entity.EntityType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntitySpawnEvent; + +public class NoGravity implements Listener { + + public NoGravity() { + new StateDependentListener(Winconditions.NO_GRAVITY, FightState.All, this); + } + + @EventHandler + public void onEntitySpawn(EntitySpawnEvent event) { + if (event.getEntityType() == EntityType.PLAYER) return; + event.getEntity().setGravity(false); + } +} diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java index 296cf97e..2aaecae6 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/Winconditions.java @@ -39,5 +39,6 @@ public enum Winconditions { METEOR, AMONG_US, PERSISTENT_DAMAGE, - TNT_DISTRIBUTION + TNT_DISTRIBUTION, + NO_GRAVITY, } From 8defbaa18b475526a0f236fb74af6214c943dde9 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Thu, 29 May 2025 00:03:25 +0200 Subject: [PATCH 099/107] Add tech hider bug handling for arena subservers in BugCommand --- .../src/de/steamwar/velocitycore/commands/BugCommand.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/BugCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/BugCommand.java index 22c9f391..088acb09 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/BugCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/BugCommand.java @@ -19,9 +19,11 @@ package de.steamwar.velocitycore.commands; +import de.steamwar.persistent.Subserver; import de.steamwar.sql.SWException; import de.steamwar.command.SWCommand; import de.steamwar.messages.Chatter; +import de.steamwar.velocitycore.SubserverSystem; public class BugCommand extends SWCommand { public BugCommand() { @@ -35,5 +37,9 @@ public class BugCommand extends SWCommand { sender.withPlayerOrOffline(player -> player.getCurrentServer().map(connection -> connection.getServerInfo().getName()).orElse("offline"), () -> "offline") + " " + sender.user().getUserName() + " " + sender.user().getId() ); sender.system("BUG_MESSAGE", id); + + if (Subserver.isArena(Subserver.getSubserver(sender.getPlayer()))) { + sender.getPlayer().spoofChatInput("/techhiderbug"); + } } } From b14cf445dfbc017a57aeaa06d494ec8ee403039d Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 29 May 2025 11:32:50 +0200 Subject: [PATCH 100/107] Fix PR stuff --- .../src/de/steamwar/fightsystem/commands/GUI.java | 11 +++-------- .../src/de/steamwar/fightsystem/fight/FightTeam.java | 5 ----- .../fightsystem/winconditions/WinconditionBlocks.java | 5 ++++- .../winconditions/WinconditionCaptainDead.java | 2 -- .../winconditions/WinconditionPercent.java | 11 ++++++++--- 5 files changed, 15 insertions(+), 19 deletions(-) diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java index 87e72c08..237d860e 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java @@ -212,9 +212,7 @@ public class GUI { SchematicNode node = SchematicNode.getSchematicNode(-1, Config.GameName, (Integer) null); if (node != null) { inv.setItem(2, new SWItem(SWItem.getMaterial(node.getItem()), msg.parse("SCHEM_DIRT", p), click -> { - schemSelect(p, node, fightTeam -> { - fightTeam.setIgnoreWinconditions(true); - }); + schemSelect(p, node); })); } } @@ -253,19 +251,16 @@ public class GUI { private static void schemDialog(Player p, SchematicType type, boolean publicSchems, boolean unchecked){ SchematicSelector selector = new SchematicSelector(p, Config.test() ? SchematicSelector.selectSchematic() : SchematicSelector.selectSchematicType(unchecked ? type.checkType() : type), node -> { - schemSelect(p, node, fightTeam -> { - fightTeam.setIgnoreWinconditions(false); - }); + schemSelect(p, node); }); selector.setPublicMode(publicSchems?SchematicSelector.PublicMode.PUBLIC_ONLY:SchematicSelector.PublicMode.PRIVATE_ONLY); selector.open(); } - private static void schemSelect(Player p, SchematicNode node, Consumer fightTeamConsumer) { + private static void schemSelect(Player p, SchematicNode node) { FightTeam fightTeam = Fight.getPlayerTeam(p); if(fightTeam == null) return; - fightTeamConsumer.accept(fightTeam); if(Config.test() || FightState.getFightState() != FightState.POST_SCHEM_SETUP) fightTeam.pasteSchem(node); p.closeInventory(); 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 19d45690..8eed2f2a 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java @@ -42,7 +42,6 @@ import de.steamwar.inventory.SWItem; import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SteamwarUser; import lombok.Getter; -import lombok.Setter; import net.md_5.bungee.api.ChatMessageType; import org.bukkit.*; import org.bukkit.entity.LivingEntity; @@ -101,10 +100,6 @@ public class FightTeam { @Getter private boolean publicsOnly; - @Getter - @Setter - private boolean ignoreWinconditions; - private final Map players = new HashMap<>(); @Getter diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionBlocks.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionBlocks.java index 4bbaa241..72c0873a 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionBlocks.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionBlocks.java @@ -84,8 +84,11 @@ public class WinconditionBlocks extends Wincondition implements PrintableWincond } private void check() { + // Edge Case for DirtBlock + if (blocks.isEmpty()) return; + blocks.removeIf(block -> !isOfType.test(block)); - if(blocks.isEmpty() && !team.isIgnoreWinconditions()) + if(blocks.isEmpty()) win(Fight.getOpposite(team), "WIN_TECHKO", team.getColoredName()); } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionCaptainDead.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionCaptainDead.java index df7651ee..de0205ab 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionCaptainDead.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionCaptainDead.java @@ -42,8 +42,6 @@ public class WinconditionCaptainDead extends Wincondition implements Listener { return; FightTeam team = leader.getTeam(); - if (team.isIgnoreWinconditions()) - return; win(Fight.getOpposite(team), "WIN_LEADER_DEAD", team.getPrefix() + leader.getEntity().getName()); } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercent.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercent.java index 5a2cbe4f..f98bdecc 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercent.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/winconditions/WinconditionPercent.java @@ -40,8 +40,6 @@ public class WinconditionPercent extends Wincondition implements PrintableWincon private final Map teamMap = new HashMap<>(); protected Consumer checkWin = team -> { - if (team.isIgnoreWinconditions()) - return; if (getPercent(team) >= Config.PercentWin) { win(Fight.getOpposite(team), "WIN_PERCENT", team.getColoredName()); } @@ -80,6 +78,7 @@ public class WinconditionPercent extends Wincondition implements PrintableWincon private int totalBlocks = 0; private int currentBlocks = 0; + private boolean countAnyBlock = false; private TeamPercent(FightTeam team, Winconditions wincondition) { this.team = team; @@ -100,7 +99,7 @@ public class WinconditionPercent extends Wincondition implements PrintableWincon } event.blockList().forEach(block -> { - if (Config.PercentBlocks.contains(block.getType()) == Config.PercentBlocksWhitelist) { + if (countAnyBlock || Config.PercentBlocks.contains(block.getType()) == Config.PercentBlocksWhitelist) { currentBlocks--; } }); @@ -110,10 +109,16 @@ public class WinconditionPercent extends Wincondition implements PrintableWincon private void enable() { totalBlocks = 0; + countAnyBlock = false; team.getSchemRegion().forEach((x, y, z) -> { if (Config.PercentBlocks.contains(Config.world.getBlockAt(x, y, z).getType()) == Config.PercentBlocksWhitelist) totalBlocks++; }); + // Edge Case for DirtBlock + if (totalBlocks == 0) { + totalBlocks = team.getSchemRegion().volume(); + countAnyBlock = true; + } currentBlocks = totalBlocks; postEnable.accept(team); } From 9bc01a4e3bd92506ec05fbef3b2bf56cf96ed890 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 29 May 2025 12:00:12 +0200 Subject: [PATCH 101/107] Revert FightTeam --- .../src/de/steamwar/fightsystem/fight/FightTeam.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8eed2f2a..0cb68f71 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java @@ -385,7 +385,7 @@ public class FightTeam { } public void pasteSchem(SchematicNode schematic){ - if(schematic.getSchemtype().check() || schematic.getSchemtype().writeable()) { + if(schematic.getSchemtype().check()) { FightStatistics.unrank(); FightSystem.getMessage().broadcast("SCHEMATIC_UNCHECKED", getColoredName()); } From 30fa3fd66e1208ba0edfcfa7890bc7690ec4cef8 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 30 May 2025 21:37:07 +0200 Subject: [PATCH 102/107] Add WeatherCommand --- .../src/de/steamwar/teamserver/Builder.java | 1 + .../teamserver/command/WeatherCommand.java | 53 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 Teamserver/src/de/steamwar/teamserver/command/WeatherCommand.java diff --git a/Teamserver/src/de/steamwar/teamserver/Builder.java b/Teamserver/src/de/steamwar/teamserver/Builder.java index 137906ad..e049cdc6 100644 --- a/Teamserver/src/de/steamwar/teamserver/Builder.java +++ b/Teamserver/src/de/steamwar/teamserver/Builder.java @@ -46,6 +46,7 @@ public final class Builder extends JavaPlugin { new SpeedCommand(); new FreezeCommand(); new ArenaconfigCommand(); + new WeatherCommand(); if (Bukkit.getPluginManager().getPlugin("AxiomPaper") != null) { Bukkit.getPluginManager().registerEvents(new AxiomHandshakeListener(), this); diff --git a/Teamserver/src/de/steamwar/teamserver/command/WeatherCommand.java b/Teamserver/src/de/steamwar/teamserver/command/WeatherCommand.java new file mode 100644 index 00000000..2684370c --- /dev/null +++ b/Teamserver/src/de/steamwar/teamserver/command/WeatherCommand.java @@ -0,0 +1,53 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.teamserver.command; + +import de.steamwar.command.SWCommand; +import org.bukkit.WeatherType; +import org.bukkit.entity.Player; + +public class WeatherCommand extends SWCommand { + + public WeatherCommand() { + super("weather"); + } + + @Register("clear") + public void clearWeather(Player player, @OptionalValue("0") int duration) { + player.getWorld().setClearWeatherDuration(duration); + player.getWorld().setThundering(false); + } + + @Register + public void rainyWeather(Player player, WeatherType type, int duration) { + player.getWorld().setThundering(false); + if (type == WeatherType.CLEAR) { + clearWeather(player, duration); + } else { + player.getWorld().setWeatherDuration(duration); + } + } + + @Register("thunder") + public void thunderWeather(Player player, @OptionalValue("0") int duration) { + player.getWorld().setThunderDuration(duration); + player.getWorld().setThundering(true); + } +} From daede98a0fe28d8e8bb60128d66ffe2dd19eb5fc Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 31 May 2025 17:45:24 +0200 Subject: [PATCH 103/107] Hotfix TeamCommand --- .../src/de/steamwar/velocitycore/commands/TeamCommand.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/TeamCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/TeamCommand.java index 0dd865b1..f77207a6 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/TeamCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/TeamCommand.java @@ -19,9 +19,14 @@ package de.steamwar.velocitycore.commands; +import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.proxy.ConnectionRequestBuilder; import com.velocitypowered.api.proxy.server.ServerInfo; +import com.viaversion.viaversion.api.Via; +import com.viaversion.viaversion.velocity.platform.VelocityViaAPI; +import com.viaversion.viaversion.velocity.platform.VelocityViaConfig; import de.steamwar.persistent.Storage; +import de.steamwar.velocitycore.ServerVersion; import de.steamwar.velocitycore.VelocityCore; import de.steamwar.velocitycore.discord.DiscordBot; import de.steamwar.velocitycore.inventory.SWItem; @@ -405,6 +410,8 @@ public class TeamCommand extends SWCommand { ServerInfo serverInfo = Storage.teamServers.computeIfAbsent(targetTeam.getTeamId(), integer -> { ServerInfo info = new ServerInfo("Team " + targetTeam.getTeamKuerzel(), address); VelocityCore.getProxy().registerServer(info); + // This is needed because otherwise ViaVersion uses the wrong version! + ((VelocityViaConfig) Via.getConfig()).getVelocityServerProtocols().put(info.getName(), ProtocolVersion.MAXIMUM_VERSION.getProtocol()); return info; }); From f2a46e54ea9ab23bcb4d0aa7ed71d6e426c0e312 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sat, 31 May 2025 19:40:08 +0200 Subject: [PATCH 104/107] Revert "Add WeatherCommand" This reverts commit 30fa3fd66e1208ba0edfcfa7890bc7690ec4cef8. --- .../src/de/steamwar/teamserver/Builder.java | 1 - .../teamserver/command/WeatherCommand.java | 53 ------------------- 2 files changed, 54 deletions(-) delete mode 100644 Teamserver/src/de/steamwar/teamserver/command/WeatherCommand.java diff --git a/Teamserver/src/de/steamwar/teamserver/Builder.java b/Teamserver/src/de/steamwar/teamserver/Builder.java index e049cdc6..137906ad 100644 --- a/Teamserver/src/de/steamwar/teamserver/Builder.java +++ b/Teamserver/src/de/steamwar/teamserver/Builder.java @@ -46,7 +46,6 @@ public final class Builder extends JavaPlugin { new SpeedCommand(); new FreezeCommand(); new ArenaconfigCommand(); - new WeatherCommand(); if (Bukkit.getPluginManager().getPlugin("AxiomPaper") != null) { Bukkit.getPluginManager().registerEvents(new AxiomHandshakeListener(), this); diff --git a/Teamserver/src/de/steamwar/teamserver/command/WeatherCommand.java b/Teamserver/src/de/steamwar/teamserver/command/WeatherCommand.java deleted file mode 100644 index 2684370c..00000000 --- a/Teamserver/src/de/steamwar/teamserver/command/WeatherCommand.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2020 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.teamserver.command; - -import de.steamwar.command.SWCommand; -import org.bukkit.WeatherType; -import org.bukkit.entity.Player; - -public class WeatherCommand extends SWCommand { - - public WeatherCommand() { - super("weather"); - } - - @Register("clear") - public void clearWeather(Player player, @OptionalValue("0") int duration) { - player.getWorld().setClearWeatherDuration(duration); - player.getWorld().setThundering(false); - } - - @Register - public void rainyWeather(Player player, WeatherType type, int duration) { - player.getWorld().setThundering(false); - if (type == WeatherType.CLEAR) { - clearWeather(player, duration); - } else { - player.getWorld().setWeatherDuration(duration); - } - } - - @Register("thunder") - public void thunderWeather(Player player, @OptionalValue("0") int duration) { - player.getWorld().setThunderDuration(duration); - player.getWorld().setThundering(true); - } -} From c30f24ab8f480f8fd564118ee42889539c3c94b4 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 31 May 2025 21:32:19 +0200 Subject: [PATCH 105/107] Hotfix Protocol Version for real now --- .../velocitycore/commands/TeamCommand.java | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/TeamCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/TeamCommand.java index f77207a6..0655ac8b 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/TeamCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/TeamCommand.java @@ -19,18 +19,12 @@ package de.steamwar.velocitycore.commands; -import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.proxy.ConnectionRequestBuilder; +import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.api.proxy.server.ServerInfo; +import com.velocitypowered.api.proxy.server.ServerPing; import com.viaversion.viaversion.api.Via; -import com.viaversion.viaversion.velocity.platform.VelocityViaAPI; import com.viaversion.viaversion.velocity.platform.VelocityViaConfig; -import de.steamwar.persistent.Storage; -import de.steamwar.velocitycore.ServerVersion; -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.command.PreviousArguments; import de.steamwar.command.SWCommand; import de.steamwar.command.TypeMapper; @@ -38,7 +32,12 @@ import de.steamwar.command.TypeValidator; import de.steamwar.messages.Chatter; import de.steamwar.messages.Message; import de.steamwar.messages.PlayerChatter; +import de.steamwar.persistent.Storage; 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 net.kyori.adventure.text.Component; import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.HoverEvent; @@ -406,14 +405,21 @@ public class TeamCommand extends SWCommand { return; } - InetSocketAddress address = new InetSocketAddress(targetTeam.getAddress(), targetTeam.getPort()); - ServerInfo serverInfo = Storage.teamServers.computeIfAbsent(targetTeam.getTeamId(), integer -> { - ServerInfo info = new ServerInfo("Team " + targetTeam.getTeamKuerzel(), address); - VelocityCore.getProxy().registerServer(info); - // This is needed because otherwise ViaVersion uses the wrong version! - ((VelocityViaConfig) Via.getConfig()).getVelocityServerProtocols().put(info.getName(), ProtocolVersion.MAXIMUM_VERSION.getProtocol()); - return info; - }); + InetSocketAddress address; + ServerInfo serverInfo; + try { + address = new InetSocketAddress(targetTeam.getAddress(), targetTeam.getPort()); + serverInfo = Storage.teamServers.computeIfAbsent(targetTeam.getTeamId(), integer -> { + ServerInfo info = new ServerInfo("Team " + targetTeam.getTeamKuerzel(), address); + RegisteredServer server = VelocityCore.getProxy().registerServer(info); + ServerPing serverPing = server.ping().join(); + ((VelocityViaConfig) Via.getConfig()).getVelocityServerProtocols().put(info.getName(), serverPing.getVersion().getProtocol()); + return info; + }); + } catch (Exception e) { + sender.system("TEAM_NO_ADDRESS"); + return; + } if (!address.equals(serverInfo.getAddress())) { VelocityCore.getProxy().unregisterServer(Storage.teamServers.remove(targetTeam.getTeamId())); From 761977c90af5fc7b9328f7de7b812eb78c88744c Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 8 Jun 2025 16:42:45 +0200 Subject: [PATCH 106/107] BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarLuaPlugin.java aktualisiert --- .../bausystem/features/script/lua/SteamWarLuaPlugin.java | 1 + 1 file changed, 1 insertion(+) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarLuaPlugin.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarLuaPlugin.java index c047531c..16deeda1 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarLuaPlugin.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarLuaPlugin.java @@ -166,6 +166,7 @@ public class SteamWarLuaPlugin extends TwoArgFunction { env.set("rawlen", NIL); env.set("rawset", NIL); env.set("xpcall", NIL); + env.set("require", NIL); return null; } From 1a570dca172f39a8aa8e2b2ee63a59a19b02a132 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 8 Jun 2025 18:18:44 +0200 Subject: [PATCH 107/107] BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarLuaPlugin.java aktualisiert --- .../bausystem/features/script/lua/SteamWarLuaPlugin.java | 1 + 1 file changed, 1 insertion(+) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarLuaPlugin.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarLuaPlugin.java index 16deeda1..c3370904 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarLuaPlugin.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarLuaPlugin.java @@ -167,6 +167,7 @@ public class SteamWarLuaPlugin extends TwoArgFunction { env.set("rawset", NIL); env.set("xpcall", NIL); env.set("require", NIL); + env.set("package", NIL); return null; }