From 55adb1a05249fb81bd8441e2cf7e099f39e8e20c Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 22 Dec 2024 23:16:19 +0100 Subject: [PATCH 001/124] Improve SendCommand --- .../velocitycore/commands/SendCommand.java | 72 ++++++++++++++++++- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java index a0435983..ef8131ea 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java @@ -20,6 +20,7 @@ package de.steamwar.velocitycore.commands; import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ServerConnection; import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.api.proxy.server.ServerInfo; import de.steamwar.command.PreviousArguments; @@ -33,23 +34,46 @@ import de.steamwar.velocitycore.VelocityCore; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; public class SendCommand extends SWCommand { + // /send from to [only ] + // /send to only [] + // can also be current + public SendCommand() { super("send", UserPerm.TEAM); } @Register - public void sendToServer(Chatter sender, Player send, RegisteredServer server) { - send.createConnectionRequest(server).fireAndForget(); + public void sendCommand(Chatter sender, @StaticValue("from") String from, RegisteredServer fromServer, @StaticValue("to") String to, RegisteredServer toServer) { + sendPlayers(toServer, fromServer.getPlayersConnected()); + } + + @Register + public void sendCommand(Chatter sender, @StaticValue("from") String from, RegisteredServer fromServer, @StaticValue("to") String to, RegisteredServer toServer, @StaticValue("only") String only, @ArrayLength(min = 1) Player... players) { + sendPlayers(toServer, List.of(players)); + } + + @Register + public void sendCommand(Chatter sender, @StaticValue("to") String to, RegisteredServer toServer, @StaticValue("only") String only, @ArrayLength(min = 1) Player... players) { + sendPlayers(toServer, List.of(players)); + } + + private void sendPlayers(RegisteredServer toServer, Collection players) { + for (Player player : players) { + player.createConnectionRequest(toServer).fireAndForget(); + } } @ClassMapper(value = RegisteredServer.class, local = true) public TypeMapper subserverTypeMapper() { return new TypeMapper<>() { private boolean check(SteamwarUser user, RegisteredServer registeredServer) { + if (registeredServer == null) return false; ServerInfo serverInfo = registeredServer.getServerInfo(); String name = serverInfo.getName(); if (name.contains(" ")) return false; @@ -66,20 +90,64 @@ public class SendCommand extends SWCommand { return registeredServer; } } + + RegisteredServer currentServer = sender.getPlayer().getCurrentServer().map(ServerConnection::getServer).orElse(null); + if (s.equals("current") && check(user, currentServer)) { + return currentServer; + } return null; } @Override public Collection tabCompletes(Chatter sender, PreviousArguments previousArguments, String s) { SteamwarUser user = sender.user(); + List previous = previousArguments.getAll(RegisteredServer.class); + List tabCompletes = new ArrayList<>(); for (RegisteredServer registeredServer : VelocityCore.getProxy().getAllServers()) { + if (previous.contains(registeredServer)) continue; if (check(user, registeredServer)) { tabCompletes.add(registeredServer.getServerInfo().getName()); } } + + Player player = sender.getPlayer(); + if (player != null) { + RegisteredServer currentServer = player.getCurrentServer().map(ServerConnection::getServer).orElse(null); + if (currentServer != null && !previous.contains(currentServer) && check(user, currentServer)) { + tabCompletes.add("current"); + } + } + return tabCompletes; } }; } + + @ClassMapper(value = Player.class, local = true) + public TypeMapper playerTypeMapper() { + return new TypeMapper<>() { + @Override + public Player map(Chatter sender, PreviousArguments previousArguments, String s) { + return VelocityCore.getProxy().getPlayer(s).orElse(null); + } + + @Override + public Collection tabCompletes(Chatter sender, PreviousArguments previousArguments, String s) { + List previous = previousArguments.getAll(RegisteredServer.class); + if (previous.isEmpty()) { + return VelocityCore.getProxy().getAllPlayers().stream().map(Player::getUsername).collect(Collectors.toList()); + } + if (previous.size() == 1) { + Collection players = previous.get(0).getPlayersConnected(); + return VelocityCore.getProxy().getAllPlayers().stream().filter(player -> !players.contains(player)).map(Player::getUsername).collect(Collectors.toList()); + } + if (previous.size() == 2) { + Collection players = previous.get(0).getPlayersConnected(); + return players.stream().map(Player::getUsername).collect(Collectors.toList()); + } + return Collections.emptyList(); + } + }; + } } From 9a8cb543e9978829e25a8988dc57afbaec48bd2f Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Tue, 7 Jan 2025 14:27:57 +0100 Subject: [PATCH 002/124] Update SendCommand --- .../velocitycore/commands/SendCommand.java | 35 +++---------------- 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java index ef8131ea..77cd2193 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java @@ -34,13 +34,11 @@ import de.steamwar.velocitycore.VelocityCore; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.stream.Collectors; public class SendCommand extends SWCommand { - // /send from to [only ] // /send to only [] // can also be current @@ -48,22 +46,8 @@ public class SendCommand extends SWCommand { super("send", UserPerm.TEAM); } - @Register - public void sendCommand(Chatter sender, @StaticValue("from") String from, RegisteredServer fromServer, @StaticValue("to") String to, RegisteredServer toServer) { - sendPlayers(toServer, fromServer.getPlayersConnected()); - } - - @Register - public void sendCommand(Chatter sender, @StaticValue("from") String from, RegisteredServer fromServer, @StaticValue("to") String to, RegisteredServer toServer, @StaticValue("only") String only, @ArrayLength(min = 1) Player... players) { - sendPlayers(toServer, List.of(players)); - } - - @Register - public void sendCommand(Chatter sender, @StaticValue("to") String to, RegisteredServer toServer, @StaticValue("only") String only, @ArrayLength(min = 1) Player... players) { - sendPlayers(toServer, List.of(players)); - } - - private void sendPlayers(RegisteredServer toServer, Collection players) { + @Register("to") + public void sendCommand(Chatter sender, RegisteredServer toServer, @ArrayLength(min = 1) Player... players) { for (Player player : players) { player.createConnectionRequest(toServer).fireAndForget(); } @@ -135,18 +119,9 @@ public class SendCommand extends SWCommand { @Override public Collection tabCompletes(Chatter sender, PreviousArguments previousArguments, String s) { List previous = previousArguments.getAll(RegisteredServer.class); - if (previous.isEmpty()) { - return VelocityCore.getProxy().getAllPlayers().stream().map(Player::getUsername).collect(Collectors.toList()); - } - if (previous.size() == 1) { - Collection players = previous.get(0).getPlayersConnected(); - return VelocityCore.getProxy().getAllPlayers().stream().filter(player -> !players.contains(player)).map(Player::getUsername).collect(Collectors.toList()); - } - if (previous.size() == 2) { - Collection players = previous.get(0).getPlayersConnected(); - return players.stream().map(Player::getUsername).collect(Collectors.toList()); - } - return Collections.emptyList(); + if (previous.isEmpty()) return null; + Collection players = previous.get(0).getPlayersConnected(); + return VelocityCore.getProxy().getAllPlayers().stream().filter(player -> !players.contains(player)).map(Player::getUsername).collect(Collectors.toList()); } }; } From 3c1d46398d331798f445fcf80c2c05292c52f326 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 28 Dec 2024 12:26:12 +0100 Subject: [PATCH 003/124] Add RDisplay, RBlockDisplay, RItemDisplay, RTextDisplay --- .../src/de/steamwar/entity/RBlockDisplay.java | 30 ++++ .../src/de/steamwar/entity/RDisplay.java | 154 ++++++++++++++++++ .../src/de/steamwar/entity/REntity.java | 2 +- .../src/de/steamwar/entity/RItemDisplay.java | 41 +++++ .../src/de/steamwar/entity/RTextDisplay.java | 116 +++++++++++++ 5 files changed, 342 insertions(+), 1 deletion(-) create mode 100644 SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java create mode 100644 SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java create mode 100644 SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java create mode 100644 SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java new file mode 100644 index 00000000..a349e8c0 --- /dev/null +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java @@ -0,0 +1,30 @@ +package de.steamwar.entity; + +import com.comphenix.tinyprotocol.Reflection; +import de.steamwar.core.BountifulWrapper; +import de.steamwar.core.Core; +import lombok.Getter; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.data.BlockData; +import org.bukkit.entity.EntityType; + +public class RBlockDisplay extends RDisplay { + + @Getter + private BlockData block = Material.AIR.createBlockData(); + + public RBlockDisplay(REntityServer server, Location location) { + super(server, EntityType.BLOCK_DISPLAY, location); + } + + private static final Class iBlockDataClass = Reflection.getClass("{nms.world}.level.block.state.IBlockData"); + private static final Reflection.MethodInvoker getState = Reflection.getTypedMethod(Reflection.getClass("{obc}.block.data.CraftBlockData"), "getState", iBlockDataClass); + private static final Object blockWatcher = BountifulWrapper.impl.getDataWatcherObject(23, iBlockDataClass); + public void setBlock(BlockData block) { + this.block = block; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(blockWatcher, getState.invoke(block))); + } + } +} diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java new file mode 100644 index 00000000..2cc86492 --- /dev/null +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java @@ -0,0 +1,154 @@ +package de.steamwar.entity; + +import de.steamwar.core.BountifulWrapper; +import de.steamwar.core.Core; +import lombok.Getter; +import lombok.NonNull; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.entity.Display; +import org.bukkit.entity.EntityType; +import org.bukkit.util.Transformation; +import org.joml.Quaternionf; +import org.joml.Vector3f; + +public class RDisplay extends REntity { + + @Getter + private Transformation transform = new Transformation(new Vector3f(), new Quaternionf(0, 0, 0, 1), new Vector3f(1, 1, 1), new Quaternionf(0, 0, 0, 1)); + + @Getter + private int interpolationDuration = 0; + + @Getter + private float viewRange = 1.0F; + + @Getter + private float shadowRadius = 0.0F; + + @Getter + private float shadowStrength = 1.0F; + + @Getter + private float displayWidth = 0.0F; + + @Getter + private float displayHeight = 0.0F; + + @Getter + private int interpolationDelay = 0; + + @Getter + private Display.Billboard billboard = Display.Billboard.FIXED; + + @Getter + private Color glowColorOverride = null; + + @Getter + private Display.Brightness brightness = null; + + protected RDisplay(REntityServer server, EntityType entityType, Location location) { + super(server, entityType, location); + } + + private static final Object translationWatcher = BountifulWrapper.impl.getDataWatcherObject(10, Vector3f.class); + private static final Object leftRotationWatcher = BountifulWrapper.impl.getDataWatcherObject(12, Quaternionf.class); + private static final Object scaleWatcher = BountifulWrapper.impl.getDataWatcherObject(11, Vector3f.class); + private static final Object rightRotationWatcher = BountifulWrapper.impl.getDataWatcherObject(13, Quaternionf.class); + public void setTransform(@NonNull Transformation transform) { + this.transform = transform; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(translationWatcher, transform.getTranslation())); + server.updateEntity(this, getDataWatcherPacket(leftRotationWatcher, transform.getLeftRotation())); + server.updateEntity(this, getDataWatcherPacket(scaleWatcher, transform.getScale())); + server.updateEntity(this, getDataWatcherPacket(rightRotationWatcher, transform.getRightRotation())); + } + } + + private static final Object transformationInterpolationDurationWatcher = BountifulWrapper.impl.getDataWatcherObject(9, Integer.class); + private static final Object positionOrRotationInterpolationDurationWatcher = BountifulWrapper.impl.getDataWatcherObject(10, Integer.class); + public void setInterpolationDuration(int interpolationDuration) { + this.interpolationDuration = interpolationDuration; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(transformationInterpolationDurationWatcher, interpolationDuration)); + server.updateEntity(this, getDataWatcherPacket(positionOrRotationInterpolationDurationWatcher, interpolationDuration)); + } + } + + private static final Object viewRangeWatcher = BountifulWrapper.impl.getDataWatcherObject(17, Float.class); + public void setViewRange(float viewRange) { + this.viewRange = viewRange; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(viewRangeWatcher, viewRange)); + } + } + + private static final Object shadowRadiusWatcher = BountifulWrapper.impl.getDataWatcherObject(18, Float.class); + public void setShadowRadius(float shadowRadius) { + this.shadowRadius = shadowRadius; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(shadowRadiusWatcher, shadowRadius)); + } + } + + private static final Object shadowStrengthWatcher = BountifulWrapper.impl.getDataWatcherObject(19, Float.class); + public void setShadowStrength(float shadowStrength) { + this.shadowStrength = shadowStrength; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(shadowStrengthWatcher, shadowStrength)); + } + } + + private static final Object displayWidthWatcher = BountifulWrapper.impl.getDataWatcherObject(20, Float.class); + public void setDisplayWidth(float displayWidth) { + this.displayWidth = displayWidth; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(displayWidthWatcher, displayWidth)); + } + } + + private static final Object displayHeightWatcher = BountifulWrapper.impl.getDataWatcherObject(21, Float.class); + public void setDisplayHeight(float displayHeight) { + this.displayHeight = displayHeight; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(displayHeightWatcher, displayHeight)); + } + } + + private static final Object interpolationDelayWatcher = BountifulWrapper.impl.getDataWatcherObject(22, Integer.class); + public void setInterpolationDelay(int interpolationDelay) { + this.interpolationDelay = interpolationDelay; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(interpolationDelayWatcher, interpolationDelay)); + } + } + + private static final Object billboardWatcher = BountifulWrapper.impl.getDataWatcherObject(15, Byte.class); + public void setBillboard(Display.Billboard billboard) { + this.billboard = billboard; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(billboardWatcher, (byte) billboard.ordinal())); + } + } + + private static final Object glowColorOverrideWatcher = BountifulWrapper.impl.getDataWatcherObject(3, Integer.class); + public void setGlowColorOverride(Color glowColorOverride) { + this.glowColorOverride = glowColorOverride; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(glowColorOverrideWatcher, glowColorOverride == null ? -1 : glowColorOverride.asARGB())); + } + } + + private static final Object brightnessWatcher = BountifulWrapper.impl.getDataWatcherObject(16, Integer.class); + public void setBrightness(Display.Brightness brightness) { + this.brightness = brightness; + if (Core.getVersion() >= 20) { + if (brightness == null) { + server.updateEntity(this, getDataWatcherPacket(brightnessWatcher, -1)); + } else { + int brightnessData = brightness.getBlockLight() << 4 | brightness.getSkyLight() << 20; + server.updateEntity(this, getDataWatcherPacket(brightnessWatcher, brightnessData)); + } + } + } +} diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java index e7ecb1a8..66c13c40 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java @@ -45,7 +45,7 @@ public class REntity { private static int entityIdCounter = -1; private static final Random random = new Random(); - private final REntityServer server; + protected final REntityServer server; private final EntityType entityType; @Getter protected final int entityId; diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java new file mode 100644 index 00000000..c45db756 --- /dev/null +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java @@ -0,0 +1,41 @@ +package de.steamwar.entity; + +import com.comphenix.tinyprotocol.Reflection; +import de.steamwar.core.BountifulWrapper; +import de.steamwar.core.Core; +import lombok.Getter; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.ItemDisplay; +import org.bukkit.inventory.ItemStack; + +public class RItemDisplay extends RDisplay { + + @Getter + private ItemStack itemStack; + + @Getter + private ItemDisplay.ItemDisplayTransform itemDisplayTransform; + + public RItemDisplay(REntityServer server, Location location) { + super(server, EntityType.ITEM_DISPLAY, location); + } + + private static final Class itemStackClass = Reflection.getClass("{nms.world}.item.ItemStack"); + private static final Reflection.MethodInvoker asNMSCopy = Reflection.getTypedMethod(Reflection.getClass("{obc}.inventory.CraftItemStack"), "asNMSCopy", itemStackClass); + private static final Object itemStackWatcher = BountifulWrapper.impl.getDataWatcherObject(23, itemStackClass); + public void setItemStack(ItemStack itemStack) { + this.itemStack = itemStack; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(itemStackWatcher, asNMSCopy.invoke(itemStack))); + } + } + + private static final Object itemDisplayTransformWatcher = BountifulWrapper.impl.getDataWatcherObject(24, Byte.class); + public void setItemDisplayTransform(ItemDisplay.ItemDisplayTransform itemDisplayTransform) { + this.itemDisplayTransform = itemDisplayTransform; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(itemDisplayTransformWatcher, (byte) itemDisplayTransform.ordinal())); + } + } +} diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java new file mode 100644 index 00000000..459dd9e8 --- /dev/null +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java @@ -0,0 +1,116 @@ +package de.steamwar.entity; + +import com.comphenix.tinyprotocol.Reflection; +import de.steamwar.core.BountifulWrapper; +import de.steamwar.core.ChatWrapper; +import de.steamwar.core.Core; +import lombok.Getter; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.TextDisplay; + +public class RTextDisplay extends RDisplay { + + @Getter + private String text = ""; + + @Getter + private int lineWidth = 200; + + @Getter + private byte textOpacity = (byte) -1; + + @Getter + private boolean shadowed = false; + + @Getter + private boolean seeThrough = false; + + @Getter + private boolean defaultBackground = false; + + @Getter + private TextDisplay.TextAlignment alignment = TextDisplay.TextAlignment.CENTER; + + public RTextDisplay(REntityServer server, Location location) { + super(server, EntityType.TEXT_DISPLAY, location); + } + + private static final Class iChatBaseComponent = Reflection.getClass("{nms.network.chat}.IChatBaseComponent"); + private static final Object textWatcher = BountifulWrapper.impl.getDataWatcherObject(23, iChatBaseComponent); + public void setText(String text) { + this.text = text; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(textWatcher, ChatWrapper.impl.stringToChatComponent(text))); + } + } + + private static final Object lineWidthWatcher = BountifulWrapper.impl.getDataWatcherObject(24, Integer.class); + public void setLineWidth(int lineWidth) { + this.lineWidth = lineWidth; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(lineWidthWatcher, lineWidth)); + } + } + + private static final Object textOpacityWatcher = BountifulWrapper.impl.getDataWatcherObject(26, Byte.class); + public void setTextOpacity(byte textOpacity) { + this.textOpacity = textOpacity; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(textOpacityWatcher, textOpacity)); + } + } + + private static final Object textStatusWatcher = BountifulWrapper.impl.getDataWatcherObject(27, Byte.class); + + public void setShadowed(boolean shadowed) { + this.shadowed = shadowed; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(textStatusWatcher, getTextStatus())); + } + } + + public void setSeeThrough(boolean seeThrough) { + this.seeThrough = seeThrough; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(textStatusWatcher, getTextStatus())); + } + } + + public void setDefaultBackground(boolean defaultBackground) { + this.defaultBackground = defaultBackground; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(textStatusWatcher, getTextStatus())); + } + } + + public void setAlignment(TextDisplay.TextAlignment alignment) { + this.alignment = alignment; + if (Core.getVersion() >= 20) { + server.updateEntity(this, getDataWatcherPacket(textStatusWatcher, getTextStatus())); + } + } + + private byte getTextStatus() { + byte status = 0; + + if (shadowed) { + status |= 0x01; + } + if (seeThrough) { + status |= 0x02; + } + if (defaultBackground) { + status |= 0x04; + } + if (alignment == TextDisplay.TextAlignment.CENTER) { + // Do nothing + } else if (alignment == TextDisplay.TextAlignment.LEFT) { + status |= 0x08; + } else if (alignment == TextDisplay.TextAlignment.RIGHT) { + status |= 0x0F; + } + + return status; + } +} From 33f41869b601c056c5430a2b24cc050b4d845db2 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 28 Dec 2024 16:08:50 +0100 Subject: [PATCH 004/124] Fix packets --- .../src/de/steamwar/entity/RBlockDisplay.java | 4 +-- .../src/de/steamwar/entity/RDisplay.java | 36 +++++++------------ .../src/de/steamwar/entity/RItemDisplay.java | 11 +++--- .../src/de/steamwar/entity/RTextDisplay.java | 16 +++------ 4 files changed, 25 insertions(+), 42 deletions(-) diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java index a349e8c0..6dbb8fb2 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java @@ -9,9 +9,9 @@ import org.bukkit.Material; import org.bukkit.block.data.BlockData; import org.bukkit.entity.EntityType; +@Getter public class RBlockDisplay extends RDisplay { - @Getter private BlockData block = Material.AIR.createBlockData(); public RBlockDisplay(REntityServer server, Location location) { @@ -20,7 +20,7 @@ public class RBlockDisplay extends RDisplay { private static final Class iBlockDataClass = Reflection.getClass("{nms.world}.level.block.state.IBlockData"); private static final Reflection.MethodInvoker getState = Reflection.getTypedMethod(Reflection.getClass("{obc}.block.data.CraftBlockData"), "getState", iBlockDataClass); - private static final Object blockWatcher = BountifulWrapper.impl.getDataWatcherObject(23, iBlockDataClass); + private static final Object blockWatcher = BountifulWrapper.impl.getDataWatcherObject(22, iBlockDataClass); public void setBlock(BlockData block) { this.block = block; if (Core.getVersion() >= 20) { diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java index 2cc86492..39a8615a 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java @@ -12,39 +12,29 @@ import org.bukkit.util.Transformation; import org.joml.Quaternionf; import org.joml.Vector3f; -public class RDisplay extends REntity { +@Getter +public abstract class RDisplay extends REntity { - @Getter private Transformation transform = new Transformation(new Vector3f(), new Quaternionf(0, 0, 0, 1), new Vector3f(1, 1, 1), new Quaternionf(0, 0, 0, 1)); - @Getter private int interpolationDuration = 0; - @Getter private float viewRange = 1.0F; - @Getter private float shadowRadius = 0.0F; - @Getter private float shadowStrength = 1.0F; - @Getter private float displayWidth = 0.0F; - @Getter private float displayHeight = 0.0F; - @Getter private int interpolationDelay = 0; - @Getter private Display.Billboard billboard = Display.Billboard.FIXED; - @Getter private Color glowColorOverride = null; - @Getter private Display.Brightness brightness = null; protected RDisplay(REntityServer server, EntityType entityType, Location location) { @@ -65,8 +55,8 @@ public class RDisplay extends REntity { } } - private static final Object transformationInterpolationDurationWatcher = BountifulWrapper.impl.getDataWatcherObject(9, Integer.class); - private static final Object positionOrRotationInterpolationDurationWatcher = BountifulWrapper.impl.getDataWatcherObject(10, Integer.class); + private static final Object transformationInterpolationDurationWatcher = BountifulWrapper.impl.getDataWatcherObject(8, Integer.class); + private static final Object positionOrRotationInterpolationDurationWatcher = BountifulWrapper.impl.getDataWatcherObject(9, Integer.class); public void setInterpolationDuration(int interpolationDuration) { this.interpolationDuration = interpolationDuration; if (Core.getVersion() >= 20) { @@ -75,7 +65,7 @@ public class RDisplay extends REntity { } } - private static final Object viewRangeWatcher = BountifulWrapper.impl.getDataWatcherObject(17, Float.class); + private static final Object viewRangeWatcher = BountifulWrapper.impl.getDataWatcherObject(16, Float.class); public void setViewRange(float viewRange) { this.viewRange = viewRange; if (Core.getVersion() >= 20) { @@ -83,7 +73,7 @@ public class RDisplay extends REntity { } } - private static final Object shadowRadiusWatcher = BountifulWrapper.impl.getDataWatcherObject(18, Float.class); + private static final Object shadowRadiusWatcher = BountifulWrapper.impl.getDataWatcherObject(17, Float.class); public void setShadowRadius(float shadowRadius) { this.shadowRadius = shadowRadius; if (Core.getVersion() >= 20) { @@ -91,7 +81,7 @@ public class RDisplay extends REntity { } } - private static final Object shadowStrengthWatcher = BountifulWrapper.impl.getDataWatcherObject(19, Float.class); + private static final Object shadowStrengthWatcher = BountifulWrapper.impl.getDataWatcherObject(18, Float.class); public void setShadowStrength(float shadowStrength) { this.shadowStrength = shadowStrength; if (Core.getVersion() >= 20) { @@ -99,7 +89,7 @@ public class RDisplay extends REntity { } } - private static final Object displayWidthWatcher = BountifulWrapper.impl.getDataWatcherObject(20, Float.class); + private static final Object displayWidthWatcher = BountifulWrapper.impl.getDataWatcherObject(19, Float.class); public void setDisplayWidth(float displayWidth) { this.displayWidth = displayWidth; if (Core.getVersion() >= 20) { @@ -107,7 +97,7 @@ public class RDisplay extends REntity { } } - private static final Object displayHeightWatcher = BountifulWrapper.impl.getDataWatcherObject(21, Float.class); + private static final Object displayHeightWatcher = BountifulWrapper.impl.getDataWatcherObject(20, Float.class); public void setDisplayHeight(float displayHeight) { this.displayHeight = displayHeight; if (Core.getVersion() >= 20) { @@ -115,7 +105,7 @@ public class RDisplay extends REntity { } } - private static final Object interpolationDelayWatcher = BountifulWrapper.impl.getDataWatcherObject(22, Integer.class); + private static final Object interpolationDelayWatcher = BountifulWrapper.impl.getDataWatcherObject(7, Integer.class); public void setInterpolationDelay(int interpolationDelay) { this.interpolationDelay = interpolationDelay; if (Core.getVersion() >= 20) { @@ -123,7 +113,7 @@ public class RDisplay extends REntity { } } - private static final Object billboardWatcher = BountifulWrapper.impl.getDataWatcherObject(15, Byte.class); + private static final Object billboardWatcher = BountifulWrapper.impl.getDataWatcherObject(14, Byte.class); public void setBillboard(Display.Billboard billboard) { this.billboard = billboard; if (Core.getVersion() >= 20) { @@ -131,7 +121,7 @@ public class RDisplay extends REntity { } } - private static final Object glowColorOverrideWatcher = BountifulWrapper.impl.getDataWatcherObject(3, Integer.class); + private static final Object glowColorOverrideWatcher = BountifulWrapper.impl.getDataWatcherObject(21, Integer.class); public void setGlowColorOverride(Color glowColorOverride) { this.glowColorOverride = glowColorOverride; if (Core.getVersion() >= 20) { @@ -139,7 +129,7 @@ public class RDisplay extends REntity { } } - private static final Object brightnessWatcher = BountifulWrapper.impl.getDataWatcherObject(16, Integer.class); + private static final Object brightnessWatcher = BountifulWrapper.impl.getDataWatcherObject(15, Integer.class); public void setBrightness(Display.Brightness brightness) { this.brightness = brightness; if (Core.getVersion() >= 20) { diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java index c45db756..0f546957 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java @@ -9,12 +9,11 @@ import org.bukkit.entity.EntityType; import org.bukkit.entity.ItemDisplay; import org.bukkit.inventory.ItemStack; +@Getter public class RItemDisplay extends RDisplay { - @Getter private ItemStack itemStack; - @Getter private ItemDisplay.ItemDisplayTransform itemDisplayTransform; public RItemDisplay(REntityServer server, Location location) { @@ -22,16 +21,16 @@ public class RItemDisplay extends RDisplay { } private static final Class itemStackClass = Reflection.getClass("{nms.world}.item.ItemStack"); - private static final Reflection.MethodInvoker asNMSCopy = Reflection.getTypedMethod(Reflection.getClass("{obc}.inventory.CraftItemStack"), "asNMSCopy", itemStackClass); - private static final Object itemStackWatcher = BountifulWrapper.impl.getDataWatcherObject(23, itemStackClass); + private static final Reflection.MethodInvoker asNMSCopy = Reflection.getTypedMethod(Reflection.getClass("{obc}.inventory.CraftItemStack"), "asNMSCopy", itemStackClass, ItemStack.class); + private static final Object itemStackWatcher = BountifulWrapper.impl.getDataWatcherObject(22, itemStackClass); public void setItemStack(ItemStack itemStack) { this.itemStack = itemStack; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(itemStackWatcher, asNMSCopy.invoke(itemStack))); + server.updateEntity(this, getDataWatcherPacket(itemStackWatcher, asNMSCopy.invoke(null, itemStack))); } } - private static final Object itemDisplayTransformWatcher = BountifulWrapper.impl.getDataWatcherObject(24, Byte.class); + private static final Object itemDisplayTransformWatcher = BountifulWrapper.impl.getDataWatcherObject(23, Byte.class); public void setItemDisplayTransform(ItemDisplay.ItemDisplayTransform itemDisplayTransform) { this.itemDisplayTransform = itemDisplayTransform; if (Core.getVersion() >= 20) { diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java index 459dd9e8..49136d19 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java @@ -9,27 +9,21 @@ import org.bukkit.Location; import org.bukkit.entity.EntityType; import org.bukkit.entity.TextDisplay; +@Getter public class RTextDisplay extends RDisplay { - @Getter private String text = ""; - @Getter private int lineWidth = 200; - @Getter private byte textOpacity = (byte) -1; - @Getter private boolean shadowed = false; - @Getter private boolean seeThrough = false; - @Getter private boolean defaultBackground = false; - @Getter private TextDisplay.TextAlignment alignment = TextDisplay.TextAlignment.CENTER; public RTextDisplay(REntityServer server, Location location) { @@ -37,7 +31,7 @@ public class RTextDisplay extends RDisplay { } private static final Class iChatBaseComponent = Reflection.getClass("{nms.network.chat}.IChatBaseComponent"); - private static final Object textWatcher = BountifulWrapper.impl.getDataWatcherObject(23, iChatBaseComponent); + private static final Object textWatcher = BountifulWrapper.impl.getDataWatcherObject(22, iChatBaseComponent); public void setText(String text) { this.text = text; if (Core.getVersion() >= 20) { @@ -45,7 +39,7 @@ public class RTextDisplay extends RDisplay { } } - private static final Object lineWidthWatcher = BountifulWrapper.impl.getDataWatcherObject(24, Integer.class); + private static final Object lineWidthWatcher = BountifulWrapper.impl.getDataWatcherObject(23, Integer.class); public void setLineWidth(int lineWidth) { this.lineWidth = lineWidth; if (Core.getVersion() >= 20) { @@ -53,7 +47,7 @@ public class RTextDisplay extends RDisplay { } } - private static final Object textOpacityWatcher = BountifulWrapper.impl.getDataWatcherObject(26, Byte.class); + private static final Object textOpacityWatcher = BountifulWrapper.impl.getDataWatcherObject(25, Byte.class); public void setTextOpacity(byte textOpacity) { this.textOpacity = textOpacity; if (Core.getVersion() >= 20) { @@ -61,7 +55,7 @@ public class RTextDisplay extends RDisplay { } } - private static final Object textStatusWatcher = BountifulWrapper.impl.getDataWatcherObject(27, Byte.class); + private static final Object textStatusWatcher = BountifulWrapper.impl.getDataWatcherObject(26, Byte.class); public void setShadowed(boolean shadowed) { this.shadowed = shadowed; From 3c848389c92c49ac391253e03634c9189cc9423e Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 28 Dec 2024 16:28:56 +0100 Subject: [PATCH 005/124] Update structure --- .../src/de/steamwar/entity/RBlockDisplay.java | 20 ++- .../src/de/steamwar/entity/RDisplay.java | 148 +++++++++++++----- .../src/de/steamwar/entity/RItemDisplay.java | 27 +++- .../src/de/steamwar/entity/RTextDisplay.java | 60 ++++--- 4 files changed, 184 insertions(+), 71 deletions(-) diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java index 6dbb8fb2..53753962 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java @@ -9,6 +9,8 @@ import org.bukkit.Material; import org.bukkit.block.data.BlockData; import org.bukkit.entity.EntityType; +import java.util.function.Consumer; + @Getter public class RBlockDisplay extends RDisplay { @@ -18,13 +20,23 @@ public class RBlockDisplay extends RDisplay { super(server, EntityType.BLOCK_DISPLAY, location); } - private static final Class iBlockDataClass = Reflection.getClass("{nms.world}.level.block.state.IBlockData"); - private static final Reflection.MethodInvoker getState = Reflection.getTypedMethod(Reflection.getClass("{obc}.block.data.CraftBlockData"), "getState", iBlockDataClass); - private static final Object blockWatcher = BountifulWrapper.impl.getDataWatcherObject(22, iBlockDataClass); + @Override + protected void postSpawn(Consumer packetSink) { + super.postSpawn(packetSink); + sendBlock(packetSink); + } + public void setBlock(BlockData block) { this.block = block; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(blockWatcher, getState.invoke(block))); + sendBlock(o -> server.updateEntity(this, o)); } } + + private static final Class iBlockDataClass = Reflection.getClass("{nms.world}.level.block.state.IBlockData"); + private static final Reflection.MethodInvoker getState = Reflection.getTypedMethod(Reflection.getClass("{obc}.block.data.CraftBlockData"), "getState", iBlockDataClass); + private static final Object blockWatcher = BountifulWrapper.impl.getDataWatcherObject(22, iBlockDataClass); + private void sendBlock(Consumer packetSink) { + packetSink.accept(getDataWatcherPacket(blockWatcher, getState.invoke(block))); + } } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java index 39a8615a..a8819859 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java @@ -12,6 +12,8 @@ import org.bukkit.util.Transformation; import org.joml.Quaternionf; import org.joml.Vector3f; +import java.util.function.Consumer; + @Getter public abstract class RDisplay extends REntity { @@ -41,104 +43,164 @@ public abstract class RDisplay extends REntity { super(server, entityType, location); } + @Override + protected void postSpawn(Consumer packetSink) { + super.postSpawn(packetSink); + sendTransform(packetSink); + sendInterpolationDuration(packetSink); + sendViewRange(packetSink); + sendShadowRadius(packetSink); + sendShadowStrength(packetSink); + sendDisplayWidth(packetSink); + sendDisplayHeight(packetSink); + sendInterpolationDelay(packetSink); + sendBillboard(packetSink); + sendGlowColorOverride(packetSink); + sendBrightness(packetSink); + } + + public void setTransform(@NonNull Transformation transform) { + this.transform = transform; + if (Core.getVersion() >= 20) { + sendTransform(o -> server.updateEntity(this, o)); + } + } + private static final Object translationWatcher = BountifulWrapper.impl.getDataWatcherObject(10, Vector3f.class); private static final Object leftRotationWatcher = BountifulWrapper.impl.getDataWatcherObject(12, Quaternionf.class); private static final Object scaleWatcher = BountifulWrapper.impl.getDataWatcherObject(11, Vector3f.class); private static final Object rightRotationWatcher = BountifulWrapper.impl.getDataWatcherObject(13, Quaternionf.class); - public void setTransform(@NonNull Transformation transform) { - this.transform = transform; + private void sendTransform(Consumer packetSink) { + packetSink.accept(getDataWatcherPacket(translationWatcher, transform.getTranslation())); + packetSink.accept(getDataWatcherPacket(leftRotationWatcher, transform.getLeftRotation())); + packetSink.accept(getDataWatcherPacket(scaleWatcher, transform.getScale())); + packetSink.accept(getDataWatcherPacket(rightRotationWatcher, transform.getRightRotation())); + } + + public void setInterpolationDuration(int interpolationDuration) { + this.interpolationDuration = interpolationDuration; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(translationWatcher, transform.getTranslation())); - server.updateEntity(this, getDataWatcherPacket(leftRotationWatcher, transform.getLeftRotation())); - server.updateEntity(this, getDataWatcherPacket(scaleWatcher, transform.getScale())); - server.updateEntity(this, getDataWatcherPacket(rightRotationWatcher, transform.getRightRotation())); + sendInterpolationDuration(o -> server.updateEntity(this, o)); } } private static final Object transformationInterpolationDurationWatcher = BountifulWrapper.impl.getDataWatcherObject(8, Integer.class); private static final Object positionOrRotationInterpolationDurationWatcher = BountifulWrapper.impl.getDataWatcherObject(9, Integer.class); - public void setInterpolationDuration(int interpolationDuration) { - this.interpolationDuration = interpolationDuration; + private void sendInterpolationDuration(Consumer packetSink) { + packetSink.accept(getDataWatcherPacket(transformationInterpolationDurationWatcher, interpolationDuration)); + packetSink.accept(getDataWatcherPacket(positionOrRotationInterpolationDurationWatcher, interpolationDuration)); + } + + public void setViewRange(float viewRange) { + this.viewRange = viewRange; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(transformationInterpolationDurationWatcher, interpolationDuration)); - server.updateEntity(this, getDataWatcherPacket(positionOrRotationInterpolationDurationWatcher, interpolationDuration)); + sendViewRange(o -> server.updateEntity(this, o)); } } private static final Object viewRangeWatcher = BountifulWrapper.impl.getDataWatcherObject(16, Float.class); - public void setViewRange(float viewRange) { - this.viewRange = viewRange; + private void sendViewRange(Consumer packetSink) { + packetSink.accept(getDataWatcherPacket(viewRangeWatcher, viewRange)); + } + + public void setShadowRadius(float shadowRadius) { + this.shadowRadius = shadowRadius; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(viewRangeWatcher, viewRange)); + sendShadowRadius(o -> server.updateEntity(this, o)); } } private static final Object shadowRadiusWatcher = BountifulWrapper.impl.getDataWatcherObject(17, Float.class); - public void setShadowRadius(float shadowRadius) { - this.shadowRadius = shadowRadius; + private void sendShadowRadius(Consumer packetSink) { + packetSink.accept(getDataWatcherPacket(shadowRadiusWatcher, shadowRadius)); + } + + public void setShadowStrength(float shadowStrength) { + this.shadowStrength = shadowStrength; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(shadowRadiusWatcher, shadowRadius)); + sendShadowStrength(o -> server.updateEntity(this, o)); } } private static final Object shadowStrengthWatcher = BountifulWrapper.impl.getDataWatcherObject(18, Float.class); - public void setShadowStrength(float shadowStrength) { - this.shadowStrength = shadowStrength; + private void sendShadowStrength(Consumer packetSink) { + packetSink.accept(getDataWatcherPacket(shadowStrengthWatcher, shadowStrength)); + } + + public void setDisplayWidth(float displayWidth) { + this.displayWidth = displayWidth; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(shadowStrengthWatcher, shadowStrength)); + sendDisplayWidth(o -> server.updateEntity(this, o)); } } private static final Object displayWidthWatcher = BountifulWrapper.impl.getDataWatcherObject(19, Float.class); - public void setDisplayWidth(float displayWidth) { - this.displayWidth = displayWidth; + private void sendDisplayWidth(Consumer packetSink) { + packetSink.accept(getDataWatcherPacket(displayWidthWatcher, displayWidth)); + } + + public void setDisplayHeight(float displayHeight) { + this.displayHeight = displayHeight; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(displayWidthWatcher, displayWidth)); + sendDisplayHeight(o -> server.updateEntity(this, o)); } } private static final Object displayHeightWatcher = BountifulWrapper.impl.getDataWatcherObject(20, Float.class); - public void setDisplayHeight(float displayHeight) { - this.displayHeight = displayHeight; + private void sendDisplayHeight(Consumer packetSink) { + packetSink.accept(getDataWatcherPacket(displayHeightWatcher, displayHeight)); + } + + public void setInterpolationDelay(int interpolationDelay) { + this.interpolationDelay = interpolationDelay; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(displayHeightWatcher, displayHeight)); + sendInterpolationDelay(o -> server.updateEntity(this, o)); } } private static final Object interpolationDelayWatcher = BountifulWrapper.impl.getDataWatcherObject(7, Integer.class); - public void setInterpolationDelay(int interpolationDelay) { - this.interpolationDelay = interpolationDelay; + private void sendInterpolationDelay(Consumer packetSink) { + packetSink.accept(getDataWatcherPacket(interpolationDelayWatcher, interpolationDelay)); + } + + public void setBillboard(Display.Billboard billboard) { + this.billboard = billboard; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(interpolationDelayWatcher, interpolationDelay)); + sendBillboard(o -> server.updateEntity(this, o)); } } private static final Object billboardWatcher = BountifulWrapper.impl.getDataWatcherObject(14, Byte.class); - public void setBillboard(Display.Billboard billboard) { - this.billboard = billboard; + private void sendBillboard(Consumer packetSink) { + packetSink.accept(getDataWatcherPacket(billboardWatcher, (byte) billboard.ordinal())); + } + + public void setGlowColorOverride(Color glowColorOverride) { + this.glowColorOverride = glowColorOverride; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(billboardWatcher, (byte) billboard.ordinal())); + sendGlowColorOverride(o -> server.updateEntity(this, o)); } } private static final Object glowColorOverrideWatcher = BountifulWrapper.impl.getDataWatcherObject(21, Integer.class); - public void setGlowColorOverride(Color glowColorOverride) { - this.glowColorOverride = glowColorOverride; + private void sendGlowColorOverride(Consumer packetSink) { + packetSink.accept(getDataWatcherPacket(glowColorOverrideWatcher, glowColorOverride)); + } + + public void setBrightness(Display.Brightness brightness) { + this.brightness = brightness; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(glowColorOverrideWatcher, glowColorOverride == null ? -1 : glowColorOverride.asARGB())); + sendBrightness(o -> server.updateEntity(this, o)); } } private static final Object brightnessWatcher = BountifulWrapper.impl.getDataWatcherObject(15, Integer.class); - public void setBrightness(Display.Brightness brightness) { - this.brightness = brightness; - if (Core.getVersion() >= 20) { - if (brightness == null) { - server.updateEntity(this, getDataWatcherPacket(brightnessWatcher, -1)); - } else { - int brightnessData = brightness.getBlockLight() << 4 | brightness.getSkyLight() << 20; - server.updateEntity(this, getDataWatcherPacket(brightnessWatcher, brightnessData)); - } + private void sendBrightness(Consumer packetSink) { + if (brightness == null) { + packetSink.accept(getDataWatcherPacket(brightnessWatcher, -1)); + } else { + int brightnessData = brightness.getBlockLight() << 4 | brightness.getSkyLight() << 20; + packetSink.accept(getDataWatcherPacket(brightnessWatcher, brightnessData)); } } } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java index 0f546957..5b0f10bd 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java @@ -9,6 +9,8 @@ import org.bukkit.entity.EntityType; import org.bukkit.entity.ItemDisplay; import org.bukkit.inventory.ItemStack; +import java.util.function.Consumer; + @Getter public class RItemDisplay extends RDisplay { @@ -20,21 +22,36 @@ public class RItemDisplay extends RDisplay { super(server, EntityType.ITEM_DISPLAY, location); } - private static final Class itemStackClass = Reflection.getClass("{nms.world}.item.ItemStack"); - private static final Reflection.MethodInvoker asNMSCopy = Reflection.getTypedMethod(Reflection.getClass("{obc}.inventory.CraftItemStack"), "asNMSCopy", itemStackClass, ItemStack.class); - private static final Object itemStackWatcher = BountifulWrapper.impl.getDataWatcherObject(22, itemStackClass); + @Override + protected void postSpawn(Consumer packetSink) { + super.postSpawn(packetSink); + sendItemStack(packetSink); + sendItemDisplayTransform(packetSink); + } + public void setItemStack(ItemStack itemStack) { this.itemStack = itemStack; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(itemStackWatcher, asNMSCopy.invoke(null, itemStack))); + sendItemStack(o -> server.updateEntity(this, o)); } } + private static final Class itemStackClass = Reflection.getClass("{nms.world}.item.ItemStack"); + private static final Reflection.MethodInvoker asNMSCopy = Reflection.getTypedMethod(Reflection.getClass("{obc}.inventory.CraftItemStack"), "asNMSCopy", itemStackClass, ItemStack.class); + private static final Object itemStackWatcher = BountifulWrapper.impl.getDataWatcherObject(22, itemStackClass); + private void sendItemStack(Consumer packetSink) { + packetSink.accept(getDataWatcherPacket(itemStackWatcher, asNMSCopy.invoke(null, itemStack))); + } + private static final Object itemDisplayTransformWatcher = BountifulWrapper.impl.getDataWatcherObject(23, Byte.class); public void setItemDisplayTransform(ItemDisplay.ItemDisplayTransform itemDisplayTransform) { this.itemDisplayTransform = itemDisplayTransform; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(itemDisplayTransformWatcher, (byte) itemDisplayTransform.ordinal())); + sendItemDisplayTransform(o -> server.updateEntity(this, o)); } } + + private void sendItemDisplayTransform(Consumer packetSink) { + packetSink.accept(getDataWatcherPacket(itemDisplayTransformWatcher, (byte) itemDisplayTransform.ordinal())); + } } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java index 49136d19..65e3dc2f 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java @@ -9,6 +9,8 @@ import org.bukkit.Location; import org.bukkit.entity.EntityType; import org.bukkit.entity.TextDisplay; +import java.util.function.Consumer; + @Getter public class RTextDisplay extends RDisplay { @@ -30,62 +32,82 @@ public class RTextDisplay extends RDisplay { super(server, EntityType.TEXT_DISPLAY, location); } - private static final Class iChatBaseComponent = Reflection.getClass("{nms.network.chat}.IChatBaseComponent"); - private static final Object textWatcher = BountifulWrapper.impl.getDataWatcherObject(22, iChatBaseComponent); + @Override + protected void postSpawn(Consumer packetSink) { + super.postSpawn(packetSink); + sendText(packetSink); + sendLineWidth(packetSink); + sendTextOpacity(packetSink); + sendTextStatus(packetSink); + } + public void setText(String text) { this.text = text; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(textWatcher, ChatWrapper.impl.stringToChatComponent(text))); + sendText(o -> server.updateEntity(this, o)); + } + } + + private static final Class iChatBaseComponent = Reflection.getClass("{nms.network.chat}.IChatBaseComponent"); + private static final Object textWatcher = BountifulWrapper.impl.getDataWatcherObject(22, iChatBaseComponent); + private void sendText(Consumer packetSink) { + packetSink.accept(getDataWatcherPacket(textWatcher, ChatWrapper.impl.stringToChatComponent(text))); + } + + public void setLineWidth(int lineWidth) { + this.lineWidth = lineWidth; + if (Core.getVersion() >= 20) { + sendLineWidth(o -> server.updateEntity(this, o)); } } private static final Object lineWidthWatcher = BountifulWrapper.impl.getDataWatcherObject(23, Integer.class); - public void setLineWidth(int lineWidth) { - this.lineWidth = lineWidth; + private void sendLineWidth(Consumer packetSink) { + packetSink.accept(getDataWatcherPacket(lineWidthWatcher, lineWidth)); + } + + public void setTextOpacity(byte textOpacity) { + this.textOpacity = textOpacity; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(lineWidthWatcher, lineWidth)); + sendTextOpacity(o -> server.updateEntity(this, o)); } } private static final Object textOpacityWatcher = BountifulWrapper.impl.getDataWatcherObject(25, Byte.class); - public void setTextOpacity(byte textOpacity) { - this.textOpacity = textOpacity; - if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(textOpacityWatcher, textOpacity)); - } + private void sendTextOpacity(Consumer packetSink) { + packetSink.accept(getDataWatcherPacket(textOpacityWatcher, textOpacity)); } - private static final Object textStatusWatcher = BountifulWrapper.impl.getDataWatcherObject(26, Byte.class); - public void setShadowed(boolean shadowed) { this.shadowed = shadowed; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(textStatusWatcher, getTextStatus())); + sendTextStatus(o -> server.updateEntity(this, o)); } } public void setSeeThrough(boolean seeThrough) { this.seeThrough = seeThrough; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(textStatusWatcher, getTextStatus())); + sendTextStatus(o -> server.updateEntity(this, o)); } } public void setDefaultBackground(boolean defaultBackground) { this.defaultBackground = defaultBackground; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(textStatusWatcher, getTextStatus())); + sendTextStatus(o -> server.updateEntity(this, o)); } } public void setAlignment(TextDisplay.TextAlignment alignment) { this.alignment = alignment; if (Core.getVersion() >= 20) { - server.updateEntity(this, getDataWatcherPacket(textStatusWatcher, getTextStatus())); + sendTextStatus(o -> server.updateEntity(this, o)); } } - private byte getTextStatus() { + private static final Object textStatusWatcher = BountifulWrapper.impl.getDataWatcherObject(26, Byte.class); + private void sendTextStatus(Consumer packetSink) { byte status = 0; if (shadowed) { @@ -105,6 +127,6 @@ public class RTextDisplay extends RDisplay { status |= 0x0F; } - return status; + packetSink.accept(getDataWatcherPacket(textStatusWatcher, status)); } } From 1f65121c680e345394d9665a5857981d00d01f2b Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 1 Jan 2025 13:06:26 +0100 Subject: [PATCH 006/124] Fixup postSpawn because of NPE/Not Initialized Exception --- .../src/de/steamwar/entity/RBlockDisplay.java | 5 +++- .../src/de/steamwar/entity/RDisplay.java | 25 +++++++++++-------- .../src/de/steamwar/entity/RItemDisplay.java | 7 ++++-- .../src/de/steamwar/entity/RTextDisplay.java | 11 +++++--- 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java index 53753962..9041a232 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java @@ -4,6 +4,7 @@ import com.comphenix.tinyprotocol.Reflection; import de.steamwar.core.BountifulWrapper; import de.steamwar.core.Core; import lombok.Getter; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.data.BlockData; @@ -23,7 +24,9 @@ public class RBlockDisplay extends RDisplay { @Override protected void postSpawn(Consumer packetSink) { super.postSpawn(packetSink); - sendBlock(packetSink); + Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> { + sendBlock(packetSink); + }, 0); } public void setBlock(BlockData block) { diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java index a8819859..49186a0c 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java @@ -4,6 +4,7 @@ import de.steamwar.core.BountifulWrapper; import de.steamwar.core.Core; import lombok.Getter; import lombok.NonNull; +import org.bukkit.Bukkit; import org.bukkit.Color; import org.bukkit.Location; import org.bukkit.entity.Display; @@ -46,17 +47,19 @@ public abstract class RDisplay extends REntity { @Override protected void postSpawn(Consumer packetSink) { super.postSpawn(packetSink); - sendTransform(packetSink); - sendInterpolationDuration(packetSink); - sendViewRange(packetSink); - sendShadowRadius(packetSink); - sendShadowStrength(packetSink); - sendDisplayWidth(packetSink); - sendDisplayHeight(packetSink); - sendInterpolationDelay(packetSink); - sendBillboard(packetSink); - sendGlowColorOverride(packetSink); - sendBrightness(packetSink); + Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> { + sendTransform(packetSink); + sendInterpolationDuration(packetSink); + sendViewRange(packetSink); + sendShadowRadius(packetSink); + sendShadowStrength(packetSink); + sendDisplayWidth(packetSink); + sendDisplayHeight(packetSink); + sendInterpolationDelay(packetSink); + sendBillboard(packetSink); + sendGlowColorOverride(packetSink); + sendBrightness(packetSink); + }, 0); } public void setTransform(@NonNull Transformation transform) { diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java index 5b0f10bd..4c290fa7 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java @@ -4,6 +4,7 @@ import com.comphenix.tinyprotocol.Reflection; import de.steamwar.core.BountifulWrapper; import de.steamwar.core.Core; import lombok.Getter; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.EntityType; import org.bukkit.entity.ItemDisplay; @@ -25,8 +26,10 @@ public class RItemDisplay extends RDisplay { @Override protected void postSpawn(Consumer packetSink) { super.postSpawn(packetSink); - sendItemStack(packetSink); - sendItemDisplayTransform(packetSink); + Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> { + sendItemStack(packetSink); + sendItemDisplayTransform(packetSink); + }, 0); } public void setItemStack(ItemStack itemStack) { diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java index 65e3dc2f..d5c459ae 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java @@ -5,6 +5,7 @@ import de.steamwar.core.BountifulWrapper; import de.steamwar.core.ChatWrapper; import de.steamwar.core.Core; import lombok.Getter; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.EntityType; import org.bukkit.entity.TextDisplay; @@ -35,10 +36,12 @@ public class RTextDisplay extends RDisplay { @Override protected void postSpawn(Consumer packetSink) { super.postSpawn(packetSink); - sendText(packetSink); - sendLineWidth(packetSink); - sendTextOpacity(packetSink); - sendTextStatus(packetSink); + Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> { + sendText(packetSink); + sendLineWidth(packetSink); + sendTextOpacity(packetSink); + sendTextStatus(packetSink); + }, 0); } public void setText(String text) { From 82c73f936795982388a89da1c9cc01d5c3214203 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 8 Jan 2025 12:24:17 +0100 Subject: [PATCH 007/124] Fix packet count to at most 2 for the display entities at spawn --- .../src/de/steamwar/entity/RBlockDisplay.java | 24 ++- .../src/de/steamwar/entity/RDisplay.java | 158 +++++++++--------- .../src/de/steamwar/entity/RItemDisplay.java | 35 ++-- .../src/de/steamwar/entity/RTextDisplay.java | 60 +++---- 4 files changed, 131 insertions(+), 146 deletions(-) diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java index 9041a232..9e9c3c42 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java @@ -1,21 +1,22 @@ package de.steamwar.entity; -import com.comphenix.tinyprotocol.Reflection; +import de.steamwar.Reflection; import de.steamwar.core.BountifulWrapper; -import de.steamwar.core.Core; import lombok.Getter; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.data.BlockData; import org.bukkit.entity.EntityType; +import java.util.function.BiConsumer; import java.util.function.Consumer; @Getter public class RBlockDisplay extends RDisplay { - private BlockData block = Material.AIR.createBlockData(); + public static final BlockData DEFAULT_BLOCK = Material.AIR.createBlockData(); + + private BlockData block = DEFAULT_BLOCK; public RBlockDisplay(REntityServer server, Location location) { super(server, EntityType.BLOCK_DISPLAY, location); @@ -24,22 +25,19 @@ public class RBlockDisplay extends RDisplay { @Override protected void postSpawn(Consumer packetSink) { super.postSpawn(packetSink); - Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> { - sendBlock(packetSink); - }, 0); + sendPacket(packetSink, this::getBlock); } public void setBlock(BlockData block) { this.block = block; - if (Core.getVersion() >= 20) { - sendBlock(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getBlock); } private static final Class iBlockDataClass = Reflection.getClass("{nms.world}.level.block.state.IBlockData"); - private static final Reflection.MethodInvoker getState = Reflection.getTypedMethod(Reflection.getClass("{obc}.block.data.CraftBlockData"), "getState", iBlockDataClass); + private static final Reflection.Method getState = Reflection.getTypedMethod(Reflection.getClass("{obc}.block.data.CraftBlockData"), "getState", iBlockDataClass); private static final Object blockWatcher = BountifulWrapper.impl.getDataWatcherObject(22, iBlockDataClass); - private void sendBlock(Consumer packetSink) { - packetSink.accept(getDataWatcherPacket(blockWatcher, getState.invoke(block))); + private void getBlock(BiConsumer packetSink) { + if (block.getAsString(true).equals(DEFAULT_BLOCK.getAsString(true))) return; + packetSink.accept(blockWatcher, getState.invoke(block)); } } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java index 49186a0c..216103d9 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java @@ -13,12 +13,18 @@ import org.bukkit.util.Transformation; import org.joml.Quaternionf; import org.joml.Vector3f; +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiConsumer; import java.util.function.Consumer; @Getter public abstract class RDisplay extends REntity { - private Transformation transform = new Transformation(new Vector3f(), new Quaternionf(0, 0, 0, 1), new Vector3f(1, 1, 1), new Quaternionf(0, 0, 0, 1)); + protected final Consumer updatePacketSink = o -> server.updateEntity(this, o); + + public static final Transformation DEFAULT_TRANSFORM = new Transformation(new Vector3f(), new Quaternionf(0, 0, 0, 1), new Vector3f(1, 1, 1), new Quaternionf(0, 0, 0, 1)); + private Transformation transform = DEFAULT_TRANSFORM; private int interpolationDuration = 0; @@ -41,169 +47,171 @@ public abstract class RDisplay extends REntity { private Display.Brightness brightness = null; protected RDisplay(REntityServer server, EntityType entityType, Location location) { - super(server, entityType, location); + super(server, entityType, location, 0); + Bukkit.getScheduler().runTask(Core.getInstance(), () -> server.addEntity(this)); } @Override protected void postSpawn(Consumer packetSink) { super.postSpawn(packetSink); - Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> { - sendTransform(packetSink); - sendInterpolationDuration(packetSink); - sendViewRange(packetSink); - sendShadowRadius(packetSink); - sendShadowStrength(packetSink); - sendDisplayWidth(packetSink); - sendDisplayHeight(packetSink); - sendInterpolationDelay(packetSink); - sendBillboard(packetSink); - sendGlowColorOverride(packetSink); - sendBrightness(packetSink); - }, 0); + sendPacket(packetSink, + this::getTransformData, + this::getInterpolationDuration, + this::getViewRange, + this::getShadowRadius, + this::getShadowStrength, + this::getDisplayWidth, + this::getDisplayHeight, + this::getInterpolationDelay, + this::getBillboard, + this::getGlowColorOverride, + this::getBrightness + ); + } + + @SafeVarargs + protected final void sendPacket(Consumer packetSink, Consumer>... dataSinkSinks) { + List keyValueData = new ArrayList<>(); + for (Consumer> dataSinkSink : dataSinkSinks) { + dataSinkSink.accept((dataWatcher, value) -> { + keyValueData.add(dataWatcher); + keyValueData.add(value); + }); + } + if (keyValueData.isEmpty()) return; + packetSink.accept(getDataWatcherPacket(keyValueData.toArray())); } public void setTransform(@NonNull Transformation transform) { this.transform = transform; - if (Core.getVersion() >= 20) { - sendTransform(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getTransformData); } private static final Object translationWatcher = BountifulWrapper.impl.getDataWatcherObject(10, Vector3f.class); private static final Object leftRotationWatcher = BountifulWrapper.impl.getDataWatcherObject(12, Quaternionf.class); private static final Object scaleWatcher = BountifulWrapper.impl.getDataWatcherObject(11, Vector3f.class); private static final Object rightRotationWatcher = BountifulWrapper.impl.getDataWatcherObject(13, Quaternionf.class); - private void sendTransform(Consumer packetSink) { - packetSink.accept(getDataWatcherPacket(translationWatcher, transform.getTranslation())); - packetSink.accept(getDataWatcherPacket(leftRotationWatcher, transform.getLeftRotation())); - packetSink.accept(getDataWatcherPacket(scaleWatcher, transform.getScale())); - packetSink.accept(getDataWatcherPacket(rightRotationWatcher, transform.getRightRotation())); + private void getTransformData(BiConsumer dataSink) { + if (transform.equals(DEFAULT_TRANSFORM)) return; + dataSink.accept(translationWatcher, transform.getTranslation()); + dataSink.accept(leftRotationWatcher, transform.getLeftRotation()); + dataSink.accept(scaleWatcher, transform.getScale()); + dataSink.accept(rightRotationWatcher, transform.getRightRotation()); } public void setInterpolationDuration(int interpolationDuration) { this.interpolationDuration = interpolationDuration; - if (Core.getVersion() >= 20) { - sendInterpolationDuration(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getInterpolationDuration); } private static final Object transformationInterpolationDurationWatcher = BountifulWrapper.impl.getDataWatcherObject(8, Integer.class); private static final Object positionOrRotationInterpolationDurationWatcher = BountifulWrapper.impl.getDataWatcherObject(9, Integer.class); - private void sendInterpolationDuration(Consumer packetSink) { - packetSink.accept(getDataWatcherPacket(transformationInterpolationDurationWatcher, interpolationDuration)); - packetSink.accept(getDataWatcherPacket(positionOrRotationInterpolationDurationWatcher, interpolationDuration)); + private void getInterpolationDuration(BiConsumer packetSink) { + if (interpolationDelay == 0) return; + packetSink.accept(transformationInterpolationDurationWatcher, interpolationDuration); + packetSink.accept(positionOrRotationInterpolationDurationWatcher, interpolationDuration); } public void setViewRange(float viewRange) { this.viewRange = viewRange; - if (Core.getVersion() >= 20) { - sendViewRange(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getViewRange); } private static final Object viewRangeWatcher = BountifulWrapper.impl.getDataWatcherObject(16, Float.class); - private void sendViewRange(Consumer packetSink) { - packetSink.accept(getDataWatcherPacket(viewRangeWatcher, viewRange)); + private void getViewRange(BiConsumer packetSink) { + if (viewRange == 1.0F) return; + packetSink.accept(viewRangeWatcher, viewRange); } public void setShadowRadius(float shadowRadius) { this.shadowRadius = shadowRadius; - if (Core.getVersion() >= 20) { - sendShadowRadius(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getShadowRadius); } private static final Object shadowRadiusWatcher = BountifulWrapper.impl.getDataWatcherObject(17, Float.class); - private void sendShadowRadius(Consumer packetSink) { - packetSink.accept(getDataWatcherPacket(shadowRadiusWatcher, shadowRadius)); + private void getShadowRadius(BiConsumer packetSink) { + if (shadowRadius == 1.0F) return; + packetSink.accept(shadowRadiusWatcher, shadowRadius); } public void setShadowStrength(float shadowStrength) { this.shadowStrength = shadowStrength; - if (Core.getVersion() >= 20) { - sendShadowStrength(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getShadowStrength); } private static final Object shadowStrengthWatcher = BountifulWrapper.impl.getDataWatcherObject(18, Float.class); - private void sendShadowStrength(Consumer packetSink) { - packetSink.accept(getDataWatcherPacket(shadowStrengthWatcher, shadowStrength)); + private void getShadowStrength(BiConsumer packetSink) { + if (shadowStrength == 1.0F) return; + packetSink.accept(shadowStrengthWatcher, shadowStrength); } public void setDisplayWidth(float displayWidth) { this.displayWidth = displayWidth; - if (Core.getVersion() >= 20) { - sendDisplayWidth(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getDisplayWidth); } private static final Object displayWidthWatcher = BountifulWrapper.impl.getDataWatcherObject(19, Float.class); - private void sendDisplayWidth(Consumer packetSink) { - packetSink.accept(getDataWatcherPacket(displayWidthWatcher, displayWidth)); + private void getDisplayWidth(BiConsumer packetSink) { + if (displayWidth == 0.0F) return; + packetSink.accept(displayWidthWatcher, displayWidth); } public void setDisplayHeight(float displayHeight) { this.displayHeight = displayHeight; - if (Core.getVersion() >= 20) { - sendDisplayHeight(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getDisplayHeight); } private static final Object displayHeightWatcher = BountifulWrapper.impl.getDataWatcherObject(20, Float.class); - private void sendDisplayHeight(Consumer packetSink) { - packetSink.accept(getDataWatcherPacket(displayHeightWatcher, displayHeight)); + private void getDisplayHeight(BiConsumer packetSink) { + if (displayHeight == 0.0F) return; + packetSink.accept(displayHeightWatcher, displayHeight); } public void setInterpolationDelay(int interpolationDelay) { this.interpolationDelay = interpolationDelay; - if (Core.getVersion() >= 20) { - sendInterpolationDelay(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getInterpolationDelay); } private static final Object interpolationDelayWatcher = BountifulWrapper.impl.getDataWatcherObject(7, Integer.class); - private void sendInterpolationDelay(Consumer packetSink) { - packetSink.accept(getDataWatcherPacket(interpolationDelayWatcher, interpolationDelay)); + private void getInterpolationDelay(BiConsumer packetSink) { + if (interpolationDelay == 0) return; + packetSink.accept(interpolationDelayWatcher, interpolationDelay); } public void setBillboard(Display.Billboard billboard) { this.billboard = billboard; - if (Core.getVersion() >= 20) { - sendBillboard(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getBillboard); } private static final Object billboardWatcher = BountifulWrapper.impl.getDataWatcherObject(14, Byte.class); - private void sendBillboard(Consumer packetSink) { - packetSink.accept(getDataWatcherPacket(billboardWatcher, (byte) billboard.ordinal())); + private void getBillboard(BiConsumer packetSink) { + if (billboard == Display.Billboard.FIXED) return; + packetSink.accept(billboardWatcher, (byte) billboard.ordinal()); } public void setGlowColorOverride(Color glowColorOverride) { this.glowColorOverride = glowColorOverride; - if (Core.getVersion() >= 20) { - sendGlowColorOverride(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getGlowColorOverride); } private static final Object glowColorOverrideWatcher = BountifulWrapper.impl.getDataWatcherObject(21, Integer.class); - private void sendGlowColorOverride(Consumer packetSink) { - packetSink.accept(getDataWatcherPacket(glowColorOverrideWatcher, glowColorOverride)); + private void getGlowColorOverride(BiConsumer packetSink) { + if (glowColorOverride == null) return; + packetSink.accept(glowColorOverrideWatcher, glowColorOverride); } public void setBrightness(Display.Brightness brightness) { this.brightness = brightness; - if (Core.getVersion() >= 20) { - sendBrightness(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getBrightness); } private static final Object brightnessWatcher = BountifulWrapper.impl.getDataWatcherObject(15, Integer.class); - private void sendBrightness(Consumer packetSink) { + private void getBrightness(BiConsumer packetSink) { if (brightness == null) { - packetSink.accept(getDataWatcherPacket(brightnessWatcher, -1)); + packetSink.accept(brightnessWatcher, -1); // TODO: Potentially not needed, need to test/investigate } else { int brightnessData = brightness.getBlockLight() << 4 | brightness.getSkyLight() << 20; - packetSink.accept(getDataWatcherPacket(brightnessWatcher, brightnessData)); + packetSink.accept(brightnessWatcher, brightnessData); } } } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java index 4c290fa7..4428df86 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java @@ -1,23 +1,25 @@ package de.steamwar.entity; -import com.comphenix.tinyprotocol.Reflection; +import de.steamwar.Reflection; import de.steamwar.core.BountifulWrapper; -import de.steamwar.core.Core; import lombok.Getter; -import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.entity.EntityType; import org.bukkit.entity.ItemDisplay; import org.bukkit.inventory.ItemStack; +import java.util.function.BiConsumer; import java.util.function.Consumer; @Getter public class RItemDisplay extends RDisplay { - private ItemStack itemStack; + public static final ItemStack DEFAULT_ITEM_STACK = new ItemStack(Material.AIR); - private ItemDisplay.ItemDisplayTransform itemDisplayTransform; + private ItemStack itemStack = DEFAULT_ITEM_STACK; + + private ItemDisplay.ItemDisplayTransform itemDisplayTransform = ItemDisplay.ItemDisplayTransform.NONE; public RItemDisplay(REntityServer server, Location location) { super(server, EntityType.ITEM_DISPLAY, location); @@ -26,35 +28,28 @@ public class RItemDisplay extends RDisplay { @Override protected void postSpawn(Consumer packetSink) { super.postSpawn(packetSink); - Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> { - sendItemStack(packetSink); - sendItemDisplayTransform(packetSink); - }, 0); + sendPacket(packetSink, this::getItemStack, this::getItemDisplayTransform); } public void setItemStack(ItemStack itemStack) { this.itemStack = itemStack; - if (Core.getVersion() >= 20) { - sendItemStack(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getItemStack); } private static final Class itemStackClass = Reflection.getClass("{nms.world}.item.ItemStack"); - private static final Reflection.MethodInvoker asNMSCopy = Reflection.getTypedMethod(Reflection.getClass("{obc}.inventory.CraftItemStack"), "asNMSCopy", itemStackClass, ItemStack.class); + private static final Reflection.Method asNMSCopy = Reflection.getTypedMethod(Reflection.getClass("{obc}.inventory.CraftItemStack"), "asNMSCopy", itemStackClass, ItemStack.class); private static final Object itemStackWatcher = BountifulWrapper.impl.getDataWatcherObject(22, itemStackClass); - private void sendItemStack(Consumer packetSink) { - packetSink.accept(getDataWatcherPacket(itemStackWatcher, asNMSCopy.invoke(null, itemStack))); + private void getItemStack(BiConsumer packetSink) { + packetSink.accept(itemStackWatcher, asNMSCopy.invoke(null, itemStack)); } private static final Object itemDisplayTransformWatcher = BountifulWrapper.impl.getDataWatcherObject(23, Byte.class); public void setItemDisplayTransform(ItemDisplay.ItemDisplayTransform itemDisplayTransform) { this.itemDisplayTransform = itemDisplayTransform; - if (Core.getVersion() >= 20) { - sendItemDisplayTransform(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getItemDisplayTransform); } - private void sendItemDisplayTransform(Consumer packetSink) { - packetSink.accept(getDataWatcherPacket(itemDisplayTransformWatcher, (byte) itemDisplayTransform.ordinal())); + private void getItemDisplayTransform(BiConsumer packetSink) { + packetSink.accept(itemDisplayTransformWatcher, (byte) itemDisplayTransform.ordinal()); } } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java index d5c459ae..f8c7db3c 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java @@ -1,15 +1,14 @@ package de.steamwar.entity; -import com.comphenix.tinyprotocol.Reflection; +import de.steamwar.Reflection; import de.steamwar.core.BountifulWrapper; import de.steamwar.core.ChatWrapper; -import de.steamwar.core.Core; import lombok.Getter; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.EntityType; import org.bukkit.entity.TextDisplay; +import java.util.function.BiConsumer; import java.util.function.Consumer; @Getter @@ -36,81 +35,65 @@ public class RTextDisplay extends RDisplay { @Override protected void postSpawn(Consumer packetSink) { super.postSpawn(packetSink); - Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> { - sendText(packetSink); - sendLineWidth(packetSink); - sendTextOpacity(packetSink); - sendTextStatus(packetSink); - }, 0); + sendPacket(packetSink, this::getText, this::getLineWidth, this::getTextOpacity, this::getTextStatus); } public void setText(String text) { this.text = text; - if (Core.getVersion() >= 20) { - sendText(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getText); } private static final Class iChatBaseComponent = Reflection.getClass("{nms.network.chat}.IChatBaseComponent"); private static final Object textWatcher = BountifulWrapper.impl.getDataWatcherObject(22, iChatBaseComponent); - private void sendText(Consumer packetSink) { - packetSink.accept(getDataWatcherPacket(textWatcher, ChatWrapper.impl.stringToChatComponent(text))); + private void getText(BiConsumer packetSink) { + if (text.isEmpty()) return; + packetSink.accept(textWatcher, ChatWrapper.impl.stringToChatComponent(text)); } public void setLineWidth(int lineWidth) { this.lineWidth = lineWidth; - if (Core.getVersion() >= 20) { - sendLineWidth(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getLineWidth); } private static final Object lineWidthWatcher = BountifulWrapper.impl.getDataWatcherObject(23, Integer.class); - private void sendLineWidth(Consumer packetSink) { - packetSink.accept(getDataWatcherPacket(lineWidthWatcher, lineWidth)); + private void getLineWidth(BiConsumer packetSink) { + if (lineWidth == 200) return; + packetSink.accept(lineWidthWatcher, lineWidth); } public void setTextOpacity(byte textOpacity) { this.textOpacity = textOpacity; - if (Core.getVersion() >= 20) { - sendTextOpacity(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getTextOpacity); } private static final Object textOpacityWatcher = BountifulWrapper.impl.getDataWatcherObject(25, Byte.class); - private void sendTextOpacity(Consumer packetSink) { - packetSink.accept(getDataWatcherPacket(textOpacityWatcher, textOpacity)); + private void getTextOpacity(BiConsumer packetSink) { + if (textOpacity == (byte) -1) return; + packetSink.accept(textOpacityWatcher, textOpacity); } public void setShadowed(boolean shadowed) { this.shadowed = shadowed; - if (Core.getVersion() >= 20) { - sendTextStatus(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getTextStatus); } public void setSeeThrough(boolean seeThrough) { this.seeThrough = seeThrough; - if (Core.getVersion() >= 20) { - sendTextStatus(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getTextStatus); } public void setDefaultBackground(boolean defaultBackground) { this.defaultBackground = defaultBackground; - if (Core.getVersion() >= 20) { - sendTextStatus(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getTextStatus); } public void setAlignment(TextDisplay.TextAlignment alignment) { this.alignment = alignment; - if (Core.getVersion() >= 20) { - sendTextStatus(o -> server.updateEntity(this, o)); - } + sendPacket(updatePacketSink, this::getTextStatus); } private static final Object textStatusWatcher = BountifulWrapper.impl.getDataWatcherObject(26, Byte.class); - private void sendTextStatus(Consumer packetSink) { + private void getTextStatus(BiConsumer packetSink) { byte status = 0; if (shadowed) { @@ -130,6 +113,7 @@ public class RTextDisplay extends RDisplay { status |= 0x0F; } - packetSink.accept(getDataWatcherPacket(textStatusWatcher, status)); + if (status == 0) return; + packetSink.accept(textStatusWatcher, status); } } From e418109ab70a493230a9cb6b0cd0c1f87b63428e Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 8 Jan 2025 16:27:18 +0100 Subject: [PATCH 008/124] Reduce spawn packets to 0 if everything is default --- .../src/de/steamwar/entity/RBlockDisplay.java | 8 ++- .../src/de/steamwar/entity/RDisplay.java | 56 +++++++++---------- .../src/de/steamwar/entity/REntity.java | 2 +- .../src/de/steamwar/entity/RItemDisplay.java | 16 +++--- .../src/de/steamwar/entity/RTextDisplay.java | 24 +++++--- 5 files changed, 57 insertions(+), 49 deletions(-) diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java index 9e9c3c42..a134dea7 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java @@ -16,10 +16,12 @@ public class RBlockDisplay extends RDisplay { public static final BlockData DEFAULT_BLOCK = Material.AIR.createBlockData(); - private BlockData block = DEFAULT_BLOCK; + private BlockData block; public RBlockDisplay(REntityServer server, Location location) { super(server, EntityType.BLOCK_DISPLAY, location); + this.block = DEFAULT_BLOCK; + server.addEntity(this); } @Override @@ -33,8 +35,8 @@ public class RBlockDisplay extends RDisplay { sendPacket(updatePacketSink, this::getBlock); } - private static final Class iBlockDataClass = Reflection.getClass("{nms.world}.level.block.state.IBlockData"); - private static final Reflection.Method getState = Reflection.getTypedMethod(Reflection.getClass("{obc}.block.data.CraftBlockData"), "getState", iBlockDataClass); + private static final Class iBlockDataClass = Reflection.getClass("net.minecraft.world.level.block.state.BlockState"); + private static final Reflection.Method getState = Reflection.getTypedMethod(Reflection.getClass("org.bukkit.craftbukkit.block.data.CraftBlockData"), "getState", iBlockDataClass); private static final Object blockWatcher = BountifulWrapper.impl.getDataWatcherObject(22, iBlockDataClass); private void getBlock(BiConsumer packetSink) { if (block.getAsString(true).equals(DEFAULT_BLOCK.getAsString(true))) return; diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java index 216103d9..077be91f 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java @@ -1,10 +1,8 @@ package de.steamwar.entity; import de.steamwar.core.BountifulWrapper; -import de.steamwar.core.Core; import lombok.Getter; import lombok.NonNull; -import org.bukkit.Bukkit; import org.bukkit.Color; import org.bukkit.Location; import org.bukkit.entity.Display; @@ -24,31 +22,32 @@ public abstract class RDisplay extends REntity { protected final Consumer updatePacketSink = o -> server.updateEntity(this, o); public static final Transformation DEFAULT_TRANSFORM = new Transformation(new Vector3f(), new Quaternionf(0, 0, 0, 1), new Vector3f(1, 1, 1), new Quaternionf(0, 0, 0, 1)); - private Transformation transform = DEFAULT_TRANSFORM; - private int interpolationDuration = 0; - - private float viewRange = 1.0F; - - private float shadowRadius = 0.0F; - - private float shadowStrength = 1.0F; - - private float displayWidth = 0.0F; - - private float displayHeight = 0.0F; - - private int interpolationDelay = 0; - - private Display.Billboard billboard = Display.Billboard.FIXED; - - private Color glowColorOverride = null; - - private Display.Brightness brightness = null; + private Transformation transform; + private int interpolationDuration; + private float viewRange; + private float shadowRadius; + private float shadowStrength; + private float displayWidth; + private float displayHeight; + private int interpolationDelay; + private Display.Billboard billboard; + private Color glowColorOverride; + private Display.Brightness brightness; protected RDisplay(REntityServer server, EntityType entityType, Location location) { super(server, entityType, location, 0); - Bukkit.getScheduler().runTask(Core.getInstance(), () -> server.addEntity(this)); + this.transform = DEFAULT_TRANSFORM; + this.interpolationDuration = 0; + this.viewRange = 1.0F; + this.shadowRadius = 0.0F; + this.shadowStrength = 1.0F; + this.displayWidth = 0.0F; + this.displayHeight = 0.0F; + this.interpolationDelay = 0; + this.billboard = Display.Billboard.FIXED; + this.glowColorOverride = null; + this.brightness = null; } @Override @@ -130,7 +129,7 @@ public abstract class RDisplay extends REntity { private static final Object shadowRadiusWatcher = BountifulWrapper.impl.getDataWatcherObject(17, Float.class); private void getShadowRadius(BiConsumer packetSink) { - if (shadowRadius == 1.0F) return; + if (shadowRadius == 0.0F) return; packetSink.accept(shadowRadiusWatcher, shadowRadius); } @@ -207,11 +206,8 @@ public abstract class RDisplay extends REntity { private static final Object brightnessWatcher = BountifulWrapper.impl.getDataWatcherObject(15, Integer.class); private void getBrightness(BiConsumer packetSink) { - if (brightness == null) { - packetSink.accept(brightnessWatcher, -1); // TODO: Potentially not needed, need to test/investigate - } else { - int brightnessData = brightness.getBlockLight() << 4 | brightness.getSkyLight() << 20; - packetSink.accept(brightnessWatcher, brightnessData); - } + if (brightness == null) return; + int brightnessData = brightness.getBlockLight() << 4 | brightness.getSkyLight() << 20; + packetSink.accept(brightnessWatcher, brightnessData); } } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java index 66c13c40..0c02a889 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/REntity.java @@ -441,7 +441,7 @@ public class REntity { private static final Reflection.Field equipmentEntity = Reflection.getField(ProtocolWrapper.equipmentPacket, int.class, 0); private static final Class craftItemStack = Reflection.getClass("org.bukkit.craftbukkit.inventory.CraftItemStack"); - private static final Reflection.Method asNMSCopy = Reflection.getTypedMethod(REntity.craftItemStack, "asNMSCopy", ProtocolWrapper.itemStack, ItemStack.class); + protected static final Reflection.Method asNMSCopy = Reflection.getTypedMethod(REntity.craftItemStack, "asNMSCopy", ProtocolWrapper.itemStack, ItemStack.class); protected Object getEquipmentPacket(Object slot, ItemStack stack){ Object packet = Reflection.newInstance(ProtocolWrapper.equipmentPacket); equipmentEntity.set(packet, entityId); diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java index 4428df86..0b2a8d89 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java @@ -1,7 +1,7 @@ package de.steamwar.entity; -import de.steamwar.Reflection; import de.steamwar.core.BountifulWrapper; +import de.steamwar.core.ProtocolWrapper; import lombok.Getter; import org.bukkit.Location; import org.bukkit.Material; @@ -17,12 +17,14 @@ public class RItemDisplay extends RDisplay { public static final ItemStack DEFAULT_ITEM_STACK = new ItemStack(Material.AIR); - private ItemStack itemStack = DEFAULT_ITEM_STACK; - - private ItemDisplay.ItemDisplayTransform itemDisplayTransform = ItemDisplay.ItemDisplayTransform.NONE; + private ItemStack itemStack; + private ItemDisplay.ItemDisplayTransform itemDisplayTransform; public RItemDisplay(REntityServer server, Location location) { super(server, EntityType.ITEM_DISPLAY, location); + this.itemStack = DEFAULT_ITEM_STACK; + this.itemDisplayTransform = ItemDisplay.ItemDisplayTransform.NONE; + server.addEntity(this); } @Override @@ -36,10 +38,9 @@ public class RItemDisplay extends RDisplay { sendPacket(updatePacketSink, this::getItemStack); } - private static final Class itemStackClass = Reflection.getClass("{nms.world}.item.ItemStack"); - private static final Reflection.Method asNMSCopy = Reflection.getTypedMethod(Reflection.getClass("{obc}.inventory.CraftItemStack"), "asNMSCopy", itemStackClass, ItemStack.class); - private static final Object itemStackWatcher = BountifulWrapper.impl.getDataWatcherObject(22, itemStackClass); + private static final Object itemStackWatcher = BountifulWrapper.impl.getDataWatcherObject(22, ProtocolWrapper.itemStack); private void getItemStack(BiConsumer packetSink) { + if (itemStack.equals(DEFAULT_ITEM_STACK)) return; packetSink.accept(itemStackWatcher, asNMSCopy.invoke(null, itemStack)); } @@ -50,6 +51,7 @@ public class RItemDisplay extends RDisplay { } private void getItemDisplayTransform(BiConsumer packetSink) { + if (itemDisplayTransform == ItemDisplay.ItemDisplayTransform.NONE) return; packetSink.accept(itemDisplayTransformWatcher, (byte) itemDisplayTransform.ordinal()); } } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java index f8c7db3c..1720096d 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java @@ -14,22 +14,30 @@ import java.util.function.Consumer; @Getter public class RTextDisplay extends RDisplay { - private String text = ""; + private String text; - private int lineWidth = 200; + private int lineWidth; - private byte textOpacity = (byte) -1; + private byte textOpacity; - private boolean shadowed = false; + private boolean shadowed; - private boolean seeThrough = false; + private boolean seeThrough; - private boolean defaultBackground = false; + private boolean defaultBackground; - private TextDisplay.TextAlignment alignment = TextDisplay.TextAlignment.CENTER; + private TextDisplay.TextAlignment alignment; public RTextDisplay(REntityServer server, Location location) { super(server, EntityType.TEXT_DISPLAY, location); + this.text = ""; + this.lineWidth = 200; + this.textOpacity = (byte) -1; + this.shadowed = false; + this.seeThrough = false; + this.defaultBackground = false; + this.alignment = TextDisplay.TextAlignment.CENTER; + server.addEntity(this); } @Override @@ -43,7 +51,7 @@ public class RTextDisplay extends RDisplay { sendPacket(updatePacketSink, this::getText); } - private static final Class iChatBaseComponent = Reflection.getClass("{nms.network.chat}.IChatBaseComponent"); + private static final Class iChatBaseComponent = Reflection.getClass("net.minecraft.network.chat.Component"); private static final Object textWatcher = BountifulWrapper.impl.getDataWatcherObject(22, iChatBaseComponent); private void getText(BiConsumer packetSink) { if (text.isEmpty()) return; From bfdf6471d2844bcd24e8b90debc87ce55e899849 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 8 Jan 2025 16:52:24 +0100 Subject: [PATCH 009/124] Cleanup things and fix setting back to default --- .../src/de/steamwar/entity/RBlockDisplay.java | 7 +- .../src/de/steamwar/entity/RDisplay.java | 109 +++++++++++------- .../src/de/steamwar/entity/RItemDisplay.java | 14 ++- .../src/de/steamwar/entity/RTextDisplay.java | 28 +++-- 4 files changed, 94 insertions(+), 64 deletions(-) diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java index a134dea7..c01fdea2 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java @@ -38,8 +38,9 @@ public class RBlockDisplay extends RDisplay { private static final Class iBlockDataClass = Reflection.getClass("net.minecraft.world.level.block.state.BlockState"); private static final Reflection.Method getState = Reflection.getTypedMethod(Reflection.getClass("org.bukkit.craftbukkit.block.data.CraftBlockData"), "getState", iBlockDataClass); private static final Object blockWatcher = BountifulWrapper.impl.getDataWatcherObject(22, iBlockDataClass); - private void getBlock(BiConsumer packetSink) { - if (block.getAsString(true).equals(DEFAULT_BLOCK.getAsString(true))) return; - packetSink.accept(blockWatcher, getState.invoke(block)); + private void getBlock(boolean ignoreDefault, BiConsumer packetSink) { + if (ignoreDefault || !block.getAsString(true).equals(DEFAULT_BLOCK.getAsString(true))) { + packetSink.accept(blockWatcher, getState.invoke(block)); + } } } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java index 077be91f..3be30b12 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java @@ -69,16 +69,18 @@ public abstract class RDisplay extends REntity { } @SafeVarargs - protected final void sendPacket(Consumer packetSink, Consumer>... dataSinkSinks) { + protected final void sendPacket(Consumer packetSink, BiConsumer>... dataSinkSinks) { List keyValueData = new ArrayList<>(); - for (Consumer> dataSinkSink : dataSinkSinks) { - dataSinkSink.accept((dataWatcher, value) -> { + boolean ignoreDefault = packetSink == updatePacketSink; + for (BiConsumer> dataSinkSink : dataSinkSinks) { + dataSinkSink.accept(ignoreDefault, (dataWatcher, value) -> { keyValueData.add(dataWatcher); keyValueData.add(value); }); } - if (keyValueData.isEmpty()) return; - packetSink.accept(getDataWatcherPacket(keyValueData.toArray())); + if (!keyValueData.isEmpty()) { + packetSink.accept(getDataWatcherPacket(keyValueData.toArray())); + } } public void setTransform(@NonNull Transformation transform) { @@ -90,12 +92,14 @@ public abstract class RDisplay extends REntity { private static final Object leftRotationWatcher = BountifulWrapper.impl.getDataWatcherObject(12, Quaternionf.class); private static final Object scaleWatcher = BountifulWrapper.impl.getDataWatcherObject(11, Vector3f.class); private static final Object rightRotationWatcher = BountifulWrapper.impl.getDataWatcherObject(13, Quaternionf.class); - private void getTransformData(BiConsumer dataSink) { - if (transform.equals(DEFAULT_TRANSFORM)) return; - dataSink.accept(translationWatcher, transform.getTranslation()); - dataSink.accept(leftRotationWatcher, transform.getLeftRotation()); - dataSink.accept(scaleWatcher, transform.getScale()); - dataSink.accept(rightRotationWatcher, transform.getRightRotation()); + + private void getTransformData(boolean ignoreDefault, BiConsumer dataSink) { + if (ignoreDefault || !transform.equals(DEFAULT_TRANSFORM)) { + dataSink.accept(translationWatcher, transform.getTranslation()); + dataSink.accept(leftRotationWatcher, transform.getLeftRotation()); + dataSink.accept(scaleWatcher, transform.getScale()); + dataSink.accept(rightRotationWatcher, transform.getRightRotation()); + } } public void setInterpolationDuration(int interpolationDuration) { @@ -105,10 +109,12 @@ public abstract class RDisplay extends REntity { private static final Object transformationInterpolationDurationWatcher = BountifulWrapper.impl.getDataWatcherObject(8, Integer.class); private static final Object positionOrRotationInterpolationDurationWatcher = BountifulWrapper.impl.getDataWatcherObject(9, Integer.class); - private void getInterpolationDuration(BiConsumer packetSink) { - if (interpolationDelay == 0) return; - packetSink.accept(transformationInterpolationDurationWatcher, interpolationDuration); - packetSink.accept(positionOrRotationInterpolationDurationWatcher, interpolationDuration); + + private void getInterpolationDuration(boolean ignoreDefault, BiConsumer packetSink) { + if (ignoreDefault || interpolationDelay != 0) { + packetSink.accept(transformationInterpolationDurationWatcher, interpolationDuration); + packetSink.accept(positionOrRotationInterpolationDurationWatcher, interpolationDuration); + } } public void setViewRange(float viewRange) { @@ -117,9 +123,11 @@ public abstract class RDisplay extends REntity { } private static final Object viewRangeWatcher = BountifulWrapper.impl.getDataWatcherObject(16, Float.class); - private void getViewRange(BiConsumer packetSink) { - if (viewRange == 1.0F) return; - packetSink.accept(viewRangeWatcher, viewRange); + + private void getViewRange(boolean ignoreDefault, BiConsumer packetSink) { + if (ignoreDefault || viewRange != 1.0F) { + packetSink.accept(viewRangeWatcher, viewRange); + } } public void setShadowRadius(float shadowRadius) { @@ -128,9 +136,11 @@ public abstract class RDisplay extends REntity { } private static final Object shadowRadiusWatcher = BountifulWrapper.impl.getDataWatcherObject(17, Float.class); - private void getShadowRadius(BiConsumer packetSink) { - if (shadowRadius == 0.0F) return; - packetSink.accept(shadowRadiusWatcher, shadowRadius); + + private void getShadowRadius(boolean ignoreDefault, BiConsumer packetSink) { + if (ignoreDefault || shadowRadius != 0.0F) { + packetSink.accept(shadowRadiusWatcher, shadowRadius); + } } public void setShadowStrength(float shadowStrength) { @@ -139,9 +149,11 @@ public abstract class RDisplay extends REntity { } private static final Object shadowStrengthWatcher = BountifulWrapper.impl.getDataWatcherObject(18, Float.class); - private void getShadowStrength(BiConsumer packetSink) { - if (shadowStrength == 1.0F) return; - packetSink.accept(shadowStrengthWatcher, shadowStrength); + + private void getShadowStrength(boolean ignoreDefault, BiConsumer packetSink) { + if (ignoreDefault || shadowStrength != 1.0F) { + packetSink.accept(shadowStrengthWatcher, shadowStrength); + } } public void setDisplayWidth(float displayWidth) { @@ -150,9 +162,11 @@ public abstract class RDisplay extends REntity { } private static final Object displayWidthWatcher = BountifulWrapper.impl.getDataWatcherObject(19, Float.class); - private void getDisplayWidth(BiConsumer packetSink) { - if (displayWidth == 0.0F) return; - packetSink.accept(displayWidthWatcher, displayWidth); + + private void getDisplayWidth(boolean ignoreDefault, BiConsumer packetSink) { + if (ignoreDefault || displayWidth != 0.0F) { + packetSink.accept(displayWidthWatcher, displayWidth); + } } public void setDisplayHeight(float displayHeight) { @@ -161,9 +175,11 @@ public abstract class RDisplay extends REntity { } private static final Object displayHeightWatcher = BountifulWrapper.impl.getDataWatcherObject(20, Float.class); - private void getDisplayHeight(BiConsumer packetSink) { - if (displayHeight == 0.0F) return; - packetSink.accept(displayHeightWatcher, displayHeight); + + private void getDisplayHeight(boolean ignoreDefault, BiConsumer packetSink) { + if (ignoreDefault || displayHeight != 0.0F) { + packetSink.accept(displayHeightWatcher, displayHeight); + } } public void setInterpolationDelay(int interpolationDelay) { @@ -172,9 +188,11 @@ public abstract class RDisplay extends REntity { } private static final Object interpolationDelayWatcher = BountifulWrapper.impl.getDataWatcherObject(7, Integer.class); - private void getInterpolationDelay(BiConsumer packetSink) { - if (interpolationDelay == 0) return; - packetSink.accept(interpolationDelayWatcher, interpolationDelay); + + private void getInterpolationDelay(boolean ignoreDefault, BiConsumer packetSink) { + if (ignoreDefault || interpolationDelay != 0) { + packetSink.accept(interpolationDelayWatcher, interpolationDelay); + } } public void setBillboard(Display.Billboard billboard) { @@ -183,9 +201,11 @@ public abstract class RDisplay extends REntity { } private static final Object billboardWatcher = BountifulWrapper.impl.getDataWatcherObject(14, Byte.class); - private void getBillboard(BiConsumer packetSink) { - if (billboard == Display.Billboard.FIXED) return; - packetSink.accept(billboardWatcher, (byte) billboard.ordinal()); + + private void getBillboard(boolean ignoreDefault, BiConsumer packetSink) { + if (ignoreDefault || billboard != Display.Billboard.FIXED) { + packetSink.accept(billboardWatcher, (byte) billboard.ordinal()); + } } public void setGlowColorOverride(Color glowColorOverride) { @@ -194,9 +214,11 @@ public abstract class RDisplay extends REntity { } private static final Object glowColorOverrideWatcher = BountifulWrapper.impl.getDataWatcherObject(21, Integer.class); - private void getGlowColorOverride(BiConsumer packetSink) { - if (glowColorOverride == null) return; - packetSink.accept(glowColorOverrideWatcher, glowColorOverride); + + private void getGlowColorOverride(boolean ignoreDefault, BiConsumer packetSink) { + if (ignoreDefault || glowColorOverride != null) { + packetSink.accept(glowColorOverrideWatcher, glowColorOverride == null ? -1 : glowColorOverride.asARGB()); + } } public void setBrightness(Display.Brightness brightness) { @@ -205,9 +227,10 @@ public abstract class RDisplay extends REntity { } private static final Object brightnessWatcher = BountifulWrapper.impl.getDataWatcherObject(15, Integer.class); - private void getBrightness(BiConsumer packetSink) { - if (brightness == null) return; - int brightnessData = brightness.getBlockLight() << 4 | brightness.getSkyLight() << 20; - packetSink.accept(brightnessWatcher, brightnessData); + + private void getBrightness(boolean ignoreDefault, BiConsumer packetSink) { + if (ignoreDefault || brightness != null) { + packetSink.accept(brightnessWatcher, brightness == null ? -1 : brightness.getBlockLight() << 4 | brightness.getSkyLight() << 20); + } } } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java index 0b2a8d89..4ed1a4dc 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java @@ -39,9 +39,10 @@ public class RItemDisplay extends RDisplay { } private static final Object itemStackWatcher = BountifulWrapper.impl.getDataWatcherObject(22, ProtocolWrapper.itemStack); - private void getItemStack(BiConsumer packetSink) { - if (itemStack.equals(DEFAULT_ITEM_STACK)) return; - packetSink.accept(itemStackWatcher, asNMSCopy.invoke(null, itemStack)); + private void getItemStack(boolean ignoreDefault, BiConsumer packetSink) { + if (ignoreDefault || !itemStack.equals(DEFAULT_ITEM_STACK)) { + packetSink.accept(itemStackWatcher, asNMSCopy.invoke(null, itemStack)); + } } private static final Object itemDisplayTransformWatcher = BountifulWrapper.impl.getDataWatcherObject(23, Byte.class); @@ -50,8 +51,9 @@ public class RItemDisplay extends RDisplay { sendPacket(updatePacketSink, this::getItemDisplayTransform); } - private void getItemDisplayTransform(BiConsumer packetSink) { - if (itemDisplayTransform == ItemDisplay.ItemDisplayTransform.NONE) return; - packetSink.accept(itemDisplayTransformWatcher, (byte) itemDisplayTransform.ordinal()); + private void getItemDisplayTransform(boolean ignoreDefault, BiConsumer packetSink) { + if (ignoreDefault || itemDisplayTransform != ItemDisplay.ItemDisplayTransform.NONE) { + packetSink.accept(itemDisplayTransformWatcher, (byte) itemDisplayTransform.ordinal()); + } } } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java index 1720096d..3abf9f18 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java @@ -53,9 +53,10 @@ public class RTextDisplay extends RDisplay { private static final Class iChatBaseComponent = Reflection.getClass("net.minecraft.network.chat.Component"); private static final Object textWatcher = BountifulWrapper.impl.getDataWatcherObject(22, iChatBaseComponent); - private void getText(BiConsumer packetSink) { - if (text.isEmpty()) return; - packetSink.accept(textWatcher, ChatWrapper.impl.stringToChatComponent(text)); + private void getText(boolean ignoreDefault, BiConsumer packetSink) { + if (ignoreDefault || !text.isEmpty()) { + packetSink.accept(textWatcher, ChatWrapper.impl.stringToChatComponent(text)); + } } public void setLineWidth(int lineWidth) { @@ -64,9 +65,10 @@ public class RTextDisplay extends RDisplay { } private static final Object lineWidthWatcher = BountifulWrapper.impl.getDataWatcherObject(23, Integer.class); - private void getLineWidth(BiConsumer packetSink) { - if (lineWidth == 200) return; - packetSink.accept(lineWidthWatcher, lineWidth); + private void getLineWidth(boolean ignoreDefault, BiConsumer packetSink) { + if (ignoreDefault || lineWidth != 200) { + packetSink.accept(lineWidthWatcher, lineWidth); + } } public void setTextOpacity(byte textOpacity) { @@ -75,9 +77,10 @@ public class RTextDisplay extends RDisplay { } private static final Object textOpacityWatcher = BountifulWrapper.impl.getDataWatcherObject(25, Byte.class); - private void getTextOpacity(BiConsumer packetSink) { - if (textOpacity == (byte) -1) return; - packetSink.accept(textOpacityWatcher, textOpacity); + private void getTextOpacity(boolean ignoreDefault, BiConsumer packetSink) { + if (ignoreDefault || textOpacity != (byte) -1) { + packetSink.accept(textOpacityWatcher, textOpacity); + } } public void setShadowed(boolean shadowed) { @@ -101,7 +104,7 @@ public class RTextDisplay extends RDisplay { } private static final Object textStatusWatcher = BountifulWrapper.impl.getDataWatcherObject(26, Byte.class); - private void getTextStatus(BiConsumer packetSink) { + private void getTextStatus(boolean ignoreDefault, BiConsumer packetSink) { byte status = 0; if (shadowed) { @@ -121,7 +124,8 @@ public class RTextDisplay extends RDisplay { status |= 0x0F; } - if (status == 0) return; - packetSink.accept(textStatusWatcher, status); + if (ignoreDefault || status != 0) { + packetSink.accept(textStatusWatcher, status); + } } } From 3d153d49b52b162fdfacf3d5537d5fe3c433ef8f Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sat, 1 Feb 2025 21:50:36 +0100 Subject: [PATCH 010/124] Make TNTLeague Event System Capable --- .../src/de/steamwar/message/Message.java | 7 +- .../src/de/steamwar/message/SubMessage.java | 29 +++++--- .../tntleague/command/InviteCommand.kt | 7 +- .../tntleague/config/TNTLeagueConfig.kt | 33 +++++++++ .../tntleague/config/TNTLeagueWorldConfig.kt | 41 ++---------- .../steamwar/tntleague/config/TeamConfig.kt | 67 +++++++++++++++++++ .../tntleague/events/GlobalListener.kt | 6 +- .../steamwar/tntleague/game/TNTLeagueGame.kt | 30 +++++++-- .../steamwar/tntleague/game/TNTLeagueTeam.kt | 37 +++++----- .../tntleague/util/TNTLeagueScoreboard.kt | 4 +- 10 files changed, 182 insertions(+), 79 deletions(-) create mode 100644 TNTLeague/src/de/steamwar/tntleague/config/TeamConfig.kt diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/message/Message.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/message/Message.java index b9ae84b7..f953ce8d 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/message/Message.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/message/Message.java @@ -72,9 +72,12 @@ public class Message { pattern += fromRB(resourceBundle, message); for (int i = 0; i < params.length; i++) { - if (params[i] instanceof SubMessage) { - SubMessage smsg = (SubMessage) params[i]; + if (params[i] instanceof SubMessage.Translatable) { + SubMessage.Translatable smsg = (SubMessage.Translatable) params[i]; params[i] = parse(smsg.getMessage(), sender, smsg.getParams()); + } else if (params[i] instanceof SubMessage.Literal) { + SubMessage.Literal smsg = (SubMessage.Literal) params[i]; + params[i] = smsg.getMessage(); } } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/message/SubMessage.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/message/SubMessage.java index e40b74a5..4c302689 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/message/SubMessage.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/message/SubMessage.java @@ -19,20 +19,33 @@ package de.steamwar.message; +import lombok.AllArgsConstructor; import lombok.Getter; @Getter -public class SubMessage { +@AllArgsConstructor +public abstract class SubMessage { private final String message; - private final Object[] params; - public SubMessage(String message, Object... params) { - this.message = message; - this.params = params; + @Getter + public static class Translatable extends SubMessage { + private final Object[] params; + + public Translatable(String message, Object... params) { + super(message); + this.params = params; + } + + public Translatable(String message) { + super(message); + this.params = new Object[0]; + } } - public SubMessage(String message) { - this.message = message; - this.params = new Object[0]; + @Getter + public static class Literal extends SubMessage { + public Literal(String message) { + super(message); + } } } diff --git a/TNTLeague/src/de/steamwar/tntleague/command/InviteCommand.kt b/TNTLeague/src/de/steamwar/tntleague/command/InviteCommand.kt index 8ecf50cb..e89e3443 100644 --- a/TNTLeague/src/de/steamwar/tntleague/command/InviteCommand.kt +++ b/TNTLeague/src/de/steamwar/tntleague/command/InviteCommand.kt @@ -21,8 +21,8 @@ package de.steamwar.tntleague.command import de.steamwar.command.SWCommand import de.steamwar.command.TypeValidator -import de.steamwar.message.SubMessage import de.steamwar.tntleague.colorByTeam +import de.steamwar.tntleague.config.TNTLeagueConfig import de.steamwar.tntleague.game.TNTLeagueGame import de.steamwar.tntleague.message import net.md_5.bungee.api.chat.ClickEvent @@ -32,6 +32,7 @@ object InviteCommand: SWCommand("invite") { @Register fun invitePlayer(@Validator("isLeader") sender: Player, target: Player) { + if (TNTLeagueConfig.isEvent()) return if (TNTLeagueGame.state != TNTLeagueGame.GameState.LOBBY) return if (TNTLeagueGame.getTeam(target) != null) return @@ -39,8 +40,8 @@ object InviteCommand: SWCommand("invite") { team.invites.add(target) message - .send("INVITED", target, message.parse("INVITED_HOVER", target, SubMessage(team.name)), - ClickEvent(ClickEvent.Action.RUN_COMMAND, "/accept " + sender.name), sender.name.colorByTeam(team), SubMessage(team.name), ) + .send("INVITED", target, message.parse("INVITED_HOVER", target, team.name), + ClickEvent(ClickEvent.Action.RUN_COMMAND, "/accept " + sender.name), sender.name.colorByTeam(team), team.name) message.send("INVITED_PLAYER", sender, target.name) } diff --git a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt index e4677a4e..e5bccb08 100644 --- a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt +++ b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt @@ -19,6 +19,10 @@ package de.steamwar.tntleague.config +import de.steamwar.message.SubMessage +import de.steamwar.sql.Event +import de.steamwar.sql.EventFight +import de.steamwar.sql.Team import de.steamwar.tntleague.plugin import org.bukkit.Material import org.bukkit.configuration.ConfigurationSection @@ -36,7 +40,34 @@ data class TNTLeagueConfig( val blueLeader: UUID? = System.getProperty("blueLeader")?.let { UUID.fromString(it) }, val redLeader: UUID? = System.getProperty("redLeader")?.let { UUID.fromString(it) }, + + val eventFightId: Int? = System.getProperty("fightID")?.toInt() ) { + lateinit var eventFight: EventFight + lateinit var event: Event + lateinit var eventTeamBlue: Team + lateinit var eventTeamRed: Team + + val blueTeam: TeamConfig + val redTeam: TeamConfig + + init { + if (eventFightId != null) { + eventFight = EventFight.get(eventFightId) ?: throw IllegalArgumentException("EventFight with ID $eventFightId not found") + + event = Event.get(eventFight.eventID) + + eventTeamBlue = Team.get(eventFight.teamBlue) + eventTeamRed = Team.get(eventFight.teamRed) + + blueTeam = TeamConfig(TNTLeagueWorldConfig.blueTeam, SubMessage.Literal("§${eventTeamBlue.teamColor}${eventTeamBlue.teamName}"), eventTeamBlue.teamColor[0]) + redTeam = TeamConfig(TNTLeagueWorldConfig.redTeam, SubMessage.Literal("§${eventTeamRed.teamColor}${eventTeamRed.teamName}"), eventTeamRed.teamColor[0]) + } else { + blueTeam = TeamConfig(TNTLeagueWorldConfig.blueTeam, SubMessage.Translatable("BLUE"), '3') + redTeam = TeamConfig(TNTLeagueWorldConfig.redTeam, SubMessage.Translatable("RED"), 'c') + } + } + companion object { val config: TNTLeagueConfig by lazy { loadConfig(plugin.config) } @@ -55,6 +86,8 @@ data class TNTLeagueConfig( ) }.mapKeys { Material.getMaterial(it.key) ?: Material.BARRIER } } + + fun isEvent() = config.eventFightId != null } data class Price( diff --git a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueWorldConfig.kt b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueWorldConfig.kt index df2dd34e..01667abd 100644 --- a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueWorldConfig.kt +++ b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueWorldConfig.kt @@ -54,8 +54,8 @@ object TNTLeagueWorldConfig { ) } - lateinit var blueTeam: TeamConfig - lateinit var redTeam: TeamConfig + lateinit var blueTeam: TeamWorldConfig + lateinit var redTeam: TeamWorldConfig lateinit var lobby: Location var teamsOnSameLine by Delegates.notNull() lateinit var targetMaterial: Material @@ -64,8 +64,8 @@ object TNTLeagueWorldConfig { init { try { - blueTeam = TeamConfig.fromConfig(config.getConfigurationSection("blueTeam")!!) - redTeam = TeamConfig.fromConfig(config.getConfigurationSection("redTeam")!!) + blueTeam = TeamWorldConfig.fromConfig(config.getConfigurationSection("blueTeam")!!) + redTeam = TeamWorldConfig.fromConfig(config.getConfigurationSection("redTeam")!!) teamsOnSameLine = abs(blueTeam.spawnLocation.blockX - redTeam.spawnLocation.blockX) < 20 lobby = config.getWorldLocation("lobby", blueTeam.spawnLocation.clone().add(redTeam.spawnLocation).multiply(0.5)) targetMaterial = Material.matchMaterial(config.getString("targetMaterial", "IRON_BLOCK")!!)!! @@ -76,39 +76,6 @@ object TNTLeagueWorldConfig { Bukkit.shutdown() } } - - @JvmRecord - data class TeamConfig( - val spawnLocation: Location, - val dealerSpawn: Location, - val itemSpawn: Location, - val target: Area - ) { - companion object { - fun fromConfig(config: ConfigurationSection): TeamConfig { - val spawnLocation = config.getWorldLocation("spawn") - val dealerSpawn = config.getWorldLocation("dealerSpawn") - val itemSpawn = config.getWorldLocation("itemSpawn") - val targetPos1 = config.getWorldLocation("targetMin") - val targetPos2 = config.getWorldLocation("targetMax") - - spawnDealer(dealerSpawn) - - return TeamConfig(spawnLocation, dealerSpawn, itemSpawn, Area(targetPos1, targetPos2)) - } - - private fun spawnDealer(loc: Location) = world.spawn(loc, WanderingTrader::class.java) - .apply { - customName(Component.text("Shop")) - isCustomNameVisible = false - isInvulnerable = true - isSilent = true - isCollidable = false - isAware = false - setAI(false) - } - } - } } fun ConfigurationSection.getWorldLocation(s: String, default: Location? = null): Location { diff --git a/TNTLeague/src/de/steamwar/tntleague/config/TeamConfig.kt b/TNTLeague/src/de/steamwar/tntleague/config/TeamConfig.kt new file mode 100644 index 00000000..61cb3431 --- /dev/null +++ b/TNTLeague/src/de/steamwar/tntleague/config/TeamConfig.kt @@ -0,0 +1,67 @@ +/* + * 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.tntleague.config + +import de.steamwar.kotlin.util.Area +import de.steamwar.message.SubMessage +import net.kyori.adventure.text.Component +import org.bukkit.Location +import org.bukkit.configuration.ConfigurationSection +import org.bukkit.entity.WanderingTrader + +data class TeamConfig( + val worldConfig: TeamWorldConfig, + + val name: SubMessage, + val color: Char +) + +@JvmRecord +data class TeamWorldConfig( + val spawnLocation: Location, + val dealerSpawn: Location, + val itemSpawn: Location, + val target: Area +) { + companion object { + fun fromConfig(config: ConfigurationSection): TeamWorldConfig { + val spawnLocation = config.getWorldLocation("spawn") + val dealerSpawn = config.getWorldLocation("dealerSpawn") + val itemSpawn = config.getWorldLocation("itemSpawn") + val targetPos1 = config.getWorldLocation("targetMin") + val targetPos2 = config.getWorldLocation("targetMax") + + spawnDealer(dealerSpawn) + + return TeamWorldConfig(spawnLocation, dealerSpawn, itemSpawn, Area(targetPos1, targetPos2)) + } + + private fun spawnDealer(loc: Location) = world.spawn(loc, WanderingTrader::class.java) + .apply { + customName(Component.text("Shop")) + isCustomNameVisible = false + isInvulnerable = true + isSilent = true + isCollidable = false + isAware = false + setAI(false) + } + } +} diff --git a/TNTLeague/src/de/steamwar/tntleague/events/GlobalListener.kt b/TNTLeague/src/de/steamwar/tntleague/events/GlobalListener.kt index 77aa9dfb..60f921fc 100644 --- a/TNTLeague/src/de/steamwar/tntleague/events/GlobalListener.kt +++ b/TNTLeague/src/de/steamwar/tntleague/events/GlobalListener.kt @@ -66,7 +66,7 @@ object GlobalListener: Listener { fun onPlayerMove(e: PlayerMoveEvent) { if (e.to.blockY < TNTLeagueWorldConfig.minHeight) { when (val team = TNTLeagueGame.getTeam(e.player)) { - is TNTLeagueTeam -> e.player.teleport(team.config.spawnLocation) + is TNTLeagueTeam -> e.player.teleport(team.config.worldConfig.spawnLocation) null -> e.player.teleport(TNTLeagueWorldConfig.blueTeam.spawnLocation) } } @@ -87,7 +87,7 @@ object GlobalListener: Listener { @EventHandler fun onPlayerRespawn(e: PlayerRespawnEvent) { when (val team = TNTLeagueGame.getTeam(e.player)) { - is TNTLeagueTeam -> e.respawnLocation = team.config.spawnLocation + is TNTLeagueTeam -> e.respawnLocation = team.config.worldConfig.spawnLocation null -> e.respawnLocation = TNTLeagueWorldConfig.lobby } } @@ -100,7 +100,7 @@ object GlobalListener: Listener { val fightTeam = TNTLeagueGame.getTeam(player) if (fightTeam != null) { - message.broadcastPrefixless("PARTICIPANT_CHAT", SubMessage(fightTeam.name), player.name, msg) + message.broadcastPrefixless("PARTICIPANT_CHAT", fightTeam.name, player.name, msg) } else { message.broadcastPrefixless("SPECTATOR_CHAT", player.name, msg) } diff --git a/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt b/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt index e064a350..80c86314 100644 --- a/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt +++ b/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt @@ -64,8 +64,8 @@ object TNTLeagueGame { var gameTimeRemaining: Int = TNTLeagueConfig.config.gameTime - val blueTeam = TNTLeagueTeam(TNTLeagueWorldConfig.blueTeam, TNTLeagueTeam.Team.BLUE) - val redTeam = TNTLeagueTeam(TNTLeagueWorldConfig.redTeam, TNTLeagueTeam.Team.RED) + val blueTeam = TNTLeagueTeam(TNTLeagueConfig.config.blueTeam) + val redTeam = TNTLeagueTeam(TNTLeagueConfig.config.redTeam) private lateinit var start: Timestamp @@ -156,10 +156,18 @@ object TNTLeagueGame { fun getTeam(player: Player) = if (player in blueTeam.members) blueTeam else if (player in redTeam.members) redTeam else null - fun getFreeTeam(player: Player) = if (blueTeam.leader == null && (TNTLeagueConfig.config.blueLeader == null || player.uniqueId == TNTLeagueConfig.config.blueLeader)) blueTeam + fun getFreeTeam(player: Player) = if (TNTLeagueConfig.isEvent()) getEventFreeTeam(player) else getNormalFreeTeam(player) + + private fun getNormalFreeTeam(player: Player) = if (blueTeam.leader == null && (TNTLeagueConfig.config.blueLeader == null || player.uniqueId == TNTLeagueConfig.config.blueLeader)) blueTeam else if (redTeam.leader == null && TNTLeagueConfig.config.redLeader == null || player.uniqueId == TNTLeagueConfig.config.redLeader) redTeam else null + private fun getEventFreeTeam(player: Player) = SteamwarUser.get(player.uniqueId).let { user -> + if (user.team == TNTLeagueConfig.config.eventTeamBlue.teamId && blueTeam.members.size < TNTLeagueConfig.config.event.maximumTeamMembers) blueTeam + else if (user.team == TNTLeagueConfig.config.eventTeamRed.teamId && redTeam.members.size < TNTLeagueConfig.config.event.maximumTeamMembers) redTeam + else null + } + fun checkStart() { if (blueTeam.isReady && redTeam.isReady) { blueTeam.leader?.inventory?.clear() @@ -209,18 +217,26 @@ object TNTLeagueGame { fun win(tntLeagueTeam: TNTLeagueTeam, reason: WinReason) { if (state != GameState.RUNNING) return end() - plugin.server.onlinePlayers.forEach { message.send("TEAM_WIN", it, SubMessage(tntLeagueTeam.name)) } + plugin.server.onlinePlayers.forEach { message.send("TEAM_WIN", it, tntLeagueTeam.name) } explode(tntLeagueTeam.opposite) + + if (TNTLeagueConfig.isEvent()) { + TNTLeagueConfig.config.eventFight.ergebnis = tntLeagueTeam.ergebnisInt + } } fun draw(reason: WinReason) { if (state != GameState.RUNNING) return end() message.broadcast("DRAW") + + if (TNTLeagueConfig.isEvent()) { + TNTLeagueConfig.config.eventFight.ergebnis = 3 + } } fun explode(team: TNTLeagueTeam) { - Area(team.config.spawnLocation.clone().add(20.0, 30.0, 20.0), team.config.spawnLocation.clone().subtract(20.0, 0.0, 20.0).add(0.0, 30.0, 0.0)) + Area(team.config.worldConfig.spawnLocation.clone().add(20.0, 30.0, 20.0), team.config.worldConfig.spawnLocation.clone().subtract(20.0, 0.0, 20.0).add(0.0, 30.0, 0.0)) .locations .filterIndexed { index, _ -> index % 7 == 0 } .forEachIndexed { index, location -> @@ -235,8 +251,8 @@ object TNTLeagueGame { plugin.server.worlds.first().name, "TNTLeague", "", - blueTeam.name.colorByTeam(blueTeam), - redTeam.name.colorByTeam(redTeam), + blueTeam.name.message.colorByTeam(blueTeam), + redTeam.name.message.colorByTeam(redTeam), state.lobbyName, TNTLeagueConfig.config.gameTime - gameTimeRemaining, blueTeam.leader?.let { SteamwarUser.get(it.uniqueId).id } ?: 0, diff --git a/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueTeam.kt b/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueTeam.kt index 200f457e..773c4a46 100644 --- a/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueTeam.kt +++ b/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueTeam.kt @@ -22,6 +22,7 @@ package de.steamwar.tntleague.game import de.steamwar.message.SubMessage import de.steamwar.tntleague.colorByTeam import de.steamwar.tntleague.config.TNTLeagueWorldConfig +import de.steamwar.tntleague.config.TeamConfig import de.steamwar.tntleague.config.targetedBlocks import de.steamwar.tntleague.game.TNTLeagueGame.WinReason import de.steamwar.tntleague.game.TNTLeagueGame.updateFightinfo @@ -32,11 +33,10 @@ import net.kyori.adventure.text.Component import org.bukkit.GameMode import org.bukkit.Material import org.bukkit.Sound -import org.bukkit.enchantments.Enchantment import org.bukkit.entity.Player import org.bukkit.inventory.ItemStack -data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private val team: Team) { +data class TNTLeagueTeam(val config: TeamConfig) { var leader: Player? = null set(player) { @@ -52,11 +52,11 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va val members = mutableListOf() val invites = mutableListOf() - val name: String - get() = team.name.uppercase() + val name: SubMessage + get() = config.name val color: Char - get() = team.color + get() = config.color var isReady: Boolean = false set(value) { @@ -64,7 +64,7 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va leader?.inventory?.setItem(4, readyItem()) leader?.let { it.playSound(it.location, Sound.BLOCK_NOTE_BLOCK_PLING, 1f, 1f) } - message.broadcastActionbar(if (value) "IS_READY" else "IS_NOT_READY", SubMessage(name)) + message.broadcastActionbar(if (value) "IS_READY" else "IS_NOT_READY", name) if (value && opposite.isReady) { TNTLeagueGame.checkStart() @@ -82,19 +82,27 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va var coins: Int = 0 val opposite: TNTLeagueTeam - get() = when (team) { - Team.BLUE -> TNTLeagueGame.redTeam - Team.RED -> TNTLeagueGame.blueTeam + get() = when (this) { + TNTLeagueGame.redTeam -> TNTLeagueGame.blueTeam + TNTLeagueGame.blueTeam -> TNTLeagueGame.redTeam + else -> error("Invalid Team") + } + + val ergebnisInt: Int + get() = when (this) { + TNTLeagueGame.redTeam -> 2 + TNTLeagueGame.blueTeam -> 3 + else -> error("Invalid Team") } fun join(player: Player): Boolean { members.add(player) with(player) { - teleport(config.spawnLocation) + teleport(config.worldConfig.spawnLocation) gameMode = GameMode.ADVENTURE inventory.clear() - message.broadcast("JOIN_TEAM", name.colorByTeam(this@TNTLeagueTeam), SubMessage(this@TNTLeagueTeam.name)) + message.broadcast("JOIN_TEAM", name.colorByTeam(this@TNTLeagueTeam), this@TNTLeagueTeam.name) } if (leader == null) { @@ -154,13 +162,8 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va teleport(TNTLeagueWorldConfig.lobby) gameMode = GameMode.SPECTATOR inventory.clear() - message.broadcast("QUIT_TEAM", name.colorByTeam(this@TNTLeagueTeam), SubMessage(this@TNTLeagueTeam.name)) + message.broadcast("QUIT_TEAM", name.colorByTeam(this@TNTLeagueTeam), this@TNTLeagueTeam.name) } updateFightinfo() } - - enum class Team(val color: Char) { - BLUE('3'), - RED('c'); - } } \ No newline at end of file diff --git a/TNTLeague/src/de/steamwar/tntleague/util/TNTLeagueScoreboard.kt b/TNTLeague/src/de/steamwar/tntleague/util/TNTLeagueScoreboard.kt index 77ba1d48..204680d0 100644 --- a/TNTLeague/src/de/steamwar/tntleague/util/TNTLeagueScoreboard.kt +++ b/TNTLeague/src/de/steamwar/tntleague/util/TNTLeagueScoreboard.kt @@ -50,10 +50,10 @@ data class TNTLeagueScoreboard(val p: Player): ScoreboardCallback { lines.add("§3") with(TNTLeagueGame.redTeam) { - lines.add(message.parse("SCOREBOARD_TEAM", p, SubMessage(name), targetedBlocks - damagedBlocks)) + lines.add(message.parse("SCOREBOARD_TEAM", p, name, targetedBlocks - damagedBlocks)) } with(TNTLeagueGame.blueTeam) { - lines.add(message.parse("SCOREBOARD_TEAM", p, SubMessage(name), targetedBlocks - damagedBlocks)) + lines.add(message.parse("SCOREBOARD_TEAM", p, name, targetedBlocks - damagedBlocks)) } lines.add("§4") From 482282f913cceb3011b6e6fd7b258630880d40ef Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sat, 1 Feb 2025 22:00:36 +0100 Subject: [PATCH 011/124] Make TNTLeague Event System Capable --- .../src/de/steamwar/message/Message.java | 7 ++--- .../src/de/steamwar/message/SubMessage.java | 29 +++++-------------- .../steamwar/tntleague/TNTLeague.properties | 1 + .../tntleague/config/TNTLeagueConfig.kt | 8 ++--- 4 files changed, 15 insertions(+), 30 deletions(-) diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/message/Message.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/message/Message.java index f953ce8d..b9ae84b7 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/message/Message.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/message/Message.java @@ -72,12 +72,9 @@ public class Message { pattern += fromRB(resourceBundle, message); for (int i = 0; i < params.length; i++) { - if (params[i] instanceof SubMessage.Translatable) { - SubMessage.Translatable smsg = (SubMessage.Translatable) params[i]; + if (params[i] instanceof SubMessage) { + SubMessage smsg = (SubMessage) params[i]; params[i] = parse(smsg.getMessage(), sender, smsg.getParams()); - } else if (params[i] instanceof SubMessage.Literal) { - SubMessage.Literal smsg = (SubMessage.Literal) params[i]; - params[i] = smsg.getMessage(); } } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/message/SubMessage.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/message/SubMessage.java index 4c302689..e40b74a5 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/message/SubMessage.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/message/SubMessage.java @@ -19,33 +19,20 @@ package de.steamwar.message; -import lombok.AllArgsConstructor; import lombok.Getter; @Getter -@AllArgsConstructor -public abstract class SubMessage { +public class SubMessage { private final String message; + private final Object[] params; - @Getter - public static class Translatable extends SubMessage { - private final Object[] params; - - public Translatable(String message, Object... params) { - super(message); - this.params = params; - } - - public Translatable(String message) { - super(message); - this.params = new Object[0]; - } + public SubMessage(String message, Object... params) { + this.message = message; + this.params = params; } - @Getter - public static class Literal extends SubMessage { - public Literal(String message) { - super(message); - } + public SubMessage(String message) { + this.message = message; + this.params = new Object[0]; } } diff --git a/TNTLeague/src/de/steamwar/tntleague/TNTLeague.properties b/TNTLeague/src/de/steamwar/tntleague/TNTLeague.properties index 05d998e2..73e3b416 100644 --- a/TNTLeague/src/de/steamwar/tntleague/TNTLeague.properties +++ b/TNTLeague/src/de/steamwar/tntleague/TNTLeague.properties @@ -18,6 +18,7 @@ # PREFIX=§eTNT§7League§8» +PLAIN_STRING={0} JOIN=§e{0} §7joined the game! JOIN_TEAM={0} §7joined the {1} §7team! QUIT={0} §7left the game! diff --git a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt index e5bccb08..7b1e865a 100644 --- a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt +++ b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt @@ -60,11 +60,11 @@ data class TNTLeagueConfig( eventTeamBlue = Team.get(eventFight.teamBlue) eventTeamRed = Team.get(eventFight.teamRed) - blueTeam = TeamConfig(TNTLeagueWorldConfig.blueTeam, SubMessage.Literal("§${eventTeamBlue.teamColor}${eventTeamBlue.teamName}"), eventTeamBlue.teamColor[0]) - redTeam = TeamConfig(TNTLeagueWorldConfig.redTeam, SubMessage.Literal("§${eventTeamRed.teamColor}${eventTeamRed.teamName}"), eventTeamRed.teamColor[0]) + blueTeam = TeamConfig(TNTLeagueWorldConfig.blueTeam, SubMessage("PLAIN_STRING", "§${eventTeamBlue.teamColor}${eventTeamBlue.teamName}"), eventTeamBlue.teamColor[0]) + redTeam = TeamConfig(TNTLeagueWorldConfig.redTeam, SubMessage("PLAIN_STRING", "§${eventTeamRed.teamColor}${eventTeamRed.teamName}"), eventTeamRed.teamColor[0]) } else { - blueTeam = TeamConfig(TNTLeagueWorldConfig.blueTeam, SubMessage.Translatable("BLUE"), '3') - redTeam = TeamConfig(TNTLeagueWorldConfig.redTeam, SubMessage.Translatable("RED"), 'c') + blueTeam = TeamConfig(TNTLeagueWorldConfig.blueTeam, SubMessage("BLUE"), '3') + redTeam = TeamConfig(TNTLeagueWorldConfig.redTeam, SubMessage("RED"), 'c') } } From 414bd20eb9eaa6d01c0d1678b89278b3a76b690b Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sat, 1 Feb 2025 22:58:49 +0100 Subject: [PATCH 012/124] Make TowerRun Event System Capable --- .../src/de/steamwar/towerrun/TowerRun.java | 1 - .../de/steamwar/towerrun/config/Config.java | 33 +++++++++++++++++++ .../steamwar/towerrun/game/TowerRunGame.java | 11 ++++++- .../towerrun/listener/GlobalListener.java | 5 --- .../towerrun/listener/LobbyListener.java | 22 +++++++++++++ 5 files changed, 65 insertions(+), 7 deletions(-) diff --git a/TowerRun/src/de/steamwar/towerrun/TowerRun.java b/TowerRun/src/de/steamwar/towerrun/TowerRun.java index 23f00488..7e6df112 100644 --- a/TowerRun/src/de/steamwar/towerrun/TowerRun.java +++ b/TowerRun/src/de/steamwar/towerrun/TowerRun.java @@ -73,7 +73,6 @@ public class TowerRun extends JavaPlugin { new LobbyListener(); new IngameListener(); new GlobalListener(); - new LobbyListener(); new NotLobbyListener(); final LobbyCountdown lobbyCountdown = new LobbyCountdown(); new EndCountdown(lobbyCountdown); diff --git a/TowerRun/src/de/steamwar/towerrun/config/Config.java b/TowerRun/src/de/steamwar/towerrun/config/Config.java index 91fb02b4..fe6acd07 100644 --- a/TowerRun/src/de/steamwar/towerrun/config/Config.java +++ b/TowerRun/src/de/steamwar/towerrun/config/Config.java @@ -19,6 +19,8 @@ package de.steamwar.towerrun.config; +import de.steamwar.sql.Event; +import de.steamwar.sql.EventFight; import de.steamwar.towerrun.TowerRun; import lombok.experimental.UtilityClass; import org.bukkit.Bukkit; @@ -41,6 +43,12 @@ public class Config { private static final int EVENT_KAMPF_ID; + // Event + public static final EventFight EVENT_FIGHT; + public static final int EVENT_TEAM_BLUE_ID; + public static final int EVENT_TEAM_RED_ID; + public static final int EVENT_MAXIMUM_TEAM_MEMBERS; + static { File configFile = new File(TowerRun.getInstance().getDataFolder(), "config.yml"); if (!configFile.exists()) { @@ -57,9 +65,34 @@ public class Config { DESTROYABLE_BLOCKS = EnumSet.copyOf(config.getStringList("destroyable").stream().map(Material::valueOf).collect(Collectors.toSet())); EVENT_KAMPF_ID = Integer.parseInt(System.getProperty("fightID", "0")); + + if (event()) { + EVENT_FIGHT = EventFight.get(EVENT_KAMPF_ID); + + if (EVENT_FIGHT == null) { + Bukkit.shutdown(); + throw new IllegalStateException("Event not found"); + } + + Event event = Event.get(EVENT_FIGHT.getEventID()); + + EVENT_TEAM_BLUE_ID = EVENT_FIGHT.getTeamBlue(); + EVENT_TEAM_RED_ID = EVENT_FIGHT.getTeamRed(); + EVENT_MAXIMUM_TEAM_MEMBERS = event.getMaximumTeamMembers(); + } else { + EVENT_FIGHT = null; + + EVENT_TEAM_BLUE_ID = 0; + EVENT_TEAM_RED_ID = 0; + EVENT_MAXIMUM_TEAM_MEMBERS = Integer.MAX_VALUE; + } } public static boolean test() { return EVENT_KAMPF_ID == -1; } + + public static boolean event() { + return EVENT_KAMPF_ID > 0; + } } diff --git a/TowerRun/src/de/steamwar/towerrun/game/TowerRunGame.java b/TowerRun/src/de/steamwar/towerrun/game/TowerRunGame.java index c83138d4..2c014cb5 100644 --- a/TowerRun/src/de/steamwar/towerrun/game/TowerRunGame.java +++ b/TowerRun/src/de/steamwar/towerrun/game/TowerRunGame.java @@ -20,7 +20,9 @@ package de.steamwar.towerrun.game; import de.steamwar.core.CraftbukkitWrapper; +import de.steamwar.sql.SteamwarUser; import de.steamwar.towerrun.TowerRun; +import de.steamwar.towerrun.config.Config; import de.steamwar.towerrun.config.WorldConfig; import de.steamwar.towerrun.state.GameState; import de.steamwar.towerrun.state.GameStates; @@ -64,7 +66,6 @@ public class TowerRunGame { public static void start() { if (GameState.getCurrentState() == GameStates.GENERATING_TOWER) { - PLAYERS_ALIVE.addAll(TowerRunPlayer.getAll()); PLAYERS_ALIVE.forEach(p -> { p.reset(); p.player().setGameMode(GameMode.SURVIVAL); @@ -108,6 +109,10 @@ public class TowerRunGame { PLAYERS_ALIVE.clear(); Bukkit.getOnlinePlayers().forEach(player -> player.sendTitle(TowerRun.getMessage().parse("GAME_TIE", player), "", 10, 70, 20)); GameState.nextState(); + + if (Config.event()) { + Config.EVENT_FIGHT.setErgebnis(3); + } } public static void win(TowerRunPlayer tPlayer) { @@ -120,6 +125,10 @@ public class TowerRunGame { player.playSound(player.getLocation(), Sound.ENTITY_ENDER_DRAGON_DEATH, 1, 1); }); GameState.nextState(); + + if (Config.event()) { + Config.EVENT_FIGHT.setErgebnis(SteamwarUser.get(tPlayer.player().getUniqueId()).getTeam() == Config.EVENT_TEAM_BLUE_ID ? 1 : 2); + } } public static void reset() { diff --git a/TowerRun/src/de/steamwar/towerrun/listener/GlobalListener.java b/TowerRun/src/de/steamwar/towerrun/listener/GlobalListener.java index 353adc20..b8256d80 100644 --- a/TowerRun/src/de/steamwar/towerrun/listener/GlobalListener.java +++ b/TowerRun/src/de/steamwar/towerrun/listener/GlobalListener.java @@ -38,11 +38,6 @@ public class GlobalListener extends GameStateBukkitListener { super(EnumSet.allOf(GameStates.class)); } - @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { - TowerRunPlayer.get(event.getPlayer()); - } - @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { if (TowerRunGame.isAlive(TowerRunPlayer.get(event.getPlayer()))) { diff --git a/TowerRun/src/de/steamwar/towerrun/listener/LobbyListener.java b/TowerRun/src/de/steamwar/towerrun/listener/LobbyListener.java index 52d600ca..c93bc4bb 100644 --- a/TowerRun/src/de/steamwar/towerrun/listener/LobbyListener.java +++ b/TowerRun/src/de/steamwar/towerrun/listener/LobbyListener.java @@ -19,8 +19,12 @@ package de.steamwar.towerrun.listener; +import de.steamwar.sql.SteamwarUser; 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.game.TowerRunPlayer; import de.steamwar.towerrun.state.GameStateBukkitListener; import de.steamwar.towerrun.state.GameStates; import org.bukkit.GameMode; @@ -34,6 +38,7 @@ import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerMoveEvent; import java.util.EnumSet; +import java.util.HashMap; public class LobbyListener extends GameStateBukkitListener { public LobbyListener() { @@ -43,6 +48,7 @@ public class LobbyListener extends GameStateBukkitListener { @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { Player player = event.getPlayer(); + if (TowerRun.getTowerGenerator() != null) { player.teleport(TowerRun.getTowerGenerator().getSpawn()); player.setGameMode(GameMode.SPECTATOR); @@ -50,6 +56,22 @@ public class LobbyListener extends GameStateBukkitListener { player.teleport(WorldConfig.SPAWN); player.setGameMode(GameMode.SURVIVAL); } + + if (Config.event()) { + SteamwarUser user = SteamwarUser.get(player.getUniqueId()); + 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 { + TowerRunGame.PLAYERS_ALIVE.add(TowerRunPlayer.get(player)); + } } @EventHandler From 93ab1a50f32d624dbe90d920b0848dc40d437d2c Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 2 Feb 2025 14:12:25 +0100 Subject: [PATCH 013/124] Fix team auto-assign logic in lobby state Replaced `members.add` with `join` to correctly integrate new players into teams during the lobby phase. This ensures proper team setup and adherence to game mechanics. --- TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueTeam.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueTeam.kt b/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueTeam.kt index 773c4a46..8b452fca 100644 --- a/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueTeam.kt +++ b/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueTeam.kt @@ -139,7 +139,7 @@ data class TNTLeagueTeam(val config: TeamConfig) { if (TNTLeagueGame.state == TNTLeagueGame.GameState.LOBBY) { if (members.isEmpty()) { plugin.server.onlinePlayers.firstOrNull { it != player && TNTLeagueGame.getTeam(it) == null }?.run { - members.add(this) + join(this) } } if (leader == player) { From b4baef321fa5c3069fd08af61019830f5ecd01a3 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Sun, 2 Feb 2025 15:28:33 +0100 Subject: [PATCH 014/124] Trigger rebuild --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ad9f4739..65e4bf0e 100644 --- a/README.md +++ b/README.md @@ -1 +1,2 @@ # SteamWar + From e39db5978bd60d6939bb66d6e70a3492cb714541 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 2 Feb 2025 16:06:48 +0100 Subject: [PATCH 015/124] Add server shutdown if less than 2 players after 5 minutes --- TNTLeague/src/de/steamwar/tntleague/TNTLeague.kt | 7 +++++++ .../src/de/steamwar/tntleague/events/LobbyListener.kt | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/TNTLeague/src/de/steamwar/tntleague/TNTLeague.kt b/TNTLeague/src/de/steamwar/tntleague/TNTLeague.kt index 378dbfc7..d24cdf6f 100644 --- a/TNTLeague/src/de/steamwar/tntleague/TNTLeague.kt +++ b/TNTLeague/src/de/steamwar/tntleague/TNTLeague.kt @@ -27,6 +27,8 @@ import de.steamwar.tntleague.command.RemoveCommand import de.steamwar.tntleague.events.GlobalListener import de.steamwar.tntleague.events.LobbyListener import de.steamwar.tntleague.game.TNTLeagueTeam +import net.kyori.adventure.text.Component +import org.bukkit.Bukkit import org.bukkit.plugin.java.JavaPlugin lateinit var plugin: TNTLeague @@ -49,6 +51,11 @@ class TNTLeague : JavaPlugin() { AcceptCommand.register() RemoveCommand.register() LeaveCommand.register() + + plugin.server.scheduler.runTaskLater(plugin, Runnable { + if (server.onlinePlayers.size >= 2) return@Runnable + Bukkit.shutdown() + }, 20 * 60 * 5) } } diff --git a/TNTLeague/src/de/steamwar/tntleague/events/LobbyListener.kt b/TNTLeague/src/de/steamwar/tntleague/events/LobbyListener.kt index bb570498..d160498f 100644 --- a/TNTLeague/src/de/steamwar/tntleague/events/LobbyListener.kt +++ b/TNTLeague/src/de/steamwar/tntleague/events/LobbyListener.kt @@ -23,7 +23,6 @@ import de.steamwar.tntleague.game.TNTLeagueGame import org.bukkit.GameMode import org.bukkit.entity.EntityType import org.bukkit.event.EventHandler -import org.bukkit.event.EventPriority import org.bukkit.event.Listener import org.bukkit.event.entity.EntityDamageEvent import org.bukkit.event.inventory.InventoryClickEvent From 1715fdccdf717a3b56241d8723cf68c9dd7c86d8 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 2 Feb 2025 16:07:24 +0100 Subject: [PATCH 016/124] Remove unused imports in TNTLeague classes --- TNTLeague/src/de/steamwar/tntleague/TNTLeague.kt | 1 - TNTLeague/src/de/steamwar/tntleague/util/TNTLeagueScoreboard.kt | 2 -- 2 files changed, 3 deletions(-) diff --git a/TNTLeague/src/de/steamwar/tntleague/TNTLeague.kt b/TNTLeague/src/de/steamwar/tntleague/TNTLeague.kt index d24cdf6f..ef3b8a81 100644 --- a/TNTLeague/src/de/steamwar/tntleague/TNTLeague.kt +++ b/TNTLeague/src/de/steamwar/tntleague/TNTLeague.kt @@ -27,7 +27,6 @@ import de.steamwar.tntleague.command.RemoveCommand import de.steamwar.tntleague.events.GlobalListener import de.steamwar.tntleague.events.LobbyListener import de.steamwar.tntleague.game.TNTLeagueTeam -import net.kyori.adventure.text.Component import org.bukkit.Bukkit import org.bukkit.plugin.java.JavaPlugin diff --git a/TNTLeague/src/de/steamwar/tntleague/util/TNTLeagueScoreboard.kt b/TNTLeague/src/de/steamwar/tntleague/util/TNTLeagueScoreboard.kt index 204680d0..40fb4138 100644 --- a/TNTLeague/src/de/steamwar/tntleague/util/TNTLeagueScoreboard.kt +++ b/TNTLeague/src/de/steamwar/tntleague/util/TNTLeagueScoreboard.kt @@ -19,9 +19,7 @@ package de.steamwar.tntleague.util -import de.steamwar.message.SubMessage import de.steamwar.scoreboard.ScoreboardCallback -import de.steamwar.tntleague.colorByTeam import de.steamwar.tntleague.config.targetedBlocks import de.steamwar.tntleague.game.TNTLeagueGame import de.steamwar.tntleague.game.TNTLeagueTeam From 25cf1ab314dacee4d7479390542b36a2ad5b4720 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 2 Feb 2025 16:11:02 +0100 Subject: [PATCH 017/124] Add ReadyCommand --- .../src/de/steamwar/tntleague/TNTLeague.kt | 6 ++-- .../tntleague/command/ReadyCommand.kt | 33 +++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 TNTLeague/src/de/steamwar/tntleague/command/ReadyCommand.kt diff --git a/TNTLeague/src/de/steamwar/tntleague/TNTLeague.kt b/TNTLeague/src/de/steamwar/tntleague/TNTLeague.kt index 378dbfc7..2c63ae94 100644 --- a/TNTLeague/src/de/steamwar/tntleague/TNTLeague.kt +++ b/TNTLeague/src/de/steamwar/tntleague/TNTLeague.kt @@ -20,10 +20,7 @@ package de.steamwar.tntleague import de.steamwar.message.Message -import de.steamwar.tntleague.command.AcceptCommand -import de.steamwar.tntleague.command.InviteCommand -import de.steamwar.tntleague.command.LeaveCommand -import de.steamwar.tntleague.command.RemoveCommand +import de.steamwar.tntleague.command.* import de.steamwar.tntleague.events.GlobalListener import de.steamwar.tntleague.events.LobbyListener import de.steamwar.tntleague.game.TNTLeagueTeam @@ -45,6 +42,7 @@ class TNTLeague : JavaPlugin() { logger.info("TNTLeague enabled") + ReadyCommand.register() InviteCommand.register() AcceptCommand.register() RemoveCommand.register() diff --git a/TNTLeague/src/de/steamwar/tntleague/command/ReadyCommand.kt b/TNTLeague/src/de/steamwar/tntleague/command/ReadyCommand.kt new file mode 100644 index 00000000..e53444ce --- /dev/null +++ b/TNTLeague/src/de/steamwar/tntleague/command/ReadyCommand.kt @@ -0,0 +1,33 @@ +/* + * 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.tntleague.command + +import de.steamwar.command.SWCommand +import de.steamwar.tntleague.game.TNTLeagueGame +import org.bukkit.entity.Player + +object ReadyCommand: SWCommand("ready") { + + @Register + fun invitePlayer(@Validator("isLeader") sender: Player) { + if (TNTLeagueGame.state != TNTLeagueGame.GameState.LOBBY) return + TNTLeagueGame.getTeam(sender)?.also { it.isReady = it.isReady.not() } + } +} \ No newline at end of file From ec43e7eba8d4ffecd4c44f3670486f4cf2bfae2a Mon Sep 17 00:00:00 2001 From: Lixfel Date: Sun, 2 Feb 2025 16:29:10 +0100 Subject: [PATCH 018/124] Trigger rebuild --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 65e4bf0e..ad9f4739 100644 --- a/README.md +++ b/README.md @@ -1,2 +1 @@ # SteamWar - From 6aeecd444e2cdd3bfaf78c05e6ff07ede2db3e6a Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Tue, 4 Feb 2025 21:47:29 +0100 Subject: [PATCH 019/124] Authentication v2 --- .../src/de/steamwar/plugins/Plugins.kt | 12 ++ .../src/de/steamwar/routes/Routes.kt | 4 + .../src/de/steamwar/routes/v2/Auth.kt | 151 ++++++++++++++++++ .../src/de/steamwar/util/TokenUtils.kt | 57 +++++++ 4 files changed, 224 insertions(+) create mode 100644 WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt create mode 100644 WebsiteBackend/src/de/steamwar/util/TokenUtils.kt diff --git a/WebsiteBackend/src/de/steamwar/plugins/Plugins.kt b/WebsiteBackend/src/de/steamwar/plugins/Plugins.kt index fc8dde36..0cff0a03 100644 --- a/WebsiteBackend/src/de/steamwar/plugins/Plugins.kt +++ b/WebsiteBackend/src/de/steamwar/plugins/Plugins.kt @@ -20,7 +20,11 @@ package de.steamwar.plugins import de.steamwar.sql.Token +import de.steamwar.util.TokenType +import de.steamwar.util.isValid +import de.steamwar.util.type import io.ktor.http.* +import io.ktor.http.auth.* import io.ktor.serialization.kotlinx.json.* import io.ktor.server.application.* import io.ktor.server.auth.* @@ -66,6 +70,14 @@ fun Application.configurePlugins() { if (token == null) { null } else { + if (!token.isValid) { + token.delete() + return@authenticate null + } + if (token.type == TokenType.RESET_PASSWORD || token.type == TokenType.REFRESH_TOKEN) { + token.delete() + } + SWAuthPrincipal(token, token.owner) } } diff --git a/WebsiteBackend/src/de/steamwar/routes/Routes.kt b/WebsiteBackend/src/de/steamwar/routes/Routes.kt index 041d4b31..1da4ed29 100644 --- a/WebsiteBackend/src/de/steamwar/routes/Routes.kt +++ b/WebsiteBackend/src/de/steamwar/routes/Routes.kt @@ -19,6 +19,7 @@ package de.steamwar.routes +import de.steamwar.routes.v2.configureNewAuth import io.ktor.server.application.* import io.ktor.server.auth.* import io.ktor.server.routing.* @@ -34,6 +35,9 @@ fun Application.configureRoutes() { configurePage() configureSchematic() configureAuthRoutes() + route("/v2") { + configureNewAuth() + } } } } \ No newline at end of file diff --git a/WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt b/WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt new file mode 100644 index 00000000..24e5cee6 --- /dev/null +++ b/WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt @@ -0,0 +1,151 @@ +/* + * 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.routes.v2 + +import de.steamwar.ResponseError +import de.steamwar.plugins.SWAuthPrincipal +import de.steamwar.sql.SWException +import de.steamwar.sql.SteamwarUser +import de.steamwar.sql.Token +import de.steamwar.util.TokenType +import de.steamwar.util.isValid +import de.steamwar.util.lifetime +import de.steamwar.util.type +import io.ktor.http.* +import io.ktor.server.application.* +import io.ktor.server.auth.* +import io.ktor.server.http.* +import io.ktor.server.plugins.* +import io.ktor.server.request.* +import io.ktor.server.response.* +import io.ktor.server.routing.* +import kotlinx.serialization.Serializable +import java.time.LocalDateTime +import kotlin.time.Duration +import kotlin.time.toJavaDuration + +@Serializable +data class UsernamePassword(val name: String, val password: String, val keepLoggedIn: Boolean = false) + +@Serializable +data class ResponseToken(val token: String, val expires: String) { + constructor(token: String, lifetime: Duration) : this(token, LocalDateTime.now().plus(lifetime.toJavaDuration()).toString()) +} + +@Serializable +data class AuthTokenResponse(val accessToken: ResponseToken, val refreshToken: ResponseToken? = null) + +fun SteamwarUser.createAccessAndRefreshToken(keepLoggedIn: Boolean = false): AuthTokenResponse { + val code = System.currentTimeMillis() % 1000 + val accessToken = Token.createToken("AT-${userName}-${code}", this) + val refreshToken = if (keepLoggedIn) Token.createToken("RT-${userName}-${code}", this) else null + + return AuthTokenResponse(ResponseToken(accessToken, TokenType.ACCESS_TOKEN.lifetime), refreshToken?.let { ResponseToken(it, TokenType.REFRESH_TOKEN.lifetime) }) +} + +fun Route.configureNewAuth() { + route("/auth") { + route("/enroll") { + post("/{userId}") { + if (call.request.headers.contains("X-Forwarded-For")) { + SWException.log("Request to /auth/register from", "Invalid IP") + call.respond(HttpStatusCode.Forbidden, ResponseError("Invalid IP", "F_U")) + return@post + } + + val userId = call.parameters["userId"]?.toInt() + if (userId == null) { + call.respond(HttpStatusCode.BadRequest, ResponseError("Missing or invalid userId")) + return@post + } + + val user = SteamwarUser.get(userId) + if (user == null) { + call.respond(HttpStatusCode.BadRequest, ResponseError("Invalid userId")) + return@post + } + + val token = Token.createToken("PT-${user.userName}", user) + + call.respond(HttpStatusCode.OK, ResponseToken(token, TokenType.RESET_PASSWORD.lifetime)) + } + } + + post("/register") { + val requester = call.request.header("X-Forwarded-For") ?: call.request.origin.remoteAddress + + val request = call.receive() + val token = call.principal() + + if (token == null || token.token.type != TokenType.RESET_PASSWORD || !token.token.isValid) { + SWException.log("$requester tried registering with invalid token", "") + call.respond(HttpStatusCode.Forbidden, ResponseError("Invalid token", "invalid")) + return@post + } + + val user = token.user + + if (user.userName != request.name) { + SWException.log("$requester tried registering for invalid User", """ + User: ${user.userName} + Request: ${request.name} + """.trimIndent()) + call.respond(HttpStatusCode.Forbidden, ResponseError("Invalid username", "invalid")) + return@post + } + + user.setPassword(request.password) + + call.respond(HttpStatusCode.OK) + } + route("/state") { + post("/create") { + val request = call.receive() + + val user = SteamwarUser.get(request.name) + val valid = user?.verifyPassword(request.password) ?: false + + if (!valid) { + call.respond(HttpStatusCode.Forbidden, ResponseError("Invalid username or password", "invalid")) + return@post + } + + call.respond(user.createAccessAndRefreshToken(request.keepLoggedIn)) + } + post("/refresh") { + val token = call.principal() + + if (token == null || token.token.type != TokenType.REFRESH_TOKEN) { + call.respond(HttpStatusCode.Forbidden, ResponseError("Invalid token type", "invalid")) + return@post + } + + val code = token.token.name.substringAfterLast('-') + + Token.listUser(token.user) + .filter { it.type == TokenType.ACCESS_TOKEN } + .filter { it.name.endsWith(code) } + .forEach { it.delete() } + + call.respond(token.user.createAccessAndRefreshToken(true)) + } + } + } +} \ No newline at end of file diff --git a/WebsiteBackend/src/de/steamwar/util/TokenUtils.kt b/WebsiteBackend/src/de/steamwar/util/TokenUtils.kt new file mode 100644 index 00000000..7a70c2f3 --- /dev/null +++ b/WebsiteBackend/src/de/steamwar/util/TokenUtils.kt @@ -0,0 +1,57 @@ +/* + * 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.util + +import de.steamwar.sql.Token +import java.time.LocalDateTime +import kotlin.time.Duration +import kotlin.time.Duration.Companion.days +import kotlin.time.Duration.Companion.hours +import kotlin.time.Duration.Companion.minutes +import kotlin.time.toJavaDuration + +val Token.type: TokenType + get() = when (name.substring((0..1))) { + "RT" -> TokenType.REFRESH_TOKEN + "AT" -> TokenType.ACCESS_TOKEN + "PT" -> TokenType.RESET_PASSWORD + else -> TokenType.OLD_TOKEN + } + +val TokenType.lifetime: Duration + get() = when (this) { + TokenType.REFRESH_TOKEN -> 7.days + TokenType.ACCESS_TOKEN -> 1.hours + TokenType.RESET_PASSWORD -> 10.minutes + TokenType.OLD_TOKEN -> 1.days + } + +val Token.lifetime: Duration + get() = type.lifetime + +val Token.isValid: Boolean + get() = created.toLocalDateTime().plus(lifetime.toJavaDuration()).isAfter(LocalDateTime.now()) + +enum class TokenType { + RESET_PASSWORD, + ACCESS_TOKEN, + REFRESH_TOKEN, + OLD_TOKEN +} \ No newline at end of file From dd9467fa36912e8130d78f78bd00d8306a6404fd Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 14 Feb 2025 16:53:26 +0100 Subject: [PATCH 020/124] Hotfix TeamPlayer.onPlayerInteractEntity --- LobbySystem/src/de/steamwar/lobby/team/TeamPlayer.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/LobbySystem/src/de/steamwar/lobby/team/TeamPlayer.java b/LobbySystem/src/de/steamwar/lobby/team/TeamPlayer.java index 989fca7a..ce14aa04 100644 --- a/LobbySystem/src/de/steamwar/lobby/team/TeamPlayer.java +++ b/LobbySystem/src/de/steamwar/lobby/team/TeamPlayer.java @@ -148,6 +148,8 @@ public class TeamPlayer extends BasicListener { return; } + event.setCancelled(true); + SteamwarUser target = SteamwarUser.get(event.getRightClicked().getName()); String message; try { From 5420c19b391cc91580a5826346d78e754d6d3986 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 14 Feb 2025 20:34:49 +0100 Subject: [PATCH 021/124] Add SCRIPT.md and sw.def.lua --- BauSystem/SCRIPT.md | 419 ++++++++++++++++++++++++++++++++++++++++++ BauSystem/sw.def.lua | 428 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 847 insertions(+) create mode 100644 BauSystem/SCRIPT.md create mode 100644 BauSystem/sw.def.lua diff --git a/BauSystem/SCRIPT.md b/BauSystem/SCRIPT.md new file mode 100644 index 00000000..ae9cb181 --- /dev/null +++ b/BauSystem/SCRIPT.md @@ -0,0 +1,419 @@ +# SteamWar.de - Script System + +--- + +* [SteamWar.de - Script System](#steamwarde---script-system) + * [Einleitung](#einleitung) + * [Nutzung mit einer IDE](#nutzung-mit-einer-ide) +* [Basis-Apis](#basis-apis) +* [SteamWar.de-Api](#steamwarde-api) + * [player](#player) + * [random](#random) + * [region](#region) + * [tnt](#tnt) + * [trace](#trace) + * [server](#server) + * [tps](#tps) + * [storage](#storage) + * [inventory](#inventory) +* [SteamWar.de-Global-Api](#steamwarde-global-api) + * [Commands](#commands) + * [Hotkeys](#hotkeys) + * [Eventtypen](#eventtypen) + * [BlockEvent](#blockevent) + * [InteractEvent](#interactevent) + * [Position](#position) +* [Instabile APIs](#instabile-apis) + * [_worldedit](#worldedit) +* [Beispiele](#beispiele) + * [Hello, World!](#hello-world) + * [Code](#code) + * [Ausgabe](#ausgabe) + * [BauGUI on DoubleSwap](#baugui-on-doubleswap) + * [Code](#code-1) + * [SL Command](#sl-command) + * [Code](#code-2) + * [Paste Hotkey](#paste-hotkey) + * [Code](#code-3) + * [Inventory](#inventory-1) + * [Code](#code-4) + + + +## Einleitung +Das Script System auf SteamWar.de basiert auf [Lua](https://www.lua.org/docs.html). +Der Code wird einfach in ein Minecraft Buch geschrieben und kann mit einem Links-Klick ausgeführt werden. + +## Nutzung mit einer IDE +Im Repository liegen [Lua-Definitionen](sw.def.lua) für [Luanalysis](https://plugins.jetbrains.com/plugin/14698-luanalysis). +Diese können in der IDE genutzt werden, um die APIs zu nutzen. + +Einfach die `sw.def.lua` in denselben Ordner wie das Script legen und die IDE sollte die APIs erkennen. + +# Basis-Apis +Es werden folgende Standard-Apis zur Verfügung gestellt: +- [`math`](https://www.lua.org/manual/5.4/manual.html#6.7) +- [`string`](https://www.lua.org/manual/5.4/manual.html#6.4) +- [`table`](https://www.lua.org/manual/5.4/manual.html#6.6) +- [`bit32`](https://www.lua.org/manual/5.2/manual.html#6.7) + +# SteamWar.de-Api +APIs, die mit einem `_` beginnen sind noch nicht stabil und können sich jederzeit ändern. +Sie sollten daher nicht verwendet werden, da sie sich noch in der Entwicklung befinden. +Diese können auch undokumentierte Funktionen enthalten, die nicht in der Dokumentation aufgeführt sind. + +In den Scripten gibt es dazu noch folgende globale Variablen: +- [`player`](#player) +- [`random`](#random) +- [`region`](#region) +- [`server`](#server) +- [`storage`](#storage) +- [`inventory`](#inventory) +- `_worldedit` + +Ohne eine Kategorie sind folgende Funktionen verfügbar, die nicht allgemein sind: + +| Name | Signature | Beschreibung | +|-----------|-----------------------------------|-------------------------------------------------------------------------------------------------------------------| +| `print` | print(String...) | @see chat(String...) | +| `input` | input(String, Function\) | Fragt den User nach einer Eingabe mit der Nachricht und called die zugehörige Funktion nach dieser | +| `delayed` | delayed(Number, Function\) | Wartet die angegebene Anzahl an Ticks und führt danach die zugehörige Funktion aus | +| `pos` | pos(Number, Number, Number) | Erstellt aus drei Zahlen eine Position-Table. Die Koordinaten sind unter den Namen `x`, `y` und `z` abgespeichert | +| `exec` | exec(String...) | Führt den angegebenen Befehl als Spieler aus | +| `length` | length(Any): Int | Gibt die Länge des Objekts zurück | +| `join` | length(String, String...): String | Füge die Texte mit den ersten Parameter zusammen | + +### player +Das `player`-Modul stellt Funktionen zur Verfügung, die den Spieler betreffen. +Es gibt folgende Funktionen: + +| Name | Signature | Beschreibung | +|------------------|--------------------------------|---------------------------------------------------------------------------------------------------------------------------| +| `name` | name(): String | Gibt den `displayName` des Spielers zurück | +| `chat` | chat(String...) | Sendet den Text in den Chat des Spielers | +| `actionbar` | actionbar(String...) | Sendet den Text in die ActionBar des Spielers | +| `x` | x(Number), x(): Number | Setzt oder gibt die X-Koordinate des Spielers | +| `y` | y(Number), y(): Number | Setzt oder gibt die Y-Koordinate des Spielers | +| `z` | z(Number), z(): Number | Setzt oder gibt die Z-Koordinate des Spielers | +| `yaw` | yaw(Number), yaw(): Number | Setzt oder gibt die Gierung des Spielers | +| `pitch` | pitch(Number), pitch(): Number | Setzt oder gibt die Steigung des Spielers | +| `sneaking` | sneaking(): Boolean | Wahr, wenn der Spieler am Sneaken ist | +| `sprinting` | sprinting(): Boolean | Wahr, wenn der Spieler am Sprinten ist | +| `slot` | slot(Number), slot(): Number | Setzt oder gibt den Slot des gehaltenden Items des Spielers [(Wiki)](https://minecraft.fandom.com/wiki/Slot#Java_Edition) | +| `item` | item(): String | Gibt den Itemtyp der Main-Hand zurück | +| `offHandItem` | offHandItem(): String | Gibt den Itemtyp der Off-Hand zurück | +| `closeInventory` | closeInventory() | Schließe das aktuell geöffnete Inventar des Spielers | + +### random +Das `random`-Modul stellt Funktionen zur Verfügung, die Zufallszahlen betreffen. +Es gibt folgende Funktionen: + +| Name | Signature | Beschreibung | +|------------|------------------------------------|-------------------------------------------------------------------------------| +| nextInt | nextInt(): Int | Gibt eine Zufallszahl zurück zwischen Integer.MIN_VALUE und Integer.MAX_VALUE | +| -"- | nextInt(Int): Int | Gibt eine Zufallszahl zurück zischen 0 und dem Argument | +| -"- | nextInt(Int, Int): Int | Gibt eine Zufallszahl zurück zwischen dem ersten und zweiten Argument | +| nextDouble | nextDouble(): Double | Gibt eine Zufallszahl zurück zwischen 0 und 1 | +| -"- | nextDouble(Double): Double | Gibt eine Zufallszahl zurück zwischen 0 und dem Argument | +| -"- | nextDouble(Double, Double): Double | Gibt eine Zufallszahl zurück zwischen ersten und zweiten Argument | +| nextBool | nextBool(): Boolean | Gibt true oder false zurück | + +### region +Das `region`-Modul stellt Funktion zur Verfügung, die die Region des Spielers betreffen. +Es gibt folgende Funktionen: + +| Name | Signature | Beschreibung | +|-----------|---------------------|------------------------------------------------------------------------------------------------------------| +| `name` | name(): String | Gibt den Regionsnamen | +| `type` | type(): String | Gibt den Regionstyp | +| `fire` | fire(): Boolean | Gibt den Fire-Modus der Region zurück | +| `freeze` | freeze(): Boolean | Gibt den Freeze-Modus der Region zurück | +| `protect` | protect(): Boolean | Gibt den Protect-Modus der Region zurück | +| `loader` | loader(): String | Gibt den Status des Loaders des Spielers zurück, die Werte sind: `OFF`, `SETUP`, `RUNNING`, `PAUSE`, `END` | +| `get` | get(String): Region | Gibt die Region mit dem Namen zurück. Die Region ist gleich aufgebaut wie das Regions-Modul | +| `list` | list(): Region[] | Gibt alle Region zurück. Die Region ist gleich aufgebaut wie das Regions-Modul | + +Es gibt folgende weitere Module: + +| Name | Beschreibung | +|---------|-----------------| +| `tnt` | [tnt](#tnt) | +| `trace` | [trace](#trace) | + +#### tnt +Das `tnt`-Modul stellt Funktionen zur Verfügung, die den TNT-Modus in der Region des Spielers betreffen. +Es gibt folgende Funktionen: + +| Name | Signature | Beschreibung | +|-------------|----------------------|-------------------------------------------------------------------------------------| +| `mode` | mode(): String | Gibt den Aktuellen TNT-Modus zurück, die werte sind: `ALLOW`, `DENY` oder `ONLY_TB` | +| `enabled` | enabled(): Boolean | Gibt zurück, ob der TNT-Modus in der Region des Spielers aktiviert ist oder nicht | +| `onlyTb` | onlyTb(): Boolean | Gibt zurück, ob der TNT-Modus auf Only-Tb ist | +| `onlyBuild` | onlyBuild(): Boolean | Gibt zurück, ob der TNT-Modus auf Only-Build ist | + + +#### trace +Das `trace`-Modul stellt Funktionen zur Verfügung, die den Status des Tracers der Region betreffen. +Es gibt folgende Funktionen: + +| Name | Signature | Beschreibung | +|----------|-------------------|--------------------------------------------------------------------------------| +| `active` | active(): Boolean | Gibt zurück, ob der Tracer in der Region des Spielers aktiviert ist oder nicht | +| `auto` | auto(): Boolean | Gibt zurück, ob der Tracer in der Region ein Auto-Tracer ist | +| `status` | status(): String | Gibt den Status des Tracers zurück | +| `time` | time(): String | Gibt die Zeit des Tracers zurück | + +## server +Das `server`-Modul stellt Funktionen zur Verfügung, die den Server betreffen. +Es gibt folgende Funktionen: + +| Name | Signature | Beschreibung | +|--------------|-------------------------|---------------------------------------------------------------------| +| `time` | time(): String | Gibt die aktuelle Zeit im Format `HH:mm:ss` zurück | +| `ticks` | ticks(): Number | Gibt die Ticks seit start des Serverstarts zurück | +| `getBlockAt` | getBlockAt(Pos): String | Gibt das Material an der Position zurück | +| `setBlockAt` | setBlockAt(Pos, String) | Setzt das Material an der angegebenen Stelle (z.B. Stein = `STONE`) | + +Es gibt folgende weitere Module: + +| Name | Beschreibung | +|-------|--------------| +| `tps` | [tps](#tps) | + +#### tps +Das `tps`-Modul stellt Funktionen zur Verfügung, die die TPS des Servers betreffen. +Es gibt folgende Funktionen: + +| Name | Signature | Beschreibung | +|--------------|----------------------|-------------------------------------------------------------------| +| `current` | current(): Number | Gibt die aktuelle TPS zurück (Das selbe wie `oneSecound()`) | +| `oneSecond` | oneSecond(): Number | Gibt die durchschnittliche TPS über die letzte Sekunde zurück | +| `tenSecond` | tenSecond(): Number | Gibt die durchschnittliche TPS über die letzte 10 Sekunden zurück | +| `oneMinute` | oneMinute(): Number | Gibt die durchschnittliche TPS über die letzte Minute zurück | +| `fiveMinute` | fiveMinute(): Number | Gibt die durchschnittliche TPS über die letzte 5 Minuten zurück | +| `tenMinute` | tenMinute(): Number | Gibt die durchschnittliche TPS über die letzte 10 Minuten zurück | +| `limit` | limit(): Number | Gibt das TPS-Limit zurück | + +## storage +Das `storage`-Modul stellt Funktionen zur Verfügung, mit welchen man Werte speichern kann. + +Es gibt folgende Module: + +| Name | Beschreibung | +|----------|---------------------| +| `player` | Spieler abhängig | +| `region` | Region des Spielers | +| `global` | Alle Skripte | + +Alle Module haben folgende Funktionen: + +| Name | Signature | Beschreibung | +|------------|----------------------------|--------------------------------------------------------| +| `get` | get(String): Any | Gibt den Wert des Schlüssels zurück | +| `set` | set(String, Any) | Setzt den Wert des Schlüssels auf den angegebenen Wert | +| `has` | has(String): Boolean | Prüft ob ein Wert vorhanden ist | +| `remove` | remove(String) | Löscht den Schlüssel | +| `accessor` | accessor(String): Accessor | Gibt einen Accessor zurück | + +Ein Accessor ist ein Objekt, womit du direkt auf einen Wert zugreifen kannst und es ändern kannst. +Es geht wie folgt: +```lua +keyAccessor = storage.player.accessor("key") + +keyAccessor("Hello World") -- Setzt den Wert auf "Hello World" +print(keyAccessor()) -- Gibt den Wert zurück +``` + +## inventory +Das `inventory`-Modul stellt Funktionen zur Verfügung, um ein Inventar zu öffnen. +Es gibt folgende Funktionen: + +| Name | Signature | Beschreibung | +|----------|-----------------------------------|-------------------------------------------------------------------| +| `create` | create(String, Number): Inventory | Erstellt ein Inventar mit dem Title und der Anzahl an Zeilen | + +Das `Inventory`-Objekt hat folgende Funktionen: + +| Name | Signature | Beschreibung | +|-------------------|--------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `item` | item(Number, String, String, Function\) | Setze ein Item mit dem Typen des ersten Strings an den Slot (Startet bei 0) mit dem Namen des zweiten Strings mit einem Klick-Handler der den Klick-Typen rein gibt (z.B. `LEFT`, `SHIFT_LEFT`, `RIGHT`, `SHIFT_RIGHT`) | +| -"- | item(Number, String, String, Function\, List) | Füge eine Lore an das Item hinzu | +| -"- | item(Number, String, String, Function\, List, Boolean) | Gebe an, ob das Item enchanted sein soll | +| -"- | item(Number, String, String, Function\, List, Boolean, Number) | Gebe die Anzahl der Items an | +| `setCloseHandler` | setCloseHandler(Function\) | Gebe einen Handler an, der beim schließen des Inventares ausgeführt wird | +| `open` | open() | Öffne das Inventar | + +Siehe auch: [Inventory Beispiel](#inventory-1) + +Siehe auch: [Liste an Materials](https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/Material.html) + +``` +⚠️⚠️⚠️ + +Wenn eine Barrier statt des richtigen Items angezeigt wird, dann ist das angegebene Material nicht gültig. + +⚠️⚠️⚠️ +``` + +# SteamWar.de-Global-Api +Mit `/script` kann man Script-Bücher global abspeichern. Diese haben dann zugrif auf die `global`-Api. +Die `global`-Api stellt Funktionen zur Verfügung um auf Events, Commands und Hotkeys mit einem Script zu reagieren. + +Es gibt folgende Funktionen: + +| Name | Signature | Beschreibung | +|-----------|-----------------------------------|-----------------------------------------------------------------------------| +| `event` | event(EventType, Function(Any)) | Registriere einen Event Listener | +| `command` | command(String, Function(Args)) | Registriere einen Befehl | +| `hotkey` | hotkey(String, Function(Boolean)) | Registriere einen Hotkey, the function gets a boolean if the key is pressed | + +Es gibt folgende Variablen: + +| Name | Beschreibung | +|----------|----------------------------------| +| `events` | Siehe: [Event Type](#eventtypen) | + +## Commands +Der Command Handler kriegt eine Liste aller angegeben argumenten. Die Argumente sind vom Typ `String`. Mit dem Wert gespeichert unter `args.alias` oder `args["alias"]` erhältst du, welcher command eingegeben wurde. Wenn ein handler für mehrere Befehle registriert wurde kannst du es hiermit erkennen. +Du kannst `args.hasShortFlag(String)` um herauszufinden ob eine Flag angegeben wurde wie zum Beispiel `-f`. Mit `args.removeShortFlag(String)` kannst du die Flag entfernen und erhältst ob sie angegeben wurde. + +## Hotkeys + +Hotkeys werden im folgenden Format angegeben: `MODIFIER+KEY`. Bei den Hotkey erstellung ist die Großschreibung egal. Es gibt folgende Modifier: +- `ctrl` +- `shift` +- `alt` +- `meta` + +Es können auch mehrere Modifier angegeben werden, z.B. `ctrl+shift+alt+c`. Die Reihenfolge der Modifier und des Keys ist egal. + +## Eventtypen +Einige Events sind auch abbrechbar, dazu muss die Funktion `setCancelled()` aufgerufen werden. + +| Name | Wenn | Parameter | Abbrechbar | +|---------------------|-----------------------------------------------------|---------------------------------|------------| +| `DoubleSwap` | Beim Doppelten Drücken der Swap-Hands taste | NIL | false | +| `PlaceBlock` | Beim Platzieren von Blöcken | [BlockEvent](#blockevent) | true | +| `BreakBlock` | Beim Zerstören von Blöcken | [BlockEvent](#blockevent) | true | +| `RightClick` | Beim Rechtsklick | [InteractEvent](#interactevent) | true | +| `LeftClick` | Beim Linksklick | [InteractEvent](#interactevent) | true | +| `TNTSpawn` | Wenn ein TNT in der aktuellen Region spawnt | NIL | false | +| `TNTExplode` | Wenn ein TNT in der aktuellen Region explodiert | [Position](#position) | true | +| `TNTExplodeInBuild` | Wenn ein TNT in der aktuellen Bau Region explodiert | [Position](#position) | true | +| `SelfJoin` | Wenn man selbst den Server betritt | NIL | false | +| `SelfLeave` | Wenn man den Server verlässt | NIL | false | +| `DropItem` | Wenn man ein Item droppt | (type: Material) | true | +| `EntityDeath` | Wenn ein Entity stirbt | (type: Entity Type) | false | + +### BlockEvent +Das übergebene Objekt an den Handler hat folgende Variablen: + +| Name | Beschreibung | +|--------|-----------------------------| +| `x` | Die X-Koordinate des Blocks | +| `y` | Die Y-Koordinate des Blocks | +| `z` | Die Z-Koordinate des Blocks | +| `type` | Das Material des Blocks | + +### InteractEvent +Das übergebene Objekt an den Handler hat folgende Variablen: + +| Name | Beschreibung | +|------------|-------------------------------------------------------------------------------------------------------------------------------| +| `action` | Die Action die ausgeführt wurde, Mögliche Werte: `RIGHT_CLICK_BLOCK`, `RIGHT_CLICK_AIR`, `LEFT_CLICK_BLOCK`, `LEFT_CLICK_AIR` | +| `hand` | Die Hand die zum ausführen genutzt wird, Mögliche Werte: `HAND`, `OFF_HAND`, `null` | +| `block` | Der Typ des Items mit dem geklickt wurde | +| `hasBlock` | Wahr, wenn auf einen Block geklickt wurde | + +Wenn `hasBlock` wahr ist, gibt es folgende Variablen: + +| Name | Beschreibung | +|-------------|-----------------------------------------| +| `blockX` | Die X-Koordinate des Blocks | +| `blockY` | Die Y-Koordinate des Blocks | +| `blockZ` | Die Z-Koordinate des Blocks | +| `blockFace` | Die Seite des Blocks die geklickt wurde | + + +### Position +Die Position ist ein Objekt mit folgenden Variablen: + +| Name | Beschreibung | +|------|------------------| +| `x` | Die X-Koordinate | +| `y` | Die Y-Koordinate | +| `z` | Die Z-Koordinate | + +# Instabile APIs +Hier sind einige APIs aufgelistet, die nicht stabil sind und sich jederzeit ändern können. + +## _worldedit + +| Name | Signatur | Beschreibung | +|-------------|-----------------------------------------------------------|-----------------------------------| +| `selection` | selection(Liste\), selection(): {min: Pos, max: Pos} | Die aktuelle auswahl des Spielers | + + + +# Beispiele + +## Hello, World! +Ein einfaches Hello, World!-Script. + +#### Code +```lua +print("Hello, World!") +``` + +#### Ausgabe +``` +Hello, World! +``` + +## BauGUI on DoubleSwap +Das Standardskript für das Öffnen des BauGUIs + +#### Code +```lua +function handler(event) + exec("gui") +end + +event(events.DoubleSwap, handler) +``` + +## SL Command +Ein einfacher Command Redefiner. + +#### Code +```lua +function handler(args) + exec("stoplag") +end + +command("sl", handler) +``` + +## Paste Hotkey +Ein Hotkey zum Pasten des Clipboard-Inhalts. + +#### Code +```lua +function handler(pressed) + if pressed then + exec("/paste -o") + end +end + +hotkey("ctrl+v", handler) +``` + +## Inventory +Ein Beispiel für ein Inventar. + +#### Code +```lua +inv = inventory.create("Test Inv", 3) +inv.item(13, "STONE", "Ich bin ein Stein", function(e) player.chat(e) end, {"Die Lore", "Die Zweite Zeile"}, true) +inv.open() +``` \ No newline at end of file diff --git a/BauSystem/sw.def.lua b/BauSystem/sw.def.lua new file mode 100644 index 00000000..613437a1 --- /dev/null +++ b/BauSystem/sw.def.lua @@ -0,0 +1,428 @@ +-- This file is a part of the SteamWar software. +-- +-- Copyright (C) 2021 SteamWar.de-Serverteam +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU Affero General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Affero General Public License for more details. +-- +-- You should have received a copy of the GNU Affero General Public License +-- along with this program. If not, see . + +--- +--- This file contains the definitions for the SteamWar.de script API. +--- It is used by the IDE to provide code completion and type checking. +--- Created by Chaoscaot +--- + +inventory = {} + +---@param title string +---@param size number +---@return Inventory +function inventory.create(title, size) return nil end + +---@alias InventoryClick 'LEFT' | 'SHIFT_LEFT' | 'RIGHT' | 'SHIFT_RIGHT' | 'MIDDLE' | 'NUMBER_KEY' + +---@class Inventory +local Inventory = {} + +---@overload fun(slot: number, material: string, name: string, handler: fun(click: InventoryClick)): void +---@overload fun(slot: number, material: string, name: string, handler: fun(click: InventoryClick), lore: string[]): void +---@overload fun(slot: number, material: string, name: string, handler: fun(click: InventoryClick), lore: string[], enchanted: boolean): void +---@param slot number +---@param material string +---@param name string +---@param handler fun(click: InventoryClick): void +---@param lore string[] +---@param enchanted boolean +---@param amount number +---@return void +function Inventory.item(slot, material, name, handler, lore, enchanted, amount) end + +---@param handler fun(): void +---@return void +function Inventory.setCloseHandler(handler) end + +---@return void +function Inventory.open() end + +player = {} + +---@return string +---Get the name of the player. +function player.name() return "" end + +---@return void +function player.chat(...) end + +---@return void +---Send a message to the actionbar of the player. +function player.actionbar(...) end + +---@overload fun(): number +---@param newX number +function player.x(newX) end + +---@overload fun(): number +---@param newY number +function player.y(newY) end + +---@overload fun(): number +---@param newZ number +function player.z(newZ) end + +---@overload fun(): number +---@param newYaw number +function player.yaw(newYaw) end + +---@overload fun(): number +---@param newPitch number +function player.pitch(newPitch) end + +---@return boolean +function player.sneaking() return nil end + +---@return boolean +function player.sprinting() return nil end + +---@overload fun(): number +---@param newSlot number +function player.slot(newSlot) end + +---@return string +function player.item() return nil end + +---@return string +function player.offHandItem() return nil end + +---@return void +function player.closeInventory() end + +---@field nextBool fun(): boolean +random = {} + +---@overload fun(): number +---@overload fun(bound: number): number +---@param origin number +---@param bound number +---@return number +function random.nextInt(origin, bound) return nil end + +---@overload fun(): number +---@overload fun(bound: number): number +---@param origin number +---@param bound number +---@return number +function random.nextDouble(origin, bound) return nil end + +---@return boolean +function random.nextBool() return nil end + +---@alias RegionType 'wg' | 'mwg' | 'as' | 'ws' | 'ws_inner' | 'ws_rumpf' | 'ws_rahmen' | 'spawn' + +---@class iregion +---@field tnt tnt +---@field trace trace +local iregion = {} + +---@class region: iregion +region = {} + +---@return string +function iregion.name() return nil end + +---@return RegionType +function iregion.type() return nil end + +---@return boolean +function iregion.fire() return nil end + +---@return boolean +function iregion.freeze() return nil end + +---@return boolean +function iregion.protect() return nil end + +---@return string +function iregion.loader() return nil end + +---@return Position +function iregion.copyPoint() return nil end + +---@return Position +function iregion.minPointBuild() return nil end + +---@return Position +function iregion.maxPointBuild() return nil end + +---@return Position +function iregion.minPointBuildExtension() return nil end + +---@return Position +function iregion.maxPointBuildExtension() return nil end + +---@return Position +function iregion.testblockPoint() return nil end + +---@return Position +function iregion.minPointTestblock() return nil end + +---@return Position +function iregion.maxPointTestblock() return nil end + +---@return Position +function iregion.minPointTestblockExtension() return nil end + +---@return Position +function iregion.maxPointTestblockExtension() return nil end + +---@alias TNTMode 'ALLOW' | 'DENY' | 'ONLY_TB' + +---@class tnt +local tnt = {} + +---@return TNTMode +function tnt.mode() return nil end + +---@return boolean +function tnt.enabled() return nil end + +---@return boolean +function tnt.onlyTb() return nil end + +---@return boolean +function tnt.onlyBuild() return nil end + +---@class trace +local trace = {} + +---@return boolean +function trace.active() return nil end + +---@return boolean +function trace.auto() return nil end + +---@return string +function trace.status() return nil end + +---@return number +function trace.time() return nil end + +---@param name string +---@return iregion +function region.get(name) return nil end + +---@return iregion[] +function region.list() return nil end + +---@class Position +---@field x number +---@field y number +---@field z number + +---@class server +---@field tps tps +server = {} + +---@return string +function server.time() return nil end + +---@return number +function server.ticks() return nil end + +---@param position Position +---@return string +function getBlockAt(position) return nil end + +---@param position Position +---@param material string +---@return void +function setBlockAt(position, material) return nil end + +---@class tps +local tps = {} + +---@return number +function tps.oneSecond() return nil end + +---@return number +function tps.tenSecond() return nil end + +---@return number +function tps.oneMinute() return nil end + +---@return number +function tps.fiveMinute() return nil end + +---@return number +function tps.tenMinute() return nil end + +---@return number +function tps.current() return nil end + +---@return number +function tps.limit() return nil end + +---@class storage +---@field global storageLib +---@field player storageLib +---@field region storageLib +storage = {} + +---@class storageLib +---Any Primitive, Array or Table will be saved across restarts, everything else will be discarded +local storageLib = {} + +---@param key string +---@return any +function storageLib.get(key) return nil end + +---@param key string +---@param value any +---@return void +function storageLib.set(key, value) end + +---@param key string +---@return boolean +function storageLib.has(key) return nil end + +---@param key string +---@return void +function storageLib.remove(key) end + +---@param key string +---@return Accessor +function storageLib.accessor(key) return nil end + +---@class Accessor +---@overload fun(): any +---@overload fun(value: any) + +---@class Selection +---@field max Position +---@field min Position + +---@class _worldedit +_worldedit = {} + +---@overload fun(pos: Position[]): void +---@return Selection +function _worldedit.selection() return nil end + +---@param msg string +---@param callback fun(value: string): void +---@return void +function input(msg, callback) end + +---@param ticks number +---@param callback fun(): void +---@return void +function delayed(ticks, callback) end + +---@param x number +---@param y number +---@param z number +---@return Position +function pos(x, y, z) return nil end + +---@return void +function exec(...) end + +---@param obj any +---@return number +function length(obj) return 0 end + +---@param separator string +---@param table any[] +---@return string +function join(separator, table) return "" end + +---@class EventType +---@class events +---@field DoubleSwap EventType +---@field PlaceBlock EventType +---@field BreakBlock EventType +---@field RightClick EventType +---@field LeftClick EventType +---@field TNTSpawn EventType +---@field TNTExplode EventType +---@field TNTExplodeInBuild EventType +---@field SelfJoin EventType +---@field SelfLeave EventType +---@field DropItem EventType +---@field EntityDeath EventType +events = {} + + +---@param id EventType +---@param handler fun(params: any): void +---@return void +function event(id, handler) end + +---@param command string +---@param handler fun(params: string[]): void +---@return void +function command(command, handler) end + +---@param trigger string +---@param handler fun(pressed: boolean): void +---@return void +function hotkey(trigger, handler) end + +---@class bossbar +bossbar = {} + +---@alias BossBarColor 'PINK' | 'BLUE' | 'RED' | 'GREEN' | 'YELLOW' | 'PURPLE' | 'WHITE' +---@alias BossBarStyle 'SEGMENTED_6' | 'SEGMENTED_10' | 'SEGMENTED_12' | 'SEGMENTED_20' | 'SOLID' +---@alias BossBarFlag 'DARKEN_SKY' | 'PLAY_BOSS_MUSIC' | 'CREATE_FOG' + +---@class BossBar +local BossBar = {} + +---@param title string +---@param color BossBarColor +---@param style BossBarStyle +---@return BossBar +function bossbar.create(title, color, style) return nil end + +---@return string +---@overload fun(title: string): void +function BossBar.title() end + +---@return BossBarColor +---@overload fun(color: BossBarColor): void +function BossBar.color() end + +---@return BossBarStyle +---@overload fun(style: BossBarStyle): void +function BossBar.style() end + +---@return number +---@overload fun(progress: number): void +function BossBar.progress() end + +---@return boolean +---@overload fun(visible: boolean): void +function BossBar.visible() end + +---@return boolean +---@param flag BossBarFlag +function BossBar.hasFlag(flag) return nil end + +---@return void +---@param flag BossBarFlag +function BossBar.addFlag(flag) end + +---@return boolean +---@param flag BossBarFlag +function BossBar.removeFlag(flag) return nil end + +---@return void +function BossBar.destroy() end From 56e1abca7e46aed8961a7ead6e3767580a8e885f Mon Sep 17 00:00:00 2001 From: Lixfel Date: Sun, 16 Feb 2025 17:09:27 +0100 Subject: [PATCH 022/124] Kick player on Channel injection failure --- .../comphenix/tinyprotocol/TinyProtocol.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java b/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java index 3a0124e0..7cca9c95 100644 --- a/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java +++ b/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java @@ -22,10 +22,8 @@ package com.comphenix.tinyprotocol; import de.steamwar.Reflection; import de.steamwar.Reflection.Field; import de.steamwar.core.Core; -import io.netty.channel.Channel; -import io.netty.channel.ChannelDuplexHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelPromise; +import io.netty.channel.*; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -57,15 +55,14 @@ public class TinyProtocol implements Listener { private static final Class networkManager = Reflection.getClass("net.minecraft.network.NetworkManager"); public static final Field networkManagers = Reflection.getField(serverConnection, List.class, 0, networkManager); + private static final String HANDLER_NAME = "tiny-steamwar"; public static final TinyProtocol instance = new TinyProtocol(Core.getInstance()); - private static int id = 0; public static void init() { //enforce init } private final Plugin plugin; - private final String handlerName; private final List connections; private boolean closed; @@ -74,7 +71,6 @@ public class TinyProtocol implements Listener { private TinyProtocol(final Plugin plugin) { this.plugin = plugin; - this.handlerName = "tiny-" + plugin.getName() + "-" + ++id; this.connections = networkManagers.get(getServerConnection(plugin)); plugin.getServer().getPluginManager().registerEvents(this, plugin); @@ -148,7 +144,7 @@ public class TinyProtocol implements Listener { this.player = player; channel = getChannel.get(connections.stream().filter(connection -> player.getUniqueId().equals(getUUID.get(connection))).findAny().orElseThrow(() -> { - player.kickPlayer("An injection failure happend."); + Bukkit.getScheduler().runTask(plugin, () -> player.kickPlayer("Connection failure.")); return new SecurityException("Could not find channel for player " + player.getName()); })); @@ -159,7 +155,12 @@ public class TinyProtocol implements Listener { playerInterceptors.put(player, this); } - channel.pipeline().addBefore("packet_handler", handlerName, this); + try { + channel.pipeline().addBefore("packet_handler", HANDLER_NAME, this); + } catch (IllegalArgumentException e) { + Bukkit.getScheduler().runTask(plugin, () -> player.kickPlayer("Connection failure.")); + throw new SecurityException(e); + } } private void sendPacket(Object packet) { @@ -174,7 +175,7 @@ public class TinyProtocol implements Listener { if(channel.isActive()) { channel.eventLoop().execute(() -> { try { - channel.pipeline().remove(handlerName); + channel.pipeline().remove(HANDLER_NAME); } catch (NoSuchElementException e) { // ignore } From b516d1d569b7bfc2f0605c24c9cec0814303c514 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Sun, 16 Feb 2025 17:14:55 +0100 Subject: [PATCH 023/124] Configurable techhider interaction suppression --- .../fightsystem/utils/TechHiderWrapper.java | 6 ++++++ .../src/de/steamwar/techhider/TechHider.java | 15 ++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java index a01e61b4..c45d7ab6 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java @@ -32,6 +32,7 @@ import de.steamwar.fightsystem.states.StateDependent; import de.steamwar.fightsystem.states.StateDependentListener; import de.steamwar.sql.SteamwarUser; import de.steamwar.techhider.TechHider; +import org.bukkit.GameMode; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -114,6 +115,11 @@ public class TechHiderWrapper extends StateDependent implements TechHider.Locati }); } + @Override + public boolean suppressInteractions(Player player) { + return player.getGameMode() == GameMode.SPECTATOR; + } + @Override public boolean skipChunk(Player player, int chunkX, int chunkZ) { return getHiddenRegion(player).chunkOutside(chunkX, chunkZ); diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java index bae5b7be..03063eb8 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java @@ -19,15 +19,16 @@ package de.steamwar.techhider; -import de.steamwar.Reflection; import com.comphenix.tinyprotocol.TinyProtocol; +import de.steamwar.Reflection; import de.steamwar.core.Core; import lombok.Getter; -import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.entity.Player; -import java.util.*; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.UnaryOperator; @@ -91,9 +92,9 @@ public class TechHider { } if(Core.getVersion() > 8){ - techhiders.put(Reflection.getClass("net.minecraft.network.protocol.game.ServerboundUseItemOnPacket"), (p, packet) -> p.getGameMode() == GameMode.SPECTATOR ? null : packet); + techhiders.put(Reflection.getClass("net.minecraft.network.protocol.game.ServerboundUseItemOnPacket"), (p, packet) -> locationEvaluator.suppressInteractions(p) ? null : packet); } - techhiders.put(Reflection.getClass("net.minecraft.network.protocol.game.ServerboundInteractPacket"), (p, packet) -> p.getGameMode() == GameMode.SPECTATOR ? null : packet); + techhiders.put(Reflection.getClass("net.minecraft.network.protocol.game.ServerboundInteractPacket"), (p, packet) -> locationEvaluator.suppressInteractions(p) ? null : packet); } @@ -161,6 +162,10 @@ public class TechHider { } public interface LocationEvaluator { + default boolean suppressInteractions(Player player) { + return false; + } + boolean skipChunk(Player player, int x, int z); default boolean skipChunkSection(Player player, int x, int y, int z) { return skipChunk(player, x, z); From 9f108a7cea8766146c1be1bebba40ec70b4726f9 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Sun, 16 Feb 2025 17:25:18 +0100 Subject: [PATCH 024/124] Update VV dependency version --- settings.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index cea601bf..cd1db040 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -137,8 +137,8 @@ dependencyResolutionManagement { library("velocity", "de.steamwar:velocity:RELEASE") 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("viaapi", "com.viaversion:viaversion-api:5.2.1") + library("viavelocity", "com.viaversion:viaversion-velocity:5.2.1") library("jda", "net.dv8tion:JDA:5.2.0") library("msgpack", "org.msgpack:msgpack-core:0.9.8") library("apolloprotos", "com.lunarclient:apollo-protos:1.0-SNAPSHOT") From ef029eb420205e2c7d431529523ad07cb26a4307 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Sun, 16 Feb 2025 19:40:18 +0100 Subject: [PATCH 025/124] Add LegacyBauSystem with adaptions to current SpigotCore --- LegacyBauSystem/build.gradle.kts | 29 + .../src/de/steamwar/bausystem/BauSystem.java | 197 +++++++ .../bausystem/CraftbukkitWrapper.java | 43 ++ .../bausystem/CraftbukkitWrapper12.java | 80 +++ .../steamwar/bausystem/FlatteningWrapper.java | 53 ++ .../bausystem/FlatteningWrapper12.java | 148 +++++ .../src/de/steamwar/bausystem/Mapper.java | 87 +++ .../src/de/steamwar/bausystem/Permission.java | 26 + .../src/de/steamwar/bausystem/RamUsage.java | 44 ++ .../src/de/steamwar/bausystem/SWUtils.java | 64 +++ .../de/steamwar/bausystem/TraceEntity12.java | 77 +++ .../steamwar/bausystem/WorldeditWrapper.java | 44 ++ .../bausystem/WorldeditWrapper12.java | 114 ++++ .../bausystem/commands/CommandClear.java | 71 +++ .../bausystem/commands/CommandColor.java | 73 +++ .../bausystem/commands/CommandDebugStick.java | 41 ++ .../bausystem/commands/CommandDetonator.java | 114 ++++ .../bausystem/commands/CommandFire.java | 92 +++ .../bausystem/commands/CommandFreeze.java | 148 +++++ .../bausystem/commands/CommandGUI.java | 530 +++++++++++++++++ .../bausystem/commands/CommandGamemode.java | 50 ++ .../bausystem/commands/CommandGills.java | 53 ++ .../bausystem/commands/CommandInfo.java | 80 +++ .../bausystem/commands/CommandKillAll.java | 74 +++ .../bausystem/commands/CommandLoader.java | 134 +++++ .../bausystem/commands/CommandLockschem.java | 67 +++ .../bausystem/commands/CommandNV.java | 54 ++ .../bausystem/commands/CommandProtect.java | 127 ++++ .../commands/CommandRedstoneTester.java | 52 ++ .../bausystem/commands/CommandRegion.java | 132 +++++ .../bausystem/commands/CommandReset.java | 91 +++ .../bausystem/commands/CommandScript.java | 94 +++ .../bausystem/commands/CommandScriptVars.java | 120 ++++ .../bausystem/commands/CommandSelect.java | 124 ++++ .../bausystem/commands/CommandSkull.java | 49 ++ .../bausystem/commands/CommandSpeed.java | 70 +++ .../bausystem/commands/CommandTNT.java | 173 ++++++ .../bausystem/commands/CommandTPSLimiter.java | 176 ++++++ .../bausystem/commands/CommandTeleport.java | 46 ++ .../bausystem/commands/CommandTestblock.java | 128 +++++ .../bausystem/commands/CommandTime.java | 99 ++++ .../bausystem/commands/CommandTrace.java | 132 +++++ .../bausystem/commands/CommandWorldSpawn.java | 45 ++ .../bausystem/commands/RegionUtils.java | 42 ++ .../steamwar/bausystem/gui/GuiTraceShow.java | 133 +++++ .../bausystem/tracer/AbstractTraceEntity.java | 34 ++ .../bausystem/tracer/RoundedTNTPosition.java | 65 +++ .../bausystem/tracer/TNTPosition.java | 63 ++ .../tracer/record/RecordStateMachine.java | 94 +++ .../bausystem/tracer/record/RecordStatus.java | 55 ++ .../bausystem/tracer/record/Recorder.java | 96 ++++ .../tracer/record/TraceAutoHandler.java | 70 +++ .../bausystem/tracer/show/Record.java | 94 +++ .../bausystem/tracer/show/ShowMode.java | 28 + .../tracer/show/ShowModeParameter.java | 57 ++ .../tracer/show/ShowModeParameterType.java | 44 ++ .../bausystem/tracer/show/StoredRecords.java | 45 ++ .../tracer/show/TraceShowManager.java | 59 ++ .../tracer/show/mode/EntityShowMode.java | 120 ++++ .../steamwar/bausystem/world/AFKStopper.java | 56 ++ .../bausystem/world/AbstractAutoLoader.java | 122 ++++ .../steamwar/bausystem/world/AutoLoader.java | 266 +++++++++ .../bausystem/world/BauScoreboard.java | 111 ++++ .../bausystem/world/ClipboardListener.java | 63 ++ .../de/steamwar/bausystem/world/Color.java | 39 ++ .../steamwar/bausystem/world/Detoloader.java | 87 +++ .../steamwar/bausystem/world/Detonator.java | 120 ++++ .../bausystem/world/DetonatorListener.java | 65 +++ .../bausystem/world/ItemFrameListener.java | 52 ++ .../bausystem/world/PredefinedBook.java | 124 ++++ .../bausystem/world/RegionListener.java | 137 +++++ .../bausystem/world/ScriptListener.java | 542 ++++++++++++++++++ .../steamwar/bausystem/world/SizedStack.java | 123 ++++ .../de/steamwar/bausystem/world/TPSUtils.java | 77 +++ .../src/de/steamwar/bausystem/world/Welt.java | 51 ++ .../bausystem/world/regions/GlobalRegion.java | 64 +++ .../bausystem/world/regions/PasteOptions.java | 99 ++++ .../bausystem/world/regions/Point.java | 31 + .../bausystem/world/regions/Prototype.java | 204 +++++++ .../bausystem/world/regions/Region.java | 388 +++++++++++++ .../world/regions/RegionExtensionType.java | 25 + .../world/regions/RegionSelectionType.java | 25 + .../bausystem/world/regions/RegionType.java | 26 + LegacyBauSystem/src/plugin.yml | 9 + settings.gradle.kts | 2 + steamwarci.yml | 1 + 86 files changed, 8253 insertions(+) create mode 100644 LegacyBauSystem/build.gradle.kts create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/BauSystem.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/CraftbukkitWrapper.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/CraftbukkitWrapper12.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/FlatteningWrapper.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/FlatteningWrapper12.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/Mapper.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/Permission.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/RamUsage.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/SWUtils.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/TraceEntity12.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/WorldeditWrapper.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/WorldeditWrapper12.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandClear.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandColor.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandDebugStick.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandDetonator.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandFire.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandFreeze.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandGUI.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandGamemode.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandGills.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandInfo.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandKillAll.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandLoader.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandLockschem.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandNV.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandProtect.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandRedstoneTester.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandRegion.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandReset.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandScript.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandScriptVars.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandSelect.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandSkull.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandSpeed.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTNT.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTPSLimiter.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTeleport.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTestblock.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTime.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTrace.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandWorldSpawn.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/commands/RegionUtils.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/gui/GuiTraceShow.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/tracer/AbstractTraceEntity.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/tracer/RoundedTNTPosition.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/tracer/TNTPosition.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/tracer/record/RecordStateMachine.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/tracer/record/RecordStatus.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/tracer/record/Recorder.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/tracer/record/TraceAutoHandler.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/Record.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/ShowMode.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/ShowModeParameter.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/ShowModeParameterType.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/StoredRecords.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/TraceShowManager.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/mode/EntityShowMode.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/AFKStopper.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/AbstractAutoLoader.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/AutoLoader.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/BauScoreboard.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/ClipboardListener.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/Color.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/Detoloader.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/Detonator.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/DetonatorListener.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/ItemFrameListener.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/PredefinedBook.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/RegionListener.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/ScriptListener.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/SizedStack.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/TPSUtils.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/Welt.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/regions/GlobalRegion.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/regions/PasteOptions.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/regions/Point.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/regions/Prototype.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/regions/Region.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/regions/RegionExtensionType.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/regions/RegionSelectionType.java create mode 100644 LegacyBauSystem/src/de/steamwar/bausystem/world/regions/RegionType.java create mode 100644 LegacyBauSystem/src/plugin.yml diff --git a/LegacyBauSystem/build.gradle.kts b/LegacyBauSystem/build.gradle.kts new file mode 100644 index 00000000..a3f42811 --- /dev/null +++ b/LegacyBauSystem/build.gradle.kts @@ -0,0 +1,29 @@ +/* + * 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(libs.nms12) + compileOnly(libs.worldedit12) +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/BauSystem.java b/LegacyBauSystem/src/de/steamwar/bausystem/BauSystem.java new file mode 100644 index 00000000..56af8fd7 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/BauSystem.java @@ -0,0 +1,197 @@ +/* + 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; + +import de.steamwar.bausystem.commands.*; +import de.steamwar.bausystem.world.*; +import de.steamwar.bausystem.world.regions.Region; +import de.steamwar.core.Core; +import de.steamwar.providers.BauServerInfo; +import de.steamwar.scoreboard.SWScoreboard; +import de.steamwar.sql.SteamwarUser; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitTask; + +import java.util.UUID; +import java.util.logging.Level; + +public class BauSystem extends JavaPlugin implements Listener { + + private static BauSystem plugin; + private static Integer owner; + public static final String PREFIX = "§eBauSystem§8» §7"; + + private BukkitTask autoShutdown; + + @Override + public void onEnable() { + plugin = this; + + Mapper.init(); + + new CommandTrace(); + new CommandTPSLimiter(); + new CommandNV(); + new CommandReset(); + new CommandSpeed(); + new CommandTNT(); + new CommandGamemode(); + new CommandClear(); + new CommandTime(); + new CommandTeleport(); + new CommandFire(); + new CommandFreeze(); + new CommandTestblock(); + new CommandInfo(); + new CommandProtect(); + new CommandSkull(); + new CommandLoader(); + new CommandLockschem(); + new CommandDebugStick(); + new CommandGills(); + new CommandDetonator(); + new CommandScript(); + new CommandScriptVars(); + new CommandRedstoneTester(); + new CommandGUI(); + new CommandWorldSpawn(); + new CommandRegion(); + new CommandSelect(); + new CommandKillAll(); + + if (Core.getVersion() > 14 && Region.buildAreaEnabled()) { + new CommandColor(); + } + + Bukkit.getPluginManager().registerEvents(this, this); + Bukkit.getPluginManager().registerEvents(new RegionListener(), this); + Bukkit.getPluginManager().registerEvents(new ScriptListener(), this); + Bukkit.getPluginManager().registerEvents(new BauScoreboard(), this); + Bukkit.getPluginManager().registerEvents(new ClipboardListener(), this); + Bukkit.getPluginManager().registerEvents(new CommandGUI(), this); + Bukkit.getPluginManager().registerEvents(new DetonatorListener(), this); + Bukkit.getPluginManager().registerEvents(new ItemFrameListener(), this); + new AFKStopper(); + + autoShutdown = Bukkit.getScheduler().runTaskLater(this, Bukkit::shutdown, 1200); + TPSUtils.init(); + } + + @Override + public void onDisable() { + Region.save(); + } + + public static BauSystem getPlugin() { + return plugin; + } + + public static UUID getOwner() { + return SteamwarUser.get(getOwnerID()).getUUID(); + } + + public static int getOwnerID() { + //Lazy loading to improve startup time of the server in 1.15 + if (owner == null) { + owner = BauServerInfo.getOwnerId(); + } + return owner; + } + + @EventHandler + public void onDeath(PlayerDeathEvent e) { + e.setDeathMessage(null); + } + + @EventHandler + public void onJoin(PlayerLoginEvent e) { + if (autoShutdown != null) { + autoShutdown.cancel(); + autoShutdown = null; + } + + Player p = e.getPlayer(); + p.setOp(true); + } + + @EventHandler + public void onLeave(PlayerQuitEvent e) { + Player p = e.getPlayer(); + SWScoreboard.impl.removeScoreboard(p); + if (Bukkit.getOnlinePlayers().isEmpty() || (Bukkit.getOnlinePlayers().size() == 1 && Bukkit.getOnlinePlayers().contains(p))) { + if (autoShutdown != null) { + autoShutdown.cancel(); + } + CommandTPSLimiter.setTPS(20.0); + autoShutdown = Bukkit.getScheduler().runTaskTimer(this, new Runnable() { + int count = 0; + + @Override + public void run() { + if (count >= 300) { + Bukkit.shutdown(); + return; + } + count++; + try { + if (RamUsage.getUsage() > 0.8) { + Bukkit.shutdown(); + } + } catch (Throwable throwable) { + Bukkit.getLogger().log(Level.WARNING, throwable.getMessage(), throwable); + Bukkit.shutdown(); + } + } + }, 20, 20); + } + } + + @EventHandler + public void onInventoryClick(InventoryClickEvent e) { + ItemStack stack = e.getCursor(); + if (stack == null || !stack.hasItemMeta()) + return; + assert stack.getItemMeta() != null; + if (stack.getItemMeta().hasEnchants()) { + for (Enchantment en : Enchantment.values()) { + if (stack.getEnchantmentLevel(en) > en.getMaxLevel()) + stack.removeEnchantment(en); + } + } + + Material material = stack.getType(); + if (material == Material.POTION || material == Material.SPLASH_POTION || material == Material.LINGERING_POTION) { + stack.setType(Material.MILK_BUCKET); + } + + e.setCurrentItem(stack); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/CraftbukkitWrapper.java b/LegacyBauSystem/src/de/steamwar/bausystem/CraftbukkitWrapper.java new file mode 100644 index 00000000..8dca9a27 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/CraftbukkitWrapper.java @@ -0,0 +1,43 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem; + +import de.steamwar.bausystem.tracer.AbstractTraceEntity; +import de.steamwar.core.VersionDependent; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +public class CraftbukkitWrapper { + private CraftbukkitWrapper() {} + + public static final ICraftbukkitWrapper impl = VersionDependent.getVersionImpl(BauSystem.getPlugin()); + + public interface ICraftbukkitWrapper { + void initTPS(); + void createTickCache(World world); + void sendTickPackets(); + + void openSignEditor(Player player, Location location); + + AbstractTraceEntity create(World world, Vector tntPosition, boolean tnt); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/CraftbukkitWrapper12.java b/LegacyBauSystem/src/de/steamwar/bausystem/CraftbukkitWrapper12.java new file mode 100644 index 00000000..46c1dbcb --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/CraftbukkitWrapper12.java @@ -0,0 +1,80 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem; + +import de.steamwar.bausystem.tracer.AbstractTraceEntity; +import de.steamwar.bausystem.world.TPSUtils; +import net.minecraft.server.v1_12_R1.*; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_12_R1.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.List; + +public class CraftbukkitWrapper12 implements CraftbukkitWrapper.ICraftbukkitWrapper { + + private final List> packets = new ArrayList<>(); + + @Override + public void initTPS() { + TPSUtils.disableWarp(); + } + + @Override + public void createTickCache(World world) { + packets.clear(); + world.getEntities().stream().filter(entity -> !(entity instanceof Player)).forEach(entity -> { + packets.add(new PacketPlayOutEntityVelocity(entity.getEntityId(), 0, 0, 0)); + packets.add(new PacketPlayOutEntityTeleport(((CraftEntity) entity).getHandle())); + + if (entity instanceof TNTPrimed) { + net.minecraft.server.v1_12_R1.Entity serverEntity = ((CraftEntity) entity).getHandle(); + packets.add(new PacketPlayOutEntityMetadata(serverEntity.getId(), serverEntity.getDataWatcher(), true)); + } + }); + } + + @Override + public void sendTickPackets() { + Bukkit.getOnlinePlayers().forEach(player -> { + PlayerConnection connection = ((CraftPlayer) player).getHandle().playerConnection; + for (Packet p : packets) { + connection.sendPacket(p); + } + }); + } + + @Override + public void openSignEditor(Player player, Location location) { + PacketPlayOutOpenSignEditor packet = new PacketPlayOutOpenSignEditor(new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ())); + ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); + } + + @Override + public AbstractTraceEntity create(World world, Vector tntPosition, boolean tnt) { + return new TraceEntity12(world, tntPosition, tnt); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/FlatteningWrapper.java b/LegacyBauSystem/src/de/steamwar/bausystem/FlatteningWrapper.java new file mode 100644 index 00000000..2fbbcb64 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/FlatteningWrapper.java @@ -0,0 +1,53 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem; + +import de.steamwar.bausystem.world.Detoloader; +import de.steamwar.core.VersionDependent; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +public class FlatteningWrapper { + private FlatteningWrapper(){} + + public static final IFlatteningWrapper impl = VersionDependent.getVersionImpl(BauSystem.getPlugin()); + + public interface IFlatteningWrapper { + boolean tntPlaceActionPerform(Location location); + boolean setRedstone(Location location, boolean active); + Detoloader onPlayerInteractLoader(PlayerInteractEvent event); + boolean getLever(Block block); + + boolean isNoBook(ItemStack item); + + boolean inWater(World world, Vector tntPosition); + Material getTraceShowMaterial(); + Material getTraceHideMaterial(); + Material getTraceXZMaterial(); + + void giveStick(Player player); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/FlatteningWrapper12.java b/LegacyBauSystem/src/de/steamwar/bausystem/FlatteningWrapper12.java new file mode 100644 index 00000000..b6cf7359 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/FlatteningWrapper12.java @@ -0,0 +1,148 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem; + +import de.steamwar.bausystem.world.Detoloader; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +import java.util.List; +import java.util.stream.Collectors; + +public class FlatteningWrapper12 implements FlatteningWrapper.IFlatteningWrapper { + + @Override + public boolean tntPlaceActionPerform(Location location) { + Material m = location.getBlock().getType(); + if (m != Material.AIR && m != Material.STATIONARY_WATER && m != Material.WATER) + return false; + + location.getBlock().setType(Material.TNT); + return true; + } + + @Override + @SuppressWarnings("deprecation") + public boolean setRedstone(Location location, boolean active) { + Block block = location.getBlock(); + Material material = block.getType(); + if (material == Material.LEVER || material == Material.STONE_BUTTON || material == Material.WOOD_BUTTON) { + if (active) + block.setData((byte) (block.getData() | 8)); + else + block.setData((byte) (block.getData() & -9)); + } else if (material == Material.STONE_PLATE || material == Material.WOOD_PLATE) { + if (active) + block.setData((byte) 1); + else + block.setData((byte) 0); + } else if (material == Material.TRIPWIRE) { + if (active) { + ArmorStand armorStand = (ArmorStand) Bukkit.getWorlds().get(0).spawnEntity(location, EntityType.ARMOR_STAND); + armorStand.setVisible(false); + armorStand.setBasePlate(false); + armorStand.addScoreboardTag("detonator-" + location.getBlockX() + location.getBlockY() + location.getBlockZ()); + } else { + List entityList = Bukkit.getWorlds().get(0).getEntitiesByClasses(ArmorStand.class).stream().filter(entity -> + entity.getScoreboardTags().contains("detonator-" + location.getBlockX() + location.getBlockY() + location.getBlockZ())) + .limit(1) + .collect(Collectors.toList()); + if (entityList.isEmpty()) return false; + entityList.get(0).remove(); + } + } else { + return false; + } + block.getState().update(true); + return true; + } + + @Override + @SuppressWarnings("deprecation") + public Detoloader onPlayerInteractLoader(PlayerInteractEvent event) { + Block block = event.getClickedBlock(); + Material material = block.getType(); + if (material == Material.LEVER) { + if ((block.getData() & 8) == 8) { + return new Detoloader("Hebel", 0).setActive(false); + } else { + return new Detoloader("Hebel", 0).setActive(true); + } + } else if (material == Material.STONE_BUTTON) { + return new Detoloader("Knopf", Detoloader.STONE_BUTTON); + } else if (material == Material.WOOD_BUTTON) { + return new Detoloader("Knopf", Detoloader.WOODEN_BUTTON); + } else if (material == Material.NOTE_BLOCK) { + return new Detoloader("Noteblock", Detoloader.NOTE_BLOCK); + } else if (material == Material.STONE_PLATE || material == Material.WOOD_PLATE) { + return new Detoloader("Druckplatte", Detoloader.PRESSURE_PLATE); + } else if (material == Material.TRIPWIRE) { + return new Detoloader("Tripwire", Detoloader.TRIPWIRE); + } + return new Detoloader("§eUnbekannter Block betätigt (nicht aufgenommen)", -1).setAddBack(false); + } + + @Override + @SuppressWarnings("deprecation") + public boolean getLever(Block block) { + return (block.getData() & 8) == 8; + } + + @Override + public boolean isNoBook(ItemStack item) { + return item.getType() != Material.BOOK_AND_QUILL && item.getType() != Material.WRITTEN_BOOK; + } + + @Override + public boolean inWater(World world, Vector tntPosition) { + Material material = world.getBlockAt(tntPosition.getBlockX(), tntPosition.getBlockY(), tntPosition.getBlockZ()).getType(); + return material == Material.WATER || material == Material.STATIONARY_WATER; + } + + @Override + public Material getTraceShowMaterial() { + return Material.CONCRETE; + } + + @Override + public Material getTraceHideMaterial() { + return Material.CONCRETE; + } + + @Override + public Material getTraceXZMaterial() { + return Material.STEP; + } + + @Override + public void giveStick(Player player) { + player.sendMessage(BauSystem.PREFIX + "§cDen Debugstick gibt es nicht in der 1.12."); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/Mapper.java b/LegacyBauSystem/src/de/steamwar/bausystem/Mapper.java new file mode 100644 index 00000000..591fdd08 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/Mapper.java @@ -0,0 +1,87 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem; + +import de.steamwar.bausystem.tracer.show.ShowModeParameterType; +import de.steamwar.command.SWCommandUtils; +import de.steamwar.command.TypeMapper; +import de.steamwar.sql.BauweltMember; +import de.steamwar.sql.SteamwarUser; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + + +public class Mapper { + + private Mapper() { + throw new IllegalStateException("Utility Class"); + } + + public static void init() { + SWCommandUtils.addMapper(ShowModeParameterType.class, showModeParameterTypesTypeMapper()); + SWCommandUtils.addMapper(BauweltMember.class, bauweltMemberTypeMapper()); + } + + private static TypeMapper showModeParameterTypesTypeMapper() { + Map showModeParameterTypesMap = new HashMap<>(); + showModeParameterTypesMap.put("-water", ShowModeParameterType.WATER); + + showModeParameterTypesMap.put("-interpolatey", ShowModeParameterType.INTERPOLATE_Y); + showModeParameterTypesMap.put("-interpolate-y", ShowModeParameterType.INTERPOLATE_Y); + showModeParameterTypesMap.put("-interpolate_y", ShowModeParameterType.INTERPOLATE_Y); + showModeParameterTypesMap.put("-y", ShowModeParameterType.INTERPOLATE_Y); + + showModeParameterTypesMap.put("-interpolatex", ShowModeParameterType.INTERPOLATE_XZ); + showModeParameterTypesMap.put("-interpolate-x", ShowModeParameterType.INTERPOLATE_XZ); + showModeParameterTypesMap.put("-interpolate_x", ShowModeParameterType.INTERPOLATE_XZ); + showModeParameterTypesMap.put("-x", ShowModeParameterType.INTERPOLATE_XZ); + + showModeParameterTypesMap.put("-interpolatez", ShowModeParameterType.INTERPOLATE_XZ); + showModeParameterTypesMap.put("-interpolate-z", ShowModeParameterType.INTERPOLATE_XZ); + showModeParameterTypesMap.put("-interpolate_z", ShowModeParameterType.INTERPOLATE_XZ); + showModeParameterTypesMap.put("-z", ShowModeParameterType.INTERPOLATE_XZ); + + showModeParameterTypesMap.put("-interpolatexz", ShowModeParameterType.INTERPOLATE_XZ); + showModeParameterTypesMap.put("-interpolate-xz", ShowModeParameterType.INTERPOLATE_XZ); + showModeParameterTypesMap.put("-interpolate_xz", ShowModeParameterType.INTERPOLATE_XZ); + showModeParameterTypesMap.put("-xz", ShowModeParameterType.INTERPOLATE_XZ); + + showModeParameterTypesMap.put("-advanced", ShowModeParameterType.ADVANCED); + showModeParameterTypesMap.put("-a", ShowModeParameterType.ADVANCED); + showModeParameterTypesMap.put("advanced", ShowModeParameterType.ADVANCED); + showModeParameterTypesMap.put("a", ShowModeParameterType.ADVANCED); + + List tabCompletes = new ArrayList<>(showModeParameterTypesMap.keySet()); + return SWCommandUtils.createMapper(s -> showModeParameterTypesMap.getOrDefault(s, null), s -> tabCompletes); + } + + private static TypeMapper bauweltMemberTypeMapper() { + return SWCommandUtils.createMapper(s -> BauweltMember.getMembers(BauSystem.getOwnerID()) + .stream() + .filter(m -> SteamwarUser.get(m.getMemberID()).getUserName().equals(s)).findFirst().orElse(null), + s -> BauweltMember.getMembers(BauSystem.getOwnerID()) + .stream() + .map(m -> SteamwarUser.get(m.getMemberID()).getUserName()) + .collect(Collectors.toList())); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/Permission.java b/LegacyBauSystem/src/de/steamwar/bausystem/Permission.java new file mode 100644 index 00000000..f3e50856 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/Permission.java @@ -0,0 +1,26 @@ +/* + 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; + +public enum Permission { + WORLD, + WORLDEDIT, + MEMBER +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/RamUsage.java b/LegacyBauSystem/src/de/steamwar/bausystem/RamUsage.java new file mode 100644 index 00000000..b3fc6fd4 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/RamUsage.java @@ -0,0 +1,44 @@ +/* + * 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; + +import org.bukkit.Bukkit; + +import java.lang.management.ManagementFactory; +import java.util.logging.Level; + +public class RamUsage { + + private RamUsage() { + throw new IllegalStateException("Utility Class"); + } + + public static double getUsage() { + try { + long memorySize = ((com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getTotalPhysicalMemorySize(); + long freeMemory = ((com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getFreePhysicalMemorySize(); + return (memorySize - freeMemory) / (double) memorySize; + } catch (Throwable throwable) { + Bukkit.getLogger().log(Level.WARNING, throwable.getMessage(), throwable); + return 1D; + } + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/SWUtils.java b/LegacyBauSystem/src/de/steamwar/bausystem/SWUtils.java new file mode 100644 index 00000000..5f22d5be --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/SWUtils.java @@ -0,0 +1,64 @@ +/* + * 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; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.List; + +public class SWUtils { + + public static void giveItemToPlayer(Player player, ItemStack itemStack) { + if (itemStack == null || itemStack.getType() == Material.AIR) { + return; + } + for (int i = 0; i < player.getInventory().getSize(); i++) { + ItemStack current = player.getInventory().getItem(i); + if (current != null && current.isSimilar(itemStack)) { + player.getInventory().setItem(i, null); + itemStack = current; + break; + } + } + ItemStack current = player.getInventory().getItemInMainHand(); + player.getInventory().setItemInMainHand(itemStack); + if (current.getType() != Material.AIR) { + player.getInventory().addItem(current); + } + } + + public static List manageList(List strings, String[] args, int index) { + strings = new ArrayList<>(strings); + for (int i = strings.size() - 1; i >= 0; i--) { + if (!strings.get(i).startsWith(args[index])) { + strings.remove(i); + } + } + return strings; + } + + public static List manageList(List strings, String[] args) { + return manageList(strings, args, args.length - 1); + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/TraceEntity12.java b/LegacyBauSystem/src/de/steamwar/bausystem/TraceEntity12.java new file mode 100644 index 00000000..b30fc9eb --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/TraceEntity12.java @@ -0,0 +1,77 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem; + +import de.steamwar.bausystem.tracer.AbstractTraceEntity; +import net.minecraft.server.v1_12_R1.*; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_12_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +class TraceEntity12 extends EntityFallingBlock implements AbstractTraceEntity { + + private boolean exploded; + private int references; + + public TraceEntity12(World world, Vector position, boolean tnt) { + super(((CraftWorld) world).getHandle(), position.getX(), position.getY(), position.getZ(), tnt ? Blocks.TNT.getBlockData() : Blocks.STAINED_GLASS.getBlockData()); + + this.setNoGravity(true); + this.ticksLived = -12000; + } + + @Override + public void display(Player player, boolean exploded) { + if (!this.exploded && exploded) { + this.setCustomNameVisible(true); + this.setCustomName("Bumm"); + this.exploded = true; + if (references++ > 0) + sendDestroy(player); + } else if (references++ > 0) + return; + + PacketPlayOutSpawnEntity packetPlayOutSpawnEntity = new PacketPlayOutSpawnEntity(this, 70, Block.getCombinedId(getBlock())); + PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection; + playerConnection.sendPacket(packetPlayOutSpawnEntity); + + PacketPlayOutEntityMetadata packetPlayOutEntityMetadata = new PacketPlayOutEntityMetadata(getId(), datawatcher, true); + playerConnection.sendPacket(packetPlayOutEntityMetadata); + + } + + @Override + public boolean hide(Player player, boolean force) { + if (!force && --references > 0) + return false; + + sendDestroy(player); + die(); + return true; + } + + private void sendDestroy(Player player) { + PacketPlayOutEntityDestroy packetPlayOutEntityDestroy = new PacketPlayOutEntityDestroy(getId()); + ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packetPlayOutEntityDestroy); + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/WorldeditWrapper.java b/LegacyBauSystem/src/de/steamwar/bausystem/WorldeditWrapper.java new file mode 100644 index 00000000..8ba9bcc7 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/WorldeditWrapper.java @@ -0,0 +1,44 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import de.steamwar.bausystem.world.regions.PasteOptions; +import de.steamwar.bausystem.world.regions.Point; +import de.steamwar.core.VersionDependent; +import org.bukkit.entity.Player; + +import java.io.File; + +public class WorldeditWrapper { + private WorldeditWrapper() {} + + public static final IWorldeditWrapper impl = VersionDependent.getVersionImpl(BauSystem.getPlugin()); + + public interface IWorldeditWrapper { + void setSelection(Player p, Point minPoint, Point maxPoint); + + EditSession paste(File file, int x, int y, int z, PasteOptions pasteOptions); + EditSession paste(Clipboard clipboard, int x, int y, int z, PasteOptions pasteOptions); + + boolean isWorldEditCommand(String command); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/WorldeditWrapper12.java b/LegacyBauSystem/src/de/steamwar/bausystem/WorldeditWrapper12.java new file mode 100644 index 00000000..8fdf94ac --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/WorldeditWrapper12.java @@ -0,0 +1,114 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.BlockID; +import com.sk89q.worldedit.bukkit.BukkitWorld; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; +import com.sk89q.worldedit.function.operation.Operations; +import com.sk89q.worldedit.math.transform.AffineTransform; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.selector.CuboidRegionSelector; +import com.sk89q.worldedit.session.ClipboardHolder; +import com.sk89q.worldedit.world.World; +import de.steamwar.bausystem.world.regions.PasteOptions; +import de.steamwar.bausystem.world.regions.Point; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Objects; + +public class WorldeditWrapper12 implements WorldeditWrapper.IWorldeditWrapper { + + private final WorldEditPlugin WORLDEDIT_PLUGIN = ((WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit")); + private final World BUKKITWORLD = new BukkitWorld(Bukkit.getWorlds().get(0)); + + @Override + public void setSelection(Player p, Point minPoint, Point maxPoint) { + WORLDEDIT_PLUGIN.getSession(p).setRegionSelector(BUKKITWORLD, new CuboidRegionSelector(BUKKITWORLD, toVector(minPoint), toVector(maxPoint))); + } + + @Override + public EditSession paste(File file, int x, int y, int z, PasteOptions pasteOptions) { + World w = new BukkitWorld(Bukkit.getWorlds().get(0)); + Clipboard clipboard; + try { + clipboard = Objects.requireNonNull(ClipboardFormat.findByFile(file)).getReader(new FileInputStream(file)).read(w.getWorldData()); + } catch (NullPointerException | IOException e) { + throw new SecurityException("Bausystem schematic not found", e); + } + + return paste(clipboard, x, y, z, pasteOptions); + } + + @Override + public EditSession paste(Clipboard clipboard, int x, int y, int z, PasteOptions pasteOptions) { + World w = new BukkitWorld(Bukkit.getWorlds().get(0)); + + Vector dimensions = clipboard.getDimensions(); + Vector v = new Vector(x, y, z); + Vector offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin()); + AffineTransform aT = new AffineTransform(); + if (pasteOptions.isRotate()) { + aT = aT.rotateY(180); + v = v.add(dimensions.getX() / 2 + dimensions.getX() % 2, 0, dimensions.getZ() / 2 + dimensions.getZ() % 2).subtract(offset.multiply(-1, 1, -1)).subtract(1, 0, 1); + } else { + v = v.subtract(dimensions.getX() / 2 - dimensions.getX() % 2, 0, dimensions.getZ() / 2 - dimensions.getZ() % 2).subtract(offset); + } + + EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(w, -1); + ClipboardHolder ch = new ClipboardHolder(clipboard, w.getWorldData()); + ch.setTransform(aT); + + if (pasteOptions.isReset()) { + try { + e.setBlocks(new CuboidRegion(toVector(pasteOptions.getMinPoint()), toVector(pasteOptions.getMaxPoint())), new BaseBlock(BlockID.AIR)); + } catch (MaxChangedBlocksException ex) { + throw new SecurityException("Max blocks changed?", ex); + } + } + Operations.completeBlindly(ch.createPaste(e, w.getWorldData()).to(v).ignoreAirBlocks(pasteOptions.isIgnoreAir()).build()); + return e; + } + + @Override + public boolean isWorldEditCommand(String command) { + if (command.startsWith("/")) { + command = command.replaceFirst("/", ""); + } + command = command.toLowerCase(); + return ((WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit")).getWorldEdit().getPlatformManager() + .getCommandManager().getDispatcher().get(command) != null; + } + + private Vector toVector(Point point) { + return Vector.toBlockPoint(point.getX(), point.getY(), point.getZ()); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandClear.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandClear.java new file mode 100644 index 00000000..195d0f35 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandClear.java @@ -0,0 +1,71 @@ +/* + * 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.world.Welt; +import de.steamwar.command.SWCommand; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class CommandClear extends SWCommand { + + public CommandClear() { + super("clear"); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§eclear §8- §7Leere dein Inventar"); + p.sendMessage("§8/§ebau clear §8[§7Player§8] §8- §7Leere ein Spieler Inventar"); + } + + @Register + public void genericClearCommand(Player p) { + clear(p); + p.sendMessage(BauSystem.PREFIX + "Dein Inventar wurde geleert."); + } + + @Register + public void clearPlayerCommand(Player p, Player target) { + if (!permissionCheck(p)) return; + clear(target); + target.sendMessage(BauSystem.PREFIX + "Dein Inventar wurde von " + p.getDisplayName() + " §7geleert."); + p.sendMessage(BauSystem.PREFIX + "Das Inventar von " + target.getDisplayName() + " §7wurde geleert."); + } + + private boolean permissionCheck(Player player) { + if (Welt.noPermission(player, Permission.WORLD)) { + player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier keine fremden Inventare leeren."); + return false; + } + return true; + } + + private void clear(Player player) { + player.getInventory().clear(); + player.getInventory().setHelmet(new ItemStack(Material.AIR)); + player.getInventory().setChestplate(new ItemStack(Material.AIR)); + player.getInventory().setLeggings(new ItemStack(Material.AIR)); + player.getInventory().setBoots(new ItemStack(Material.AIR)); + } +} \ No newline at end of file diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandColor.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandColor.java new file mode 100644 index 00000000..ddd04fe9 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandColor.java @@ -0,0 +1,73 @@ +package de.steamwar.bausystem.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.world.Color; +import de.steamwar.bausystem.world.regions.GlobalRegion; +import de.steamwar.bausystem.world.regions.Region; +import de.steamwar.command.SWCommand; +import org.bukkit.entity.Player; + + +public class CommandColor extends SWCommand { + + private static CommandColor instance = null; + + public CommandColor() { + super("color"); + instance = this; + } + + public static CommandColor getInstance() { + return instance; + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§ecolor §8[§7Color§8] §8- §7Setze die Farbe der Region"); + p.sendMessage("§8/§ecolor §8[§7Color§8] §8[§7Type§8] §8- §7Setze die Farbe der Region oder Global"); + } + + @Register + public void genericColor(Player p, Color color) { + genericColorSet(p, color, ColorizationType.LOCAL); + } + + @Register + public void genericColorSet(Player p, Color color, ColorizationType colorizationType) { + if (!permissionCheck(p)) { + return; + } + if (colorizationType == ColorizationType.GLOBAL) { + Region.setGlobalColor(color); + p.sendMessage(BauSystem.PREFIX + "Alle Regions farben auf §e" + color.name().toLowerCase() + "§7 gesetzt"); + return; + } + Region region = Region.getRegion(p.getLocation()); + if (GlobalRegion.isGlobalRegion(region)) { + p.sendMessage(BauSystem.PREFIX + "§cDu befindest dich derzeit in keiner Region"); + return; + } + region.setColor(color); + p.sendMessage(BauSystem.PREFIX + "Regions farben auf §e" + color.name().toLowerCase() + "§7 gesetzt"); + } + + @Register + public void genericColorSet(Player p, ColorizationType colorizationType, Color color) { + genericColorSet(p, color, colorizationType); + } + + private boolean permissionCheck(Player p) { + if (!BauSystem.getOwner().equals(p.getUniqueId())) { + p.sendMessage(BauSystem.PREFIX + "§cDies ist nicht deine Welt!"); + return false; + } else { + return true; + } + } + + public enum ColorizationType { + LOCAL, + GLOBAL + } + +} \ No newline at end of file diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandDebugStick.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandDebugStick.java new file mode 100644 index 00000000..33c045a0 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandDebugStick.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.bausystem.commands; + +import de.steamwar.bausystem.FlatteningWrapper; +import de.steamwar.command.SWCommand; +import org.bukkit.entity.Player; + +public class CommandDebugStick extends SWCommand { + + public CommandDebugStick() { + super("debugstick"); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§edebugstick §8- §7Erhalte einen DebugStick"); + } + + @Register + public void genericCommand(Player p) { + FlatteningWrapper.impl.giveStick(p); + } +} \ No newline at end of file diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandDetonator.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandDetonator.java new file mode 100644 index 00000000..ca2bb9c7 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandDetonator.java @@ -0,0 +1,114 @@ +/* + * 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.SWUtils; +import de.steamwar.bausystem.world.Detonator; +import de.steamwar.bausystem.world.Welt; +import de.steamwar.command.SWCommand; +import org.bukkit.entity.Player; + +public class CommandDetonator extends SWCommand { + + public CommandDetonator() { + super ("detonator", "dt"); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§edetonator wand §8- §7Legt den Fernzünder ins Inventar"); + p.sendMessage("§8/§edetonator detonate §8- §7Benutzt den nächst besten Fernzünder"); + p.sendMessage("§8/§edetonator reset §8- §7Löscht alle markierten Positionen"); + p.sendMessage("§8/§edetonator remove §8- §7Entfernt den Fernzünder"); + } + + @Register("wand") + public void wandCommand(Player p) { + if (!permissionCheck(p)) return; + SWUtils.giveItemToPlayer(p, Detonator.WAND); + } + + @Register("detonator") + public void detonatorCommand(Player p) { + if (!permissionCheck(p)) return; + SWUtils.giveItemToPlayer(p, Detonator.WAND); + } + + @Register("item") + public void itemCommand(Player p) { + if (!permissionCheck(p)) return; + SWUtils.giveItemToPlayer(p, Detonator.WAND); + } + + + @Register("remove") + public void removeCommand(Player p) { + if (!permissionCheck(p)) return; + p.getInventory().removeItem(Detonator.WAND); + } + + + @Register("detonate") + public void detonateCommand(Player p) { + if (!permissionCheck(p)) return; + Detonator.execute(p); + } + + @Register("click") + public void clickCommand(Player p) { + if (!permissionCheck(p)) return; + Detonator.execute(p); + } + + @Register("use") + public void useCommand(Player p) { + if (!permissionCheck(p)) return; + Detonator.execute(p); + } + + + @Register("clear") + public void clearCommand(Player p) { + if (!permissionCheck(p)) return; + Detonator.clear(p); + } + + @Register("delete") + public void deleteCommand(Player p) { + if (!permissionCheck(p)) return; + Detonator.clear(p); + } + + @Register("reset") + public void resetCommand(Player p) { + if (!permissionCheck(p)) return; + Detonator.clear(p); + } + + private boolean permissionCheck(Player player) { + if (Welt.noPermission(player, Permission.WORLD)) { + player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht den Detonator nutzen"); + return false; + } + return true; + } +} \ No newline at end of file diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandFire.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandFire.java new file mode 100644 index 00000000..56b48621 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandFire.java @@ -0,0 +1,92 @@ +/* + 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.world.regions.Region; +import de.steamwar.bausystem.world.Welt; +import de.steamwar.command.SWCommand; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockSpreadEvent; + +public class CommandFire extends SWCommand implements Listener { + + public CommandFire() { + super("fire"); + Bukkit.getPluginManager().registerEvents(this, BauSystem.getPlugin()); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§efire §8- §7Toggle Feuerschaden"); + } + + @Register + public void toggleCommand(Player p) { + if (!permissionCheck(p)) return; + Region region = Region.getRegion(p.getLocation()); + if (toggle(region)) { + RegionUtils.actionBar(region, getEnableMessage()); + } else { + RegionUtils.actionBar(region, getDisableMessage()); + } + } + + private String getNoPermMessage() { + return "§cDu darfst hier nicht Feuerschaden (de-)aktivieren"; + } + + private String getEnableMessage() { + return "§cRegions Feuerschaden deaktiviert"; + } + + private String getDisableMessage() { + return "§aRegions Feuerschaden aktiviert"; + } + + private boolean toggle(Region region) { + region.setFire(!region.isFire()); + return region.isFire(); + } + + private boolean permissionCheck(Player player) { + if (Welt.noPermission(player, Permission.WORLD)) { + player.sendMessage(BauSystem.PREFIX + getNoPermMessage()); + return false; + } + return true; + } + + @EventHandler + public void onFireDamage(BlockBurnEvent e) { + if (Region.getRegion(e.getBlock().getLocation()).isFire()) e.setCancelled(true); + } + + @EventHandler + public void onFireSpread(BlockSpreadEvent e) { + if (Region.getRegion(e.getBlock().getLocation()).isFire()) e.setCancelled(true); + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandFreeze.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandFreeze.java new file mode 100644 index 00000000..a3460edd --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandFreeze.java @@ -0,0 +1,148 @@ +/* + 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.world.regions.Region; +import de.steamwar.bausystem.world.Welt; +import de.steamwar.command.SWCommand; +import de.steamwar.core.Core; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.*; +import org.bukkit.event.entity.EntityChangeBlockEvent; +import org.bukkit.event.entity.EntitySpawnEvent; +import org.bukkit.event.inventory.InventoryMoveItemEvent; + +public class CommandFreeze extends SWCommand implements Listener { + + public CommandFreeze() { + super("freeze", "stoplag"); + Bukkit.getPluginManager().registerEvents(this, BauSystem.getPlugin()); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§efreeze §8- §7Toggle Freeze"); + } + + @Register + public void toggleCommand(Player p) { + if (!permissionCheck(p)) return; + Region region = Region.getRegion(p.getLocation()); + if (toggle(region)) { + RegionUtils.actionBar(region, getEnableMessage()); + } else { + RegionUtils.actionBar(region, getDisableMessage()); + } + } + + private String getNoPermMessage() { + return "§cDu darfst diese Welt nicht einfrieren"; + } + + private String getEnableMessage(){ + return "§cRegion eingefroren"; + } + + private String getDisableMessage(){ + return "§aRegion aufgetaut"; + } + + private boolean toggle(Region region) { + region.setFreeze(!region.isFreeze()); + return region.isFreeze(); + } + + private boolean permissionCheck(Player player) { + if (Welt.noPermission(player, Permission.WORLD)) { + player.sendMessage(BauSystem.PREFIX + getNoPermMessage()); + return false; + } + return true; + } + + @EventHandler + public void onEntitySpawn(EntitySpawnEvent e) { + if (!Region.getRegion(e.getLocation()).isFreeze()) return; + e.setCancelled(true); + if (e.getEntityType() == EntityType.PRIMED_TNT) { + Bukkit.getScheduler().runTaskLater(BauSystem.getPlugin(), () -> { + e.getLocation().getBlock().setType(Material.TNT, false); + }, 1L); + } + } + + @EventHandler + public void onBlockCanBuild(BlockCanBuildEvent e) { + if (Core.getVersion() == 12) return; + if (!e.isBuildable()) return; + if (!Region.getRegion(e.getBlock().getLocation()).isFreeze()) return; + if (e.getMaterial() == Material.TNT) { + e.setBuildable(false); + e.getBlock().setType(Material.TNT, false); + } + } + + @EventHandler + public void onEntityChangeBlock(EntityChangeBlockEvent e) { + if (Region.getRegion(e.getBlock().getLocation()).isFreeze()) e.setCancelled(true); + } + + @EventHandler + public void onPhysicsEvent(BlockPhysicsEvent e){ + if (Region.getRegion(e.getBlock().getLocation()).isFreeze()) e.setCancelled(true); + } + + @EventHandler + public void onPistonExtend(BlockPistonExtendEvent e){ + if (Region.getRegion(e.getBlock().getLocation()).isFreeze()) e.setCancelled(true); + } + + @EventHandler + public void onPistonRetract(BlockPistonRetractEvent e){ + if (Region.getRegion(e.getBlock().getLocation()).isFreeze()) e.setCancelled(true); + } + + @EventHandler + public void onBlockGrow(BlockGrowEvent e){ + if (Region.getRegion(e.getBlock().getLocation()).isFreeze()) e.setCancelled(true); + } + + @EventHandler + public void onRedstoneEvent(BlockRedstoneEvent e) { + if (Region.getRegion(e.getBlock().getLocation()).isFreeze()) e.setNewCurrent(e.getOldCurrent()); + } + + @EventHandler + public void onBlockDispense(BlockDispenseEvent e) { + if (Region.getRegion(e.getBlock().getLocation()).isFreeze()) e.setCancelled(true); + } + + @EventHandler + public void onInventoryMoveEvent(InventoryMoveItemEvent e){ + if (Region.getRegion(e.getDestination().getLocation()).isFreeze()) e.setCancelled(true); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandGUI.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandGUI.java new file mode 100644 index 00000000..076d7c9d --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandGUI.java @@ -0,0 +1,530 @@ +/* + * 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.SWUtils; +import de.steamwar.bausystem.tracer.record.RecordStateMachine; +import de.steamwar.bausystem.tracer.show.TraceShowManager; +import de.steamwar.bausystem.world.*; +import de.steamwar.bausystem.world.regions.GlobalRegion; +import de.steamwar.bausystem.world.regions.Region; +import de.steamwar.command.SWCommand; +import de.steamwar.core.Core; +import de.steamwar.inventory.SWAnvilInv; +import de.steamwar.inventory.SWInventory; +import de.steamwar.inventory.SWItem; +import de.steamwar.inventory.SWListInv; +import de.steamwar.sql.BauweltMember; +import de.steamwar.sql.SteamwarUser; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Bukkit; +import org.bukkit.Material; +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.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerSwapHandItemsEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.potion.PotionEffectType; + +import java.util.*; + +public class CommandGUI extends SWCommand implements Listener { + + private static final Set OPEN_INVS = new HashSet<>(); + private static final Set OPEN_TRACER_INVS = new HashSet<>(); + private static final Set LAST_F_PLAYER = new HashSet<>(); + private static boolean isRefreshing = false; + + public CommandGUI() { + super("gui"); + Bukkit.getScheduler().runTaskTimerAsynchronously(BauSystem.getPlugin(), LAST_F_PLAYER::clear, 0, 20); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§egui §8- §7Öffne die GUI"); + p.sendMessage("§8/§egui item §8- §7Gebe das GUI item"); + } + + @Register + public void genericCommand(Player p) { + openBauGui(p); + OPEN_INVS.add(p); + } + + @Register({"item"}) + public void itemCommand(Player p) { + SWUtils.giveItemToPlayer(p, new ItemStack(Material.NETHER_STAR)); + } + + public static void openBauGui(Player player) { + Region region = Region.getRegion(player.getLocation()); + SWInventory inv = new SWInventory(player, 5 * 9, SteamwarUser.get(BauSystem.getOwner()).getUserName() + "s Bau"); + inv.setCallback(-1, clickType -> { + if (!isRefreshing) + OPEN_INVS.remove(player); + }); + + inv.setItem(43, getMaterial("GLASS_PANE", "THIN_GLASS"), "§7Platzhalter", clickType -> { + }); + inv.setItem(42, Material.NETHER_STAR, "§7Bau GUI Item", Arrays.asList("§7Du kannst dieses Item zum Öffnen der BauGUI nutzen", "§7oder Doppel F (Swap hands) drücken."), false, clickType -> { + player.closeInventory(); + player.performCommand("gui item"); + }); + + ItemStack dtWand = wand(player, Detonator.WAND, "§8/§7dt wand", Permission.WORLD, "§cDu hast keine Worldrechte"); + inv.setItem(39, dtWand, clickType -> { + if (Welt.noPermission(player, Permission.WORLD)) + return; + player.closeInventory(); + player.performCommand("dt wand"); + }); + + ItemStack redstoneWand = wand(player, CommandRedstoneTester.WAND, "§8/§7redstonetester", null, ""); + inv.setItem(37, redstoneWand, clickType -> { + player.closeInventory(); + player.performCommand("redstonetester"); + }); + + inv.setItem(40, getMaterial("WOODEN_AXE", "WOOD_AXE"), "§eWorldedit Axt", getNoPermsLore(Arrays.asList("§8//§7wand"), player, "§cDu hast keine Worldeditrechte", Permission.WORLDEDIT), false, clickType -> { + if (Welt.noPermission(player, Permission.WORLD)) + return; + player.closeInventory(); + player.performCommand("/wand"); + }); + inv.setItem(41, getMaterial("DEBUG_STICK", "STICK"), "§eDebugstick", getNoPermsLore(Arrays.asList("§8/§7debugstick"), player, "§cDu hast keine Worldrechte", Permission.WORLD), Core.getVersion() < 13, clickType -> { + if (Welt.noPermission(player, Permission.WORLD)) + return; + player.closeInventory(); + player.performCommand("debugstick"); + }); + + inv.setItem(20, Material.COMPASS, "§7TPS Limitieren", getNoPermsLore(Arrays.asList("§7Aktuell: §e" + CommandTPSLimiter.getCurrentTPSLimit(), "§8/§7tpslimit §8[§e0,5 - " + (TPSUtils.isWarpAllowed() ? 40 : 20) + "§8]"), player, "§cDu hast keine Worldrechte", Permission.WORLD), false, clickType -> { + if (Welt.noPermission(player, Permission.WORLD)) + return; + SWAnvilInv anvilInv = new SWAnvilInv(player, "TPS Limitieren"); + anvilInv.setItem(Material.COMPASS); + anvilInv.setCallback(s -> player.performCommand("tpslimit " + s)); + anvilInv.open(); + }); + inv.setItem(5, Material.FEATHER, "§7Geschwindigkeit", Arrays.asList("§7Aktuell: §e" + player.getFlySpeed() * 10, "§8/§7speed §8[§e1 - 10§8]"), false, clickType -> { + SWAnvilInv anvilInv = new SWAnvilInv(player, "Geschwindigkeit"); + anvilInv.setItem(Material.FEATHER); + anvilInv.setCallback(s -> player.performCommand("speed " + s)); + anvilInv.open(); + }); + + if (player.getUniqueId().equals(BauSystem.getOwner())) { + SWItem skull = SWItem.getPlayerSkull(player.getName()); + skull.setName("§7Bau verwalten"); + List skullLore = new ArrayList<>(); + skullLore.add("§7TNT: §e" + region.getTntMode().getName()); + skullLore.add("§7StopLag: §e" + (region.isFreeze() ? "Eingeschaltet" : "Ausgeschaltet")); + skullLore.add("§7Fire: §e" + (region.isFire() ? "Ausgeschaltet" : "Eingeschaltet")); + skullLore.add("§7Members: §e" + (BauweltMember.getMembers(BauSystem.getOwnerID()).size() - 1)); + skull.setLore(skullLore); + inv.setItem(4, skull); + } + + inv.setItem(6, Material.BOOK, "§7Script Bücher", Arrays.asList("§7Aktuell §e" + PredefinedBook.getBookCount() + " §7Bücher"), true, clickType -> { + player.closeInventory(); + scriptBooksGUI(player); + }); + + inv.setItem(21, Material.OBSERVER, "§7Tracer", getNoPermsLore(Arrays.asList("§7Status: §e" + RecordStateMachine.getRecordStatus().getName()), player, "§cDu hast keine Worldrechte", Permission.WORLD), false, clickType -> { + if (Welt.noPermission(player, Permission.WORLD)) + return; + player.closeInventory(); + OPEN_TRACER_INVS.add(player); + traceGUI(player); + }); + + inv.setItem(22, Material.DISPENSER, "§7Auto-Loader", getNoPermsLore(Arrays.asList("§7Status: " + (AutoLoader.hasLoader(player) ? "§aan" : "§caus")), player, "§cDu hast keine Worldrechte", Permission.WORLD), false, clickType -> { + if (Welt.noPermission(player, Permission.WORLD)) + return; + player.closeInventory(); + autoLoaderGUI(player); + }); + + inv.setItem(17, getMaterial("PLAYER_HEAD", "SKULL_ITEM"), (byte) 3, "§7Spielerkopf geben", Arrays.asList("§8/§7skull §8[§eSpieler§8]"), false, clickType -> { + SWAnvilInv anvilInv = new SWAnvilInv(player, "Spielerköpfe"); + anvilInv.setItem(Material.NAME_TAG); + anvilInv.setCallback(s -> player.performCommand("skull " + s)); + anvilInv.open(); + }); + + if (GlobalRegion.isGlobalRegion(region)) { + inv.setItem(9, Material.BARRIER, "§eKeine Region", clickType -> { + }); + inv.setItem(18, Material.BARRIER, "§eKeine Region", clickType -> { + }); + inv.setItem(27, Material.BARRIER, "§eKeine Region", clickType -> { + }); + } else { + inv.setItem(27, getMaterial("HEAVY_WEIGHTED_PRESSURE_PLATE", "IRON_PLATE"), "§eRegion Reseten", getNoPermsLore(Arrays.asList("§8/§7reset"), player, "§cDu hast keine Worldrechte", Permission.WORLD), false, clickType -> { + if (Welt.noPermission(player, Permission.WORLD)) + return; + confirmationInventory(player, "Region Reseten?", () -> player.performCommand("reset"), () -> openBauGui(player)); + }); + + if (region.hasProtection()) { + inv.setItem(18, Material.OBSIDIAN, "§eRegion Protecten", getNoPermsLore(Arrays.asList("§8/§7protect"), player, "§cDu hast keine Worldrechte", Permission.WORLD), false, clickType -> { + if (Welt.noPermission(player, Permission.WORLD)) + return; + confirmationInventory(player, "Region Protecten", () -> player.performCommand("protect"), () -> openBauGui(player)); + }); + } else { + inv.setItem(18, Material.BARRIER, "§eRegion nicht Protect bar", clickType -> { + }); + } + + if (region.hasTestblock()) { + inv.setItem(9, getMaterial("END_STONE", "ENDER_STONE"), "§eTestblock erneuern", getNoPermsLore(Arrays.asList("§8/§7testblock"), player, "§cDu hast keine Worldrechte", Permission.WORLD), false, clickType -> { + if (Welt.noPermission(player, Permission.WORLD)) + return; + confirmationInventory(player, "Testblock erneuern", () -> player.performCommand("testblock"), () -> openBauGui(player)); + }); + } else { + inv.setItem(9, Material.BARRIER, "§eDie Region hat keinen Testblock", clickType -> { + }); + } + } + + if (player.hasPotionEffect(PotionEffectType.NIGHT_VISION)) { + inv.setItem(26, Material.POTION, "§7Nightvision: §eEingeschaltet", Collections.singletonList("§8/§7nv"), false, clickType -> { + CommandNV.toggleNightvision(player); + openBauGui(player); + }); + } else { + inv.setItem(26, Material.GLASS_BOTTLE, "§7Nightvision: §eAusgeschaltet", Collections.singletonList("§8/§7nv"), false, clickType -> { + CommandNV.toggleNightvision(player); + openBauGui(player); + }); + } + + if (player.hasPotionEffect(PotionEffectType.WATER_BREATHING)) { + inv.setItem(35, Material.WATER_BUCKET, "§7Waterbreathing: §eEingeschaltet", Collections.singletonList("§8/§7wv"), false, clickType -> { + CommandGills.toggleGills(player); + openBauGui(player); + }); + } else { + inv.setItem(35, Material.BUCKET, "§7Waterbreathing: §eAusgeschaltet", Collections.singletonList("§8/§7wv"), false, clickType -> { + CommandGills.toggleGills(player); + openBauGui(player); + }); + } + + boolean isBuildArea = region.hasBuildRegion(); + List tntLore = getNoPermsLore(Arrays.asList("§8/§7tnt §8[" + (isBuildArea ? "§eTB§7, " : "") + "§eOff §7oder §eOn§7]"), player, "§cDu hast keine Worldrechte", Permission.WORLD); + switch (region.getTntMode()) { + case OFF: + inv.setItem(23, Material.MINECART, "§7TNT: §eAusgeschaltet", tntLore, false, clickType -> { + if (Welt.noPermission(player, Permission.WORLD)) + return; + player.performCommand("tnt " + (isBuildArea ? "tb" : "on")); + updateInventories(); + }); + break; + case ONLY_TB: + inv.setItem(23, getMaterial("TNT_MINECART", "EXPLOSIVE_MINECART"), "§7TNT: §enur Testblock", tntLore, false, clickType -> { + if (Welt.noPermission(player, Permission.WORLD)) + return; + player.performCommand("tnt on"); + updateInventories(); + }); + break; + default: + inv.setItem(23, Material.TNT, "§7TNT: §eEingeschaltet", tntLore, false, clickType -> { + if (Welt.noPermission(player, Permission.WORLD)) + return; + player.performCommand("tnt off"); + updateInventories(); + }); + } + + if (region.isFreeze()) { + inv.setItem(24, getMaterial("GUNPOWDER", "SULPHUR"), "§7Freeze: §eEingeschaltet", getNoPermsLore(Arrays.asList("§8/§7freeze"), player, "§cDu hast keine Worldrechte", Permission.WORLD), false, clickType -> { + if (Welt.noPermission(player, Permission.WORLD)) + return; + player.performCommand("freeze"); + updateInventories(); + }); + } else { + inv.setItem(24, Material.REDSTONE, "§7Freeze: §eAusgeschaltet", getNoPermsLore(Arrays.asList("§8/§7freeze"), player, "§cDu hast keine Worldrechte", Permission.WORLD), false, clickType -> { + if (Welt.noPermission(player, Permission.WORLD)) + return; + player.performCommand("freeze"); + updateInventories(); + }); + } + + if (region.isFire()) { + inv.setItem(3, getMaterial("FIREWORK_STAR", "FIREWORK_CHARGE"), "§7Fire: §eAusgeschaltet", getNoPermsLore(Arrays.asList("§8/§7fire"), player, "§cDu hast keine Worldrechte", Permission.WORLD), false, clickType -> { + if (Welt.noPermission(player, Permission.WORLD)) + return; + player.performCommand("fire"); + updateInventories(); + }); + } else { + inv.setItem(3, getMaterial("FIRE_CHARGE", "FIREBALL"), "§7Fire: §eEingeschaltet", getNoPermsLore(Arrays.asList("§8/§7fire"), player, "§cDu hast keine Worldrechte", Permission.WORLD), false, clickType -> { + if (Welt.noPermission(player, Permission.WORLD)) + return; + player.performCommand("fire"); + updateInventories(); + }); + } + + inv.setItem(2, Material.ENDER_PEARL, "§7Teleporter", getNoPermsLore(Arrays.asList("§8/§7tp §8[§eSpieler§8]"), player, "", null), false, clickType -> { + List> playerSWListEntry = new ArrayList<>(); + Bukkit.getOnlinePlayers().forEach(player1 -> { + if (player1.equals(player)) + return; + playerSWListEntry.add(new SWListInv.SWListEntry<>(SWItem.getPlayerSkull(player1.getName()), player1.getName())); + }); + SWListInv playerSWListInv = new SWListInv<>(player, "Teleporter", playerSWListEntry, (clickType1, player1) -> { + player.closeInventory(); + player.performCommand("tp " + player1); + }); + playerSWListInv.open(); + }); + + inv.open(); + } + + private static void traceGUI(Player player) { + SWInventory inv = new SWInventory(player, 9, "Tracer"); + inv.setCallback(-1, clickType -> { + if (!isRefreshing) + OPEN_TRACER_INVS.remove(player); + }); + List stateLore = Arrays.asList("§7Aktuell: §e" + RecordStateMachine.getRecordStatus().getName(), "§8/§7trace §8[§estart§8, stop §8oder §eauto§8]"); + switch (RecordStateMachine.getRecordStatus()) { + case IDLE: + inv.setItem(0, getMaterial("SNOWBALL", "SNOW_BALL"), "§7Tracerstatus", stateLore, false, clickType -> { + RecordStateMachine.commandAuto(); + updateInventories(); + }); + break; + case IDLE_AUTO: + inv.setItem(0, Material.ENDER_PEARL, "§7Tracerstatus", stateLore, false, clickType -> { + RecordStateMachine.commandStart(); + updateInventories(); + }); + break; + case RECORD: + case RECORD_AUTO: + inv.setItem(0, getMaterial("ENDER_EYE", "EYE_OF_ENDER"), "§7Tracerstatus", stateLore, false, clickType -> { + RecordStateMachine.commandStop(); + updateInventories(); + }); + } + if (TraceShowManager.hasActiveShow(player)) { + inv.setItem(2, Material.TNT, "§7Showstatus", Arrays.asList("§7Aktuell: §eGezeigt", "§8/§7trace §8[§eshow§8/§ehide§8]"), false, clickType -> { + player.performCommand("trace hide"); + traceGUI(player); + }); + } else { + inv.setItem(2, Material.GLASS, "§7Showstatus", Arrays.asList("§7Aktuell: §eVersteckt", "§8/§7trace §8[§eshow§8/§ehide§8]"), false, clickType -> { + player.performCommand("trace show"); + traceGUI(player); + }); + } + + inv.setItem(4, getMaterial("TNT_MINECART", "EXPLOSIVE_MINECART"), "§7Trace GUI", Collections.singletonList("§8/§7trace show gui"), false, clickType -> { + player.closeInventory(); + player.performCommand("trace show gui"); + }); + + inv.setItem(6, Material.BARRIER, "§7Trace löschen", Arrays.asList("§8/§7trace delete"), false, clickType -> confirmationInventory(player, "Trace löschen", () -> player.performCommand("trace delete"), () -> { + })); + + inv.setItem(8, Material.ARROW, "§7Zurück", clickType -> { + player.closeInventory(); + openBauGui(player); + OPEN_INVS.add(player); + }); + + inv.open(); + } + + private static void scriptBooksGUI(Player player) { + List> entries = new ArrayList<>(); + List books = PredefinedBook.getBooks(); + books.forEach(predefinedBook -> entries.add(new SWListInv.SWListEntry<>(new SWItem(predefinedBook.getBookMat(), predefinedBook.getName(), predefinedBook.getLore(), false, clickType -> { + }), predefinedBook))); + SWListInv inv = new SWListInv<>(player, "Script Bücher", entries, (clickType, predefinedBook) -> { + player.closeInventory(); + player.getInventory().addItem(predefinedBook.toItemStack()); + }); + inv.open(); + } + + private static void autoLoaderGUI(Player player) { + SWInventory inv = new SWInventory(player, 9, "Autoloader"); + + boolean hasLoader = AutoLoader.hasLoader(player); + + if (hasLoader) { + AutoLoader loader = AutoLoader.getLoader(player); + if (loader.isSetup()) { + inv.setItem(0, Material.DROPPER, "§7Loader Starten", Collections.singletonList("§8/§7loader start"), false, clickType -> { + loader.start(); + autoLoaderGUI(player); + }); + + inv.setItem(2, Material.ARROW, "§7Letzte Aktion entfernen", Collections.singletonList("§8/§7loader undo"), false, clickType -> { + + }); + } else { + inv.setItem(0, Material.BLAZE_ROD, "§7Loader Bearbeiten", Collections.singletonList("§8/§7loader setup"), false, clickType -> { + loader.setup(); + autoLoaderGUI(player); + }); + } + + inv.setItem(4, Material.COMPASS, "§7Schuss Delay", Arrays.asList("§7Aktuell: §e" + loader.getTicksBetweenShots(), "§8/§7loader wait §8[§eTicks§8]"), false, clickType -> { + SWAnvilInv anvilInv = new SWAnvilInv(player, "Schuss Delay", loader.getTicksBetweenShots() + ""); + anvilInv.setItem(Material.STONE); + anvilInv.setCallback(s -> { + player.performCommand("loader wait " + s); + autoLoaderGUI(player); + }); + anvilInv.open(); + }); + + inv.setItem(6, getMaterial("CLOCK", "WATCH"), "§7Block platzier Geschwindigkeit", Arrays.asList("§7Aktuell: §e" + loader.getTicksBetweenBlocks(), "§8/§7loader speed §8[§eTicks§8]"), false, clickType -> { + SWAnvilInv anvilInv = new SWAnvilInv(player, "Platzier Geschwindigkeit", loader.getTicksBetweenBlocks() + ""); + anvilInv.setItem(Material.STONE); + anvilInv.setCallback(s -> { + player.performCommand("loader speed " + s); + autoLoaderGUI(player); + }); + anvilInv.open(); + }); + + inv.setItem(8, Material.BARRIER, "§7Loader löschen", Collections.singletonList("§8/§7loader stop"), false, clickType -> confirmationInventory(player, "Loader löschen?", () -> { + loader.stop(); + autoLoaderGUI(player); + }, () -> autoLoaderGUI(player))); + } else { + inv.setItem(4, Material.GOLD_NUGGET, "§eNeuer Autoloader", clickType -> { + AutoLoader.getLoader(player); + player.closeInventory(); + }); + inv.setItem(8, Material.ARROW, "§7Zurück", clickType -> { + player.closeInventory(); + openBauGui(player); + OPEN_INVS.add(player); + }); + } + + inv.open(); + } + + + private static void confirmChatMessage(Player player, String command) { + player.sendMessage(BauSystem.PREFIX + "§7Klicke auf die Nachricht zum bestätigen"); + TextComponent t = new TextComponent(); + t.setText("[Hier]"); + t.setColor(ChatColor.YELLOW); + t.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, command)); + t.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText("§7" + command))); + player.spigot().sendMessage(t); + } + + private static List getNoPermsLore(List lore, Player player, String noPerms, Permission perm) { + if (perm != null && Welt.noPermission(player, perm)) { + lore = new ArrayList<>(lore); + lore.add(noPerms); + } + return lore; + } + + private static void updateInventories() { + isRefreshing = true; + OPEN_INVS.forEach(CommandGUI::openBauGui); + OPEN_TRACER_INVS.forEach(CommandGUI::traceGUI); + isRefreshing = false; + } + + private static void confirmationInventory(Player player, String title, Runnable confirm, Runnable decline) { + SWInventory inv = new SWInventory(player, 9, title); + inv.setItem(0, SWItem.getDye(1), (byte) 1, "§cAbbrechen", clickType -> { + player.closeInventory(); + decline.run(); + }); + inv.setItem(8, SWItem.getDye(10), (byte) 10, "§aBestätigen", clickType -> { + player.closeInventory(); + confirm.run(); + }); + inv.open(); + } + + private static Material getMaterial(String... names) { + for (String name : names) { + try { + return Material.valueOf(name); + } catch (IllegalArgumentException ignored) { + //Ignored /\ + } + } + return null; + } + + private static ItemStack wand(Player player, ItemStack base, String command, Permission permission, String noPermissionMessage) { + base = base.clone(); + ItemMeta meta = base.getItemMeta(); + List lore = meta.getLore(); + lore.add(command); + if (permission != null && Welt.noPermission(player, permission)) + lore.add(noPermissionMessage); + meta.setLore(lore); + base.setItemMeta(meta); + return base; + } + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + if (event.getAction() != Action.RIGHT_CLICK_AIR && event.getAction() != Action.RIGHT_CLICK_BLOCK) + return; + if (event.getItem() == null || event.getItem().getType() != Material.NETHER_STAR) + return; + openBauGui(event.getPlayer()); + OPEN_INVS.add(event.getPlayer()); + } + + @EventHandler + public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) { + if (LAST_F_PLAYER.contains(event.getPlayer())) { + openBauGui(event.getPlayer()); + OPEN_INVS.add(event.getPlayer()); + } else { + LAST_F_PLAYER.add(event.getPlayer()); + } + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandGamemode.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandGamemode.java new file mode 100644 index 00000000..5ddbfa0d --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandGamemode.java @@ -0,0 +1,50 @@ +/* + * 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.commands; + +import de.steamwar.command.SWCommand; +import org.bukkit.GameMode; +import org.bukkit.entity.Player; + +public class CommandGamemode extends SWCommand { + + public CommandGamemode() { + super("gamemode", "gm", "g"); + } + + @Register(help = true) + public void gamemodeHelp(Player p, String... args) { + p.sendMessage("§cUnbekannter Spielmodus"); + } + + @Register + public void genericCommand(Player p) { + if (p.getGameMode() == GameMode.CREATIVE) { + p.setGameMode(GameMode.SPECTATOR); + } else { + p.setGameMode(GameMode.CREATIVE); + } + } + + @Register + public void gamemodeCommand(Player p, GameMode gameMode) { + p.setGameMode(gameMode); + } +} \ No newline at end of file diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandGills.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandGills.java new file mode 100644 index 00000000..051ea107 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandGills.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.bausystem.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.command.SWCommand; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class CommandGills extends SWCommand { + + public CommandGills() { + super("watervision", "wv"); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§ewatervision §8- §7Toggle WaterBreathing"); + } + + @Register + public void genericCommand(Player p) { + toggleGills(p); + } + + public static void toggleGills(Player player) { + if (player.hasPotionEffect(PotionEffectType.WATER_BREATHING)) { + player.sendMessage(BauSystem.PREFIX + "Wassersicht deaktiviert"); + player.removePotionEffect(PotionEffectType.WATER_BREATHING); + return; + } + player.addPotionEffect(new PotionEffect(PotionEffectType.WATER_BREATHING, 1000000, 255, false, false)); + player.sendMessage(BauSystem.PREFIX + "Wassersicht aktiviert"); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandInfo.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandInfo.java new file mode 100644 index 00000000..b1831409 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandInfo.java @@ -0,0 +1,80 @@ +/* + 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.world.TPSUtils; +import de.steamwar.bausystem.world.regions.Region; +import de.steamwar.command.SWCommand; +import de.steamwar.core.TPSWatcher; +import de.steamwar.sql.BauweltMember; +import de.steamwar.sql.SteamwarUser; +import org.bukkit.entity.Player; + +import java.util.List; + +import static de.steamwar.bausystem.world.TPSUtils.getTps; + +public class CommandInfo extends SWCommand { + + public CommandInfo() { + super("bauinfo"); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§ebauinfo §8- §7Gibt Informationen über den Bau"); + } + + @Register + public void genericCommand(Player p) { + CommandInfo.sendBauInfo(p); + } + + public static void sendBauInfo(Player p) { + p.sendMessage(BauSystem.PREFIX + "Besitzer: §e" + SteamwarUser.get(BauSystem.getOwnerID()).getUserName()); + Region region = Region.getRegion(p.getLocation()); + p.sendMessage(BauSystem.PREFIX + "§eTNT§8: " + region.getTntMode().getName() + " §eFire§8: " + (region.isFire() ? "§aAUS" : "§cAN") + " §eFreeze§8: " + (region.isFreeze() ? "§aAN" : "§cAUS")); + if (region.hasProtection()) { + p.sendMessage(BauSystem.PREFIX + "§eProtect§8: " + (region.isProtect() ? "§aAN" : "§cAUS")); + } + + List members = BauweltMember.getMembers(BauSystem.getOwnerID()); + StringBuilder membermessage = new StringBuilder().append(BauSystem.PREFIX).append("Mitglieder: "); + + for (BauweltMember member : members) { + membermessage.append("§e").append(SteamwarUser.get(member.getMemberID()).getUserName()).append("§8["); + membermessage.append(member.isWorldEdit() ? "§a" : "§c").append("WE").append("§8,"); + membermessage.append(member.isWorld() ? "§a" : "§c").append("W").append("§8]").append(" "); + } + p.sendMessage(membermessage.toString()); + + StringBuilder tpsMessage = new StringBuilder(); + tpsMessage.append(BauSystem.PREFIX).append("TPS:§e"); + tpsMessage.append(" ").append(getTps(TPSWatcher.TPSType.ONE_SECOND)); + tpsMessage.append(" ").append(getTps(TPSWatcher.TPSType.TEN_SECONDS)); + if (!TPSUtils.isWarping()) { + tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_MINUTE)); + tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.FIVE_MINUTES)); + tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES)); + } + p.sendMessage(tpsMessage.toString()); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandKillAll.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandKillAll.java new file mode 100644 index 00000000..389a191a --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandKillAll.java @@ -0,0 +1,74 @@ +/* + * 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.commands; + +import de.steamwar.bausystem.world.regions.*; +import de.steamwar.command.SWCommand; +import java.util.concurrent.atomic.AtomicLong; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.entity.Player; + +public class CommandKillAll extends SWCommand { + + private static final World WORLD = Bukkit.getWorlds().get(0); + + public CommandKillAll() { + super("killall", "removeall"); + } + + @Register(help = true) + public void genericHelp(Player player, String... args) { + player.sendMessage("§8/§ekillall §8- §7Entferne alle Entities aus deiner Region"); + player.sendMessage("§8/§ekillall §8[§7Global§8/Local§7] §8- §7Entferne alle Entities aus deiner Region oder global"); + } + + @Register + public void genericCommand(Player player) { + genericCommand(player, RegionSelectionType.LOCAL); + } + + @Register + public void genericCommand(Player player, RegionSelectionType regionSelectionType) { + Region region = Region.getRegion(player.getLocation()); + AtomicLong removedEntities = new AtomicLong(); + if (regionSelectionType == RegionSelectionType.GLOBAL || GlobalRegion.isGlobalRegion(region)) { + WORLD.getEntities() + .stream() + .filter(e -> !(e instanceof Player)) + .forEach(entity -> { + entity.remove(); + removedEntities.getAndIncrement(); + }); + RegionUtils.actionBar(GlobalRegion.getInstance(), "§a" + removedEntities.get() + " Entities aus der Welt entfernt"); + } else { + WORLD.getEntities() + .stream() + .filter(e -> !(e instanceof Player)) + .filter(e -> region.inRegion(e.getLocation(), RegionType.NORMAL, RegionExtensionType.NORMAL)) + .forEach(entity -> { + entity.remove(); + removedEntities.getAndIncrement(); + }); + RegionUtils.actionBar(region, "§a" + removedEntities.get() + " Entities aus der Region entfernt"); + } + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandLoader.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandLoader.java new file mode 100644 index 00000000..628db208 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandLoader.java @@ -0,0 +1,134 @@ +/* + 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.world.AutoLoader; +import de.steamwar.bausystem.world.Welt; +import de.steamwar.command.SWCommand; +import org.bukkit.entity.Player; + +public class CommandLoader extends SWCommand { + + public CommandLoader() { + super("loader"); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§eloader setup §8- §7Startet die Aufnahme der Aktionen"); + p.sendMessage("§8/§7loader undo §8- §7Entfernt die zuletzt aufgenommene Aktion"); + p.sendMessage("§8/§eloader start §8- §7Spielt die zuvor aufgenommenen Aktionen ab"); + p.sendMessage("§8/§7loader wait §8[§7Ticks§8] - §7Setzt die Wartezeit zwischen Schüssen"); + p.sendMessage("§8/§7loader speed §8[§7Ticks§8] - §7Setzt die Wartezeit zwischen Aktionen"); + p.sendMessage("§8/§eloader stop §8- §7Stoppt die Aufnahme bzw. das Abspielen"); + p.sendMessage("§7Der AutoLader arbeitet mit §eIngame§8-§eTicks §8(20 Ticks pro Sekunde)"); + } + + @Register({"setup"}) + public void setupCommand(Player p) { + setup(p); + } + + @Register({"undo"}) + public void undoCommand(Player p) { + undo(p); + } + + @Register({"start"}) + public void startCommand(Player p) { + start(p); + } + + @Register({"stop"}) + public void stopCommand(Player p) { + stop(p); + } + + @Register({"wait"}) + public void waitCommand(Player p, int time) { + wait(p, time); + } + + @Register({"speed"}) + public void speedCommand(Player p, int time) { + speed(p, time); + } + + private void setup(Player player) { + AutoLoader.getLoader(player).setup(); + } + + private void undo(Player player) { + AutoLoader loader = loader(player); + if (loader == null) + return; + + if (!loader.isSetup()) { + player.sendMessage("§cDer AutoLader wird in den Setup-Zustand versetzt"); + setup(player); + } + + loader.undo(); + } + + private void start(Player player) { + AutoLoader loader = loader(player); + if (loader == null) + return; + + loader.start(); + } + + private void stop(Player player) { + if (!AutoLoader.hasLoader(player)) { + player.sendMessage(BauSystem.PREFIX + "§cDu hast keinen aktiven AutoLader"); + return; + } + AutoLoader.getLoader(player).stop(); + } + + private void wait(Player player, int time) { + AutoLoader loader = loader(player); + if (loader == null) { + loader = AutoLoader.getLoader(player); + } + loader.wait(time); + } + + private void speed(Player player, int time) { + AutoLoader loader = loader(player); + if (loader == null) { + loader = AutoLoader.getLoader(player); + } + loader.blockWait(time); + } + + private AutoLoader loader(Player player) { + if (AutoLoader.hasLoader(player)) { + return AutoLoader.getLoader(player); + } + player.sendMessage(BauSystem.PREFIX + "§cDu hast keinen aktiven AutoLader"); + player.sendMessage(BauSystem.PREFIX + "§7Es wird ein neuer AutoLader gestartet"); + setup(player); + return null; + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandLockschem.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandLockschem.java new file mode 100644 index 00000000..c5f20eb3 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandLockschem.java @@ -0,0 +1,67 @@ +/* + 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.command.SWCommand; +import de.steamwar.sql.*; +import org.bukkit.entity.Player; + +public class CommandLockschem extends SWCommand { + + public CommandLockschem() { + super("lockschem"); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + if (!SteamwarUser.get(p.getUniqueId()).hasPerm(UserPerm.CHECK)) { + return; + } + + sendHelp(p); + } + + @Register + public void genericCommand(Player p, String owner, String schematicName) { + if (!SteamwarUser.get(p.getUniqueId()).hasPerm(UserPerm.CHECK)) { + return; + } + + SteamwarUser schemOwner = SteamwarUser.get(owner); + if (schemOwner == null) { + p.sendMessage(BauSystem.PREFIX + "Dieser Spieler existiert nicht!"); + return; + } + SchematicNode node = SchematicNode.getNodeFromPath(schemOwner, schematicName); + if (node == null) { + p.sendMessage(BauSystem.PREFIX + "Dieser Spieler besitzt keine Schematic mit diesem Namen!"); + return; + } + p.sendMessage(BauSystem.PREFIX + "Schematic " + node .getName() + " von " + + SteamwarUser.get(node.getOwner()).getUserName() + " von " + node.getSchemtype().toString() + + " auf NORMAL zurückgesetzt!"); + node.setSchemtype(SchematicType.Normal); + } + + private void sendHelp(Player player) { + player.sendMessage("§8/§eschemlock §8[§7Owner§8] §8[§7Schematic§8] §8- §7 Sperre eine Schematic"); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandNV.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandNV.java new file mode 100644 index 00000000..7b232a22 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandNV.java @@ -0,0 +1,54 @@ +/* + 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.command.SWCommand; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class CommandNV extends SWCommand { + + public CommandNV() { + super("nightvision", "nv"); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§enightvision §8- §7Toggle NightVision"); + } + + @Register + public void genericCommand(Player p) { + toggleNightvision(p); + } + + public static void toggleNightvision(Player player) { + if (player.hasPotionEffect(PotionEffectType.NIGHT_VISION)) { + player.sendMessage(BauSystem.PREFIX + "Nachtsicht deaktiviert"); + player.removePotionEffect(PotionEffectType.NIGHT_VISION); + return; + } + + player.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION, 1000000, 255, false, false)); + player.sendMessage(BauSystem.PREFIX + "Nachtsicht aktiviert"); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandProtect.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandProtect.java new file mode 100644 index 00000000..f97d18e8 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandProtect.java @@ -0,0 +1,127 @@ +/* + 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.world.Welt; +import de.steamwar.bausystem.world.regions.Region; +import de.steamwar.command.SWCommand; +import de.steamwar.sql.SchematicNode; +import de.steamwar.sql.SteamwarUser; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityExplodeEvent; + +import java.io.IOException; +import java.util.logging.Level; + +public class CommandProtect extends SWCommand implements Listener { + + public CommandProtect() { + super("protect"); + if (Region.buildAreaEnabled()) { + Bukkit.getPluginManager().registerEvents(this, BauSystem.getPlugin()); + } + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§eprotect §8- §7Schütze die Region"); + p.sendMessage("§8/§eprotect §8[§7Schematic§8] §8- §7Schütze die Region mit einer Schematic"); + } + + @Register + public void genericProtectCommand(Player p) { + if (!permissionCheck(p)) return; + Region region = regionCheck(p); + if (region == null) return; + if (Region.buildAreaEnabled()) { + region.setProtect(!region.isProtect()); + if (region.isProtect()) { + RegionUtils.actionBar(region, "§aBoden geschützt"); + } else { + RegionUtils.actionBar(region, "§cBoden Schutz aufgehoben"); + } + return; + } + try { + region.protect(null); + p.sendMessage(BauSystem.PREFIX + "§7Boden geschützt"); + } catch (IOException e) { + p.sendMessage(BauSystem.PREFIX + "§cFehler beim Schützen der Region"); + Bukkit.getLogger().log(Level.WARNING, "Failed protect", e); + } + } + + @Register + public void schematicProtectCommand(Player p, String s) { + if (!permissionCheck(p)) return; + if (Region.buildAreaEnabled()) { + genericHelp(p); + return; + } + Region region = regionCheck(p); + if (region == null) return; + SteamwarUser owner = SteamwarUser.get(p.getUniqueId()); + SchematicNode schem = SchematicNode.getNodeFromPath(owner, s); + if (schem == null) { + p.sendMessage(BauSystem.PREFIX + "§cSchematic nicht gefunden"); + return; + } + try { + region.protect(schem); + p.sendMessage(BauSystem.PREFIX + "§7Boden geschützt"); + } catch (IOException e) { + p.sendMessage(BauSystem.PREFIX + "§cFehler beim Schützen der Region"); + Bukkit.getLogger().log(Level.WARNING, "Failed protect", e); + } + } + + private boolean permissionCheck(Player player) { + if (Welt.noPermission(player, Permission.WORLDEDIT)) { + player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht den Boden schützen"); + return false; + } + return true; + } + + private Region regionCheck(Player player) { + Region region = Region.getRegion(player.getLocation()); + if (!region.hasProtection()) { + player.sendMessage(BauSystem.PREFIX + "§cDu befindest dich derzeit in keiner (M)WG-Region"); + return null; + } + return region; + } + + @EventHandler + public void onExplode(EntityExplodeEvent event) { + Region region = Region.getRegion(event.getLocation()); + if (!region.isProtect() || !region.hasProtection()) { + return; + } + event.blockList().removeIf(block -> { + return block.getY() < region.getProtectYLevel(); + }); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandRedstoneTester.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandRedstoneTester.java new file mode 100644 index 00000000..91a8626a --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandRedstoneTester.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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.SWUtils; +import de.steamwar.command.SWCommand; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.Arrays; + +public class CommandRedstoneTester extends SWCommand { + + public static final ItemStack WAND = new SWItem(Material.BLAZE_ROD, "§eRedstonetester", Arrays.asList("§eLinksklick Block §8- §7Setzt die 1. Position", "§eRechtsklick Block §8- §7Setzt die 2. Position", "§eShift-Rechtsklick Luft §8- §7Zurücksetzten"), false, null).getItemStack(); + + public CommandRedstoneTester() { + super("redstonetester", "rt"); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§eredstonetester §8- §7Gibt den RedstoneTester"); + } + + @Register + public void genericCommand(Player p) { + p.sendMessage(BauSystem.PREFIX + "Messe die Zeit zwischen der Aktivierung zweier Redstone Komponenten"); + SWUtils.giveItemToPlayer(p, WAND); + } + + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandRegion.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandRegion.java new file mode 100644 index 00000000..2efb478e --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandRegion.java @@ -0,0 +1,132 @@ +package de.steamwar.bausystem.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.world.Color; +import de.steamwar.bausystem.world.Welt; +import de.steamwar.bausystem.world.regions.GlobalRegion; +import de.steamwar.bausystem.world.regions.Region; +import de.steamwar.bausystem.world.regions.RegionExtensionType; +import de.steamwar.bausystem.world.regions.RegionType; +import de.steamwar.command.SWCommand; +import de.steamwar.sql.SchematicNode; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.io.IOException; +import java.util.logging.Level; + +public class CommandRegion extends SWCommand { + + public CommandRegion() { + super("region", "rg"); + } + + @Register + public void genericCommand(Player player) { + genericHelp(player); + } + + @Register(help = true) + public void genericHelp(Player player, String... args) { + player.sendMessage("§8/§eregion undo §8- §7Mache die letzten 20 /testblock oder /reset rückgängig"); + player.sendMessage("§8/§eregion redo §8- §7Wiederhole die letzten 20 §8/§7rg undo"); + player.sendMessage("§8/§eregion restore §8- §7Setzte die Region zurück, ohne das Gebaute zu löschen"); + player.sendMessage("§8/§eregion §8[§7RegionsTyp§8] §8- §7Wähle einen RegionsTyp aus"); + player.sendMessage("§8/§eregion §8[§7RegionsTyp§8] §8[§7Extension§8] §8- §7Wähle einen RegionsTyp aus mit oder ohne Extension"); + player.sendMessage("§8/§eregion color §8[§7Color§8] §8- §7Ändere die Regions Farbe"); + } + + @Register("undo") + public void undoCommand(Player p) { + if(!permissionCheck(p)) return; + Region region = Region.getRegion(p.getLocation()); + if(checkGlobalRegion(region, p)) return; + + if (region.undo()) { + p.sendMessage(BauSystem.PREFIX + "Letzte Aktion rückgangig gemacht"); + } else { + p.sendMessage(BauSystem.PREFIX + "§cNichts zum rückgängig machen"); + } + } + + @Register("redo") + public void redoCommand(Player p) { + if (!permissionCheck(p)) { + return; + } + Region region = Region.getRegion(p.getLocation()); + if (checkGlobalRegion(region, p)) { + return; + } + + if (region.redo()) { + p.sendMessage(BauSystem.PREFIX + "Letzte Aktion wiederhohlt"); + } else { + p.sendMessage(BauSystem.PREFIX + "§cNichts zum wiederhohlen"); + } + } + + @Register + public void baurahmenCommand(Player p, RegionType regionType) { + CommandSelect.getInstance().baurahmenCommand(p, regionType, RegionExtensionType.NORMAL); + } + + @Register + public void baurahmenCommand(Player p, RegionType regionType, RegionExtensionType regionExtensionType) { + CommandSelect.getInstance().baurahmenCommand(p, regionType, regionExtensionType); + } + + @Register("restore") + public void genericRestoreCommand(Player p) { + if (!permissionCheck(p)) return; + Region region = Region.getRegion(p.getLocation()); + if(checkGlobalRegion(region, p)) return; + + if (region == null) return; + try { + region.reset(null, true); + p.sendMessage(BauSystem.PREFIX + "§7Region zurückgesetzt"); + } catch (IOException e) { + p.sendMessage(BauSystem.PREFIX + "§cFehler beim Zurücksetzen der Region"); + Bukkit.getLogger().log(Level.WARNING, "Failed testblock", e); + } + } + + @Register("restore") + public void schematicRestoreCommand(Player p, SchematicNode schem) { + if (!permissionCheck(p)) return; + Region region = Region.getRegion(p.getLocation()); + if(checkGlobalRegion(region, p)) return; + + if (region == null) return; + try { + region.reset(schem, true); + p.sendMessage(BauSystem.PREFIX + "§7Region zurückgesetzt"); + } catch (IOException e) { + p.sendMessage(BauSystem.PREFIX + "§cFehler beim Zurücksetzen der Region"); + Bukkit.getLogger().log(Level.WARNING, "Failed reset", e); + } + } + + @Register("color") + public void colorCommand(Player p, Color color) { + CommandColor.getInstance().genericColor(p, color); + } + + static boolean checkGlobalRegion(Region region, Player p) { + if (GlobalRegion.isGlobalRegion(region)) { + p.sendMessage(BauSystem.PREFIX + "§cDu bist in keiner Region"); + return true; + } + return false; + } + + private boolean permissionCheck(Player player) { + if (Welt.noPermission(player, Permission.WORLDEDIT)) { + player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht die Region verändern"); + return false; + } + return true; + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandReset.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandReset.java new file mode 100644 index 00000000..4ec404e5 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandReset.java @@ -0,0 +1,91 @@ +/* + 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.world.Welt; +import de.steamwar.bausystem.world.regions.GlobalRegion; +import de.steamwar.bausystem.world.regions.Region; +import de.steamwar.command.SWCommand; +import de.steamwar.sql.SchematicNode; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.io.IOException; +import java.util.logging.Level; + +public class CommandReset extends SWCommand { + + public CommandReset() { + super("reset"); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§ereset §8- §7Setzte die Region zurück"); + p.sendMessage("§8/§ereset §8[§7Schematic§8] §8- §7Setzte die Region mit einer Schematic zurück"); + } + + @Register + public void genericResetCommand(Player p) { + if (!permissionCheck(p)) return; + Region region = regionCheck(p); + if (region == null) return; + try { + region.reset(null, false); + p.sendMessage(BauSystem.PREFIX + "§7Region zurückgesetzt"); + } catch (IOException e) { + p.sendMessage(BauSystem.PREFIX + "§cFehler beim Zurücksetzen der Region"); + Bukkit.getLogger().log(Level.WARNING, "Failed testblock", e); + } + } + + @Register + public void schematicResetCommand(Player p, SchematicNode schem) { + if (!permissionCheck(p)) return; + Region region = regionCheck(p); + if (region == null) return; + try { + region.reset(schem, false); + p.sendMessage(BauSystem.PREFIX + "§7Region zurückgesetzt"); + } catch (IOException e) { + p.sendMessage(BauSystem.PREFIX + "§cFehler beim Zurücksetzen der Region"); + Bukkit.getLogger().log(Level.WARNING, "Failed reset", e); + } + } + + private boolean permissionCheck(Player player) { + if (Welt.noPermission(player, Permission.WORLD)) { + player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht die Region zurücksetzen"); + return false; + } + return true; + } + + private Region regionCheck(Player player) { + Region region = Region.getRegion(player.getLocation()); + if (region == GlobalRegion.getInstance()) { + player.sendMessage(BauSystem.PREFIX + "§cDu befindest dich derzeit in keiner Region"); + return null; + } + return region; + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandScript.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandScript.java new file mode 100644 index 00000000..8e071ea9 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandScript.java @@ -0,0 +1,94 @@ +/* + * + * 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.commands; + +import de.steamwar.bausystem.SWUtils; +import de.steamwar.command.SWCommand; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; + +import java.util.ArrayList; +import java.util.List; + +public class CommandScript extends SWCommand { + + public CommandScript() { + super("script"); + } + + public static final ItemStack BOOK = new ItemStack(Material.WRITTEN_BOOK, 1); + + static { + List pages = new ArrayList<>(); + pages.add("§6Script System§8\n\n- Commands\n- Kommentare\n- Scriptausführung\n- Sleep\n- Variablen\n- Konstanten\n- Abfragen\n- Schleifen\n- \"echo\"\n- \"input\"\n- Arithmetik\n- Logik"); + pages.add("§6Commands§8\n\nEin minecraft Befehl wird im Scriptbuch so hingeschrieben. Dabei kann man ein '/' weglassen. Um Befehle zu trennen kommen diese in neue Zeilen.\n\nStatt\n/tnt -> tnt\n//pos1 -> /pos1"); + pages.add("§6Kommentare§8\n\nFür ein Kommentar fängt die Zeile mit einem '#' an. Diese Zeilen werden bei dem Ausführen dann ignoriert.\n\nBeispiel:\n§9# TNT an/aus\ntnt"); + pages.add("§6Scriptausführung§8\n\nWenn du mit dem Buch in der Hand links klickst wird dieses ausgeführt."); + pages.add("§6Sleep§8\n\nUm Sachen langsamer zu machen kann man ein 'sleep' in sein Script schreiben. Danach kommt eine Zahl mit der Anzahl der GameTicks die zu schlafen sind.\n\nBeispiel:\n§9# 1 Sekunde schlafen\nsleep 20"); + pages.add("§6Variablen§8\n\nMit Variablen kann man sich Zahlen speichern. Man definiert diese mit 'var '.\n\nBeispiel:\n§9# Setze i zu 0\nvar i 0§8\n\nEs gibt einige spezial values. Dazu zählen"); + pages.add("§8'true', 'yes', 'false' und 'no', welche für 1, 1, 0 und 0 stehen.\n\nMan kann eine Variable auch um einen erhöhen oder verkleinern. Hierfür schreibt man statt einer Zahl '++', 'inc' oder '--', 'dec'.\n\nBeispiel:\n§9var i ++"); + pages.add("§8Variablen kann man referenzieren\ndurch '<' vor dem Variablennamen und '>' nach diesem. Diese kann man in jedem Befehl verwenden.\n\nBeispiel:\n§9# Stacked um 10\nvar stacks 10\n/stack "); + pages.add("§8Man kann auch explizit eine globale, locale, oder konstante variable referenzieren, indem 'global.', 'local.' oder 'const.' vor den Namen in die Klammern zu schreiben."); + pages.add("§8Um Variablen über das Script ausführen zu speichern gibt es 'global' und 'unglobal' als Befehle. Der erste speichert eine locale Variable global und das zweite löscht eine globale wieder."); + pages.add("§8Des weiteren kann man Lokale Variablen mit 'unvar' löschen. Nach dem verlassen einer Welt werden alle Globalen Variablen gelöscht. Globale Variablen kann man mit '/scriptvars' einsehen."); + pages.add("§6Konstanten§8\n\nNeben den variablen gibt es noch 5 Konstante Werte, welche nicht mit dem 'var' Befehl verändert werden können.\n\nDiese sind:\n- trace/autotrace\n- tnt\n- freeze\n- fire"); + pages.add("§8Des weiteren gibt es 3 weitere Variablen, welche explizit Spieler gebunden sind\n\nDiese sind:\n- x\n- y\n- z"); + pages.add("§6Abfragen§8\n\nMit Abfragen kann man nur Gleichheit von 2 Werten überprüft werden. Hierfür verwendet man\n'if '.\nNach den zwei Werten kann man ein oder 2 Jump-Points schreiben\n'if [...] (JP)'."); + pages.add("§8Des weiteren kann man überprüfen, ob eine Variable existiert mit 'if exists' wonach dann wieder 1 oder 2 Jump-Points sein müssen."); + pages.add("§8Ein Jump-Point ist eine Zeile Script, wohin man springen kann. Dieser wird mit einem '.' am Anfang der Zeile beschrieben und direkt danach der Jump-Point Namen ohne Leerzeichen.\n\nBeispiel:\n§9# Jump-Point X\n.X§8"); + pages.add("§8Um zu einem Jump-Point ohne Abfrage zu springen kann man den\n'jump ' Befehl verwenden."); + pages.add("§6Schleifen§8\n\nSchleifen werden mit Jump-Points, if Abfragen und Jumps gebaut.\n\nBeispiel:\n§9var i 0\n.JUMP\nvar i ++\nif i 10 END JUMP\n.END§8"); + pages.add("§6\"echo\"§8\n\nDer echo Befehl ist da um Ausgaben zu tätigen. Hier drin kann man sowohl Variablen ausgeben, als auch Farbcodes verwenden. Es wird alles nach dem Befehl ausgegeben.\n\nBeispiel:\n§9echo &eSteam&8war &7war hier!"); + pages.add("§6\"input\"§8\n\nDer input Befehl ist eine Aufforderung einer Eingabe des Users. Die Argumente sind eine Variable und ein Text als Nachricht.\n\nBeispiel:\n§9input age &eDein Alter?"); + pages.add("§6Arithmetik§8\n\nEs gibt 4 Arithmetische Befehle:\n- add\n- sub\n- mul\n- div\n\nDer erste Parameter ist die Variable welche den ausgerechneten Wert halten soll. Hiernach muss ein"); + pages.add("§8Wert oder Variable kommen welcher verrechnet wird. Hierbei wird das erste Argument als ersten Operand genommen.\n\nBeispiel:\n§9var i 2\nvar j 3\nadd i j\necho $i"); + pages.add("§8Man kann auch 3 Argumente angeben. Dann wird die arithmetische Operation zwischen den letzten beiden Argumenten berechnet und als Variable des ersten Arguments abgespeichert. \n\nBeispiel auf der nächsten Seite -->"); + pages.add("§8Beispiel:\n§9var i 2\nvar j 2\nadd k i j\necho $k"); + pages.add("§6Logik§8\n\nEs gibt 3 Vergleichs Befehle:\n- equal\n- less\n- greater\n\nUnd 3 Logik Befehle:\n- and\n- or\n- not"); + pages.add("§8Der erste Parameter ist die Variable welche den ausgerechneten Wert halten soll. Hiernach muss ein Wert oder Variable kommen welcher verrechnet wird. Hierbei wird das erste Argument als ersten Operand genommen. Dies gilt nicht für den 'not' Befehl, welcher"); + pages.add("§8nur 2 Parameter nimmt. Der erste die Variable und der zweite eine optionale Variable oder ein Wert. Equal vergleicht 2 Werte, less gibt zurück ob der erste kleiner als der zweite Wert ist, greater gibt zurück ob der erste größer als der zweite Wert ist."); + pages.add("§8And vergleicht ob 2 Werte true (1) sind. Or vergleicht ob 1 Wert oder 2 Werte true (1) ist/sind. Not invertiert den Wert von true (1) auf false und anders rum."); + pages.add("§8Beispiel:\n§9var i 1\nvar j 1\n#Ist i und j gleich\nequal k i j\nvar j 0\n#Ist i kleiner j\nless k i j\n#Ist i größer j\ngreater k i j\n#Ist i und j true\nand k i j\n#Beispiel weiter auf nächster Seite"); + pages.add("§9#Ist i oder j true\nor k i j\n#Invertiere i\nnot k i"); + + BookMeta bookMeta = (BookMeta) BOOK.getItemMeta(); + bookMeta.setGeneration(BookMeta.Generation.ORIGINAL); + bookMeta.setAuthor("§eSteam§8war"); + bookMeta.setTitle("§7Script Buch"); + bookMeta.setDisplayName("§7Script Buch"); + bookMeta.setPages(pages); + BOOK.setItemMeta(bookMeta); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§escript §8- §7Gibt das Script Buch"); + } + + @Register + public void giveCommand(Player p) { + SWUtils.giveItemToPlayer(p, BOOK); + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandScriptVars.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandScriptVars.java new file mode 100644 index 00000000..f352fca8 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandScriptVars.java @@ -0,0 +1,120 @@ +/* + * 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.world.ScriptListener; +import de.steamwar.command.SWCommand; +import de.steamwar.command.SWCommandUtils; +import de.steamwar.command.TypeMapper; +import org.bukkit.entity.Player; + +import java.util.*; + +public class CommandScriptVars extends SWCommand { + + public CommandScriptVars() { + super("scripvars"); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§escriptvars §8- §7Zähle alle globalen Variablen auf"); + p.sendMessage("§8/§escriptvars §8[§7Variable§8] §8- §7Gebe den Wert der Variable zurück"); + p.sendMessage("§8/§escriptvars §8[§7Variable§8] §8[§7Value§8] §8- §7Setzte eine Variable auf einen Wert"); + p.sendMessage("§8/§escriptvars §8[§7Variable§8] §8<§7remove§8|§7delete§8|§7clear§8> §8- §7Lösche eine Variable"); + } + + @Register + public void genericCommand(Player p) { + Map globalVariables = ScriptListener.GLOBAL_VARIABLES.get(p); + if (globalVariables == null) { + p.sendMessage(BauSystem.PREFIX + "§cKeine globalen Variablen definiert"); + return; + } + int i = 0; + p.sendMessage(BauSystem.PREFIX + globalVariables.size() + " Variable(n)"); + for (Map.Entry var : globalVariables.entrySet()) { + if (i++ >= 40) break; + p.sendMessage("- " + var.getKey() + "=" + var.getValue()); + } + } + + @Register + public void removeCommand(Player p, String varName) { + Map globalVariables = ScriptListener.GLOBAL_VARIABLES.get(p); + if (globalVariables == null) { + p.sendMessage(BauSystem.PREFIX + "§cKeine globalen Variablen definiert"); + return; + } + if (!globalVariables.containsKey(varName)) { + p.sendMessage(BauSystem.PREFIX + "§cUnbekannte Variable"); + return; + } + p.sendMessage(BauSystem.PREFIX + varName + "=" + globalVariables.get(varName)); + } + + @Register + public void booleanValueCommand(Player p, String varName, int value) { + ScriptListener.GLOBAL_VARIABLES.computeIfAbsent(p, player -> new HashMap<>()).put(varName, value); + p.sendMessage(BauSystem.PREFIX + varName + " auf " + value + " gesetzt"); + } + + @Register + public void removeCommand(Player p, String varName, @Mapper(value = "Delete") String remove) { + if (!ScriptListener.GLOBAL_VARIABLES.containsKey(p)) { + p.sendMessage(BauSystem.PREFIX + "§cKeine globalen Variablen definiert"); + return; + } + ScriptListener.GLOBAL_VARIABLES.get(p).remove(varName); + p.sendMessage(BauSystem.PREFIX + "Variable " + varName + " gelöscht"); + } + + @ClassMapper(value = String.class, local = true) + public TypeMapper stringTypeMapper() { + return SWCommandUtils.createMapper(s -> s, (commandSender, s) -> { + if (commandSender instanceof Player) { + Player player = (Player) commandSender; + return new ArrayList<>(ScriptListener.GLOBAL_VARIABLES.getOrDefault(player, new HashMap<>()).keySet()); + } + return null; + }); + } + + @Mapper(value = "Delete", local = true) + public TypeMapper clearStringTypeMapper() { + List tabCompletes = Arrays.asList("delete", "clear", "remove"); + return SWCommandUtils.createMapper(s -> { + if (s.equalsIgnoreCase("delete") || s.equalsIgnoreCase("clear") || s.equalsIgnoreCase("remove")) { + return s; + } + return null; + }, s -> tabCompletes); + } + + @ClassMapper(value = int.class, local = true) + public TypeMapper integerTypeMapper() { + List tabCompletes = Arrays.asList("true", "false", "yes", "no"); + return SWCommandUtils.createMapper(s -> { + if (s.equalsIgnoreCase("remove") || s.equalsIgnoreCase("clear") || s.equalsIgnoreCase("delete")) return null; + return ScriptListener.parseValue(s); + }, s -> tabCompletes); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandSelect.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandSelect.java new file mode 100644 index 00000000..96e6105e --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandSelect.java @@ -0,0 +1,124 @@ +package de.steamwar.bausystem.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.WorldeditWrapper; +import de.steamwar.bausystem.world.Welt; +import de.steamwar.bausystem.world.regions.*; +import de.steamwar.command.SWCommand; +import lombok.Getter; +import org.bukkit.entity.Player; + + +public class CommandSelect extends SWCommand { + + @Getter + private static CommandSelect instance = null; + + public CommandSelect() { + super("select"); + } + + { + instance = this; + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§eselect §8[§7RegionsTyp§8] §8- §7Wähle einen RegionsTyp aus"); + p.sendMessage("§8/§eselect §8[§7RegionsTyp§8] §8[§7Extension§8] §8- §7Wähle einen RegionsTyp aus mit oder ohne Extension"); + } + + @Register + public void baurahmenCommand(Player p, RegionType regionType) { + if (!permissionCheck(p)) { + return; + } + + Region region = Region.getRegion(p.getLocation()); + + if (GlobalRegion.isGlobalRegion(region)) { + p.sendMessage(BauSystem.PREFIX + "§cDie globale Region kannst du nicht auswählen"); + return; + } + + if (regionType == RegionType.TESTBLOCK) { + if (!region.hasTestblock()) { + p.sendMessage(BauSystem.PREFIX + "§cDiese Region hat keinen Testblock"); + return; + } + setSelection(regionType, RegionExtensionType.NORMAL, region, p); + return; + } + + if (regionType == RegionType.BUILD) { + if (!region.hasBuildRegion()) { + p.sendMessage(BauSystem.PREFIX + "§cDiese Region hat keinen BuildArea"); + return; + } + setSelection(regionType, RegionExtensionType.NORMAL, region, p); + return; + } + + setSelection(regionType, RegionExtensionType.NORMAL, region, p); + } + + @Register + public void baurahmenCommand(Player p, RegionType regionType, RegionExtensionType regionExtensionType) { + if (!permissionCheck(p)) { + return; + } + + Region region = Region.getRegion(p.getLocation()); + + if (GlobalRegion.isGlobalRegion(region)) { + p.sendMessage(BauSystem.PREFIX + "§cDie globale Region kannst du nicht auswählen"); + return; + } + + if (regionType == RegionType.TESTBLOCK) { + if (!region.hasTestblock()) { + p.sendMessage(BauSystem.PREFIX + "§cDiese Region hat keinen Testblock"); + return; + } + if (regionExtensionType == RegionExtensionType.EXTENSION && !region.hasExtensionArea(regionType)) { + p.sendMessage(BauSystem.PREFIX + "§cDiese Region hat keine Ausfahrmaße"); + return; + } + setSelection(regionType, regionExtensionType, region, p); + return; + } + + if (regionType == RegionType.BUILD) { + if (!region.hasBuildRegion()) { + p.sendMessage(BauSystem.PREFIX + "§cDiese Region hat keinen BuildArea"); + return; + } + if (regionExtensionType == RegionExtensionType.EXTENSION && !region.hasExtensionArea(regionType)) { + p.sendMessage(BauSystem.PREFIX + "§cDiese Region hat keine Ausfahrmaße"); + return; + } + setSelection(regionType, regionExtensionType, region, p); + return; + } + + setSelection(regionType, regionExtensionType, region, p); + } + + + private boolean permissionCheck(Player player) { + if (Welt.noPermission(player, Permission.WORLDEDIT)) { + player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht den Select verwenden"); + return false; + } + return true; + } + + private void setSelection(RegionType regionType, RegionExtensionType regionExtensionType, Region region, Player p) { + Point minPoint = region.getMinPoint(regionType, regionExtensionType); + Point maxPoint = region.getMaxPoint(regionType, regionExtensionType); + + WorldeditWrapper.impl.setSelection(p, minPoint, maxPoint); + p.sendMessage(BauSystem.PREFIX + "WorldEdit auswahl auf " + minPoint.getX() + ", " + minPoint.getY() + ", " + minPoint.getZ() + " und " + maxPoint.getX() + ", " + maxPoint.getY() + ", " + maxPoint.getZ() + " gesetzt"); + } +} \ No newline at end of file diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandSkull.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandSkull.java new file mode 100644 index 00000000..ca98a7ed --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandSkull.java @@ -0,0 +1,49 @@ +/* + 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.commands; + +import de.steamwar.bausystem.SWUtils; +import de.steamwar.command.SWCommand; +import de.steamwar.inventory.SWItem; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; + +public class CommandSkull extends SWCommand { + + public CommandSkull() { + super("skull"); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§eskull §8[§eSpieler§8] §8- §7Gibt einen SpielerKopf"); + } + + @Register + public void giveCommand(Player p, String skull) { + ItemStack is = SWItem.getPlayerSkull(skull).getItemStack(); + SkullMeta sm = (SkullMeta) is.getItemMeta(); + assert sm != null; + sm.setDisplayName("§e" + skull + "§8s Kopf"); + is.setItemMeta(sm); + SWUtils.giveItemToPlayer(p, is); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandSpeed.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandSpeed.java new file mode 100644 index 00000000..195cefcd --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandSpeed.java @@ -0,0 +1,70 @@ +/* + 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.command.SWCommand; +import de.steamwar.command.SWCommandUtils; +import de.steamwar.command.TypeMapper; +import org.bukkit.entity.Player; + +import java.util.Arrays; +import java.util.List; + +public class CommandSpeed extends SWCommand { + + public CommandSpeed() { + super("speed"); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§espeed §8[§7Geschwindigkeit§8] §8- §7Setzte deine Flug- und Gehgeschwindigkeit"); + } + + @Register({"default"}) + public void defaultCommand(Player p) { + speedCommand(p, 1); + } + + @Register + public void speedCommand(Player p, float speed) { + if (speed < 0 || speed > 10) { + p.sendMessage(BauSystem.PREFIX + "§cBitte gib eine Zahl zwischen 0 und 10 an"); + return; + } + + p.sendMessage("§aGeschwindigkeit wurde auf §6" + speed + " §agesetzt"); + p.setFlySpeed(speed / 10); + p.setWalkSpeed((speed >= 9 ? speed : speed + 1) / 10); + } + + @ClassMapper(value = float.class, local = true) + public TypeMapper doubleTypeMapper() { + List tabCompletes = Arrays.asList("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"); + return SWCommandUtils.createMapper(s -> { + try { + return Float.parseFloat(s.replace(',', '.')); + } catch (NumberFormatException e) { + return null; + } + }, s -> tabCompletes); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTNT.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTNT.java new file mode 100644 index 00000000..a96daf31 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTNT.java @@ -0,0 +1,173 @@ +/* + 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.world.regions.Region; +import de.steamwar.bausystem.world.Welt; +import de.steamwar.bausystem.world.regions.RegionExtensionType; +import de.steamwar.bausystem.world.regions.RegionType; +import de.steamwar.command.SWCommand; +import de.steamwar.command.SWCommandUtils; +import de.steamwar.command.TypeMapper; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityExplodeEvent; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CommandTNT extends SWCommand implements Listener { + + public enum TNTMode { + ON("§aan"), + ONLY_TB("§7Kein §eBaurahmen"), + OFF("§caus"); + + private String name; + + TNTMode(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + public CommandTNT() { + super("tnt"); + Bukkit.getPluginManager().registerEvents(this, BauSystem.getPlugin()); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§etnt §8- §7Ändere das TNT verhalten"); + p.sendMessage("§8/§etnt §8[§7Mode§8] §8- §7Setzte das TNT verhalten auf einen Modus"); + } + + @Register + public void toggleCommand(Player p) { + if (!permissionCheck(p)) return; + Region region = Region.getRegion(p.getLocation()); + tntToggle(region, null, null); + } + + @Register + public void setCommand(Player p, TNTMode tntMode) { + if (!permissionCheck(p)) return; + Region region = Region.getRegion(p.getLocation()); + + String requestedMessage = null; + switch (tntMode) { + case ON: + requestedMessage = getEnableMessage(); + break; + case OFF: + requestedMessage = getDisableMessage(); + break; + case ONLY_TB: + requestedMessage = getTestblockEnableMessage(); + break; + } + tntToggle(region, tntMode, requestedMessage); + } + + private boolean permissionCheck(Player p) { + if (Welt.noPermission(p, Permission.WORLD)) { + p.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht TNT-Schaden (de-)aktivieren"); + return false; + } + return true; + } + + @ClassMapper(value = TNTMode.class, local = true) + public TypeMapper tntModeTypeMapper() { + Map tntModeMap = new HashMap<>(); + tntModeMap.put("an", TNTMode.ON); + tntModeMap.put("on", TNTMode.ON); + tntModeMap.put("aus", TNTMode.OFF); + tntModeMap.put("off", TNTMode.OFF); + if (Region.buildAreaEnabled()) { + tntModeMap.put("testblock", TNTMode.ONLY_TB); + tntModeMap.put("tb", TNTMode.ONLY_TB); + } + List tabCompletes = new ArrayList<>(tntModeMap.keySet()); + return SWCommandUtils.createMapper(s -> tntModeMap.getOrDefault(s, null), s -> tabCompletes); + } + + private String getEnableMessage() { + return "§aTNT-Schaden aktiviert"; + } + + private String getDisableMessage() { + return "§cTNT-Schaden deaktiviert"; + } + + private String getTestblockEnableMessage() { + return "§aTNT-Schaden außerhalb Baurahmen aktiviert"; + } + + private void tntToggle(Region region, TNTMode requestedMode, String requestedMessage) { + if (requestedMode != null && region.hasTestblock()) { + region.setTntMode(requestedMode); + RegionUtils.actionBar(region, requestedMessage); + return; + } + switch (region.getTntMode()) { + case ON: + case ONLY_TB: + region.setTntMode(TNTMode.OFF); + RegionUtils.actionBar(region, getDisableMessage()); + break; + case OFF: + if (Region.buildAreaEnabled() && region.hasTestblock()) { + region.setTntMode(TNTMode.ONLY_TB); + RegionUtils.actionBar(region, getTestblockEnableMessage()); + } else { + region.setTntMode(TNTMode.ON); + RegionUtils.actionBar(region, getEnableMessage()); + } + break; + } + } + + @EventHandler + public void onExplode(EntityExplodeEvent event) { + event.blockList().removeIf(block -> { + Region region = Region.getRegion(block.getLocation()); + if (region.getTntMode() == TNTMode.ON) return false; + if (region.hasBuildRegion() && region.inRegion(block.getLocation(), RegionType.BUILD, RegionExtensionType.NORMAL)) { + RegionUtils.actionBar(region, "§cEine Explosion hätte Blöcke im Baubereich zerstört"); + return true; + } + if (region.hasBuildRegion() && region.inRegion(block.getLocation(), RegionType.BUILD, RegionExtensionType.EXTENSION)) { + RegionUtils.actionBar(region, "§cEine Explosion hätte Blöcke im Ausfahrbereich zerstört"); + return true; + } + return region.getTntMode() == TNTMode.OFF; + }); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTPSLimiter.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTPSLimiter.java new file mode 100644 index 00000000..fe73d863 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTPSLimiter.java @@ -0,0 +1,176 @@ +/* + 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.CraftbukkitWrapper; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.world.TPSUtils; +import de.steamwar.bausystem.world.Welt; +import de.steamwar.command.SWCommand; +import de.steamwar.command.SWCommandUtils; +import de.steamwar.command.TypeMapper; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitTask; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class CommandTPSLimiter extends SWCommand { + + private static CommandTPSLimiter instance = null; + + { + instance = this; + } + + private static final World WORLD = Bukkit.getWorlds().get(0); + private static double currentTPSLimit = 20; + + private long lastTime = System.nanoTime(); + private long currentTime = System.nanoTime(); + + private double delay = 0; + private int loops = 0; + private long sleepDelay = 0; + + private BukkitTask tpsLimiter = null; + + private List tabCompletions = new ArrayList<>(Arrays.asList("0,5", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20")); + + public CommandTPSLimiter() { + super("tpslimit"); + if (TPSUtils.isWarpAllowed()) { + for (int i = 20; i <= 60; i += 5) { + tabCompletions.add(i + ""); + } + } + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage(BauSystem.PREFIX + "Jetziges TPS limit: " + currentTPSLimit); + p.sendMessage("§8/§etpslimit §8[§7TPS§8|§edefault§8] §8- §7Setzte die TPS auf dem Bau"); + } + + @Register({"default"}) + public void defaultCommand(Player p) { + if (!permissionCheck(p)) return; + currentTPSLimit = 20; + sendNewTPSLimitMessage(); + tpsLimiter(); + } + + @Register + public void valueCommand(Player p, double tpsLimitDouble) { + if (!permissionCheck(p)) return; + if (tpsLimitDouble < 0.5 || tpsLimitDouble > (TPSUtils.isWarpAllowed() ? 60 : 20)) { + sendInvalidArgumentMessage(p); + return; + } + currentTPSLimit = tpsLimitDouble; + sendNewTPSLimitMessage(); + tpsLimiter(); + } + + @ClassMapper(value = double.class, local = true) + public TypeMapper doubleTypeMapper() { + return SWCommandUtils.createMapper(s -> { + try { + return Double.parseDouble(s.replace(',', '.')); + } catch (NumberFormatException e) { + return 0D; + } + }, s -> tabCompletions); + } + + private boolean permissionCheck(Player player) { + if (Welt.noPermission(player, Permission.WORLD)) { + player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht den TPS-Limiter nutzen"); + return false; + } + return true; + } + + private void sendNewTPSLimitMessage() { + Bukkit.getOnlinePlayers().forEach(p -> p.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§eTPS limit auf " + currentTPSLimit + " gesetzt."))); + } + + private void sendInvalidArgumentMessage(Player player) { + player.sendMessage(BauSystem.PREFIX + "§cNur Zahlen zwischen 0,5 und " + (TPSUtils.isWarpAllowed() ? 60 : 20) + ", und 'default' erlaubt."); + } + + private void tpsLimiter() { + delay = 20 / currentTPSLimit; + loops = (int) Math.ceil(delay); + sleepDelay = (long) (50 * delay) / loops; + + TPSUtils.setTPS(currentTPSLimit); + if (currentTPSLimit >= 20) { + if (tpsLimiter == null) return; + tpsLimiter.cancel(); + tpsLimiter = null; + } else { + if (tpsLimiter != null) return; + tpsLimiter = Bukkit.getScheduler().runTaskTimer(BauSystem.getPlugin(), () -> { + CraftbukkitWrapper.impl.createTickCache(WORLD); + + for (int i = 0; i < loops; i++) { + sleepUntilNextTick(sleepDelay); + CraftbukkitWrapper.impl.sendTickPackets(); + } + }, 0, 1); + } + } + + private void sleepUntilNextTick(long neededDelta) { + lastTime = currentTime; + currentTime = System.nanoTime(); + + long timeDelta = (currentTime - lastTime) / 1000000; + if (neededDelta - timeDelta < 0) return; + + try { + Thread.sleep(neededDelta - timeDelta); + currentTime = System.nanoTime(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + public static double getCurrentTPSLimit() { + return (double) Math.round(currentTPSLimit * 10.0D) / 10.0D; + } + + public static void setTPS(double d) { + if (d < 0.5) d = 0.5; + if (d > (TPSUtils.isWarpAllowed() ? 60 : 20)) d = (TPSUtils.isWarpAllowed() ? 60 : 20); + if (instance != null) { + currentTPSLimit = d; + instance.tpsLimiter(); + } + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTeleport.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTeleport.java new file mode 100644 index 00000000..04fa8c72 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTeleport.java @@ -0,0 +1,46 @@ +/* + * 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.command.SWCommand; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerTeleportEvent; + +public class CommandTeleport extends SWCommand { + + public CommandTeleport() { + super("teleport", "tp"); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§etp §8[§7Player§8] §8- §7Teleportiere dich zu einem Spieler"); + } + + @Register + public void genericCommand(Player p, Player target) { + if (p.getUniqueId().equals(target.getUniqueId())) { + p.sendMessage(BauSystem.PREFIX + "§cSei eins mit dir selbst!"); + return; + } + p.teleport(target, PlayerTeleportEvent.TeleportCause.COMMAND); + } +} \ No newline at end of file diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTestblock.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTestblock.java new file mode 100644 index 00000000..ec206fa9 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTestblock.java @@ -0,0 +1,128 @@ +/* + 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.tracer.show.ShowModeParameterType; +import de.steamwar.bausystem.world.regions.Region; +import de.steamwar.bausystem.world.Welt; +import de.steamwar.bausystem.world.regions.RegionExtensionType; +import de.steamwar.command.SWCommand; +import de.steamwar.command.SWCommandUtils; +import de.steamwar.command.TypeMapper; +import de.steamwar.sql.SchematicNode; +import de.steamwar.sql.SteamwarUser; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; + +public class CommandTestblock extends SWCommand { + + public CommandTestblock() { + super("testblock", "tb"); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§etestblock §8- §7Setzte den Testblock zurück"); + p.sendMessage("§8/§etestblock §8[§7Schematic§8] §8- §7Setzte den Testblock mit einer Schematic zurück"); + } + + @Register + public void genericTestblockCommand(Player p) { + genericTestblockCommand(p, RegionExtensionType.NORMAL); + } + + @Register + public void genericTestblockCommand(Player p, RegionExtensionType regionExtensionType) { + if (!permissionCheck(p)) return; + Region region = regionCheck(p); + if (region == null) return; + try { + region.resetTestblock(null, regionExtensionType == RegionExtensionType.EXTENSION); + p.sendMessage(BauSystem.PREFIX + "§7Testblock zurückgesetzt"); + } catch (IOException e) { + p.sendMessage(BauSystem.PREFIX + "§cFehler beim Zurücksetzen des Testblocks"); + Bukkit.getLogger().log(Level.WARNING, "Failed testblock", e); + } + } + + + @Register + public void schematicTestblockCommand(Player p, SchematicNode schem) { + schematicTestblockCommand(p, schem, RegionExtensionType.NORMAL); + } + + @Register + public void schematicTestblockCommand(Player p, RegionExtensionType regionExtensionType, SchematicNode schem) { + schematicTestblockCommand(p, schem, regionExtensionType); + } + + @Register + public void schematicTestblockCommand(Player p, SchematicNode schem, RegionExtensionType regionExtensionType) { + if (!permissionCheck(p)) return; + Region region = regionCheck(p); + if (region == null) return; + try { + region.resetTestblock(schem, regionExtensionType == RegionExtensionType.EXTENSION); + p.sendMessage(BauSystem.PREFIX + "§7Testblock zurückgesetzt"); + } catch (IOException e) { + p.sendMessage(BauSystem.PREFIX + "§cFehler beim Zurücksetzen des Testblocks"); + Bukkit.getLogger().log(Level.WARNING, "Failed testblock", e); + } + } + + @ClassMapper(value = RegionExtensionType.class, local = true) + private TypeMapper regionExtensionTypeTypeMapper() { + Map showModeParameterTypesMap = new HashMap<>(); + showModeParameterTypesMap.put("-normal", RegionExtensionType.NORMAL); + showModeParameterTypesMap.put("-n", RegionExtensionType.NORMAL); + showModeParameterTypesMap.put("-extension", RegionExtensionType.EXTENSION); + showModeParameterTypesMap.put("-e", RegionExtensionType.EXTENSION); + + List tabCompletes = new ArrayList<>(showModeParameterTypesMap.keySet()); + return SWCommandUtils.createMapper(s -> showModeParameterTypesMap.getOrDefault(s, null), s -> tabCompletes); + } + + private boolean permissionCheck(Player player) { + if (Welt.noPermission(player, Permission.WORLDEDIT)) { + player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht den Testblock zurücksetzen"); + return false; + } + return true; + } + + private Region regionCheck(Player player) { + Region region = Region.getRegion(player.getLocation()); + if (!region.hasTestblock()) { + player.sendMessage(BauSystem.PREFIX + "§cDu befindest dich derzeit in keiner Region"); + return null; + } + return region; + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTime.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTime.java new file mode 100644 index 00000000..8a231052 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTime.java @@ -0,0 +1,99 @@ +/* + * 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.world.Welt; +import de.steamwar.command.SWCommand; +import de.steamwar.command.SWCommandUtils; +import de.steamwar.command.TypeMapper; +import java.util.Arrays; +import java.util.List; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +public class CommandTime extends SWCommand { + + private static List tabCompletions = Arrays.asList("0", "6000", "12000", "18000"); + + public CommandTime() { + super("time"); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§etime §8<§7Zeit 0=Morgen§8, §76000=Mittag§8, §718000=Mitternacht§8> §8- §7Setzt die Zeit auf dem Bau"); + } + + @Register + public void genericCommand(Player p, int time) { + if (Welt.noPermission(p, Permission.WORLD)) { + p.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht die Zeit ändern"); + return; + } + if (time < 0 || time > 24000) { + p.sendMessage(BauSystem.PREFIX + "§cBitte gib eine Zahl zwischen 0 und 24000 an"); + return; + } + Bukkit.getWorlds().get(0).setTime(time); + } + + @Register + public void genericCommand(Player p, Time time) { + if (Welt.noPermission(p, Permission.WORLD)) { + p.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht die Zeit ändern"); + return; + } + Bukkit.getWorlds().get(0).setTime(time.getValue()); + } + + @ClassMapper(value = int.class, local = true) + public TypeMapper doubleTypeMapper() { + return SWCommandUtils.createMapper(s -> { + try { + return Integer.parseInt(s); + } catch (NumberFormatException e) { + return 0; + } + }, s -> tabCompletions); + } + + public enum Time { + NIGHT(18000), + DAY(6000), + DAWN(0), + SUNSET(12000), + NACHT(18000), + TAG(6000), + MORGEN(0), + ABEND(12000); + + private int value; + + private Time(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } +} \ No newline at end of file diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTrace.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTrace.java new file mode 100644 index 00000000..d1c9e2f0 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandTrace.java @@ -0,0 +1,132 @@ +/* + 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.commands; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.gui.GuiTraceShow; +import de.steamwar.bausystem.tracer.record.RecordStateMachine; +import de.steamwar.bausystem.tracer.show.ShowModeParameter; +import de.steamwar.bausystem.tracer.show.ShowModeParameterType; +import de.steamwar.bausystem.tracer.show.StoredRecords; +import de.steamwar.bausystem.tracer.show.TraceShowManager; +import de.steamwar.bausystem.tracer.show.mode.EntityShowMode; +import de.steamwar.bausystem.world.Welt; +import de.steamwar.command.SWCommand; +import org.bukkit.entity.Player; + +public class CommandTrace extends SWCommand { + + public CommandTrace() { + super("trace"); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§etrace start §8- §7Startet die Aufnahme aller TNT-Positionen"); + p.sendMessage("§8/§etrace stop §8- §7Stoppt den TNT-Tracer"); + p.sendMessage("§8/§etrace toggleauto §8- §7Automatischer Aufnahmenstart"); + p.sendMessage("§8/§etrace show gui §8- §7Zeigt die Trace show gui"); + p.sendMessage("§8/§etrace show §8<§e-water§8|§e-interpolate-xz§8|§e-interpolate-y§8> §8- §7Zeigt alle TNT-Positionen"); + p.sendMessage("§8/§etrace hide §8- §7Versteckt alle TNT-Positionen"); + p.sendMessage("§8/§etrace delete §8- §7Löscht alle TNT-Positionen"); + // p.sendMessage("§8/§etrace list §8<§7FRAME-ID§8> §8- §7Listet alle TNT auf"); + // p.sendMessage("§8/§etrace gui §8- §7Zeigt die Trace Oberfläche an"); + // p.sendMessage("§7Optionale Parameter mit §8<>§7, Benötigte Parameter mit §8[]"); + } + + @Register({"start"}) + public void startCommand(Player p) { + if (!permissionCheck(p)) return; + RecordStateMachine.commandStart(); + p.sendMessage(BauSystem.PREFIX + "§aTNT-Tracer gestartet"); + } + + @Register({"stop"}) + public void stopCommand(Player p) { + if (!permissionCheck(p)) return; + RecordStateMachine.commandStop(); + p.sendMessage(BauSystem.PREFIX + "§cTNT-Tracer gestoppt"); + } + + @Register({"toggleauto"}) + public void toggleAutoCommand(Player p) { + autoCommand(p); + } + + @Register({"auto"}) + public void autoCommand(Player p) { + if (!permissionCheck(p)) return; + RecordStateMachine.commandAuto(); + p.sendMessage(BauSystem.PREFIX + RecordStateMachine.getRecordStatus().getAutoMessage()); + } + + @Register({"clear"}) + public void clearCommand(Player p) { + deleteCommand(p); + } + + @Register({"delete"}) + public void deleteCommand(Player p) { + if (!permissionCheck(p)) return; + StoredRecords.clear(); + p.sendMessage(BauSystem.PREFIX + "§cAlle TNT-Positionen gelöscht"); + } + + @Register({"show"}) + public void showCommand(Player p) { + if (!permissionCheck(p)) return; + TraceShowManager.show(p, new EntityShowMode(p, new ShowModeParameter())); + p.sendMessage(BauSystem.PREFIX + "§aAlle TNT-Positionen angezeigt"); + } + + @Register({"show"}) + public void showCommand(Player p, ShowModeParameterType... showModeParameterTypes) { + if (!permissionCheck(p)) return; + ShowModeParameter showModeParameter = new ShowModeParameter(); + for (ShowModeParameterType showModeParameterType : showModeParameterTypes) { + showModeParameterType.getShowModeParameterConsumer().accept(showModeParameter); + } + TraceShowManager.show(p, new EntityShowMode(p, showModeParameter)); + p.sendMessage(BauSystem.PREFIX + "§aAlle TNT-Positionen angezeigt"); + } + + @Register({"show", "gui"}) + public void showGuiCommand(Player p) { + if (!permissionCheck(p)) return; + GuiTraceShow.openGui(p); + } + + @Register({"hide"}) + public void hideCommand(Player p) { + if (!permissionCheck(p)) return; + TraceShowManager.hide(p); + p.sendMessage(BauSystem.PREFIX + "§cAlle TNT-Positionen ausgeblendet"); + } + + + private boolean permissionCheck(Player player) { + if (Welt.noPermission(player, Permission.WORLD)) { + player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht den TNT-Tracer nutzen"); + return false; + } + return true; + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandWorldSpawn.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandWorldSpawn.java new file mode 100644 index 00000000..2f9c1340 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/CommandWorldSpawn.java @@ -0,0 +1,45 @@ +/* + * 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.commands; + +import de.steamwar.command.SWCommand; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerTeleportEvent; + +public class CommandWorldSpawn extends SWCommand { + + private World world = Bukkit.getWorlds().get(0); + + public CommandWorldSpawn() { + super("worldspawn"); + } + + @Register(help = true) + public void genericHelp(Player p, String... args) { + p.sendMessage("§8/§eworldspawn §8- §7Teleportiere dich zum Spawn"); + } + + @Register + public void genericCommand(Player p) { + p.teleport(world.getSpawnLocation(), PlayerTeleportEvent.TeleportCause.COMMAND); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/commands/RegionUtils.java b/LegacyBauSystem/src/de/steamwar/bausystem/commands/RegionUtils.java new file mode 100644 index 00000000..1c783030 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/commands/RegionUtils.java @@ -0,0 +1,42 @@ +/* + * 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.commands; + +import de.steamwar.bausystem.world.regions.GlobalRegion; +import de.steamwar.bausystem.world.regions.Region; +import de.steamwar.bausystem.world.regions.RegionExtensionType; +import de.steamwar.bausystem.world.regions.RegionType; +import lombok.experimental.UtilityClass; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Bukkit; + +@UtilityClass +public class RegionUtils { + + public static void actionBar(Region region, String s) { + if (GlobalRegion.isGlobalRegion(region)) { + Bukkit.getOnlinePlayers().forEach(player -> player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(s))); + } else { + Bukkit.getOnlinePlayers().stream().filter(player -> region.inRegion(player.getLocation(), RegionType.NORMAL, RegionExtensionType.NORMAL)).forEach(player -> player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(s))); + } + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/gui/GuiTraceShow.java b/LegacyBauSystem/src/de/steamwar/bausystem/gui/GuiTraceShow.java new file mode 100644 index 00000000..caa03eb2 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/gui/GuiTraceShow.java @@ -0,0 +1,133 @@ +/* + * + * 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.gui; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.FlatteningWrapper; +import de.steamwar.bausystem.tracer.show.ShowModeParameter; +import de.steamwar.bausystem.tracer.show.TraceShowManager; +import de.steamwar.bausystem.tracer.show.mode.EntityShowMode; +import de.steamwar.inventory.SWInventory; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +public class GuiTraceShow { + + private static final Map ShowModeParameterMap = new HashMap<>(); + + private GuiTraceShow() { + + } + + public static void openGui(Player player) { + ShowModeParameter playerShowMode = new ShowModeParameter(); + playerShowMode.setInterpolate_Y(false); + playerShowMode.setInterpolate_XZ(false); + ShowModeParameterMap.put(player, playerShowMode); + + SWInventory swInventory = new SWInventory(player, 9, "Trace Show GUI"); + swInventory.addCloseCallback(clickType -> ShowModeParameterMap.remove(player)); + setActiveShow(player, swInventory); + + SWItem water = new SWItem(Material.TNT, "§eWasser §7Positionen", Arrays.asList("§7Zeigt alles TNT, welches", "§7im Wasser explodiert ist."), false, clickType -> { + }); + swInventory.setItem(5, water); + swInventory.setCallback(5, clickType -> toggleHideTNTinWaterExploded(player, swInventory, water)); + + SWItem interpolateY = new SWItem(Material.QUARTZ_STAIRS, "§eInterpolation §7Y-Achse", Arrays.asList("§7Zeigt die Interpolation", "§7auf der Y-Achse."), false, clickType -> { + }); + swInventory.setItem(6, interpolateY); + swInventory.setCallback(6, clickType -> toggleInterpolateYPosition(player, swInventory, interpolateY)); + + Material xzMaterial = FlatteningWrapper.impl.getTraceXZMaterial(); + SWItem interpolateXZ = new SWItem(xzMaterial, (byte) 7, "§eInterpolation §7XZ-Achse", Arrays.asList("§7Zeigt die Interpolation", "§7auf der XZ-Achse."), false, clickType -> { + }); + swInventory.setItem(7, interpolateXZ); + swInventory.setCallback(7, clickType -> toggleInterpolateXZPosition(player, swInventory, interpolateXZ)); + // Water Bucket (-water) + // TNT (-water-exploded) + // Quartz_Stair (-interpolate-y) + // Quartz_Slab (-interpolate-xz) + swInventory.open(); + } + + private static void setActiveShow(Player player, SWInventory swInventory) { + if (TraceShowManager.hasActiveShow(player)) { + Material showMaterial = FlatteningWrapper.impl.getTraceShowMaterial(); + SWItem shown = new SWItem(showMaterial, (byte) 5, "§aTraces angezeigt", new ArrayList<>(), false, clickType -> { + TraceShowManager.hide(player); + player.sendMessage(BauSystem.PREFIX + "§cAlle TNT-Positionen ausgeblendet"); + setActiveShow(player, swInventory); + }); + swInventory.setItem(1, shown); + } else { + Material hideMaterial = FlatteningWrapper.impl.getTraceHideMaterial(); + SWItem hidden = new SWItem(hideMaterial, (byte) 14, "§cTraces ausgeblendet", new ArrayList<>(), false, clickType -> { + show(player); + player.sendMessage(BauSystem.PREFIX + "§aAlle TNT-Positionen angezeigt"); + setActiveShow(player, swInventory); + }); + swInventory.setItem(1, hidden); + } + } + + private static void toggleHideTNTinWaterExploded(Player player, SWInventory swInventory, SWItem swItem) { + ShowModeParameter showModeParameter = ShowModeParameterMap.get(player); + showModeParameter.setWater(!showModeParameter.isWater()); + show(player); + + swItem.setEnchanted(showModeParameter.isWater()); + swInventory.setItem(5, swItem); + swInventory.setCallback(5, clickType -> toggleHideTNTinWaterExploded(player, swInventory, swItem)); + } + + private static void toggleInterpolateYPosition(Player player, SWInventory swInventory, SWItem swItem) { + ShowModeParameter showModeParameter = ShowModeParameterMap.get(player); + showModeParameter.setInterpolate_Y(!showModeParameter.isInterpolate_Y()); + show(player); + + swItem.setEnchanted(showModeParameter.isInterpolate_Y()); + swInventory.setItem(6, swItem); + swInventory.setCallback(6, clickType -> toggleInterpolateYPosition(player, swInventory, swItem)); + } + + private static void toggleInterpolateXZPosition(Player player, SWInventory swInventory, SWItem swItem) { + ShowModeParameter showModeParameter = ShowModeParameterMap.get(player); + showModeParameter.setInterpolate_XZ(!showModeParameter.isInterpolate_XZ()); + show(player); + + swItem.setEnchanted(showModeParameter.isInterpolate_XZ()); + swInventory.setItem(7, swItem); + swInventory.setCallback(7, clickType -> toggleInterpolateXZPosition(player, swInventory, swItem)); + } + + private static void show(Player player) { + TraceShowManager.show(player, new EntityShowMode(player, ShowModeParameterMap.get(player))); + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/tracer/AbstractTraceEntity.java b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/AbstractTraceEntity.java new file mode 100644 index 00000000..1df4d96d --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/AbstractTraceEntity.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.tracer; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +public interface AbstractTraceEntity { + + void display(Player player, boolean exploded); + + boolean hide(Player player, boolean always); + + int getId(); + + Entity getBukkitEntity(); +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/tracer/RoundedTNTPosition.java b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/RoundedTNTPosition.java new file mode 100644 index 00000000..73960575 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/RoundedTNTPosition.java @@ -0,0 +1,65 @@ +/* + * + * 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.tracer; + +import org.bukkit.util.Vector; + +import java.util.Objects; + +public class RoundedTNTPosition { + + private static final int factor = 10; + + private int x; + private int y; + private int z; + + public RoundedTNTPosition(TNTPosition tntPosition) { + this(tntPosition.getLocation().getX(), tntPosition.getLocation().getY(), tntPosition.getLocation().getZ()); + } + + public RoundedTNTPosition(Vector vector) { + this(vector.getX(), vector.getY(), vector.getZ()); + } + + public RoundedTNTPosition(double x, double y, double z) { + this.x = (int) (x * factor); + this.y = (int) (y * factor); + this.z = (int) (z * factor); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof RoundedTNTPosition)) return false; + RoundedTNTPosition that = (RoundedTNTPosition) o; + return x == that.x && + y == that.y && + z == that.z; + } + + @Override + public int hashCode() { + return Objects.hash(x, y, z); + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/tracer/TNTPosition.java b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/TNTPosition.java new file mode 100644 index 00000000..d8deae6b --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/TNTPosition.java @@ -0,0 +1,63 @@ +/* + 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.tracer; + +import de.steamwar.bausystem.tracer.show.Record; +import org.bukkit.entity.Entity; +import org.bukkit.util.Vector; + +public class TNTPosition { + + private final Record.TNTRecord record; + private final Vector location; + private final Vector previousLocation; + private final boolean exploded; + + public TNTPosition(Record.TNTRecord record, Entity entity, Vector previousLocation, boolean exploded) { + this.location = entity.getLocation().toVector(); + this.record = record; + this.previousLocation = previousLocation; + this.exploded = exploded; + } + + public Vector getLocation() { + return location; + } + + public Vector getPreviousLocation() { + return previousLocation; + } + + public boolean isExploded() { + return exploded; + } + + public Record.TNTRecord getRecord() { + return record; + } + + @Override + public String toString() { + return "Position{" + + "location=" + location + + '}'; + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/tracer/record/RecordStateMachine.java b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/record/RecordStateMachine.java new file mode 100644 index 00000000..bd679386 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/record/RecordStateMachine.java @@ -0,0 +1,94 @@ +/* + 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.tracer.record; + +public class RecordStateMachine { + private RecordStateMachine() { + } + + private static final TraceAutoHandler autoHandler = new TraceAutoHandler(); + + private static RecordStatus recordStatus = RecordStatus.IDLE; + private static Recorder recorder = null; + + public static void commandStart() { + autoHandler.disable(); + recordStart(); + recordStatus = RecordStatus.RECORD; + } + + public static void commandStop() { + autoHandler.disable(); + recordStop(); + recordStatus = RecordStatus.IDLE; + } + + public static void commandAuto() { + if (recordStatus.isTracing()) + return; + + if (recordStatus == RecordStatus.IDLE_AUTO) { + recordStatus = RecordStatus.IDLE; + autoHandler.disable(); + } else { + recordStatus = RecordStatus.IDLE_AUTO; + autoHandler.enable(); + } + } + + static void autoRecord() { + recordStart(); + recordStatus = RecordStatus.RECORD_AUTO; + } + + static void autoIdle() { + recordStop(); + recordStatus = RecordStatus.IDLE_AUTO; + } + + private static void recordStart() { + if (recordStatus.isTracing()) return; + recorder = new Recorder(); + } + + private static void recordStop() { + if (!recordStatus.isTracing()) return; + recorder.stopRecording(); + } + + public static RecordStatus getRecordStatus() { + return recordStatus; + } + + public static int size() { + if (recorder == null) return 0; + return recorder.size(); + } + + public static long getStartTime() { + if (recorder == null) return 0; + return recorder.getStartTime(); + } + + public static void postClear() { + if (recorder == null) return; + recorder.postClear(); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/tracer/record/RecordStatus.java b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/record/RecordStatus.java new file mode 100644 index 00000000..b87e740c --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/record/RecordStatus.java @@ -0,0 +1,55 @@ +/* + 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.tracer.record; + +public enum RecordStatus { + + RECORD("§aan", true, "§cTNT-Tracer muss gestoppt werden"), + RECORD_AUTO("§aan", true, "§cTNT-Tracer darf nicht aufnehmen"), + IDLE("§caus", false, "§cAuto-Tracer gestoppt"), + IDLE_AUTO("§eauto", false, "§aAuto-Tracer gestartet"); + + String name; + boolean tracing; + String autoMessage; + + RecordStatus(String value, boolean tracing, String autoMessage) { + this.name = value; + this.tracing = tracing; + this.autoMessage = autoMessage; + } + + public String getName() { + return name; + } + + public boolean isTracing() { + return tracing; + } + + public boolean isAutoTrace() { + return this == RECORD_AUTO || this == IDLE_AUTO; + } + + public String getAutoMessage() { + return autoMessage; + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/tracer/record/Recorder.java b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/record/Recorder.java new file mode 100644 index 00000000..171afd01 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/record/Recorder.java @@ -0,0 +1,96 @@ +/* + 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.tracer.record; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.tracer.show.Record; +import de.steamwar.bausystem.tracer.show.StoredRecords; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.scheduler.BukkitTask; + +import java.util.HashMap; +import java.util.Map; + +public class Recorder implements Listener { + + private static final World world = Bukkit.getWorlds().get(0); + + private final Map recordMap = new HashMap<>(); + private final BukkitTask task; + private final Record record; + + Recorder() { + Bukkit.getPluginManager().registerEvents(this, BauSystem.getPlugin()); + task = Bukkit.getScheduler().runTaskTimer(BauSystem.getPlugin(), this::run, 1, 1); + record = new Record(); + + // To trace TNT initial positions with AutoTracer + run(); + } + + void stopRecording() { + HandlerList.unregisterAll(this); + task.cancel(); + } + + int size() { + return record.size(); + } + + long getStartTime() { + return record.getStartTime(); + } + + void postClear() { + record.clear(); + recordMap.clear(); + StoredRecords.add(record); + } + + private void run() { + world.getEntitiesByClass(TNTPrimed.class).forEach(tntPrimed -> get(tntPrimed).add(tntPrimed)); + } + + @EventHandler + public void onEntityExplode(EntityExplodeEvent event) { + if (!(event.getEntity() instanceof TNTPrimed)) + return; + TNTPrimed tntPrimed = (TNTPrimed) event.getEntity(); + + get(tntPrimed).explode(tntPrimed); + recordMap.remove(tntPrimed); + } + + private Record.TNTRecord get(TNTPrimed tntPrimed) { + Record.TNTRecord tntRecord = recordMap.get(tntPrimed); + if (tntRecord != null) + return tntRecord; + + tntRecord = this.record.spawn(); + recordMap.put(tntPrimed, tntRecord); + return tntRecord; + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/tracer/record/TraceAutoHandler.java b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/record/TraceAutoHandler.java new file mode 100644 index 00000000..58e52e41 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/record/TraceAutoHandler.java @@ -0,0 +1,70 @@ +/* + 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.tracer.record; + +import de.steamwar.bausystem.BauSystem; +import org.bukkit.Bukkit; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.scheduler.BukkitTask; + +public class TraceAutoHandler implements Listener { + /* This listener handles the en- and disabling of the Tracer in AUTO mode */ + + private BukkitTask task; + private int lastExplosion = 0; // Time since the last explosion in ticks + + public void enable() { + Bukkit.getPluginManager().registerEvents(this, BauSystem.getPlugin()); + } + + public void disable() { + HandlerList.unregisterAll(this); + if (task != null) { + task.cancel(); + task = null; + } + } + + @EventHandler + public void onEntityExplode(EntityExplodeEvent event) { + if (!(event.getEntity() instanceof TNTPrimed)) + return; + + lastExplosion = 0; + if (task == null) { + RecordStateMachine.autoRecord(); + task = Bukkit.getScheduler().runTaskTimer(BauSystem.getPlugin(), this::run, 1, 1); + } + } + + private void run() { + lastExplosion++; + + if (lastExplosion > 80) { + RecordStateMachine.autoIdle(); + task.cancel(); + task = null; + } + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/Record.java b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/Record.java new file mode 100644 index 00000000..b6ac929c --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/Record.java @@ -0,0 +1,94 @@ +/* + 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.tracer.show; + +import de.steamwar.bausystem.tracer.TNTPosition; +import org.bukkit.entity.TNTPrimed; + +import java.util.ArrayList; +import java.util.List; + +public class Record { + + private final long startTime; + private final List tnt = new ArrayList<>(); + + public int size() { + return tnt.size(); + } + + public long getStartTime() { + return startTime; + } + + public void showAll(ShowMode mode) { + for (TNTRecord record : tnt) + record.showAll(mode); + } + + /* The following methods should only be called by a recorder */ + public Record() { + startTime = System.currentTimeMillis(); + StoredRecords.add(this); + } + + public TNTRecord spawn() { + TNTRecord record = new TNTRecord(); + tnt.add(record); + return record; + } + + public void clear() { + tnt.clear(); + } + + public static class TNTRecord { + private final List positions = new ArrayList<>(41); + + public void showAll(ShowMode mode) { + for (TNTPosition position : positions) + mode.show(position); + } + + /* The following methods should only be called by a recorder */ + public void add(TNTPrimed tntPrimed) { + add(tntPrimed, false); + } + + private void add(TNTPrimed tntPrimed, boolean exploded) { + TNTPosition position; + if (positions.isEmpty()) { + position = new TNTPosition(this, tntPrimed, null, exploded); + } else { + position = new TNTPosition(this, tntPrimed, positions.get(positions.size() - 1).getLocation(), exploded); + } + positions.add(position); + TraceShowManager.show(position); + } + + public void explode(TNTPrimed tntPrimed) { + add(tntPrimed, true); + } + + public List getPositions() { + return positions; + } + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/ShowMode.java b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/ShowMode.java new file mode 100644 index 00000000..d313189d --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/ShowMode.java @@ -0,0 +1,28 @@ +/* + 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.tracer.show; + +import de.steamwar.bausystem.tracer.TNTPosition; + +public interface ShowMode { + void show(TNTPosition position); + + void hide(); +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/ShowModeParameter.java b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/ShowModeParameter.java new file mode 100644 index 00000000..ba67f716 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/ShowModeParameter.java @@ -0,0 +1,57 @@ +/* + * + * 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.tracer.show; + +public class ShowModeParameter { + + private boolean water = false; + private boolean interpolate_Y = false; + private boolean interpolate_XZ = false; + + public ShowModeParameter() { + + } + + public boolean isWater() { + return water; + } + + public boolean isInterpolate_Y() { + return interpolate_Y; + } + + public boolean isInterpolate_XZ() { + return interpolate_XZ; + } + + public void setWater(boolean water) { + this.water = water; + } + + public void setInterpolate_Y(boolean interpolate_Y) { + this.interpolate_Y = interpolate_Y; + } + + public void setInterpolate_XZ(boolean interpolate_XZ) { + this.interpolate_XZ = interpolate_XZ; + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/ShowModeParameterType.java b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/ShowModeParameterType.java new file mode 100644 index 00000000..5cb046cf --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/ShowModeParameterType.java @@ -0,0 +1,44 @@ +/* + * 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.tracer.show; + +import java.util.function.Consumer; + +public enum ShowModeParameterType { + + WATER(showModeParameter -> showModeParameter.setWater(true)), + INTERPOLATE_Y(showModeParameter -> showModeParameter.setInterpolate_Y(true)), + INTERPOLATE_XZ(showModeParameter -> showModeParameter.setInterpolate_XZ(true)), + ADVANCED(showModeParameter -> { + showModeParameter.setInterpolate_Y(true); + showModeParameter.setInterpolate_XZ(true); + }); + + private final Consumer showModeParameterConsumer; + + public Consumer getShowModeParameterConsumer() { + return showModeParameterConsumer; + } + + ShowModeParameterType(Consumer showModeParameterConsumer) { + this.showModeParameterConsumer = showModeParameterConsumer; + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/StoredRecords.java b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/StoredRecords.java new file mode 100644 index 00000000..b0a377ee --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/StoredRecords.java @@ -0,0 +1,45 @@ +/* + 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.tracer.show; + +import de.steamwar.bausystem.tracer.record.RecordStateMachine; + +import java.util.ArrayList; +import java.util.List; + +public class StoredRecords { + + private static final List records = new ArrayList<>(); + + public static void add(Record record) { + records.add(record); + } + + public static void showAll(ShowMode mode) { + for (Record record : records) record.showAll(mode); + } + + public static void clear() { + records.clear(); + TraceShowManager.clear(); + RecordStateMachine.postClear(); + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/TraceShowManager.java b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/TraceShowManager.java new file mode 100644 index 00000000..0c4b88ee --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/TraceShowManager.java @@ -0,0 +1,59 @@ +package de.steamwar.bausystem.tracer.show; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.tracer.TNTPosition; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerQuitEvent; + +import java.util.HashMap; +import java.util.Map; + +public class TraceShowManager implements Listener { + private TraceShowManager() { + } + + private static final Map showModes = new HashMap<>(); + + public static void show(Player player, ShowMode showMode) { + hide(player); + showModes.put(player, showMode); + StoredRecords.showAll(showMode); + } + + public static void hide(Player player) { + ShowMode showMode = showModes.remove(player); + if (showMode == null) + return; + showMode.hide(); + } + + /* Only to be called by record */ + static void show(TNTPosition tnt) { + for (ShowMode mode : showModes.values()) + mode.show(tnt); + } + + /* Only to be called by StoredRecords */ + static void clear() { + for (ShowMode mode : showModes.values()) + mode.hide(); + } + + /* Internal if player leaves*/ + static { + Bukkit.getPluginManager().registerEvents(new TraceShowManager(), BauSystem.getPlugin()); + } + + @EventHandler + public void onLeave(PlayerQuitEvent event) { + showModes.remove(event.getPlayer()); + } + + public static boolean hasActiveShow(Player player) { + return showModes.containsKey(player); + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/mode/EntityShowMode.java b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/mode/EntityShowMode.java new file mode 100644 index 00000000..0e1a27ef --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/tracer/show/mode/EntityShowMode.java @@ -0,0 +1,120 @@ +/* + * + * 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.tracer.show.mode; + +import de.steamwar.bausystem.CraftbukkitWrapper; +import de.steamwar.bausystem.FlatteningWrapper; +import de.steamwar.bausystem.tracer.AbstractTraceEntity; +import de.steamwar.bausystem.tracer.RoundedTNTPosition; +import de.steamwar.bausystem.tracer.TNTPosition; +import de.steamwar.bausystem.tracer.show.ShowMode; +import de.steamwar.bausystem.tracer.show.ShowModeParameter; +import org.bukkit.entity.Player; +import org.bukkit.util.Consumer; +import org.bukkit.util.Vector; + +import java.util.HashMap; +import java.util.Map; + +public class EntityShowMode implements ShowMode { + + protected final Player player; + protected final ShowModeParameter showModeParameter; + + private final Map tntEntityMap = new HashMap<>(); + private final Map updateEntityMap = new HashMap<>(); + + public EntityShowMode(Player player, ShowModeParameter showModeParameter) { + this.player = player; + this.showModeParameter = showModeParameter; + } + + @Override + public void show(TNTPosition position) { + if (!showModeParameter.isWater() && position.isExploded() && checkWater(position.getLocation())) { + // Basic + for (TNTPosition pos : position.getRecord().getPositions()) { + RoundedTNTPosition roundedTNTPosition = new RoundedTNTPosition(pos); + tntEntityMap.computeIfPresent(roundedTNTPosition, (p, tnt) -> { + return tnt.hide(player, false) ? null : tnt; + }); + } + // Advanced + for (TNTPosition pos : position.getRecord().getPositions()) { + applyOnPosition(pos, updatePointPosition -> { + updateEntityMap.computeIfPresent(new RoundedTNTPosition(updatePointPosition), (p, point) -> { + return point.hide(player, false) ? null : point; + }); + }); + } + return; + } + + RoundedTNTPosition roundedTNTPosition = new RoundedTNTPosition(position); + AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedTNTPosition, pos -> createEntity(player, position.getLocation(), true)); + entity.display(player, position.isExploded()); + + applyOnPosition(position, updatePointPosition -> { + updateEntityMap.computeIfAbsent(new RoundedTNTPosition(updatePointPosition), pos -> { + return createEntity(player, updatePointPosition, false); + }).display(player, position.isExploded()); + }); + } + + private boolean checkWater(Vector position) { + return FlatteningWrapper.impl.inWater(player.getWorld(), position); + } + + public static AbstractTraceEntity createEntity(Player player, Vector position, boolean tnt) { + return CraftbukkitWrapper.impl.create(player.getWorld(), position, tnt); + } + + private void applyOnPosition(TNTPosition position, Consumer function) { + if (position.getPreviousLocation() == null) return; + + if (showModeParameter.isInterpolate_Y()) { + Vector updatePointY = position.getPreviousLocation().clone().setY(position.getLocation().getY()); + if (!position.getLocation().equals(updatePointY)) { + function.accept(updatePointY); + } + } + + if (showModeParameter.isInterpolate_XZ()) { + Vector movement = position.getLocation().clone().subtract(position.getPreviousLocation()); + Vector updatePointXZ = Math.abs(movement.getX()) > Math.abs(movement.getZ()) + ? position.getLocation().clone().setZ(position.getPreviousLocation().getZ()) + : position.getLocation().clone().setX(position.getPreviousLocation().getX()); + if (!position.getLocation().equals(updatePointXZ)) { + function.accept(updatePointXZ); + } + } + } + + @Override + public void hide() { + tntEntityMap.forEach((roundedTNTPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true)); + tntEntityMap.clear(); + updateEntityMap.forEach((roundedTNTPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true)); + updateEntityMap.clear(); + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/AFKStopper.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/AFKStopper.java new file mode 100644 index 00000000..cf8e7bd2 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/AFKStopper.java @@ -0,0 +1,56 @@ +/* + 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.world; + +import de.steamwar.bausystem.BauSystem; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerMoveEvent; + +public class AFKStopper implements Listener { + + private static final String afkWarning = BauSystem.PREFIX + "§cDieser Server wird bei weiterer Inaktivität in einer Minute gestoppt"; + + private int minutesAfk; + + public AFKStopper() { + minutesAfk = 0; + Bukkit.getPluginManager().registerEvents(this, BauSystem.getPlugin()); + Bukkit.getScheduler().runTaskTimer(BauSystem.getPlugin(), () -> { + switch (minutesAfk) { + case 5: + for (Player p : Bukkit.getOnlinePlayers()) + p.kickPlayer("§cAuf diesem Server ist seit 5 Minuten nichts passiert."); + break; + case 4: + Bukkit.broadcastMessage(afkWarning); + default: + minutesAfk++; + } + }, 1200, 1200); //every minute + } + + @EventHandler + public void onPlayerMove(PlayerMoveEvent event) { + minutesAfk = 0; + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/AbstractAutoLoader.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/AbstractAutoLoader.java new file mode 100644 index 00000000..d30fe2dc --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/AbstractAutoLoader.java @@ -0,0 +1,122 @@ +/* + 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.world; + +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import java.util.LinkedList; + +abstract class AbstractAutoLoader { + + abstract Player getPlayer(); + abstract boolean setRedstone(Location location, boolean active); + abstract LinkedList getActions(); + abstract void resetLastActivation(); + abstract int getLastActivation(); + + void print(String message, boolean withSize){ + if(withSize) + getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(message + " §8" + getActions().size())); + else + getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(message)); + } + + abstract static class LoaderAction { + + final Location location; + final AbstractAutoLoader loader; + + LoaderAction(AbstractAutoLoader loader, Location location){ + this.location = location; + this.loader = loader; + loader.getActions().add(this); + loader.resetLastActivation(); + } + + abstract boolean perform(); + abstract int ticks(); + } + + static class RedstoneActivation extends LoaderAction{ + + final boolean active; + final int length; + int status; + + RedstoneActivation(AbstractAutoLoader loader, Location location, int ticks, boolean active){ + super(loader, location); + this.length = ticks; + this.active = active; + status = 0; + } + + @Override + public boolean perform() { + status++; + if(status < length) + return false; + + if(!loader.setRedstone(location, active)) + return false; + status = 0; + return true; + } + + @Override + int ticks() { + return 1; + } + } + + static class TemporaryActivation extends LoaderAction{ + + final int length; + int status; + + TemporaryActivation(AbstractAutoLoader loader, Location location, int ticks){ + super(loader, location); + this.length = ticks; + status = 0; + } + + @Override + public boolean perform() { + if(status == 0){ + if(!loader.setRedstone(location, true)) + return false; + }else if(status == length){ + if(!loader.setRedstone(location, false)) + return false; + status = 0; + return true; + } + status++; + return false; + } + + @Override + int ticks() { + return 1; + } + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/AutoLoader.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/AutoLoader.java new file mode 100644 index 00000000..92aa8bc1 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/AutoLoader.java @@ -0,0 +1,266 @@ +/* + 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.world; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.FlatteningWrapper; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.scheduler.BukkitTask; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.ListIterator; +import java.util.Map; + +public class AutoLoader extends AbstractAutoLoader implements Listener { + + private static final Map players = new HashMap<>(); + + public static AutoLoader getLoader(Player player){ + if(!players.containsKey(player)) + return new AutoLoader(player); + return players.get(player); + } + + public static boolean hasLoader(Player player){ + return players.containsKey(player); + } + + private final Player player; + private final BukkitTask task; + + private final LinkedList actions = new LinkedList<>(); + private int ticksBetweenShots = 80; + private int ticksBetweenBlocks = 1; + + private int lastActivation; + private int waitTicks; + private ListIterator lastAction; + private boolean setup; + private Location lastLocation; + + private AutoLoader(Player player){ + this.player = player; + Bukkit.getPluginManager().registerEvents(this, BauSystem.getPlugin()); + task = Bukkit.getScheduler().runTaskTimer(BauSystem.getPlugin(), this::run, 1, 1); + players.put(player, this); + player.sendMessage(BauSystem.PREFIX + "§7Schieße bitte einmal die Kanone ab"); + player.sendMessage(BauSystem.PREFIX + "§7Und starte anschließend den AutoLader mit §8/§eloader start"); + setup(); + } + + public void setup(){ + print("§aAutoLader im Setup-Modus", false); + setup = true; + waitTicks = 0; + lastActivation = 0; + } + + public void start(){ + if(actions.isEmpty()){ + print("§cKeine Aktion vorhanden", false); + return; + } + + if(!setup){ + print("§cAutoLader läuft bereits", false); + return; + } + + setup = false; + waitTicks = 0; + lastActivation = 0; + lastAction = actions.listIterator(); + print("§aAutoLader gestartet", false); + } + + public void stop(){ + print("§cAutoLader gestoppt", false); + players.remove(player); + HandlerList.unregisterAll(this); + if(task != null) + task.cancel(); + } + + public void undo(){ + if(actions.isEmpty()){ + print("§cKeine Aktion vorhanden", false); + return; + } + + actions.removeLast(); + print("§aUndo erfolgreich", true); + } + + public void wait(int time){ + if(time < 1){ + print("§cDie Wartezeit ist zu klein", false); + return; + } + + print("§aSchusswartezeit §e" + time + " §aTicks§8, zuvor " + ticksBetweenShots, false); + ticksBetweenShots = time; + } + + public void blockWait(int time){ + if(time < 1){ + print("§cDie Wartezeit ist zu klein", false); + return; + } + + print("§aSetzwartezeit §e" + time + " §aTicks§8, zuvor " + ticksBetweenBlocks, false); + ticksBetweenBlocks = time; + } + + public int getTicksBetweenShots() { + return ticksBetweenShots; + } + + public int getTicksBetweenBlocks() { + return ticksBetweenBlocks; + } + + public boolean isSetup() { + return setup; + } + + @EventHandler + public void onBlockPlace(BlockPlaceEvent event){ + if(!setup || !event.getPlayer().equals(player)) + return; + if(event.getBlock().getType() != Material.TNT) + return; + + new TNTPlaceAction(this, event.getBlock().getLocation()); + print("§eTNT platziert", true); + } + + //BlockRedstoneEvent? + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event){ + if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.PHYSICAL) + return; + if (event.getClickedBlock().getType() == Material.OBSERVER) + return; + if (event.getPlayer().isSneaking()) + return; + + if (!setup || !event.getPlayer().equals(player)) + return; + + Detoloader detoloader = FlatteningWrapper.impl.onPlayerInteractLoader(event); + if (detoloader == null || detoloader.getActivation() < 0) return; + + if (lastLocation != null && lastLocation.distance(event.getClickedBlock().getLocation()) <= 1) return; + + if (detoloader.useActive) { + new AbstractAutoLoader.RedstoneActivation(this, event.getClickedBlock().getLocation() + , detoloader.getActivation() == 0 ? getLastActivation() : detoloader.getActivation() + , detoloader.isActive()); + } else { + new AbstractAutoLoader.TemporaryActivation(this, event.getClickedBlock().getLocation() + , detoloader.getActivation()); + } + print(detoloader.addBack ? "§e" + detoloader.getBlock() + " betätigt" : + detoloader.getBlock(), detoloader.addBack); + lastLocation = event.getClickedBlock().getLocation(); + } + + @EventHandler + public void onLeave(PlayerQuitEvent event){ + if(!event.getPlayer().equals(player)) + return; + stop(); + } + + private void run(){ + lastActivation++; + if(setup) + return; + while(lastActivation >= waitTicks){ + lastActivation = 0; + + LoaderAction action = lastAction.next(); + if(action.perform()){ + waitTicks = action.ticks(); + }else{ + waitTicks = 1; + lastAction.previous(); + } + + if(!lastAction.hasNext()){ + lastAction = actions.listIterator(); + waitTicks = ticksBetweenShots; + } + } + } + + @Override + Player getPlayer() { + return player; + } + + @Override + boolean setRedstone(Location location, boolean active){ + return FlatteningWrapper.impl.setRedstone(location, active); + } + + @Override + LinkedList getActions() { + return actions; + } + + @Override + void resetLastActivation() { + lastActivation = 0; + } + + @Override + int getLastActivation() { + return lastActivation; + } + + class TNTPlaceAction extends AbstractAutoLoader.LoaderAction { + + TNTPlaceAction(AbstractAutoLoader loader, Location location){ + super(loader, location); + } + + @Override + public boolean perform() { + return FlatteningWrapper.impl.tntPlaceActionPerform(location); + } + + @Override + int ticks(){ + return ticksBetweenBlocks; + } + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/BauScoreboard.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/BauScoreboard.java new file mode 100644 index 00000000..380bc715 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/BauScoreboard.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.bausystem.world; + +import de.steamwar.bausystem.commands.CommandTPSLimiter; +import de.steamwar.bausystem.tracer.record.RecordStateMachine; +import de.steamwar.bausystem.world.regions.Region; +import de.steamwar.core.TPSWatcher; +import de.steamwar.scoreboard.SWScoreboard; +import de.steamwar.scoreboard.ScoreboardCallback; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; + +public class BauScoreboard implements Listener { + + @EventHandler + public void handlePlayerJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); + + SWScoreboard.impl.createScoreboard(player, new ScoreboardCallback() { + @Override + public HashMap getData() { + return sidebar(player); + } + + @Override + public String getTitle() { + return "§eSteam§8War"; + } + }); + } + + private HashMap sidebar(Player p) { + List strings = new ArrayList<>(); + strings.add("§1"); + strings.add("§eUhrzeit§8: §7" + new SimpleDateFormat("HH:mm:ss").format(Calendar.getInstance().getTime())); + strings.add("§2"); + Region region = Region.getRegion(p.getLocation()); + strings.add("§eTNT§8: " + region.getTntMode().getName()); + strings.add("§eFreeze§8: " + (region.isFreeze() ? "§aan" : "§caus")); + strings.add("§eFire§8: " + (region.isFire() ? "§aaus" : "§can")); + strings.add("§eTrace§8: " + RecordStateMachine.getRecordStatus().getName()); + strings.add("§eLoader§8: " + (AutoLoader.hasLoader(p) ? "§aan" : "§caus")); + if (region.hasProtection()) { + strings.add("§eProtect§8: " + (region.isProtect() ? "§aan" : "§caus")); + } + + if (RecordStateMachine.getRecordStatus().isTracing()) { + strings.add("§3"); + strings.add("§eTicks§8: §7" + traceTicks()); + strings.add("§eAnzahl TNT§8: §7" + RecordStateMachine.size()); + } + + strings.add("§4"); + strings.add("§eTPS§8: " + tpsColor() + TPSUtils.getTps(TPSWatcher.TPSType.ONE_SECOND) + tpsLimit()); + + int i = strings.size(); + HashMap result = new HashMap<>(); + for (String s : strings) + result.put(s, i--); + return result; + } + + private long traceTicks() { + return (System.currentTimeMillis() - RecordStateMachine.getStartTime()) / 50; + } + + private String tpsColor() { + double tps = TPSUtils.getTps(TPSWatcher.TPSType.ONE_SECOND); + if (tps > CommandTPSLimiter.getCurrentTPSLimit() * 0.9) { + return "§a"; + } + if (tps > CommandTPSLimiter.getCurrentTPSLimit() * 0.5) { + return "§e"; + } + return "§c"; + } + + private String tpsLimit() { + if (CommandTPSLimiter.getCurrentTPSLimit() == 20) { + return ""; + } + return "§8/§7" + CommandTPSLimiter.getCurrentTPSLimit(); + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/ClipboardListener.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/ClipboardListener.java new file mode 100644 index 00000000..6ab68478 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/ClipboardListener.java @@ -0,0 +1,63 @@ +/* + 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.world; + +import de.steamwar.sql.SchematicData; +import de.steamwar.sql.SchematicNode; +import de.steamwar.sql.SteamwarUser; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +public class ClipboardListener implements Listener { + + private static final String CLIPBOARD_SCHEMNAME = "//copy"; + + @EventHandler + public void onLogin(PlayerJoinEvent e) { + try { + SchematicNode schematic = SchematicNode.getSchematicNode(SteamwarUser.get(e.getPlayer().getUniqueId()).getId(), CLIPBOARD_SCHEMNAME, (Integer) null); + if (schematic != null) { + new SchematicData(schematic).loadToPlayer(e.getPlayer()); + } + } catch (Exception ex) { + // ignore cause players do all kind of stuff with schematics.... like massively oversized schems + } + } + + @EventHandler + public void onLogout(PlayerQuitEvent e) { + SchematicNode schematic = SchematicNode.getSchematicNode(SteamwarUser.get(e.getPlayer().getUniqueId()).getId(), CLIPBOARD_SCHEMNAME, (Integer) null); + boolean newSchem = false; + if (schematic == null) { + schematic = SchematicNode.createSchematic(SteamwarUser.get(e.getPlayer().getUniqueId()).getId(), CLIPBOARD_SCHEMNAME, null); + newSchem = true; + } + + try { + new SchematicData(schematic).saveFromPlayer(e.getPlayer()); + } catch (Exception ex) { + if (newSchem) { + schematic.delete(); + } + } + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/Color.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/Color.java new file mode 100644 index 00000000..2f068813 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/Color.java @@ -0,0 +1,39 @@ +/* + * 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.world; + +public enum Color { + WHITE, + ORANGE, + MAGENTA, + LIGHT_BLUE, + YELLOW, + LIME, + PINK, + GRAY, + LIGHT_GRAY, + CYAN, + PURPLE, + BLUE, + BROWN, + GREEN, + RED, + BLACK; +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/Detoloader.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/Detoloader.java new file mode 100644 index 00000000..531fff59 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/Detoloader.java @@ -0,0 +1,87 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2020 SteamWar.de-Serverteam + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +package de.steamwar.bausystem.world; + +import org.bukkit.Location; + +public class Detoloader { + + String message; + int activation; + boolean active, addBack = true, useActive = false; + + public Detoloader(String message, int activation) { + this.message = message; + this.activation = activation; + } + + public String getBlock() { + return message; + } + + public void setBlock(String message) { + this.message = message; + } + + public int getActivation() { + return activation; + } + + public boolean isActive() { + return active; + } + + public Detoloader setActive(boolean active) { + useActive = true; + this.active = active; + return this; + } + + public boolean isAddBack() { + return addBack; + } + + public Detoloader setAddBack(boolean addBack) { + this.addBack = addBack; + return this; + } + + static class DetonatorActivation { + + int activation = -1; + Location location; + + public DetonatorActivation(Location location) { + this.location = location; + } + + public DetonatorActivation(int activation, Location location) { + this.activation = activation; + this.location = location; + } + } + + //Timings + public static final int STONE_BUTTON = 20; + public static final int WOODEN_BUTTON = 30; + public static final int PRESSURE_PLATE = 20; + public static final int NOTE_BLOCK = 1; + public static final int TRIPWIRE = 20; +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/Detonator.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/Detonator.java new file mode 100644 index 00000000..93c90c54 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/Detonator.java @@ -0,0 +1,120 @@ +/* + 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.world; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.FlatteningWrapper; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.*; + +public class Detonator implements Listener { + + public static final ItemStack WAND; + + public static final Map> PLAYER_LOCS = new HashMap<>(); + + static { + WAND = new ItemStack(Material.BLAZE_ROD, 1); + ItemMeta im = WAND.getItemMeta(); + + im.setDisplayName("§eFernzünder"); + + List lorelist = Arrays.asList("§eLinks Klick §8- §7Setzte einen Punkt zum Aktivieren", + "§eLinks Klick + Shift §8- §7Füge einen Punkt hinzu", "§eRechts Klick §8- §7Löse alle Punkte aus"); + im.setLore(lorelist); + + WAND.setItemMeta(im); + } + + public static Detonator getDetonator(Player player, ItemStack item) { + return new Detonator(player, PLAYER_LOCS.get(player)); + } + + public static ItemStack setLocation(Player player, ItemStack item, Detoloader.DetonatorActivation detoloader) { + PLAYER_LOCS.computeIfAbsent(player, player1 -> new HashSet<>()).clear(); + PLAYER_LOCS.get(player).add(detoloader); + return item; + } + + public static ItemStack toggleLocation(ItemStack item, Player player, Detoloader detoloader, Location location) { + if (PLAYER_LOCS.computeIfAbsent(player, player1 -> new HashSet<>()).stream().anyMatch(activation -> activation.location.equals(location))) { + DetonatorListener.print(player, detoloader.addBack ? "§e" + detoloader.getBlock() + " entfernt" : + detoloader.getBlock(), Detonator.getDetonator(player, player.getInventory().getItemInMainHand()).getLocs().size() - 1); + PLAYER_LOCS.computeIfAbsent(player, player1 -> new HashSet<>()).removeIf(activation -> activation.location.equals(location)); + return item; + } else { + DetonatorListener.print(player, detoloader.addBack ? "§e" + detoloader.getBlock() + " hinzugefügt" : + detoloader.getBlock(), Detonator.getDetonator(player, player.getInventory().getItemInMainHand()).getLocs().size() + 1); + if (detoloader.getActivation() == 0) { + PLAYER_LOCS.computeIfAbsent(player, player1 -> new HashSet<>()).add(new Detoloader.DetonatorActivation(location)); + return item; + } else { + PLAYER_LOCS.computeIfAbsent(player, player1 -> new HashSet<>()).add(new Detoloader.DetonatorActivation(detoloader.getActivation(), location)); + return item; + } + } + } + + public static void execute(Player player) { + execute(player, PLAYER_LOCS.get(player)); + } + + private static void execute(Player player, Set locs) { + for (Detoloader.DetonatorActivation activation : locs) { + + if (activation.activation == -1) { + FlatteningWrapper.impl.setRedstone(activation.location, !FlatteningWrapper.impl.getLever(activation.location.getBlock())); + } else { + FlatteningWrapper.impl.setRedstone(activation.location, true); + Bukkit.getScheduler().runTaskLater(BauSystem.getPlugin(), () -> FlatteningWrapper.impl.setRedstone(activation.location, false), activation.activation); + } + } + player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§e" + locs.size() + " §7Punkt" + (locs.size() > 1 ? "e" : "") + " ausgelöst!")); + } + + public static void clear(Player player) { + PLAYER_LOCS.computeIfAbsent(player, player1 -> new HashSet<>()).clear(); + } + + private final Set locs; + private final Player player; + + private Detonator(Player player, Set locs) { + this.player = player; + this.locs = locs; + } + + public Set getLocs() { + return locs; + } + + public Player getPlayer() { + return player; + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/DetonatorListener.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/DetonatorListener.java new file mode 100644 index 00000000..b616fb97 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/DetonatorListener.java @@ -0,0 +1,65 @@ +package de.steamwar.bausystem.world; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.FlatteningWrapper; +import de.steamwar.bausystem.Permission; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; + +public class DetonatorListener implements Listener { + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + if (event.getItem() == null) return; + if (event.getItem().isSimilar(Detonator.WAND)) { + Player player = event.getPlayer(); + if (Welt.noPermission(player, Permission.WORLD)) { + player.sendMessage(BauSystem.PREFIX + "§cDu darfst hier nicht den Detonator nutzen"); + return; + } + ItemStack item = event.getItem(); + event.setCancelled(true); + switch (event.getAction()) { + case LEFT_CLICK_BLOCK: + Detoloader detoloader = FlatteningWrapper.impl.onPlayerInteractLoader(event); + + if (detoloader == null) { + return; + } else if (detoloader.activation == -1) { + print(player, detoloader.getBlock(), detoloader.addBack ? Detonator.getDetonator(player, player.getInventory().getItemInMainHand()).getLocs().size() : 0); + return; + } + + if (event.getPlayer().isSneaking()) { + player.getInventory().setItemInMainHand(Detonator.toggleLocation(item, player, detoloader, event.getClickedBlock().getLocation())); + } else { + if (detoloader.getActivation() == 0) { + player.getInventory().setItemInMainHand(Detonator.setLocation(player, item, new Detoloader.DetonatorActivation(event.getClickedBlock().getLocation()))); + } else { + player.getInventory().setItemInMainHand(Detonator.setLocation(player, item, new Detoloader.DetonatorActivation(detoloader.activation, event.getClickedBlock().getLocation()))); + } + print(player, detoloader.addBack ? "§e" + detoloader.getBlock() + " gesetzt" : + detoloader.getBlock(), detoloader.addBack ? Detonator.getDetonator(player, player.getInventory().getItemInMainHand()).getLocs().size() : 0); + } + break; + case RIGHT_CLICK_AIR: + case RIGHT_CLICK_BLOCK: + Detonator.execute(player); + break; + } + } + } + + public static void print(Player player, String message, int size) { + if (size == 0) { + player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(message)); + } else { + player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(message + " §8" + size)); + } + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/ItemFrameListener.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/ItemFrameListener.java new file mode 100644 index 00000000..a8c9618f --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/ItemFrameListener.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.world; + +import de.steamwar.bausystem.SWUtils; +import org.bukkit.Material; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; + +public class ItemFrameListener implements Listener { + + @EventHandler + public void onEntityDamageByEntity(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player)) { + return; + } + if (!(event.getEntity() instanceof ItemFrame)) { + return; + } + event.setCancelled(true); + ItemFrame itemFrame = (ItemFrame) event.getEntity(); + ItemStack itemStack = itemFrame.getItem(); + if (itemStack.getType() != Material.AIR) { + SWUtils.giveItemToPlayer((Player) event.getDamager(), itemFrame.getItem()); + itemFrame.setItem(null); + } else { + itemFrame.remove(); + } + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/PredefinedBook.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/PredefinedBook.java new file mode 100644 index 00000000..355fd3b8 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/PredefinedBook.java @@ -0,0 +1,124 @@ +package de.steamwar.bausystem.world; + +import de.steamwar.bausystem.BauSystem; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class PredefinedBook { + + private static final FileConfiguration configuration; + private static List bookCache; + + static { + configuration = YamlConfiguration.loadConfiguration(new File(BauSystem.getPlugin().getDataFolder(), "books.yml")); + } + + public static List getBooks() { + if (bookCache != null) + return bookCache; + List books = new ArrayList<>(); + for (String book : configuration.getKeys(false)) { + ConfigurationSection section = Objects.requireNonNull(configuration.getConfigurationSection(book)); + books.add(new PredefinedBook(section)); + } + bookCache = books; + return books; + } + + public static int getBookCount() { + return configuration.getKeys(false).size(); + } + + private List lines; + private List lore; + private String author; + private String name; + private ItemStack finishedBook; + + PredefinedBook(ConfigurationSection section) { + this.lines = section.getStringList("lines"); + this.lore = section.getStringList("lore"); + this.author = section.getString("author", "§8Steam§eWar"); + this.name = section.getName(); + } + + public ItemStack toItemStack() { + if (finishedBook != null) + return finishedBook; + ItemStack book = new ItemStack(getBookMat()); + BookMeta meta = (BookMeta) book.getItemMeta(); + meta.setPages(getPages()); + meta.setDisplayName(name); + meta.setTitle(name); + meta.setAuthor(author); + meta.setGeneration(BookMeta.Generation.ORIGINAL); + meta.setLore(lore); + book.setItemMeta(meta); + finishedBook = book; + return book; + } + + public Material getBookMat() { + return Material.WRITTEN_BOOK; + } + + public List getLines() { + return lines; + } + + public String getAuthor() { + return author; + } + + public String getName() { + return name; + } + + public List getLore() { + return lore; + } + + private String[] getPages() { + List pages = new ArrayList<>(); + pages.add(0, new StringBuilder()); + int charsPerLine = 19; + int currentLine = 0; + int currentpage = 0; + boolean first = true; + for (String line : lines) { + int linesPlus = (int) Math.ceil((double) line.length() / charsPerLine); + currentLine += linesPlus; + if (currentLine >= 14 || line.equals("!")) { + currentLine = linesPlus; + currentpage++; + if (currentpage > 50) + throw new IllegalStateException("Book " + name + " has more pages than 50"); + pages.add(currentpage, new StringBuilder()); + first = true; + if (line.equals("!")) + continue; + } + if (!first) { + pages.get(currentpage).append("\n"); + } else { + first = false; + } + pages.get(currentpage).append(line); + } + + String[] finalPages = new String[pages.size()]; + for (int i = 0; i < pages.size(); i++) { + finalPages[i] = pages.get(i).toString(); + } + return finalPages; + } +} \ No newline at end of file diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/RegionListener.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/RegionListener.java new file mode 100644 index 00000000..19f18c02 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/RegionListener.java @@ -0,0 +1,137 @@ +/* + 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.world; + +import de.steamwar.Reflection; +import com.comphenix.tinyprotocol.TinyProtocol; +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.CraftbukkitWrapper; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.WorldeditWrapper; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerInteractEvent; + +import java.util.ArrayList; +import java.util.List; + +public class RegionListener implements Listener { + + private final List signEditing = new ArrayList<>(); + + private static final Class updateSign = Reflection.getClass("{nms}.PacketPlayInUpdateSign"); + private static final Class blockPosition = Reflection.getClass("{nms}.BlockPosition"); + private static final Reflection.Field blockPos = Reflection.getField(updateSign, blockPosition, 0); + private static final Reflection.Field signText = Reflection.getField(updateSign, String[].class, 0); + private static final Class baseBlockPosition = Reflection.getClass("{nms}.BaseBlockPosition"); + private static final Reflection.Field blockPosX = Reflection.getField(baseBlockPosition, int.class, 0); + private static final Reflection.Field blockPosY = Reflection.getField(baseBlockPosition, int.class, 1); + private static final Reflection.Field blockPosZ = Reflection.getField(baseBlockPosition, int.class, 2); + public RegionListener() { + TinyProtocol.instance.addFilter(updateSign, (player, packet) -> { + if(!signEditing.contains(player)) + return packet; + + String[] lines = signText.get(packet); + Object pos = blockPos.get(packet); + + Bukkit.getScheduler().runTask(BauSystem.getPlugin(), () -> { + Block signLoc = new Location(player.getWorld(), blockPosX.get(pos), blockPosY.get(pos), blockPosZ.get(pos)).getBlock(); + if (!signLoc.getType().name().contains("SIGN")) + return; + + Sign sign = ((Sign) signLoc.getState()); + for (int i = 0; i < lines.length; i++) { + sign.setLine(i, ChatColor.translateAlternateColorCodes('&', lines[i])); + } + sign.update(); + + signEditing.remove(player); + }); + + return packet; + }); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void playerCommandHandler(PlayerCommandPreprocessEvent e) { + if (!isWorldEditCommand(e.getMessage().split(" ")[0])) + return; + + Player p = e.getPlayer(); + + if (Welt.noPermission(p, Permission.WORLDEDIT)) { + p.sendMessage(BauSystem.PREFIX + "§cDu darfst hier kein WorldEdit benutzen"); + e.setCancelled(true); + } + } + + private static final String[] shortcutCommands = {"//1", "//2", "//90", "//-90", "//180", "//p", "//c", "//flopy", "//floppy", "//flopyp", "//floppyp", "//u", "//r"}; + + private boolean isWorldEditCommand(String command) { + for (String shortcut : shortcutCommands) + if (command.startsWith(shortcut)) + return true; + + return WorldeditWrapper.impl.isWorldEditCommand(command); + } + + @EventHandler + public void onSignChange(SignChangeEvent event) { + for (int i = 0; i <= 3; ++i) { + String line = event.getLine(i); + if (line == null) + continue; + line = ChatColor.translateAlternateColorCodes('&', line); + event.setLine(i, line); + } + } + + @EventHandler + public void editSign(PlayerInteractEvent event) { + if (event.getAction() != Action.RIGHT_CLICK_BLOCK || + !event.getClickedBlock().getType().name().contains("SIGN") || + !event.getPlayer().isSneaking() || + (event.getItem() != null && event.getItem().getType() != Material.AIR)) + return; + + Player player = event.getPlayer(); + Sign sign = (Sign) event.getClickedBlock().getState(); + String[] lines = sign.getLines(); + for (int i = 0; i < lines.length; i++) { + sign.setLine(i, lines[i].replace('\u00A7' /* WINDOWS \u00A7 -> § */, '&')); + } + sign.update(); + + CraftbukkitWrapper.impl.openSignEditor(player, event.getClickedBlock().getLocation()); + signEditing.add(player); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/ScriptListener.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/ScriptListener.java new file mode 100644 index 00000000..b26055fe --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/ScriptListener.java @@ -0,0 +1,542 @@ +/* + 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.world; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.FlatteningWrapper; +import de.steamwar.bausystem.commands.CommandScript; +import de.steamwar.bausystem.commands.CommandTNT; +import de.steamwar.bausystem.tracer.record.RecordStateMachine; +import de.steamwar.bausystem.world.regions.Region; +import de.steamwar.inventory.SWAnvilInv; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; + +import java.util.*; +import java.util.function.Function; +import java.util.function.IntBinaryOperator; +import java.util.function.IntUnaryOperator; +import java.util.logging.Level; + +public class ScriptListener implements Listener { + + public static final Map> GLOBAL_VARIABLES = new HashMap<>(); + private static final Map> CONSTANTS = new HashMap<>(); + + static { + CONSTANTS.put("trace", player -> RecordStateMachine.getRecordStatus().isTracing() ? 1 : 0); + CONSTANTS.put("autotrace", player -> RecordStateMachine.getRecordStatus().isAutoTrace() ? 1 : 0); + CONSTANTS.put("tnt", player -> Region.getRegion(player.getLocation()).getTntMode() == CommandTNT.TNTMode.OFF ? 0 : 1); + CONSTANTS.put("freeze", player -> Region.getRegion(player.getLocation()).isFreeze() ? 1 : 0); + CONSTANTS.put("fire", player -> Region.getRegion(player.getLocation()).isFire() ? 1 : 0); + CONSTANTS.put("x", player -> player.getLocation().getBlockX()); + CONSTANTS.put("y", player -> player.getLocation().getBlockY()); + CONSTANTS.put("z", player -> player.getLocation().getBlockZ()); + } + + private Set playerSet = new HashSet<>(); + + public ScriptListener() { + Bukkit.getScheduler().runTaskTimer(BauSystem.getPlugin(), playerSet::clear, 5, 5); + } + + @EventHandler(priority = EventPriority.HIGH) + public void onLeftClick(PlayerInteractEvent event) { + ItemStack item = event.getItem(); + if (item == null || isNoBook(item) || item.getItemMeta() == null) + return; + + if (CommandScript.BOOK.getItemMeta() != null && item.getItemMeta().hasDisplayName() && item.getItemMeta().getDisplayName().equals(CommandScript.BOOK.getItemMeta().getDisplayName())) { + return; + } + + if (event.getAction() != Action.LEFT_CLICK_AIR && event.getAction() != Action.LEFT_CLICK_BLOCK) { + if (event.getAction() == Action.RIGHT_CLICK_AIR) { + playerSet.add(event.getPlayer()); + } + return; + } + if (playerSet.remove(event.getPlayer())) { + return; + } + + event.setCancelled(true); + new ScriptExecutor((BookMeta) item.getItemMeta(), event.getPlayer()); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + GLOBAL_VARIABLES.remove(event.getPlayer()); + } + + private boolean isNoBook(ItemStack item) { + return FlatteningWrapper.impl.isNoBook(item); + } + + private static class ScriptExecutor { + + private final Player player; + private final List commands = new ArrayList<>(); + private final Map jumpPoints = new HashMap<>(); + private Map variables = new HashMap<>(); + + private int index = 0; + + public ScriptExecutor(BookMeta bookMeta, Player player) { + this.player = player; + + for (String page : bookMeta.getPages()) { + for (String command : page.split("\n")) { + command = command.replaceAll(" +", " "); + if (command.startsWith("#") || command.trim().isEmpty()) continue; + if (command.startsWith(".")) { + jumpPoints.put(command.substring(1), commands.size()); + continue; + } + commands.add(command); + } + } + if (commands.isEmpty()) return; + resume(); + } + + private void resume() { + if (!player.isOnline()) { + return; + } + + int executionPoints = 0; + + while (index < commands.size()) { + String command = commands.get(index++); + if (executionPoints++ > 200) { + player.sendMessage(BauSystem.PREFIX + "§cFüge ein sleep in dein Script ein"); + return; + } + + String firstArg = command; + if (command.contains(" ")) { + firstArg = command.substring(0, command.indexOf(' ')); + } + switch (firstArg.toLowerCase()) { + case "sleep": + ScriptListener.sleepCommand(this, generateArgumentArray("sleep", this, command)); + return; + case "exit": + return; + case "jump": + int jumpIndex = ScriptListener.jumpCommand(this, generateArgumentArray("jump", this, command)); + if (jumpIndex != -1) { + index = jumpIndex; + } else { + player.sendMessage(BauSystem.PREFIX + "§cUnbekannter Jump Punkt: " + command); + } + continue; + case "echo": + ScriptListener.echoCommand(this, generateArgumentArray("echo", this, command)); + continue; + case "input": + ScriptListener.inputCommand(this, generateArgumentArray("input", this, command)); + return; + case "var": + ScriptListener.variableCommand(this, generateArgumentArray("var", this, command)); + continue; + case "unvar": + ScriptListener.unvariableCommand(this, generateArgumentArray("unvar", this, command)); + continue; + case "global": + ScriptListener.globalCommand(this, generateArgumentArray("global", this, command)); + continue; + case "unglobal": + ScriptListener.unglobalCommand(this, generateArgumentArray("unglobal", this, command)); + continue; + case "add": + ScriptListener.arithmeticCommand(this, generateArgumentArray("add", this, command), (left, right) -> left + right); + continue; + case "sub": + ScriptListener.arithmeticCommand(this, generateArgumentArray("sub", this, command), (left, right) -> left - right); + continue; + case "mul": + ScriptListener.arithmeticCommand(this, generateArgumentArray("mul", this, command), (left, right) -> left * right); + continue; + case "div": + ScriptListener.arithmeticCommand(this, generateArgumentArray("div", this, command), (left, right) -> left / right); + continue; + case "equal": + ScriptListener.arithmeticCommand(this, generateArgumentArray("equal", this, command), (left, right) -> left == right ? 1 : 0); + continue; + case "less": + ScriptListener.arithmeticCommand(this, generateArgumentArray("less", this, command), (left, right) -> left < right ? 1 : 0); + continue; + case "greater": + ScriptListener.arithmeticCommand(this, generateArgumentArray("greater", this, command), (left, right) -> left > right ? 1 : 0); + continue; + case "not": + ScriptListener.arithmeticInfixCommand(this, generateArgumentArray("not", this, command), (left) -> left == 1 ? 0 : 1); + continue; + case "and": + ScriptListener.arithmeticCommand(this, generateArgumentArray("and", this, command), (left, right) -> left == 1 && right == 1 ? 1 : 0); + continue; + case "or": + ScriptListener.arithmeticCommand(this, generateArgumentArray("or", this, command), (left, right) -> left == 1 || right == 1 ? 1 : 0); + continue; + case "if": + int ifJumpIndex = ScriptListener.ifCommand(this, generateArgumentArray("if", this, command)); + if (ifJumpIndex != -1) { + index = ifJumpIndex; + } + continue; + default: + break; + } + + PlayerCommandPreprocessEvent preprocessEvent = new PlayerCommandPreprocessEvent(player, "/" + command); + Bukkit.getServer().getPluginManager().callEvent(preprocessEvent); + if (preprocessEvent.isCancelled()) { + continue; + } + + // Variable Replaces in commands. + command = String.join(" ", generateArgumentArray("", this, command)); + + Bukkit.getLogger().log(Level.INFO, player.getName() + " dispatched command: " + command); + Bukkit.getServer().dispatchCommand(player, command); + } + } + + } + + private static String[] generateArgumentArray(String command, ScriptExecutor scriptExecutor, String fullCommand) { + String[] strings; + if (command.isEmpty()) { + strings = fullCommand.split(" "); + } else { + strings = fullCommand.substring(command.length()).trim().split(" "); + } + return replaceVariables(scriptExecutor, strings); + } + + private static void sleepCommand(ScriptExecutor scriptExecutor, String[] args) { + int sleepTime = 1; + if (args.length > 0) { + try { + sleepTime = Integer.parseInt(args[0]); + if (sleepTime <= 0) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cDie Zeit muss eine Zahl großer 0 sein."); + sleepTime = 1; + } + } catch (NumberFormatException e) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cDie Zeit darf nur aus Zahlen bestehen."); + } + } + Bukkit.getScheduler().runTaskLater(BauSystem.getPlugin(), scriptExecutor::resume, sleepTime); + } + + private static int jumpCommand(ScriptExecutor scriptExecutor, String[] args) { + if (args.length < 1) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cEin Jump Punkt muss angegeben sein."); + return -1; + } + return scriptExecutor.jumpPoints.getOrDefault(args[0], -1); + } + + private static String[] replaceVariables(ScriptExecutor scriptExecutor, String[] args) { + // Legacy '$' notation for variable reference, could be removed later on. + for (int i = 0; i < args.length; i++) { + if (args[i].startsWith("$") && isVariable(scriptExecutor, args[i].substring(1))) { + args[i] = getValue(scriptExecutor, args[i].substring(1)) + ""; + } + } + + String s = String.join(" ", args); + Set variables = new HashSet<>(scriptExecutor.variables.keySet()); + variables.addAll(CONSTANTS.keySet()); + if (GLOBAL_VARIABLES.containsKey(scriptExecutor.player)) { + variables.addAll(GLOBAL_VARIABLES.get(scriptExecutor.player).keySet()); + } + for (String variable : variables) { + s = s.replace("<" + variable + ">", getValue(scriptExecutor, variable) + ""); + } + for (String constVariable : CONSTANTS.keySet()) { + s = s.replace("", getConstantValue(scriptExecutor, constVariable) + ""); + } + for (String localVariable : scriptExecutor.variables.keySet()) { + s = s.replace("", getLocalValue(scriptExecutor, localVariable) + ""); + } + for (String globalVariable : GLOBAL_VARIABLES.getOrDefault(scriptExecutor.player, new HashMap<>()).keySet()) { + s = s.replace("", getGlobalValue(scriptExecutor, globalVariable) + ""); + } + return s.split(" "); + } + + private static void echoCommand(ScriptExecutor scriptExecutor, String[] args) { + scriptExecutor.player.sendMessage("§eInfo§8» §7" + ChatColor.translateAlternateColorCodes('&', String.join(" ", replaceVariables(scriptExecutor, args)))); + } + + private static void variableCommand(ScriptExecutor scriptExecutor, String[] args) { + if (args.length < 1) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cVariablen Namen und Zahlen/Boolsche Wert fehlt."); + return; + } + if (args.length < 2) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cZahlen/Boolsche Wert fehlt."); + return; + } + switch (args[1]) { + case "inc": + case "increment": + case "++": + add(scriptExecutor, args[0], 1); + return; + case "dec": + case "decrement": + case "--": + add(scriptExecutor, args[0], -1); + return; + default: + break; + } + setValue(scriptExecutor, args[0], parseValue(args[1])); + } + + private static void unvariableCommand(ScriptExecutor scriptExecutor, String[] args) { + if (args.length < 1) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cVariablen Namen fehlt."); + return; + } + if (!isLocalVariable(scriptExecutor, args[0])) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cVariable is nicht definiert"); + return; + } + scriptExecutor.variables.remove(args[0]); + } + + private static void globalCommand(ScriptExecutor scriptExecutor, String[] args) { + if (args.length < 1) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cVariablen Namen fehlt."); + return; + } + if (!isLocalVariable(scriptExecutor, args[0])) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cVariable is nicht definiert"); + return; + } + GLOBAL_VARIABLES.computeIfAbsent(scriptExecutor.player, player -> new HashMap<>()).put(args[0], scriptExecutor.variables.getOrDefault(args[0], 0)); + } + + private static void unglobalCommand(ScriptExecutor scriptExecutor, String[] args) { + if (args.length < 1) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cVariablen Namen fehlt."); + return; + } + if (!isGlobalVariable(scriptExecutor, args[0])) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cVariable is nicht definiert"); + return; + } + if (GLOBAL_VARIABLES.containsKey(scriptExecutor.player)) { + GLOBAL_VARIABLES.get(scriptExecutor.player).remove(args[0]); + } + } + + private static int ifCommand(ScriptExecutor scriptExecutor, String[] args) { + if (args.length < 2) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cDie ersten beiden Argumente sind Zahlen/Boolsche Werte oder Variablen."); + return -1; + } + if (args.length < 3) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cDas dritte Argument muss ein JumpPoint sein."); + return -1; + } + + int jumpTruePoint = scriptExecutor.jumpPoints.getOrDefault(args[2], -1); + int jumpFalsePoint = args.length > 3 ? scriptExecutor.jumpPoints.getOrDefault(args[3], -1) : -1; + + if (args[1].equals("exists")) { + if (isVariable(scriptExecutor, args[0])) { + return jumpTruePoint; + } else { + return jumpFalsePoint; + } + } + int firstValue = getValueOrParse(scriptExecutor, args[0]); + int secondValue = getValueOrParse(scriptExecutor, args[1]); + if (firstValue == secondValue) { + return jumpTruePoint; + } else { + return jumpFalsePoint; + } + } + + private static void arithmeticCommand(ScriptExecutor scriptExecutor, String[] args, IntBinaryOperator operation) { + if (args.length < 1) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cAls erstes Argument fehlt eine Variable"); + return; + } + if (args.length < 2) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cAls zweites Argument fehlt eine Zahl oder Variable"); + return; + } + + int firstValue; + int secondValue; + if (args.length < 3) { + if (!isVariable(scriptExecutor, args[0])) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cDas erste Argument muss eine Variable sein"); + return; + } + firstValue = getValue(scriptExecutor, args[0]); + secondValue = getValueOrParse(scriptExecutor, args[1]); + } else { + firstValue = getValue(scriptExecutor, args[1]); + secondValue = getValueOrParse(scriptExecutor, args[2]); + } + setValue(scriptExecutor, args[0], operation.applyAsInt(firstValue, secondValue)); + } + + private static void arithmeticInfixCommand(ScriptExecutor scriptExecutor, String[] args, IntUnaryOperator operation) { + if (args.length < 1) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cAls erstes Argument fehlt eine Variable"); + return; + } + + int firstValue; + if (args.length < 2) { + if (!isVariable(scriptExecutor, args[0])) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cDas erste Argument muss eine Variable sein"); + return; + } + firstValue = getValue(scriptExecutor, args[0]); + } else { + firstValue = getValue(scriptExecutor, args[1]); + } + setValue(scriptExecutor, args[0], operation.applyAsInt(firstValue)); + } + + private static void inputCommand(ScriptExecutor scriptExecutor, String[] args) { + if (args.length < 1) { + scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cAls erstes Argument fehlt eine Variable"); + return; + } + String varName = args[0]; + StringBuilder st = new StringBuilder(); + for (int i = 1; i < args.length; i++) { + if (i != 1) { + st.append(" "); + } + st.append(args[i]); + } + + SWAnvilInv swAnvilInv = new SWAnvilInv(scriptExecutor.player, ChatColor.translateAlternateColorCodes('&', st.toString())); + swAnvilInv.setCallback(s -> { + int value = parseValue(s); + setValue(scriptExecutor, varName, value); + scriptExecutor.resume(); + }); + swAnvilInv.open(); + } + + private static void setValue(ScriptExecutor scriptExecutor, String key, int value) { + scriptExecutor.variables.put(key, value); + } + + private static void add(ScriptExecutor scriptExecutor, String key, int value) { + if (!isVariable(scriptExecutor, key)) { + scriptExecutor.variables.put(key, 0); + } + scriptExecutor.variables.put(key, scriptExecutor.variables.get(key) + value); + } + + private static int getValueOrParse(ScriptExecutor scriptExecutor, String key) { + if (isVariable(scriptExecutor, key)) { + return getValue(scriptExecutor, key); + } else { + return parseValue(key); + } + } + + private static int getValue(ScriptExecutor scriptExecutor, String key) { + if (CONSTANTS.containsKey(key)) { + return CONSTANTS.get(key).apply(scriptExecutor.player); + } + if (GLOBAL_VARIABLES.containsKey(scriptExecutor.player) && GLOBAL_VARIABLES.get(scriptExecutor.player).containsKey(key)) { + return GLOBAL_VARIABLES.get(scriptExecutor.player).get(key); + } + return scriptExecutor.variables.getOrDefault(key, 0); + } + + private static int getConstantValue(ScriptExecutor scriptExecutor, String key) { + return CONSTANTS.getOrDefault(key, player -> 0).apply(scriptExecutor.player); + } + + private static int getGlobalValue(ScriptExecutor scriptExecutor, String key) { + if (!GLOBAL_VARIABLES.containsKey(scriptExecutor.player)) { + return 0; + } + return GLOBAL_VARIABLES.get(scriptExecutor.player).getOrDefault(key, 0); + } + + private static int getLocalValue(ScriptExecutor scriptExecutor, String key) { + return scriptExecutor.variables.getOrDefault(key, 0); + } + + private static boolean isVariable(ScriptExecutor scriptExecutor, String key) { + if (CONSTANTS.containsKey(key)) { + return true; + } + if (GLOBAL_VARIABLES.containsKey(scriptExecutor.player) && GLOBAL_VARIABLES.get(scriptExecutor.player).containsKey(key)) { + return true; + } + return scriptExecutor.variables.containsKey(key); + } + + private static boolean isLocalVariable(ScriptExecutor scriptExecutor, String key) { + return isVariable(scriptExecutor, key) && !isGlobalVariable(scriptExecutor, key); + } + + private static boolean isGlobalVariable(ScriptExecutor scriptExecutor, String key) { + if (!GLOBAL_VARIABLES.containsKey(scriptExecutor.player)) { + return false; + } + return GLOBAL_VARIABLES.get(scriptExecutor.player).containsKey(key); + } + + public static int parseValue(String value) { + if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes")) { + return 1; + } else if (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no")) { + return 0; + } + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + return 0; + } + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/SizedStack.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/SizedStack.java new file mode 100644 index 00000000..d46b181d --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/SizedStack.java @@ -0,0 +1,123 @@ +package de.steamwar.bausystem.world; + +@SuppressWarnings({"unused", "UnusedReturnValue"}) +public class SizedStack { + + private final int maxSize; + private final T[] data; + private int size; + private int head; + + public SizedStack(int size) { + this.maxSize = size; + this.data = (T[]) new Object[this.maxSize]; + this.head = 0; + this.size = 0; + } + + public T push(final T element) { + this.data[this.head] = element; + this.increaseHead(); + this.increaseSize(); + return element; + } + + public T pop() { + this.decreaseHead(); + this.decreaseSize(); + final T result = this.data[this.head]; + this.data[this.head] = null; + return result; + } + + public T peek() { + return this.data[this.head]; + } + + public boolean empty() { + return this.size == 0; + } + + protected boolean canEqual(final Object other) { + return other instanceof SizedStack; + } + + private void increaseHead() { + this.head++; + while (this.head > this.maxSize - 1) { + this.head -= this.maxSize; + } + } + + private void decreaseHead() { + this.head--; + while (this.head < 0) { + this.head += this.maxSize; + } + } + + private void increaseSize() { + if (this.size < this.maxSize) { + this.size++; + } + } + + private void decreaseSize() { + if (this.size > 0) { + this.size--; + } + } + + @Override + public int hashCode() { + final int PRIME = 59; + int result = 1; + result = result * PRIME + this.maxSize; + result = result * PRIME + this.toString().hashCode(); + result = result * PRIME + this.size; + return result; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof SizedStack)) { + return false; + } + final SizedStack other = (SizedStack) o; + if (!other.canEqual(this)) { + return false; + } + if (this.maxSize != other.maxSize) { + return false; + } + if (this.size != other.size) { + return false; + } + if (!this.data.getClass().equals(other.data.getClass())) { + return false; + } + return this.toString().equals(other.toString()); + } + + public int getMaxSize() { + return maxSize; + } + + public int getSize() { + return size; + } + + @Override + public String toString() { + final StringBuilder result = new StringBuilder("["); + for (int i = 0; i < this.size - 1; i++) { + result.append(this.data[(this.head - i - 1 < 0) ? (this.head - i - 1 + this.maxSize) : (this.head - i - 1)]).append(","); + } + result.append(this.data[(this.head - this.size < 0) ? (this.head - this.size + this.maxSize) : (this.head - this.size)]); + result.append("]"); + return result.toString(); + } +} \ No newline at end of file diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/TPSUtils.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/TPSUtils.java new file mode 100644 index 00000000..4f16230b --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/TPSUtils.java @@ -0,0 +1,77 @@ +/* + * + * 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.world; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.CraftbukkitWrapper; +import de.steamwar.bausystem.commands.CommandTPSLimiter; +import de.steamwar.core.TPSWatcher; +import org.bukkit.Bukkit; + +import java.util.function.Supplier; + +public class TPSUtils { + + private TPSUtils() { + throw new IllegalStateException("Utility Class"); + } + + private static boolean warp = true; + private static long nanoOffset = 0; + private static long nanoDOffset = 0; + + public static void disableWarp() { + warp = false; + } + + public static long getNanoOffset() { + return nanoOffset; + } + + private static long ticksSinceServerStart = 0; + public static final Supplier currentTick = () -> ticksSinceServerStart; + + public static void init() { + CraftbukkitWrapper.impl.initTPS(); + Bukkit.getScheduler().runTaskTimer(BauSystem.getPlugin(), () -> nanoOffset += nanoDOffset, 1, 1); + Bukkit.getScheduler().runTaskTimer(BauSystem.getPlugin(), () -> ticksSinceServerStart++, 1, 1); + } + + public static void setTPS(double tps) { + double d = 50 - (50 / (tps / 20.0)); + nanoDOffset = Math.max(0, Math.min((long) (d * 1000000), 37500000)); + } + + public static boolean isWarpAllowed() { + return warp; + } + + public static boolean isWarping() { + return nanoDOffset > 0; + } + + public static double getTps(TPSWatcher.TPSType tpsType) { + if (TPSUtils.isWarping()) + return TPSWatcher.getTPS(tpsType, Math.max(CommandTPSLimiter.getCurrentTPSLimit(), 20)); + return TPSWatcher.getTPS(tpsType); + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/Welt.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/Welt.java new file mode 100644 index 00000000..74c87374 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/Welt.java @@ -0,0 +1,51 @@ +/* + 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.world; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.sql.BauweltMember; +import org.bukkit.entity.Player; + +public class Welt { + + private Welt() { + } + + public static boolean noPermission(Player member, Permission perm) { + if (member.getUniqueId().equals(BauSystem.getOwner())) + return false; + + BauweltMember member1 = BauweltMember.getBauMember(BauSystem.getOwner(), member.getUniqueId()); + if (member1 == null) + return true; + + switch (perm) { + case WORLDEDIT: + return !member1.isWorldEdit(); + case WORLD: + return !member1.isWorld(); + case MEMBER: + return false; + default: + return true; + } + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/GlobalRegion.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/GlobalRegion.java new file mode 100644 index 00000000..363284c4 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/GlobalRegion.java @@ -0,0 +1,64 @@ +/* + * 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.world.regions; + +import org.bukkit.Location; + +public class GlobalRegion extends Region { + + private static final GlobalRegion GLOBAL_REGION = new GlobalRegion(); + + public static GlobalRegion getInstance() { + return GLOBAL_REGION; + } + + public static boolean isGlobalRegion(Region region) { + return region == GLOBAL_REGION; + } + + public GlobalRegion() { + super("Global"); + } + + @Override + public boolean inRegion(Location l, RegionType regionType, RegionExtensionType regionExtensionType) { + return true; + } + + @Override + public boolean hasBuildRegion() { + return false; + } + + @Override + public boolean hasTestblock() { + return false; + } + + @Override + public boolean hasProtection() { + return false; + } + + @Override + public boolean hasExtensionArea(RegionType regionType) { + return false; + } +} \ No newline at end of file diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/PasteOptions.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/PasteOptions.java new file mode 100644 index 00000000..2dfbea07 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/PasteOptions.java @@ -0,0 +1,99 @@ +/* + * 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.world.regions; + +import de.steamwar.bausystem.world.Color; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class PasteOptions { + + /** + * Used in 1.12 and 1.15 + */ + private boolean rotate = false; + + /** + * Used in 1.12 and 1.15 + */ + private boolean ignoreAir = false; + + /** + * Used in 1.15 + */ + private Color color = Color.YELLOW; + + /** + * Used in 1.15 + */ + private boolean reset = false; + + /** + * Used in 1.15 + */ + private Point minPoint = null; + + /** + * Used in 1.15 + */ + private Point maxPoint = null; + + /** + * Used in 1.15 + */ + private int waterLevel = 0; + + public PasteOptions(boolean rotate) { + this.rotate = rotate; + } + + public PasteOptions(boolean rotate, Color color) { + this.rotate = rotate; + this.color = color; + } + + public PasteOptions(boolean rotate, boolean ignoreAir) { + this.rotate = rotate; + this.ignoreAir = ignoreAir; + } + + public PasteOptions(boolean rotate, boolean ignoreAir, boolean reset) { + this.rotate = rotate; + this.ignoreAir = ignoreAir; + this.reset = reset; + } + + public PasteOptions(boolean rotate, Color color, boolean reset) { + this.rotate = rotate; + this.color = color; + this.reset = reset; + } + + public PasteOptions(boolean rotate, boolean ignoreAir, Color color) { + this.rotate = rotate; + this.ignoreAir = ignoreAir; + this.color = color; + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/Point.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/Point.java new file mode 100644 index 00000000..b7bdf43f --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/Point.java @@ -0,0 +1,31 @@ +/* + * 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.world.regions; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class Point { + final int x; + final int y; + final int z; +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/Prototype.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/Prototype.java new file mode 100644 index 00000000..f1ccca1c --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/Prototype.java @@ -0,0 +1,204 @@ +/* + * 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.world.regions; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import de.steamwar.bausystem.WorldeditWrapper; +import de.steamwar.bausystem.world.Color; +import de.steamwar.sql.NoClipboardException; +import de.steamwar.sql.SchematicData; +import de.steamwar.sql.SchematicNode; +import org.bukkit.Location; +import org.bukkit.configuration.ConfigurationSection; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class Prototype { + static final Map prototypes = new HashMap<>(); + + private final int sizeX; + private final int sizeY; + private final int sizeZ; + + private final int offsetX; + private final int offsetY; + private final int offsetZ; + + private final int extensionPositiveZ; + private final int extensionNegativeZ; + private final int extensionPositiveY; + private final int extensionAxisX; + final boolean extensionPrototypeArea; + + private final int waterLevel; + + private final String schematic; + private final boolean rotate; + + final Prototype testblock; //nullable + final Prototype buildArea; //nullable + + private final String protectSchematic; //nullable + + Prototype(ConfigurationSection config) { + sizeX = config.getInt("sizeX"); + sizeY = config.getInt("sizeY"); + sizeZ = config.getInt("sizeZ"); + schematic = config.getString("schematic"); + offsetX = config.getInt("offsetX", 0); + offsetY = config.getInt("offsetY", 0); + offsetZ = config.getInt("offsetZ", 0); + extensionPositiveZ = config.getInt("extensionPositiveZ", 0); + extensionNegativeZ = config.getInt("extensionNegativeZ", 0); + extensionPositiveY = config.getInt("extensionPositiveY", 0); + extensionAxisX = config.getInt("extensionAxisX", 0); + if (config.contains("extensionPositiveZ") || config.contains("extensionNegativeZ") || config.contains("extensionPositiveY") || config.contains("extensionAxisX")) { + Region.extensionArea = true; + } + extensionPrototypeArea = extensionNegativeZ != 0 || extensionPositiveZ != 0 || extensionPositiveY != 0 || extensionAxisX != 0; + waterLevel = config.getInt("waterLevel", 0); + rotate = config.getBoolean("rotate", false); + + ConfigurationSection testblockSection = config.getConfigurationSection("testblock"); + testblock = testblockSection != null ? new Prototype(testblockSection) : null; + + ConfigurationSection buildAreaSection = config.getConfigurationSection("buildArea"); + buildArea = buildAreaSection != null ? new Prototype(buildAreaSection) : null; + if (buildArea != null) { + Region.buildArea = true; + } + + protectSchematic = config.getString("protection", null); + + if (!config.getName().equals("testblock") && !config.getName().equals("buildArea")) + prototypes.put(config.getName(), this); + } + + public Point getMinPoint(Region region, RegionExtensionType regionExtensionType) { + switch (regionExtensionType) { + case EXTENSION: + return new Point( + region.minPoint.getX() + offsetX - extensionAxisX, + region.minPoint.getY() + offsetY, + region.minPoint.getZ() + offsetZ - extensionNegativeZ + ); + default: + case NORMAL: + return new Point( + region.minPoint.getX() + offsetX, + region.minPoint.getY() + offsetY, + region.minPoint.getZ() + offsetZ + ); + } + } + + public Point getMaxPoint(Region region, RegionExtensionType regionExtensionType) { + switch (regionExtensionType) { + case EXTENSION: + return new Point( + region.minPoint.getX() + offsetX - extensionAxisX + (sizeX + extensionAxisX * 2) - 1, + region.minPoint.getY() + offsetY + sizeY + extensionPositiveY - 1, + region.minPoint.getZ() + offsetZ - extensionNegativeZ + (sizeZ + extensionNegativeZ + extensionPositiveZ) - 1 + ); + default: + case NORMAL: + return new Point( + region.minPoint.getX() + offsetX + sizeX - 1, + region.minPoint.getY() + offsetY + sizeY - 1, + region.minPoint.getZ() + offsetZ + sizeZ - 1 + ); + } + } + + public boolean inRegion(Region region, Location l, RegionExtensionType regionExtensionType) { + switch (regionExtensionType) { + case EXTENSION: + return inRange(l.getX(), region.minPoint.getX() + offsetX - extensionAxisX, sizeX + extensionAxisX * 2) && + inRange(l.getY(), region.minPoint.getY() + offsetY, sizeY + extensionPositiveY) && + inRange(l.getZ(), region.minPoint.getZ() + offsetZ - extensionNegativeZ, sizeZ + extensionNegativeZ + extensionPositiveZ); + default: + case NORMAL: + return inRange(l.getX(), region.minPoint.getX() + offsetX, sizeX) && + inRange(l.getY(), region.minPoint.getY() + offsetY, sizeY) && + inRange(l.getZ(), region.minPoint.getZ() + offsetZ, sizeZ); + } + } + + public EditSession reset(Region region, SchematicNode schem, boolean ignoreAir, Color color) throws IOException, NoClipboardException { + return reset(region, schem, ignoreAir, color, false); + } + + public EditSession reset(Region region, SchematicNode schem, boolean ignoreAir, Color color, boolean reset) throws IOException, NoClipboardException { + PasteOptions pasteOptions; + if (reset) { + pasteOptions = new PasteOptions(rotate ^ (schem != null && (schem.getSchemtype().fightType() || schem.getSchemtype().check())), ignoreAir, color, true, getMinPoint(region, RegionExtensionType.EXTENSION), getMaxPoint(region, RegionExtensionType.EXTENSION), waterLevel); + } else { + pasteOptions = new PasteOptions(rotate ^ (schem != null && (schem.getSchemtype().fightType() || schem.getSchemtype().check())), ignoreAir, color); + } + + int x = region.minPoint.getX() + offsetX + sizeX / 2; + int y = region.minPoint.getY() + offsetY; + int z = region.minPoint.getZ() + offsetZ + sizeZ / 2; + if (schem == null) { + return paste(new File(schematic), x, y, z, pasteOptions); + } else { + return paste(new SchematicData(schem).load(), x, y, z, pasteOptions); + } + } + + public boolean hasProtection() { + return protectSchematic != null; + } + + public EditSession protect(Region region, SchematicNode schem) throws IOException, NoClipboardException { + int x = region.minPoint.getX() + offsetX + sizeX / 2; + int y = region.minPoint.getY() + testblock.offsetY - 1; + int z = region.minPoint.getZ() + offsetZ + sizeZ / 2; + if (schem == null) { + return paste(new File(protectSchematic), x, y, z, new PasteOptions(rotate, false, Color.YELLOW)); + } else { + return paste(new SchematicData(schem).load(), x, y, z, new PasteOptions(rotate, false, Color.YELLOW)); + } + } + + public boolean hasTestblock() { + return testblock != null; + } + + public EditSession resetTestblock(Region region, SchematicNode schem, Color color, boolean reset) throws IOException, NoClipboardException { + return testblock.reset(region, schem, false, color, reset && waterLevel == 0); + } + + private static boolean inRange(double l, int min, int size) { + return min <= l && l < min + size; + } + + private static EditSession paste(File file, int x, int y, int z, PasteOptions pasteOptions) { //Type of protect + return WorldeditWrapper.impl.paste(file, x, y, z, pasteOptions); + } + + private static EditSession paste(Clipboard clipboard, int x, int y, int z, PasteOptions pasteOptions) { + return WorldeditWrapper.impl.paste(clipboard, x, y, z, pasteOptions); + } +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/Region.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/Region.java new file mode 100644 index 00000000..591f8761 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/Region.java @@ -0,0 +1,388 @@ +/* + * 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.world.regions; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSyntaxException; +import com.sk89q.worldedit.EditSession; +import de.steamwar.bausystem.commands.CommandTNT.TNTMode; +import de.steamwar.bausystem.world.Color; +import de.steamwar.bausystem.world.SizedStack; +import de.steamwar.sql.NoClipboardException; +import de.steamwar.sql.SchematicNode; +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.function.Consumer; +import java.util.logging.Level; + +public class Region { + + private static final List regions = new ArrayList<>(); + static boolean buildArea = false; + static boolean extensionArea = false; + private static JsonObject regionsObject = new JsonObject(); + + static { + File regionsFile = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "regions.json"); + if (regionsFile.exists()) { + try { + regionsObject = new JsonParser().parse(new FileReader(regionsFile)).getAsJsonObject(); + } catch (JsonSyntaxException | IOException e) { + Bukkit.getLogger().log(Level.WARNING, "Item JSON error"); + } + } + + YamlConfiguration config = new YamlConfiguration(); + try { + config.load(new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections.yml")); + } catch (InvalidConfigurationException | IOException e) { + Bukkit.getLogger().log(Level.SEVERE, "Failed to load sections.yml", e); + } + + ConfigurationSection prototypes = config.getConfigurationSection("prototypes"); + assert prototypes != null; + for (String prototype : prototypes.getKeys(false)) { + new Prototype(Objects.requireNonNull(prototypes.getConfigurationSection(prototype))); + } + + ConfigurationSection regions = config.getConfigurationSection("regions"); + assert regions != null; + for (String region : regions.getKeys(false)) { + new Region(Objects.requireNonNull(regions.getConfigurationSection(region))); + } + } + + public static boolean buildAreaEnabled() { + return buildArea; + } + + public static boolean extensionAreaEnabled() { + return extensionArea; + } + + public static Region getRegion(Location location) { + for (Region region : regions) { + if (region.inRegion(location, RegionType.NORMAL, RegionExtensionType.NORMAL)) { + return region; + } + } + return GlobalRegion.getInstance(); + } + + public static void setGlobalColor(Color color) { + for (Region region : regions) { + region.setColor(color); + } + } + + public static void save() { + File colorsFile = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "regions.json"); + if (!colorsFile.exists()) { + try { + colorsFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + return; + } + } + try (FileOutputStream fileOutputStream = new FileOutputStream(colorsFile)) { + fileOutputStream.write(regionsObject.toString().getBytes()); + } catch (IOException e) { + e.printStackTrace(); + // Ignored + } + } + + private final String name; + final Point minPoint; + private final Prototype prototype; + private final String optionsLinkedWith; // nullable + private Region linkedRegion = null; // nullable + private SizedStack undosessions; + private SizedStack redosessions; + + private JsonObject regionOptions = new JsonObject(); + + @Getter + private TNTMode tntMode = Region.buildAreaEnabled() ? TNTMode.ONLY_TB : TNTMode.OFF; + + @Getter + private boolean freeze = false; + + @Getter + private boolean fire = false; + + @Getter + private boolean protect = false; + + @Getter + private Color color = Color.YELLOW; + + private Region(ConfigurationSection config) { + name = config.getName(); + minPoint = new Point(config.getInt("minX"), config.getInt("minY"), config.getInt("minZ")); + prototype = Prototype.prototypes.get(config.getString("prototype")); + optionsLinkedWith = config.getString("optionsLinkedWith", null); + if (!hasTestblock()) tntMode = TNTMode.OFF; + regions.add(this); + load(); + } + + public Region(String name) { + this.name = name; + this.minPoint = new Point(0, 0, 0); + this.prototype = null; + this.optionsLinkedWith = null; + tntMode = TNTMode.OFF; + load(); + } + + private void load() { + if (regionsObject.has(name)) { + regionOptions = regionsObject.getAsJsonObject(name); + if (regionOptions.has("tnt")) { + String tntName = regionsObject.getAsJsonObject(name).getAsJsonPrimitive("tnt").getAsString(); + try { + tntMode = TNTMode.valueOf(tntName); + } catch (Exception e) { + // Ignored + } + } + + if (regionOptions.has("fire")) { + fire = regionOptions.getAsJsonPrimitive("fire").getAsBoolean(); + } + + if (regionOptions.has("freeze")) { + freeze = regionOptions.getAsJsonPrimitive("freeze").getAsBoolean(); + } + + if (regionOptions.has("protect")) { + protect = regionOptions.getAsJsonPrimitive("protect").getAsBoolean(); + } + + if (regionOptions.has("color")) { + String colorName = regionOptions.getAsJsonPrimitive("color").getAsString(); + try { + color = Color.valueOf(colorName); + } catch (Exception e) { + // Ignored + } + } + } else { + regionsObject.add(name, regionOptions); + } + } + + public void setColor(Color color) { + this.color = color; + regionOptions.add("color", new JsonPrimitive(color.name())); + } + + private void setLinkedRegion(Consumer regionConsumer) { + if (optionsLinkedWith == null) { + return; + } + if (linkedRegion != null) { + regionConsumer.accept(linkedRegion); + return; + } + for (Region region : regions) { + if (region.name.equals(name)) { + linkedRegion = region; + regionConsumer.accept(linkedRegion); + return; + } + } + } + + public void setTntMode(TNTMode tntMode) { + this.tntMode = tntMode; + setLinkedRegion(region -> { + region.tntMode = tntMode; + region.regionOptions.add("tnt", new JsonPrimitive(tntMode.name())); + }); + regionOptions.add("tnt", new JsonPrimitive(tntMode.name())); + } + + public void setFreeze(boolean freeze) { + this.freeze = freeze; + setLinkedRegion(region -> { + region.freeze = freeze; + region.regionOptions.add("freeze", new JsonPrimitive(freeze)); + }); + regionOptions.add("freeze", new JsonPrimitive(freeze)); + } + + public void setFire(boolean fire) { + this.fire = fire; + setLinkedRegion(region -> { + region.fire = fire; + region.regionOptions.add("fire", new JsonPrimitive(fire)); + }); + regionOptions.add("fire", new JsonPrimitive(fire)); + } + + public void setProtect(boolean protect) { + this.protect = protect; + setLinkedRegion(region -> { + region.protect = protect; + region.regionOptions.add("protect", new JsonPrimitive(protect)); + }); + regionOptions.add("protect", new JsonPrimitive(protect)); + } + + public Point getMinPoint(RegionType regionType, RegionExtensionType regionExtensionType) { + switch (regionType) { + case BUILD: + return prototype.buildArea.getMinPoint(this, regionExtensionType); + case TESTBLOCK: + return prototype.testblock.getMinPoint(this, regionExtensionType); + default: + case NORMAL: + return prototype.getMinPoint(this, regionExtensionType); + } + } + + public Point getMaxPoint(RegionType regionType, RegionExtensionType regionExtensionType) { + switch (regionType) { + case BUILD: + return prototype.buildArea.getMaxPoint(this, regionExtensionType); + case TESTBLOCK: + return prototype.testblock.getMaxPoint(this, regionExtensionType); + default: + case NORMAL: + return prototype.getMaxPoint(this, regionExtensionType); + } + } + + public boolean inRegion(Location l, RegionType regionType, RegionExtensionType regionExtensionType) { + switch (regionType) { + case BUILD: + return prototype.buildArea.inRegion(this, l, regionExtensionType); + case TESTBLOCK: + return prototype.testblock.inRegion(this, l, regionExtensionType); + default: + case NORMAL: + return prototype.inRegion(this, l, regionExtensionType); + } + } + + public boolean hasBuildRegion() { + return prototype.buildArea != null; + } + + public void reset(SchematicNode schem, boolean ignoreAir) throws IOException, NoClipboardException { + initSessions(); + undosessions.push(prototype.reset(this, schem, ignoreAir, color)); + } + + public boolean hasTestblock() { + return prototype.hasTestblock(); + } + + public void resetTestblock(SchematicNode schem, boolean reset) throws IOException, NoClipboardException { + initSessions(); + undosessions.push(prototype.resetTestblock(this, schem, color, reset)); + } + + public boolean hasProtection() { + return prototype.hasProtection(); + } + + public void protect(SchematicNode schem) throws IOException, NoClipboardException { + initSessions(); + undosessions.push(prototype.protect(this, schem)); + } + + public int getProtectYLevel() { + return getMinPoint(RegionType.TESTBLOCK, RegionExtensionType.NORMAL).getY(); + } + + public boolean hasExtensionArea(RegionType regionType) { + switch (regionType) { + case BUILD: + return prototype.buildArea.extensionPrototypeArea; + case TESTBLOCK: + return prototype.testblock.extensionPrototypeArea; + default: + case NORMAL: + return prototype.extensionPrototypeArea; + } + } + + private void initSessions() { + if (undosessions == null) { + undosessions = new SizedStack<>(20); + redosessions = new SizedStack<>(20); + } + } + + public boolean undo() { + initSessions(); + EditSession session = null; + try { + session = undosessions.pop(); + if (session == null) { + return false; + } + session.undo(session); + redosessions.push(session); + return true; + } finally { + if (session != null) { + session.flushQueue(); + } + } + } + + public boolean redo() { + initSessions(); + EditSession session = null; + try { + session = redosessions.pop(); + if (session == null) { + return false; + } + session.redo(session); + undosessions.push(session); + return true; + } finally { + if (session != null) { + session.flushQueue(); + } + } + } + +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/RegionExtensionType.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/RegionExtensionType.java new file mode 100644 index 00000000..28be3b69 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/RegionExtensionType.java @@ -0,0 +1,25 @@ +/* + * 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.world.regions; + +public enum RegionExtensionType { + NORMAL, + EXTENSION +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/RegionSelectionType.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/RegionSelectionType.java new file mode 100644 index 00000000..40cb2f23 --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/RegionSelectionType.java @@ -0,0 +1,25 @@ +/* + * 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.world.regions; + +public enum RegionSelectionType { + GLOBAL, + LOCAL +} diff --git a/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/RegionType.java b/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/RegionType.java new file mode 100644 index 00000000..ac47eb9d --- /dev/null +++ b/LegacyBauSystem/src/de/steamwar/bausystem/world/regions/RegionType.java @@ -0,0 +1,26 @@ +/* + * 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.world.regions; + +public enum RegionType { + NORMAL, + BUILD, + TESTBLOCK +} diff --git a/LegacyBauSystem/src/plugin.yml b/LegacyBauSystem/src/plugin.yml new file mode 100644 index 00000000..cef3aacc --- /dev/null +++ b/LegacyBauSystem/src/plugin.yml @@ -0,0 +1,9 @@ +name: BauSystem +authors: [Lixfel, YoyoNow, Chaoscaot, Zeanon] +version: "1.0" +depend: [WorldEdit, SpigotCore] +load: POSTWORLD +main: de.steamwar.bausystem.BauSystem +api-version: "1.13" +website: "https://steamwar.de" +description: "So unseriös wie wir sind: BauSystem nur besser. Jaja" diff --git a/settings.gradle.kts b/settings.gradle.kts index cea601bf..87430368 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -207,6 +207,8 @@ include( include("KotlinCore") +include("LegacyBauSystem") + include("LobbySystem") include("MissileWars") diff --git a/steamwarci.yml b/steamwarci.yml index 0fa07cde..3e3660b1 100644 --- a/steamwarci.yml +++ b/steamwarci.yml @@ -4,6 +4,7 @@ build: artifacts: "/jars/BauSystem.jar": "BauSystem/build/libs/BauSystem-all.jar" + "/jars/BauSystem-1.12.jar": "LegacyBauSystem/build/libs/LegacyBauSystem.jar" "/jars/FightSystem.jar": "FightSystem/build/libs/FightSystem-all.jar" #"/binarys/FightSystem_Standalone.jar": "FightSystem/FightSystem_Standalone/build/libs/FightSystem_Standalone-all.jar" From 8ec12603b6dcb636f7a8be7ce043a58b7a2c2827 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Mon, 17 Feb 2025 17:48:26 +0100 Subject: [PATCH 026/124] Add password reset URL generation and backend validation --- .../steamwar/messages/BungeeCore.properties | 1 + .../messages/BungeeCore_de.properties | 1 + .../commands/WebpasswordCommand.java | 30 +++++++++++++------ .../src/de/steamwar/routes/v2/Auth.kt | 3 +- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties index c9527253..2315ed12 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties @@ -543,6 +543,7 @@ WEB_USAGE=§8/§7webpassword §8[§epassword§8] WEB_UPDATED=§7Your password was updated. WEB_CREATED=§7Your webaccount was created. WEB_PASSWORD_LENGTH=§cYour password is shorter than 8 characters. +WEB_RESET_URL=§7You can reset your Password here: §ehttps://steamwar.de/reset-password?token={0} #ChatListener CHAT_LIXFEL_ACTION_BAR=§4§lTechnical problems? diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties index c50cf682..cbbb3e2e 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties @@ -518,6 +518,7 @@ WEB_USAGE=§8/§7webpassword §8[§ePasswort§8] WEB_UPDATED=§7Dein Passwort wurde aktualisiert. WEB_CREATED=§7Dein Webaccount wurde erstellt. WEB_PASSWORD_LENGTH=§cDein Passwort ist kürzer als 8 Zeichen. +WEB_RESET_URL=§7Hier kannst du dein Passwort zurücksetzen: §ehttps://steamwar.de/passwort-setzen?token={0} #ChatListener CHAT_LIXFEL_ACTION_BAR=§4§lTechnische Probleme? diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/WebpasswordCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/WebpasswordCommand.java index d19dedd0..8f9b7b60 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/WebpasswordCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/WebpasswordCommand.java @@ -19,29 +19,41 @@ package de.steamwar.velocitycore.commands; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import de.steamwar.command.SWCommand; import de.steamwar.messages.Chatter; import de.steamwar.sql.SteamwarUser; +import java.net.URI; +import java.net.URLEncoder; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; + public class WebpasswordCommand extends SWCommand { public WebpasswordCommand() { super("webpassword", "webpw", "web"); } + private static final HttpClient client = HttpClient.newHttpClient(); @Register(description = "WEB_USAGE") - public void genericCommand(Chatter sender, String password) { - if(password.length() < 8) { - sender.system("WEB_PASSWORD_LENGTH"); - return; - } - + public void genericCommand(Chatter sender) { SteamwarUser user = sender.user(); - boolean resetPW = user.hasPassword(); - user.setPassword(password); + HttpRequest request = HttpRequest.newBuilder() + .POST(HttpRequest.BodyPublishers.noBody()) + .uri(URI.create("http://localhost:1337/v2/auth/enroll/" + user.getId())).build(); - sender.system(resetPW ? "WEB_UPDATED" : "WEB_CREATED"); + client.sendAsync(request, responseInfo -> HttpResponse.BodySubscribers.ofString(StandardCharsets.UTF_8)).thenAccept(httpResponse -> { + JsonObject jsonObject = JsonParser.parseString(httpResponse.body()).getAsJsonObject(); + + String token = jsonObject.get("token").getAsString(); + + sender.system("WEB_RESET_URL", URLEncoder.encode(token, StandardCharsets.UTF_8)); + }); } } diff --git a/WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt b/WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt index 24e5cee6..b854d619 100644 --- a/WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt +++ b/WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt @@ -31,7 +31,6 @@ import de.steamwar.util.type import io.ktor.http.* import io.ktor.server.application.* import io.ktor.server.auth.* -import io.ktor.server.http.* import io.ktor.server.plugins.* import io.ktor.server.request.* import io.ktor.server.response.* @@ -64,7 +63,7 @@ fun Route.configureNewAuth() { route("/auth") { route("/enroll") { post("/{userId}") { - if (call.request.headers.contains("X-Forwarded-For")) { + if (call.request.headers.contains("X-Forwarded-For") || call.request.header("Host") != "localhost:1337") { SWException.log("Request to /auth/register from", "Invalid IP") call.respond(HttpStatusCode.Forbidden, ResponseError("Invalid IP", "F_U")) return@post From 7f5b57516e65405ccd78f2aced3e79abe1f0924b Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Mon, 17 Feb 2025 18:28:43 +0100 Subject: [PATCH 027/124] Reduce access token duration and enhance auth endpoints --- .../src/de/steamwar/routes/v2/Auth.kt | 19 ++++++++++++++++--- .../src/de/steamwar/util/TokenUtils.kt | 3 +-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt b/WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt index b854d619..9d6a5181 100644 --- a/WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt +++ b/WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt @@ -115,7 +115,7 @@ fun Route.configureNewAuth() { call.respond(HttpStatusCode.OK) } route("/state") { - post("/create") { + post { val request = call.receive() val user = SteamwarUser.get(request.name) @@ -128,12 +128,12 @@ fun Route.configureNewAuth() { call.respond(user.createAccessAndRefreshToken(request.keepLoggedIn)) } - post("/refresh") { + put { val token = call.principal() if (token == null || token.token.type != TokenType.REFRESH_TOKEN) { call.respond(HttpStatusCode.Forbidden, ResponseError("Invalid token type", "invalid")) - return@post + return@put } val code = token.token.name.substringAfterLast('-') @@ -145,6 +145,19 @@ fun Route.configureNewAuth() { call.respond(token.user.createAccessAndRefreshToken(true)) } + delete { + val token = call.principal() + token?.let { t -> + t.token.delete() + val code = t.token.name.substringAfterLast('-') + Token.listUser(token.user) + .filter { it.type == TokenType.REFRESH_TOKEN } + .filter { it.name.endsWith(code) } + .forEach { it.delete() } + } + + call.respond(HttpStatusCode.OK) + } } } } \ No newline at end of file diff --git a/WebsiteBackend/src/de/steamwar/util/TokenUtils.kt b/WebsiteBackend/src/de/steamwar/util/TokenUtils.kt index 7a70c2f3..4f5f8a4f 100644 --- a/WebsiteBackend/src/de/steamwar/util/TokenUtils.kt +++ b/WebsiteBackend/src/de/steamwar/util/TokenUtils.kt @@ -23,7 +23,6 @@ import de.steamwar.sql.Token import java.time.LocalDateTime import kotlin.time.Duration import kotlin.time.Duration.Companion.days -import kotlin.time.Duration.Companion.hours import kotlin.time.Duration.Companion.minutes import kotlin.time.toJavaDuration @@ -38,7 +37,7 @@ val Token.type: TokenType val TokenType.lifetime: Duration get() = when (this) { TokenType.REFRESH_TOKEN -> 7.days - TokenType.ACCESS_TOKEN -> 1.hours + TokenType.ACCESS_TOKEN -> 5.minutes TokenType.RESET_PASSWORD -> 10.minutes TokenType.OLD_TOKEN -> 1.days } From dea0d3318521709510924e64b3cd5e7f4a2d3b34 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Thu, 20 Feb 2025 22:13:13 +0100 Subject: [PATCH 028/124] Refactor token generation and remove unused endpoints. --- .../commands/WebpasswordCommand.java | 19 +++----------- .../src/de/steamwar/routes/Routes.kt | 6 ++--- .../src/de/steamwar/routes/Stats.kt | 1 - .../src/de/steamwar/routes/v2/Auth.kt | 26 ------------------- 4 files changed, 5 insertions(+), 47 deletions(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/WebpasswordCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/WebpasswordCommand.java index 8f9b7b60..6115f47f 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/WebpasswordCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/WebpasswordCommand.java @@ -19,17 +19,13 @@ package de.steamwar.velocitycore.commands; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; import de.steamwar.command.SWCommand; import de.steamwar.messages.Chatter; import de.steamwar.sql.SteamwarUser; +import de.steamwar.sql.Token; -import java.net.URI; import java.net.URLEncoder; import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; public class WebpasswordCommand extends SWCommand { @@ -44,16 +40,7 @@ public class WebpasswordCommand extends SWCommand { public void genericCommand(Chatter sender) { SteamwarUser user = sender.user(); - HttpRequest request = HttpRequest.newBuilder() - .POST(HttpRequest.BodyPublishers.noBody()) - .uri(URI.create("http://localhost:1337/v2/auth/enroll/" + user.getId())).build(); - - client.sendAsync(request, responseInfo -> HttpResponse.BodySubscribers.ofString(StandardCharsets.UTF_8)).thenAccept(httpResponse -> { - JsonObject jsonObject = JsonParser.parseString(httpResponse.body()).getAsJsonObject(); - - String token = jsonObject.get("token").getAsString(); - - sender.system("WEB_RESET_URL", URLEncoder.encode(token, StandardCharsets.UTF_8)); - }); + String token = Token.createToken("PT" + user.getUserName(), user); + sender.system("WEB_RESET_URL", URLEncoder.encode(token, StandardCharsets.UTF_8)); } } diff --git a/WebsiteBackend/src/de/steamwar/routes/Routes.kt b/WebsiteBackend/src/de/steamwar/routes/Routes.kt index 1da4ed29..b28eef2e 100644 --- a/WebsiteBackend/src/de/steamwar/routes/Routes.kt +++ b/WebsiteBackend/src/de/steamwar/routes/Routes.kt @@ -19,7 +19,7 @@ package de.steamwar.routes -import de.steamwar.routes.v2.configureNewAuth +import de.steamwar.routes.v2.* import io.ktor.server.application.* import io.ktor.server.auth.* import io.ktor.server.routing.* @@ -35,9 +35,7 @@ fun Application.configureRoutes() { configurePage() configureSchematic() configureAuthRoutes() - route("/v2") { - configureNewAuth() - } + configureNewAuth() } } } \ No newline at end of file diff --git a/WebsiteBackend/src/de/steamwar/routes/Stats.kt b/WebsiteBackend/src/de/steamwar/routes/Stats.kt index 0c4e571b..11aa8b97 100644 --- a/WebsiteBackend/src/de/steamwar/routes/Stats.kt +++ b/WebsiteBackend/src/de/steamwar/routes/Stats.kt @@ -21,7 +21,6 @@ package de.steamwar.routes import de.steamwar.plugins.SWAuthPrincipal import de.steamwar.plugins.SWPermissionCheck -import de.steamwar.plugins.getUser import de.steamwar.sql.* import io.ktor.http.* import io.ktor.server.application.* diff --git a/WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt b/WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt index 9d6a5181..79fcd2ac 100644 --- a/WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt +++ b/WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt @@ -61,32 +61,6 @@ fun SteamwarUser.createAccessAndRefreshToken(keepLoggedIn: Boolean = false): Aut fun Route.configureNewAuth() { route("/auth") { - route("/enroll") { - post("/{userId}") { - if (call.request.headers.contains("X-Forwarded-For") || call.request.header("Host") != "localhost:1337") { - SWException.log("Request to /auth/register from", "Invalid IP") - call.respond(HttpStatusCode.Forbidden, ResponseError("Invalid IP", "F_U")) - return@post - } - - val userId = call.parameters["userId"]?.toInt() - if (userId == null) { - call.respond(HttpStatusCode.BadRequest, ResponseError("Missing or invalid userId")) - return@post - } - - val user = SteamwarUser.get(userId) - if (user == null) { - call.respond(HttpStatusCode.BadRequest, ResponseError("Invalid userId")) - return@post - } - - val token = Token.createToken("PT-${user.userName}", user) - - call.respond(HttpStatusCode.OK, ResponseToken(token, TokenType.RESET_PASSWORD.lifetime)) - } - } - post("/register") { val requester = call.request.header("X-Forwarded-For") ?: call.request.origin.remoteAddress From b045f16160cb66478dc9b03fabbfec281b0294de Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Thu, 20 Feb 2025 22:40:18 +0100 Subject: [PATCH 029/124] Remove deprecated configureAuthRoutes function call --- WebsiteBackend/src/de/steamwar/routes/Routes.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/WebsiteBackend/src/de/steamwar/routes/Routes.kt b/WebsiteBackend/src/de/steamwar/routes/Routes.kt index b28eef2e..f0e287f0 100644 --- a/WebsiteBackend/src/de/steamwar/routes/Routes.kt +++ b/WebsiteBackend/src/de/steamwar/routes/Routes.kt @@ -34,7 +34,6 @@ fun Application.configureRoutes() { configureStats() configurePage() configureSchematic() - configureAuthRoutes() configureNewAuth() } } From a2b3661605fae6afe061f848684daf1270229bd9 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 23 Feb 2025 17:24:14 +0100 Subject: [PATCH 030/124] Refactor V2 Auth --- .../velocitycore/listeners/ChatListener.java | 10 +- .../src/de/steamwar/plugins/Plugins.kt | 2 +- WebsiteBackend/src/de/steamwar/routes/Auth.kt | 87 ++++++----- .../src/de/steamwar/routes/Routes.kt | 3 +- .../src/de/steamwar/routes/v2/Auth.kt | 137 ------------------ .../src/de/steamwar/util/TokenUtils.kt | 3 - 6 files changed, 60 insertions(+), 182 deletions(-) delete mode 100644 WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt diff --git a/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java b/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java index 0445be62..daccaa9f 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java +++ b/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java @@ -42,6 +42,7 @@ import de.steamwar.velocitycore.network.NetworkSender; import java.util.Arrays; import java.util.List; +import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; @@ -53,6 +54,8 @@ public class ChatListener extends BasicListener { private static final List rankedModes = ArenaMode.getAllModes().stream().filter(ArenaMode::isRanked).map(ArenaMode::getSchemTypeOrInternalName).toList(); + private static final Set noLogCommands = Set.of("webpw", "webpassword"); + @Subscribe(order = PostOrder.FIRST) public void fixCommands(CommandExecuteEvent e) { String command = e.getCommand(); @@ -73,7 +76,8 @@ public class ChatListener extends BasicListener { public void logCommands(CommandExecuteEvent e) { String command = e.getCommand(); int space = command.indexOf(' '); - if(VelocityCore.getProxy().getCommandManager().hasCommand(space != -1 ? command.substring(0, space) : command)) { + String cmd = space != -1 ? command.substring(0, space) : command; + if(VelocityCore.getProxy().getCommandManager().hasCommand(cmd)) { CommandSource source = e.getCommandSource(); String name; if(source instanceof Player player) @@ -83,6 +87,10 @@ public class ChatListener extends BasicListener { else name = source.toString(); + if (noLogCommands.contains(cmd)) { + return; + } + cmdLogger.log(Level.INFO, "%s -> executed command /%s".formatted(name, command)); } else if (e.getCommandSource() instanceof Player player) { // System.out.println("spoofChatInput " + e); diff --git a/WebsiteBackend/src/de/steamwar/plugins/Plugins.kt b/WebsiteBackend/src/de/steamwar/plugins/Plugins.kt index 0cff0a03..95389abe 100644 --- a/WebsiteBackend/src/de/steamwar/plugins/Plugins.kt +++ b/WebsiteBackend/src/de/steamwar/plugins/Plugins.kt @@ -74,7 +74,7 @@ fun Application.configurePlugins() { token.delete() return@authenticate null } - if (token.type == TokenType.RESET_PASSWORD || token.type == TokenType.REFRESH_TOKEN) { + if (token.type == TokenType.REFRESH_TOKEN) { token.delete() } diff --git a/WebsiteBackend/src/de/steamwar/routes/Auth.kt b/WebsiteBackend/src/de/steamwar/routes/Auth.kt index 52238c32..e76ae47b 100644 --- a/WebsiteBackend/src/de/steamwar/routes/Auth.kt +++ b/WebsiteBackend/src/de/steamwar/routes/Auth.kt @@ -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 @@ -21,9 +21,11 @@ package de.steamwar.routes import de.steamwar.ResponseError import de.steamwar.plugins.SWAuthPrincipal -import de.steamwar.plugins.SWPermissionCheck import de.steamwar.sql.SteamwarUser import de.steamwar.sql.Token +import de.steamwar.util.TokenType +import de.steamwar.util.lifetime +import de.steamwar.util.type import io.ktor.http.* import io.ktor.server.application.* import io.ktor.server.auth.* @@ -31,64 +33,73 @@ import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* import kotlinx.serialization.Serializable -import java.time.format.DateTimeFormatter import java.time.LocalDateTime +import kotlin.time.Duration +import kotlin.time.toJavaDuration @Serializable -data class AuthLoginRequest(val username: String, val password: String) +data class UsernamePassword(val name: String, val password: String, val keepLoggedIn: Boolean = false) @Serializable -data class AuthTokenResponse(val token: String) - -@Serializable -data class ResponseToken(val id: Int, val name: String, val created: String) { - constructor(token: Token) : this(token.id, token.name, token.created.toLocalDateTime().toString()) +data class ResponseToken(val token: String, val expires: String) { + constructor(token: String, lifetime: Duration) : this(token, LocalDateTime.now().plus(lifetime.toJavaDuration()).toString()) } @Serializable -data class CreateTokenRequest(val name: String, val password: String) +data class AuthTokenResponse(val accessToken: ResponseToken, val refreshToken: ResponseToken? = null) -fun Route.configureAuthRoutes() { +fun SteamwarUser.createAccessAndRefreshToken(keepLoggedIn: Boolean = false): AuthTokenResponse { + val code = System.currentTimeMillis() % 1000 + val accessToken = Token.createToken("AT-${userName}-${code}", this) + val refreshToken = if (keepLoggedIn) Token.createToken("RT-${userName}-${code}", this) else null + + return AuthTokenResponse(ResponseToken(accessToken, TokenType.ACCESS_TOKEN.lifetime), refreshToken?.let { ResponseToken(it, TokenType.REFRESH_TOKEN.lifetime) }) +} + +fun Route.configureAuth() { route("/auth") { - post("/login") { - if (call.principal() != null) { - call.respond(HttpStatusCode.Forbidden, ResponseError("Already logged in", "already_logged_in")) - return@post - } + post { + val request = call.receive() - val request = call.receive() + val user = SteamwarUser.get(request.name) + val valid = user?.verifyPassword(request.password) ?: false - val user = SteamwarUser.get(request.username) - - if (user == null) { + if (!valid) { call.respond(HttpStatusCode.Forbidden, ResponseError("Invalid username or password", "invalid")) return@post } - if (!user.verifyPassword(request.password)) { - call.respond(HttpStatusCode.Forbidden, ResponseError("Invalid username or password", "invalid")) - return@post - } - - val code = Token.createToken("Website: ${DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(LocalDateTime.now())}", user) - call.respond(AuthTokenResponse(code)) + call.respond(user.createAccessAndRefreshToken(request.keepLoggedIn)) } - route("/tokens") { - install(SWPermissionCheck) { - mustAuth = true + put { + val token = call.principal() + + if (token == null || token.token.type != TokenType.REFRESH_TOKEN) { + call.respond(HttpStatusCode.Forbidden, ResponseError("Invalid token type", "invalid")) + return@put } - post("/logout") { - val auth = call.principal() + val code = token.token.name.substringAfterLast('-') - if(auth == null) { - call.respond(HttpStatusCode.InternalServerError) - return@post - } + Token.listUser(token.user) + .filter { it.type == TokenType.ACCESS_TOKEN } + .filter { it.name.endsWith(code) } + .forEach { it.delete() } - auth.token.delete() - call.respond(HttpStatusCode.OK) + call.respond(token.user.createAccessAndRefreshToken(true)) + } + delete { + val token = call.principal() + token?.let { t -> + t.token.delete() + val code = t.token.name.substringAfterLast('-') + Token.listUser(token.user) + .filter { it.type == TokenType.REFRESH_TOKEN } + .filter { it.name.endsWith(code) } + .forEach { it.delete() } } + + call.respond(HttpStatusCode.OK) } } } \ No newline at end of file diff --git a/WebsiteBackend/src/de/steamwar/routes/Routes.kt b/WebsiteBackend/src/de/steamwar/routes/Routes.kt index f0e287f0..388f8055 100644 --- a/WebsiteBackend/src/de/steamwar/routes/Routes.kt +++ b/WebsiteBackend/src/de/steamwar/routes/Routes.kt @@ -19,7 +19,6 @@ package de.steamwar.routes -import de.steamwar.routes.v2.* import io.ktor.server.application.* import io.ktor.server.auth.* import io.ktor.server.routing.* @@ -34,7 +33,7 @@ fun Application.configureRoutes() { configureStats() configurePage() configureSchematic() - configureNewAuth() + configureAuth() } } } \ No newline at end of file diff --git a/WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt b/WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt deleted file mode 100644 index 79fcd2ac..00000000 --- a/WebsiteBackend/src/de/steamwar/routes/v2/Auth.kt +++ /dev/null @@ -1,137 +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.routes.v2 - -import de.steamwar.ResponseError -import de.steamwar.plugins.SWAuthPrincipal -import de.steamwar.sql.SWException -import de.steamwar.sql.SteamwarUser -import de.steamwar.sql.Token -import de.steamwar.util.TokenType -import de.steamwar.util.isValid -import de.steamwar.util.lifetime -import de.steamwar.util.type -import io.ktor.http.* -import io.ktor.server.application.* -import io.ktor.server.auth.* -import io.ktor.server.plugins.* -import io.ktor.server.request.* -import io.ktor.server.response.* -import io.ktor.server.routing.* -import kotlinx.serialization.Serializable -import java.time.LocalDateTime -import kotlin.time.Duration -import kotlin.time.toJavaDuration - -@Serializable -data class UsernamePassword(val name: String, val password: String, val keepLoggedIn: Boolean = false) - -@Serializable -data class ResponseToken(val token: String, val expires: String) { - constructor(token: String, lifetime: Duration) : this(token, LocalDateTime.now().plus(lifetime.toJavaDuration()).toString()) -} - -@Serializable -data class AuthTokenResponse(val accessToken: ResponseToken, val refreshToken: ResponseToken? = null) - -fun SteamwarUser.createAccessAndRefreshToken(keepLoggedIn: Boolean = false): AuthTokenResponse { - val code = System.currentTimeMillis() % 1000 - val accessToken = Token.createToken("AT-${userName}-${code}", this) - val refreshToken = if (keepLoggedIn) Token.createToken("RT-${userName}-${code}", this) else null - - return AuthTokenResponse(ResponseToken(accessToken, TokenType.ACCESS_TOKEN.lifetime), refreshToken?.let { ResponseToken(it, TokenType.REFRESH_TOKEN.lifetime) }) -} - -fun Route.configureNewAuth() { - route("/auth") { - post("/register") { - val requester = call.request.header("X-Forwarded-For") ?: call.request.origin.remoteAddress - - val request = call.receive() - val token = call.principal() - - if (token == null || token.token.type != TokenType.RESET_PASSWORD || !token.token.isValid) { - SWException.log("$requester tried registering with invalid token", "") - call.respond(HttpStatusCode.Forbidden, ResponseError("Invalid token", "invalid")) - return@post - } - - val user = token.user - - if (user.userName != request.name) { - SWException.log("$requester tried registering for invalid User", """ - User: ${user.userName} - Request: ${request.name} - """.trimIndent()) - call.respond(HttpStatusCode.Forbidden, ResponseError("Invalid username", "invalid")) - return@post - } - - user.setPassword(request.password) - - call.respond(HttpStatusCode.OK) - } - route("/state") { - post { - val request = call.receive() - - val user = SteamwarUser.get(request.name) - val valid = user?.verifyPassword(request.password) ?: false - - if (!valid) { - call.respond(HttpStatusCode.Forbidden, ResponseError("Invalid username or password", "invalid")) - return@post - } - - call.respond(user.createAccessAndRefreshToken(request.keepLoggedIn)) - } - put { - val token = call.principal() - - if (token == null || token.token.type != TokenType.REFRESH_TOKEN) { - call.respond(HttpStatusCode.Forbidden, ResponseError("Invalid token type", "invalid")) - return@put - } - - val code = token.token.name.substringAfterLast('-') - - Token.listUser(token.user) - .filter { it.type == TokenType.ACCESS_TOKEN } - .filter { it.name.endsWith(code) } - .forEach { it.delete() } - - call.respond(token.user.createAccessAndRefreshToken(true)) - } - delete { - val token = call.principal() - token?.let { t -> - t.token.delete() - val code = t.token.name.substringAfterLast('-') - Token.listUser(token.user) - .filter { it.type == TokenType.REFRESH_TOKEN } - .filter { it.name.endsWith(code) } - .forEach { it.delete() } - } - - call.respond(HttpStatusCode.OK) - } - } - } -} \ No newline at end of file diff --git a/WebsiteBackend/src/de/steamwar/util/TokenUtils.kt b/WebsiteBackend/src/de/steamwar/util/TokenUtils.kt index 4f5f8a4f..54675dd0 100644 --- a/WebsiteBackend/src/de/steamwar/util/TokenUtils.kt +++ b/WebsiteBackend/src/de/steamwar/util/TokenUtils.kt @@ -30,7 +30,6 @@ val Token.type: TokenType get() = when (name.substring((0..1))) { "RT" -> TokenType.REFRESH_TOKEN "AT" -> TokenType.ACCESS_TOKEN - "PT" -> TokenType.RESET_PASSWORD else -> TokenType.OLD_TOKEN } @@ -38,7 +37,6 @@ val TokenType.lifetime: Duration get() = when (this) { TokenType.REFRESH_TOKEN -> 7.days TokenType.ACCESS_TOKEN -> 5.minutes - TokenType.RESET_PASSWORD -> 10.minutes TokenType.OLD_TOKEN -> 1.days } @@ -49,7 +47,6 @@ val Token.isValid: Boolean get() = created.toLocalDateTime().plus(lifetime.toJavaDuration()).isAfter(LocalDateTime.now()) enum class TokenType { - RESET_PASSWORD, ACCESS_TOKEN, REFRESH_TOKEN, OLD_TOKEN From fd8270741428dffdd46d156e8c6e2cef4052b404 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 23 Feb 2025 17:27:29 +0100 Subject: [PATCH 031/124] Update `webpassword` command and clean up deprecated logic --- .../steamwar/messages/BungeeCore.properties | 1 - .../messages/BungeeCore_de.properties | 1 - .../commands/WebpasswordCommand.java | 21 ++++++++++--------- .../velocitycore/listeners/ChatListener.java | 2 +- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties index 2315ed12..c9527253 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties @@ -543,7 +543,6 @@ WEB_USAGE=§8/§7webpassword §8[§epassword§8] WEB_UPDATED=§7Your password was updated. WEB_CREATED=§7Your webaccount was created. WEB_PASSWORD_LENGTH=§cYour password is shorter than 8 characters. -WEB_RESET_URL=§7You can reset your Password here: §ehttps://steamwar.de/reset-password?token={0} #ChatListener CHAT_LIXFEL_ACTION_BAR=§4§lTechnical problems? diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties index cbbb3e2e..c50cf682 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties @@ -518,7 +518,6 @@ WEB_USAGE=§8/§7webpassword §8[§ePasswort§8] WEB_UPDATED=§7Dein Passwort wurde aktualisiert. WEB_CREATED=§7Dein Webaccount wurde erstellt. WEB_PASSWORD_LENGTH=§cDein Passwort ist kürzer als 8 Zeichen. -WEB_RESET_URL=§7Hier kannst du dein Passwort zurücksetzen: §ehttps://steamwar.de/passwort-setzen?token={0} #ChatListener CHAT_LIXFEL_ACTION_BAR=§4§lTechnische Probleme? diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/WebpasswordCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/WebpasswordCommand.java index 6115f47f..d19dedd0 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/WebpasswordCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/WebpasswordCommand.java @@ -22,11 +22,6 @@ package de.steamwar.velocitycore.commands; import de.steamwar.command.SWCommand; import de.steamwar.messages.Chatter; import de.steamwar.sql.SteamwarUser; -import de.steamwar.sql.Token; - -import java.net.URLEncoder; -import java.net.http.HttpClient; -import java.nio.charset.StandardCharsets; public class WebpasswordCommand extends SWCommand { @@ -34,13 +29,19 @@ public class WebpasswordCommand extends SWCommand { super("webpassword", "webpw", "web"); } - private static final HttpClient client = HttpClient.newHttpClient(); @Register(description = "WEB_USAGE") - public void genericCommand(Chatter sender) { - SteamwarUser user = sender.user(); + public void genericCommand(Chatter sender, String password) { + if(password.length() < 8) { + sender.system("WEB_PASSWORD_LENGTH"); + return; + } - String token = Token.createToken("PT" + user.getUserName(), user); - sender.system("WEB_RESET_URL", URLEncoder.encode(token, StandardCharsets.UTF_8)); + SteamwarUser user = sender.user(); + boolean resetPW = user.hasPassword(); + + user.setPassword(password); + + sender.system(resetPW ? "WEB_UPDATED" : "WEB_CREATED"); } } diff --git a/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java b/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java index daccaa9f..17137bf5 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java +++ b/VelocityCore/src/de/steamwar/velocitycore/listeners/ChatListener.java @@ -54,7 +54,7 @@ public class ChatListener extends BasicListener { private static final List rankedModes = ArenaMode.getAllModes().stream().filter(ArenaMode::isRanked).map(ArenaMode::getSchemTypeOrInternalName).toList(); - private static final Set noLogCommands = Set.of("webpw", "webpassword"); + private static final Set noLogCommands = Set.of("webpw", "webpassword", "web"); @Subscribe(order = PostOrder.FIRST) public void fixCommands(CommandExecuteEvent e) { From ce907389df19de8b9558e9121a9427ff5e0687a2 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Tue, 25 Feb 2025 22:46:54 +0100 Subject: [PATCH 032/124] Refactor SQL query to remove schema qualifiers. --- WebsiteBackend/src/de/steamwar/sql/Stats.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebsiteBackend/src/de/steamwar/sql/Stats.kt b/WebsiteBackend/src/de/steamwar/sql/Stats.kt index d8beb867..e248a0df 100644 --- a/WebsiteBackend/src/de/steamwar/sql/Stats.kt +++ b/WebsiteBackend/src/de/steamwar/sql/Stats.kt @@ -34,7 +34,7 @@ private val eventFightParticipation = Statement("SELECT FightPlayer.UserID, COUN fun getEventFightParticipation(user: SteamwarUser): Int? = eventFightParticipation.select(getNum, user.id) -private val eventParticipation = Statement("SELECT FightPlayer.UserID, COUNT(DISTINCT EventID) as num FROM FightPlayer INNER JOIN core.Fight F on FightPlayer.FightID = F.FightID INNER JOIN core.EventFight EF on F.FightID = EF.Fight WHERE F.FightID = FightPlayer.FightID AND FightPlayer.FightID = EF.Fight AND F.Server LIKE '%vs%' AND FightPlayer.UserID = ? GROUP BY FightPlayer.UserID") +private val eventParticipation = Statement("SELECT FightPlayer.UserID, COUNT(DISTINCT EventID) as num FROM FightPlayer INNER JOIN Fight F on FightPlayer.FightID = F.FightID INNER JOIN EventFight EF on F.FightID = EF.Fight WHERE F.FightID = FightPlayer.FightID AND FightPlayer.FightID = EF.Fight AND F.Server LIKE '%vs%' AND FightPlayer.UserID = ? GROUP BY FightPlayer.UserID") fun getEventParticipation(user: SteamwarUser): Int? = eventParticipation.select(getNum, user.id) From ade9a1b5eb0df262bd0e07cba6c135fba79de6c6 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Sat, 1 Mar 2025 08:32:19 +0100 Subject: [PATCH 033/124] Allow TNT in shulker boxes --- .../schematicsystem/autocheck/AutoChecker15.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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 e0823263..9dd5e456 100644 --- a/SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/autocheck/AutoChecker15.java +++ b/SchematicSystem/SchematicSystem_15/src/de/steamwar/schematicsystem/autocheck/AutoChecker15.java @@ -115,7 +115,14 @@ public class AutoChecker15 implements AutoChecker.IAutoChecker { static { itemsInInv.put(Material.BUCKET, EnumSet.of(Material.DISPENSER)); - itemsInInv.put(Material.TNT, EnumSet.of(Material.CHEST, Material.BARREL)); + 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)); From e3c02cfb60deb799e0d9c9cab71f6b0fd7dfc7e4 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Sat, 1 Mar 2025 08:33:15 +0100 Subject: [PATCH 034/124] Revert "Update VV dependency version" This reverts commit 9f108a7cea8766146c1be1bebba40ec70b4726f9. --- settings.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index cd1db040..cea601bf 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -137,8 +137,8 @@ dependencyResolutionManagement { library("velocity", "de.steamwar:velocity:RELEASE") library("velocityapi", "com.velocitypowered:velocity-api:3.3.0-SNAPSHOT") - library("viaapi", "com.viaversion:viaversion-api:5.2.1") - library("viavelocity", "com.viaversion:viaversion-velocity:5.2.1") + 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("msgpack", "org.msgpack:msgpack-core:0.9.8") library("apolloprotos", "com.lunarclient:apollo-protos:1.0-SNAPSHOT") From 96a4168f379a2f095a1d7dbe6223e21856cb7c7b Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 1 Mar 2025 21:40:54 +0100 Subject: [PATCH 035/124] Add event count to Team info --- VelocityCore/src/de/steamwar/messages/BungeeCore.properties | 2 +- VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties | 2 +- .../src/de/steamwar/velocitycore/commands/TeamCommand.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties index c9527253..8f288592 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties @@ -494,7 +494,7 @@ TEAM_INFO_USAGE=§8/§7team info §8[§eTeamname§8] TEAM_INFO_TEAM=§7Team §e{0} §8[§{1}{2}§8] TEAM_INFO_LEADER=§7Leader ({0})§8: {1} TEAM_INFO_MEMBER=§7Member ({0})§8: {1} -TEAM_INFO_EVENTS=§7Events§8: §e{0} +TEAM_INFO_EVENTS=§7Events ({0})§8: §e{1} #Team List TEAM_LIST_NOT_PAGE=§cNo page number entered diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties index c50cf682..34ecb20f 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties @@ -468,7 +468,7 @@ TEAM_INFO_USAGE=§8/§7team info §8[§eTeamname§8] TEAM_INFO_TEAM=§7Team §e{0} §8[§{1}{2}§8] TEAM_INFO_LEADER=§7Leader ({0})§8: {1} TEAM_INFO_MEMBER=§7Member ({0})§8: {1} -TEAM_INFO_EVENTS=§7Events§8: §e{0} +TEAM_INFO_EVENTS=§7Events ({0})§8: §e{1} #Team List TEAM_LIST_NOT_PAGE=§cKeine Seitenzahl angegeben diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/TeamCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/TeamCommand.java index 928d6e78..0dd865b1 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/TeamCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/TeamCommand.java @@ -301,7 +301,7 @@ public class TeamCommand extends SWCommand { Set events = TeamTeilnahme.getEvents(team.getTeamId()); if(!events.isEmpty()){ - sender.prefixless("TEAM_INFO_EVENTS", events.stream().map(Event::getEventName).collect(Collectors.joining(", "))); + sender.prefixless("TEAM_INFO_EVENTS", events.size(), events.stream().map(Event::getEventName).collect(Collectors.joining(", "))); } } From b0bd7196274f428afce7ba9278860378816aa33c Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 2 Mar 2025 09:08:49 +0100 Subject: [PATCH 036/124] Backend Fixes --- WebsiteBackend/src/de/steamwar/routes/Data.kt | 3 ++- WebsiteBackend/src/de/steamwar/routes/Events.kt | 2 +- WebsiteBackend/src/de/steamwar/routes/UserPerms.kt | 5 +++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/WebsiteBackend/src/de/steamwar/routes/Data.kt b/WebsiteBackend/src/de/steamwar/routes/Data.kt index 103fb044..0a2dd3ae 100644 --- a/WebsiteBackend/src/de/steamwar/routes/Data.kt +++ b/WebsiteBackend/src/de/steamwar/routes/Data.kt @@ -45,7 +45,7 @@ data class ResponseSchematicType(val name: String, val db: String) @Serializable data class ResponseUser(val name: String, val uuid: String, val prefix: String, val perms: List) { - constructor(user: SteamwarUser) : this(user.userName, user.uuid.toString(), user.prefix().chatPrefix, user.perms().map { it.name }) { + constructor(user: SteamwarUser) : this(user.userName, user.uuid.toString(), user.prefix().chatPrefix, user.perms().filter { !it.name.startsWith("PREFIX_") }.map { it.name }) { synchronized(cache) { cache[user.id] = this } @@ -149,5 +149,6 @@ fun Route.configureDataRoutes() { inline fun catchException(yield: () -> T): T? = try { yield() } catch (e: Exception) { + e.printStackTrace() null } diff --git a/WebsiteBackend/src/de/steamwar/routes/Events.kt b/WebsiteBackend/src/de/steamwar/routes/Events.kt index d1edcf07..d40cdd3b 100644 --- a/WebsiteBackend/src/de/steamwar/routes/Events.kt +++ b/WebsiteBackend/src/de/steamwar/routes/Events.kt @@ -215,7 +215,7 @@ fun Route.configureEventsRoute() { } } event.update(eventName, deadline, start, end, schemType, maxTeamMembers, publicSchemsOnly) - call.respond(ResponseEvent(event)) + call.respond(ResponseEvent(Event.get(event.eventID))) } delete { val id = call.parameters["id"]?.toIntOrNull() diff --git a/WebsiteBackend/src/de/steamwar/routes/UserPerms.kt b/WebsiteBackend/src/de/steamwar/routes/UserPerms.kt index 2befc916..c1558787 100644 --- a/WebsiteBackend/src/de/steamwar/routes/UserPerms.kt +++ b/WebsiteBackend/src/de/steamwar/routes/UserPerms.kt @@ -79,7 +79,7 @@ fun Route.configureUserPerms() { call.respond(RespondUserPermsPrefix(RespondPrefix(prefix.name, prefixs.colorCode, prefixs.chatPrefix), perms)) } put("/prefix/{prefix}") { - val (user, prefix) = call.receivePermission("prefix") ?: return@put + val (user, prefix) = call.receivePermission("prefix", isPrefix = true) ?: return@put user.perms().filter { it.name.startsWith("PREFIX_") }.forEach { UserPerm.removePerm(user, it) @@ -121,7 +121,8 @@ suspend fun ApplicationCall.receivePermission(fieldName: String = "perm", isPref val perm = parameters[fieldName] val permission = UserPerm.entries.find { it.name == perm } - if (perm == null || perm.startsWith("PREFIX_") == isPrefix || permission == null) { + if (perm == null || perm.startsWith("PREFIX_") != isPrefix || permission == null) { + println(perm) respond(HttpStatusCode.BadRequest) return null } From 2d28cc6182d8bff9877d4be2db8ba4249b8b5fc2 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 2 Mar 2025 14:58:26 +0100 Subject: [PATCH 037/124] Fix isEvent function to correctly check eventFightId --- TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt index 7b1e865a..6f7ca84a 100644 --- a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt +++ b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt @@ -87,7 +87,7 @@ data class TNTLeagueConfig( }.mapKeys { Material.getMaterial(it.key) ?: Material.BARRIER } } - fun isEvent() = config.eventFightId != null + fun isEvent() = (config.eventFightId ?: 0) > 0 } data class Price( From 2fad352f6233553754b69eb10c2d3eece83890b1 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 2 Mar 2025 15:02:11 +0100 Subject: [PATCH 038/124] Fix event initialization check in TNTLeagueConfig --- TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt index 6f7ca84a..d3d75592 100644 --- a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt +++ b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt @@ -52,7 +52,7 @@ data class TNTLeagueConfig( val redTeam: TeamConfig init { - if (eventFightId != null) { + if (isEvent() && eventFightId != null) { eventFight = EventFight.get(eventFightId) ?: throw IllegalArgumentException("EventFight with ID $eventFightId not found") event = Event.get(eventFight.eventID) From 6d4ae9593d4e8ba28749ccf9b926f9bea080aa0f Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 2 Mar 2025 15:14:10 +0100 Subject: [PATCH 039/124] Refine eventFight ID check in TNTLeagueConfig initialization. --- TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt index d3d75592..a44fe7d5 100644 --- a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt +++ b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt @@ -52,7 +52,7 @@ data class TNTLeagueConfig( val redTeam: TeamConfig init { - if (isEvent() && eventFightId != null) { + if (eventFightId != null && eventFightId > 0) { eventFight = EventFight.get(eventFightId) ?: throw IllegalArgumentException("EventFight with ID $eventFightId not found") event = Event.get(eventFight.eventID) From 8b49b8a73653e8b7e7452689a322b64919a29e01 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 2 Mar 2025 15:31:33 +0100 Subject: [PATCH 040/124] Add player respawn handling with custom spawn location --- .../de/steamwar/towerrun/listener/GlobalListener.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/TowerRun/src/de/steamwar/towerrun/listener/GlobalListener.java b/TowerRun/src/de/steamwar/towerrun/listener/GlobalListener.java index b8256d80..5c2956b2 100644 --- a/TowerRun/src/de/steamwar/towerrun/listener/GlobalListener.java +++ b/TowerRun/src/de/steamwar/towerrun/listener/GlobalListener.java @@ -26,14 +26,17 @@ import de.steamwar.towerrun.state.GameStateBukkitListener; import de.steamwar.towerrun.state.GameStates; import org.bukkit.Bukkit; 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 java.util.EnumSet; -public class GlobalListener extends GameStateBukkitListener { +public class GlobalListener extends GameStateBukkitListener implements Listener { public GlobalListener() { super(EnumSet.allOf(GameStates.class)); } @@ -59,4 +62,9 @@ public class GlobalListener extends GameStateBukkitListener { event.setCancelled(true); } + + @EventHandler + public void onPlayerRespawn(PlayerRespawnEvent event) { + event.setRespawnLocation(WorldConfig.SPAWN); + } } From af55c946a6892cd600e00c56065e7d8a55fbe855 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 2 Mar 2025 18:51:01 +0100 Subject: [PATCH 041/124] Remove player length constraint --- .../src/de/steamwar/velocitycore/commands/SendCommand.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java index 77cd2193..5480f277 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java @@ -39,15 +39,14 @@ import java.util.stream.Collectors; public class SendCommand extends SWCommand { - // /send to only [] - // can also be current + // /send [] public SendCommand() { super("send", UserPerm.TEAM); } - @Register("to") - public void sendCommand(Chatter sender, RegisteredServer toServer, @ArrayLength(min = 1) Player... players) { + @Register + public void sendCommand(Chatter sender, RegisteredServer toServer, Player... players) { for (Player player : players) { player.createConnectionRequest(toServer).fireAndForget(); } From f0beb22856980f1d37355a91a1debc8a536d51bf Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 2 Mar 2025 18:54:59 +0100 Subject: [PATCH 042/124] Hotfix the "to" back in --- .../src/de/steamwar/velocitycore/commands/SendCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java index 5480f277..8d8fa415 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java @@ -45,7 +45,7 @@ public class SendCommand extends SWCommand { super("send", UserPerm.TEAM); } - @Register + @Register("to") public void sendCommand(Chatter sender, RegisteredServer toServer, Player... players) { for (Player player : players) { player.createConnectionRequest(toServer).fireAndForget(); From 85c0db873c34db51e48ae030be6d888ee3cbfcd4 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 2 Mar 2025 19:09:59 +0100 Subject: [PATCH 043/124] Final Hotfix of Send Command! --- .../steamwar/messages/BungeeCore.properties | 4 ++ .../messages/BungeeCore_de.properties | 4 ++ .../velocitycore/commands/SendCommand.java | 40 ++++++++++++++----- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties index 8f288592..863d1099 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore.properties @@ -127,6 +127,10 @@ HELP_BAU_LOCK_HOVER=§eLock your build server HELP_BAU_UNLOCK=§8/§ebuild unlock §8- §7Unlocks the buildserver for added users HELP_BAU_UNLOCK_HOVER=§eUnlock your build server +#Send Command +SEND_MESSAGE=§e{0}§7 send you to §e{1}§8! +SEND_MESSAGE_SELF=§eYou§7 send §e{0}§7 to §e{1}§8! + #Usage description of various commands USAGE_ALERT=§8/§7alert §8[§emessage§8] USAGE_IGNORE=§8/§7ignore §8[§eplayer§8] diff --git a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties index 34ecb20f..b758353c 100644 --- a/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties +++ b/VelocityCore/src/de/steamwar/messages/BungeeCore_de.properties @@ -112,6 +112,10 @@ HELP_BAU_LOCK_HOVER=§eSperre deinen Bau HELP_BAU_UNLOCK=§8/§ebau unlock §8- §7Öffne deinen Bauserver für alle hinzugefügten Spieler HELP_BAU_UNLOCK_HOVER=§eÖffne deinen Bau +#Send Command +SEND_MESSAGE=§e{0}§7 hat dich auf §e{1}§7 gesendet§8! +SEND_MESSAGE_SELF=§eDu§7 hast §e{0}§7 auf §e{1}§7 gesendet§8! + #Usage description of various commands USAGE_ALERT=§8/§7alert §8[§eNachricht§8] USAGE_IGNORE=§8/§7ignore §8[§eSpieler§8] diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java index 8d8fa415..1a5ba9f5 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java @@ -27,6 +27,7 @@ import de.steamwar.command.PreviousArguments; import de.steamwar.command.SWCommand; import de.steamwar.command.TypeMapper; import de.steamwar.messages.Chatter; +import de.steamwar.messages.Message; import de.steamwar.persistent.Subserver; import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.UserPerm; @@ -47,24 +48,27 @@ public class SendCommand extends SWCommand { @Register("to") public void sendCommand(Chatter sender, RegisteredServer toServer, Player... players) { + String serverName = toServer.getServerInfo().getName(); for (Player player : players) { player.createConnectionRequest(toServer).fireAndForget(); + Chatter.of(player).send(true, null, null, new Message("SEND_MESSAGE", sender.user().getUserName(), serverName)); } + sender.send(true, null, null, new Message("SEND_MESSAGE_SELF", players.length, serverName)); + } + + private boolean check(SteamwarUser user, RegisteredServer registeredServer) { + if (registeredServer == null) return false; + ServerInfo serverInfo = registeredServer.getServerInfo(); + String name = serverInfo.getName(); + if (name.contains(" ")) return false; + + Subserver subserver = Subserver.getSubserver(serverInfo); + return subserver == null || Subserver.isArena(subserver) || (Subserver.isBuilder(subserver) && user.hasPerm(UserPerm.BUILD)); } @ClassMapper(value = RegisteredServer.class, local = true) public TypeMapper subserverTypeMapper() { return new TypeMapper<>() { - private boolean check(SteamwarUser user, RegisteredServer registeredServer) { - if (registeredServer == null) return false; - ServerInfo serverInfo = registeredServer.getServerInfo(); - String name = serverInfo.getName(); - if (name.contains(" ")) return false; - - Subserver subserver = Subserver.getSubserver(serverInfo); - return subserver == null || Subserver.isArena(subserver) || (Subserver.isBuilder(subserver) && user.hasPerm(UserPerm.BUILD)); - } - @Override public RegisteredServer map(Chatter sender, PreviousArguments previousArguments, String s) { SteamwarUser user = sender.user(); @@ -115,12 +119,26 @@ public class SendCommand extends SWCommand { return VelocityCore.getProxy().getPlayer(s).orElse(null); } + @Override + public boolean validate(Chatter sender, Player value, MessageSender messageSender) { + SteamwarUser user = sender.user(); + if (user.hasPerm(UserPerm.ADMINISTRATION)) return true; + return check(user, value.getCurrentServer().map(ServerConnection::getServer).orElse(null)); + } + @Override public Collection tabCompletes(Chatter sender, PreviousArguments previousArguments, String s) { List previous = previousArguments.getAll(RegisteredServer.class); if (previous.isEmpty()) return null; + SteamwarUser user = sender.user(); Collection players = previous.get(0).getPlayersConnected(); - return VelocityCore.getProxy().getAllPlayers().stream().filter(player -> !players.contains(player)).map(Player::getUsername).collect(Collectors.toList()); + return VelocityCore.getProxy() + .getAllPlayers() + .stream() + .filter(player -> !players.contains(player)) + .filter(player -> user.hasPerm(UserPerm.ADMINISTRATION) || check(user, player.getCurrentServer().map(ServerConnection::getServer).orElse(null))) + .map(Player::getUsername) + .collect(Collectors.toList()); } }; } From 0a60654a28468fe29168bef295de1c8dbd2241bc Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Mon, 3 Mar 2025 09:35:42 +0100 Subject: [PATCH 044/124] Add some of the Easter Particles --- .../de/steamwar/lobby/LobbySystem.properties | 13 ++- .../steamwar/lobby/LobbySystem_de.properties | 4 +- .../de/steamwar/lobby/particle/Gradient.java | 53 +++++++++++ .../lobby/particle/ParticleElement.java | 4 + .../steamwar/lobby/particle/WingDesign.java | 6 ++ .../steamwar/lobby/particle/decorator/EV.png | Bin 0 -> 614 bytes .../lobby/particle/decorator/Ely_E.png | Bin 0 -> 198 bytes .../lobby/particle/decorator/Ely_L.png | Bin 0 -> 182 bytes .../lobby/particle/decorator/Ely_Y.png | Bin 0 -> 183 bytes .../lobby/particle/elements/DustParticle.java | 23 ++++- .../particle/elements/TrippleCircle.java | 61 +++++++++++++ .../particle/elements/custom/YOffset.java | 29 ++++-- .../particle/particles/EasterParticle.java | 2 +- .../particle/particles/PlayerParticle.java | 2 +- .../custom/CustomEasterParticle.java | 86 +++++++++++++++--- .../custom/CustomPlayerParticle.java | 4 +- 16 files changed, 251 insertions(+), 36 deletions(-) create mode 100644 LobbySystem/src/de/steamwar/lobby/particle/Gradient.java create mode 100644 LobbySystem/src/de/steamwar/lobby/particle/decorator/EV.png create mode 100644 LobbySystem/src/de/steamwar/lobby/particle/decorator/Ely_E.png create mode 100644 LobbySystem/src/de/steamwar/lobby/particle/decorator/Ely_L.png create mode 100644 LobbySystem/src/de/steamwar/lobby/particle/decorator/Ely_Y.png create mode 100644 LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java diff --git a/LobbySystem/src/de/steamwar/lobby/LobbySystem.properties b/LobbySystem/src/de/steamwar/lobby/LobbySystem.properties index 3375de0a..55fff341 100644 --- a/LobbySystem/src/de/steamwar/lobby/LobbySystem.properties +++ b/LobbySystem/src/de/steamwar/lobby/LobbySystem.properties @@ -50,6 +50,7 @@ PARTICLE_UNLOCKED_BY_EASTER_EGG_HUNT_DIFFICULTY = §fFind all Easter Eggs with d PARTICLE_ATTRIBUTE = §eAttributes§7: PARTICLE_ATTRIBUTE_CIRCLE = §8-§f Ring PARTICLE_ATTRIBUTE_BI_CIRCLE = §8-§f Double ring +PARTICLE_ATTRIBUTE_TRI_CIRCLE = §8-§f Tripple ring PARTICLE_ATTRIBUTE_CLOUD = §8-§f Cloud PARTICLE_ATTRIBUTE_TICK = §8-§f Always active PARTICLE_ATTRIBUTE_NON_FLOOR = §8-§f In air @@ -101,10 +102,16 @@ PARTICLE_MAGIC_ENCHANTING = §5Magic/Enchantment PARTICLE_WINGS_EVIL = §5Purple wings PARTICLE_PLAYER_HAYLIM_AURA = §fHaylim\'s Aura -PARTICLE_PLAYER_RONGAMER99091_AURA = §7Smoke Granade -PARTICLE_PLAYER_PLOMPA = §9ECAL +PARTICLE_PLAYER_1063 = §7Circling Circle +PARTICLE_PLAYER_10916_AURA = §7Tornado +PARTICLE_PLAYER_10697_AURA = §7Smoke Granade +PARTICLE_PLAYER_64 = §9ECAL +PARTICLE_PLAYER_153 = §9ELY +PARTICLE_PLAYER_3266 = §9Tricolo +PARTICLE_TEAM_158_1 = §9EV +PARTICLE_TEAM_158_2 = §9DNA -PARTICLE_TEAM_PULSE_AURA_1 = §fPulse Aura §cFlame +PARTICLE_TEAM_PULSE_AURA = §fPulse Aura §cFlame PARTICLE_TEAM_PULSE_AURA_2 = §fPulse Aura §7End Rod PARTICLE_TEAM_PULSE_AURA_3 = §fPulse Aura §fEnchanted PARTICLE_TEAM_PULSE_LOGO = §fPulse Logo diff --git a/LobbySystem/src/de/steamwar/lobby/LobbySystem_de.properties b/LobbySystem/src/de/steamwar/lobby/LobbySystem_de.properties index 9823f57c..efe41798 100644 --- a/LobbySystem/src/de/steamwar/lobby/LobbySystem_de.properties +++ b/LobbySystem/src/de/steamwar/lobby/LobbySystem_de.properties @@ -49,6 +49,7 @@ PARTICLE_UNLOCKED_BY_EASTER_EGG_HUNT_DIFFICULTY = §fAlle Eierer mit Schwierigke PARTICLE_ATTRIBUTE_CIRCLE = §8-§f Ring PARTICLE_ATTRIBUTE_BI_CIRCLE = §8-§f Doppelring +PARTICLE_ATTRIBUTE_TRI_CIRCLE = §8-§f Dreifachring PARTICLE_ATTRIBUTE_CLOUD = §8-§f Wolke PARTICLE_ATTRIBUTE_TICK = §8-§f Immer aktiv PARTICLE_ATTRIBUTE_NON_FLOOR = §8-§f In der Luft @@ -99,7 +100,8 @@ PARTICLE_WATER_FIRE = §bWasser§7/§cFeuer PARTICLE_MAGIC_ENCHANTING = §5Magie§7/§eZauber PARTICLE_WINGS_EVIL = §5Lila Flügel -PARTICLE_PLAYER_RONGAMER99091_AURA = §7Rauchgranate +PARTICLE_PLAYER_1063 = §7Kreisende Kreise +PARTICLE_PLAYER_10697_AURA = §7Rauchgranate PARTICLE_TEAM_PULSE_HEART_BEAT = §cHerzschlag diff --git a/LobbySystem/src/de/steamwar/lobby/particle/Gradient.java b/LobbySystem/src/de/steamwar/lobby/particle/Gradient.java new file mode 100644 index 00000000..f7667294 --- /dev/null +++ b/LobbySystem/src/de/steamwar/lobby/particle/Gradient.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.lobby.particle; + +import java.awt.*; +import java.util.Arrays; +import java.util.List; + +public class Gradient { + + private List colors; + + public Gradient(Color... colors) { + this.colors = Arrays.asList(colors); + } + + public Color getColor(double value, double maxValue) { + value /= maxValue / (double) (colors.size() - 1); + + return lerpColor( + colors.get((int) value), + colors.get((int) value + 1), + value - (int) value, + 1); + } + + private Color lerpColor(Color start, Color end, double step, double maxStep) { + double rStep = (end.getRed() - start.getRed()) / maxStep; + double gStep = (end.getGreen() - start.getGreen()) / maxStep; + double bStep = (end.getBlue() - start.getBlue()) / maxStep; + + return new Color(start.getRed() + (int) (rStep * step), + start.getGreen() + (int) (gStep * step), + start.getBlue() + (int) (bStep * step)); + } +} diff --git a/LobbySystem/src/de/steamwar/lobby/particle/ParticleElement.java b/LobbySystem/src/de/steamwar/lobby/particle/ParticleElement.java index c9fac94c..c0039e86 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/ParticleElement.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/ParticleElement.java @@ -24,6 +24,10 @@ public interface ParticleElement { return new Particle.DustOptions(randomColor(), randomSize()); } + default Particle.DustOptions withColor(int r, int g, int b) { + return new Particle.DustOptions(Color.fromRGB(r, g, b), randomSize()); + } + default void display(Location location, Player root, boolean onlySelf, boolean onlyOther, Consumer consumer) { if (onlySelf) { consumer.accept(root); diff --git a/LobbySystem/src/de/steamwar/lobby/particle/WingDesign.java b/LobbySystem/src/de/steamwar/lobby/particle/WingDesign.java index 6954a565..125aa170 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/WingDesign.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/WingDesign.java @@ -53,4 +53,10 @@ public interface WingDesign { WingDesign PL = new WingDesignImpl(create("/de/steamwar/lobby/particle/decorator/PL-Logo.png")); WingDesign PlompaEasterWings = new WingDesignImpl(create("/de/steamwar/lobby/particle/decorator/ECAL-Logo.png")); + + WingDesign ELY_E = new WingDesignImpl(create("/de/steamwar/lobby/particle/decorator/Ely_E.png")); + WingDesign ELY_L = new WingDesignImpl(create("/de/steamwar/lobby/particle/decorator/Ely_L.png")); + WingDesign ELY_Y = new WingDesignImpl(create("/de/steamwar/lobby/particle/decorator/Ely_Y.png")); + + WingDesign EV = new WingDesignImpl(create("/de/steamwar/lobby/particle/decorator/EV.png")); } diff --git a/LobbySystem/src/de/steamwar/lobby/particle/decorator/EV.png b/LobbySystem/src/de/steamwar/lobby/particle/decorator/EV.png new file mode 100644 index 0000000000000000000000000000000000000000..bb83cf9655e1f3e6859c34259d3e3312f1719cbb GIT binary patch literal 614 zcmeAS@N?(olHy`uVBq!ia0vp^d_c^_!2~3^cmJ5cz`)p&>FgZf>FlgfP?VpRnUl)E zpfRy_qOHea2brVs(cXVoSln2 zbvj|PF>^{w3q)BC@(YBEtGkM8eysOg=-R`6{BK41`@-*hAGT%r82)sS~QZBjJJf88M0shSjx{I|6a-F^xr%4lOyz`cs_6(DO~na?IT-Z&gCl> z?}ghVT&HxN?_6HGOW~vPb=CI!7SnUTeL6E?-sv;K?H#Q}{NA=_w01e!c*{%^o%(5S zWqazm=s8oPnoHlEjF-?^r5(BM@*D>tZx2OYMj@#ci`aw(qe6ptQZnoxK9b-5H?zp| z$*QJ_$&95M0=f1-cz5QQ>qI-$YMZJL0!dc)ESeT{;BuiW)N}Tg^b5rw57@Uhz6H8K46v{J8G8EiBeFMT9 z`NV;W%sgEjLnJOICmdk-4+i#XvpX9z4lrGJ5txvqrL3&HELzias^EUlDKooHuN9c@ w;NoE*%JAZbG=oRt)NMc$_);T0(|mmyw18|5AO?X;!IMFhr>mdKI;Vst01s;N?*IS* literal 0 HcmV?d00001 diff --git a/LobbySystem/src/de/steamwar/lobby/particle/decorator/Ely_E.png b/LobbySystem/src/de/steamwar/lobby/particle/decorator/Ely_E.png new file mode 100644 index 0000000000000000000000000000000000000000..dff09601a0cdb003a624473453348dc1796f7309 GIT binary patch literal 198 zcmeAS@N?(olHy`uVBq!ia0vp^fanMprE{`i(`ny<>Uj5 z608q&cFa%^D`ko>;o#!pN-&<>$jBhp%h378>`V?&DPL-YXPU1sgBFm@0mLA1DR?r7 N@^tlcS?83{1OWX+E5QH& literal 0 HcmV?d00001 diff --git a/LobbySystem/src/de/steamwar/lobby/particle/decorator/Ely_Y.png b/LobbySystem/src/de/steamwar/lobby/particle/decorator/Ely_Y.png new file mode 100644 index 0000000000000000000000000000000000000000..3855e46fdb1515022e714118ed6cb3be9ca24979 GIT binary patch literal 183 zcmeAS@N?(olHy`uVBq!ia0vp^LO{&T!VDxEEDx9iDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheYymzYuK)l42QotsU9JOCoCO|{#S9F5he4R}c>anMprC@Mi(`ny<>Ujb z5&zSIcMG+$o^Eg+i%h(X{|@MI9> M>FVdQ&MBb@0H!D@iU0rr literal 0 HcmV?d00001 diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/DustParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/DustParticle.java index 9c2f8389..8c143ac2 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/elements/DustParticle.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/DustParticle.java @@ -1,10 +1,13 @@ package de.steamwar.lobby.particle.elements; +import de.steamwar.lobby.particle.Gradient; import de.steamwar.lobby.particle.ParticleElement; import de.steamwar.lobby.particle.ParticleTickData; import org.bukkit.Location; import org.bukkit.Particle; +import java.awt.*; + public class DustParticle implements ParticleElement { private Particle particle; @@ -13,32 +16,44 @@ public class DustParticle implements ParticleElement { private float vz = 0.01f; private double speed = 0.01; private int count = 5; + private Gradient gradient; - public DustParticle(Particle particle) { + public DustParticle(Particle particle, Gradient gradient) { this.particle = particle; + this.gradient = gradient; } - public DustParticle(Particle particle, float vx, float vy, float vz) { + public DustParticle(Particle particle, float vx, float vy, float vz, Gradient gradient) { this.particle = particle; this.vx = vx; this.vy = vy; this.vz = vz; + this.gradient = gradient; } - public DustParticle(Particle particle, float vx, float vy, float vz, double speed, int count) { + public DustParticle(Particle particle, float vx, float vy, float vz, double speed, int count, Gradient gradient) { this.particle = particle; this.vx = vx; this.vy = vy; this.vz = vz; this.speed = speed; this.count = count; + this.gradient = gradient; } @Override public void tick(ParticleTickData particleTickData) { Location location = particleTickData.getLocation().add(0.0, 0.2, 0.0); + Particle.DustOptions dustOptions; + if (gradient != null) { + double result = particleTickData.getDeg() % 360; + Color color = gradient.getColor(result, 360); + dustOptions = withColor(color.getRed(), color.getGreen(), color.getBlue()); + } else { + dustOptions = randomParticleDust(); + } display(location, particleTickData.getPlayer(), particleTickData.isOnlySelf(), particleTickData.isOnlyOthers(), player -> { - player.spawnParticle(particle, location, count, vx, vy, vz, speed, randomParticleDust()); + player.spawnParticle(particle, location, count, vx, vy, vz, speed, dustOptions); }); } } diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java new file mode 100644 index 00000000..45e8f8a3 --- /dev/null +++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java @@ -0,0 +1,61 @@ +package de.steamwar.lobby.particle.elements; + +import de.steamwar.lobby.particle.ParticleElement; +import de.steamwar.lobby.particle.ParticleTickData; +import de.steamwar.lobby.particle.ParticleTickType; +import org.bukkit.Location; +import org.bukkit.util.Vector; + +public class TrippleCircle extends Circle { + + private ParticleElement second; + private ParticleElement third; + + private double distance; + private double speed; + + public TrippleCircle(ParticleElement first, ParticleElement second, ParticleElement third) { + super(first); + this.second = second; + this.distance = 1; + this.speed = 1; + } + + public TrippleCircle(ParticleElement first, ParticleElement second, ParticleElement third, double distance, double speed) { + super(first); + this.second = second; + this.distance = distance; + this.speed = speed; + } + + @Override + public String attribute() { + return "PARTICLE_ATTRIBUTE_TRI_CIRCLE"; + } + + @Override + public ParticleTickType tickType() { + if (particleElement.tickType() == second.tickType() && particleElement.tickType() == third.tickType()) { + return particleElement.tickType(); + } + return ParticleTickType.MOVE; + } + + @Override + public void tick(ParticleTickData particleTickData) { + Location location = particleTickData.getLocation(); + + Vector vector = new Vector(distance, 0, 0); + vector.rotateAroundY((particleTickData.getDeg() * speed) % 360); + ParticleTickData nParticleTickData = particleTickData.withLocation(location.clone().add(vector)); + particleElement.tick(nParticleTickData); + + vector.rotateAroundY(120); + nParticleTickData = particleTickData.withLocation(location.clone().add(vector)); + second.tick(nParticleTickData); + + vector.rotateAroundY(120); + nParticleTickData = particleTickData.withLocation(location.clone().add(vector)); + third.tick(nParticleTickData); + } +} diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/YOffset.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/YOffset.java index 1be82423..0af32eac 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/YOffset.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/YOffset.java @@ -10,13 +10,15 @@ public class YOffset extends DelegatingParticleElement { private double minY; private double maxY; private boolean inverted; + private boolean bounce; - public YOffset(ParticleElement particleElement, double speed, double minY, double maxY, boolean inverted) { + public YOffset(ParticleElement particleElement, double speed, double minY, double maxY, boolean inverted, boolean bounce) { super(particleElement); this.multiplication = speed; this.minY = minY; this.maxY = maxY; this.inverted = inverted; + this.bounce = bounce; } @Override @@ -26,19 +28,28 @@ public class YOffset extends DelegatingParticleElement { @Override public void tick(ParticleTickData particleTickData) { - double value = ((particleTickData.getDeg() * multiplication) % 360) / 180; double y; - if (inverted) { - if (value <= 1) { - y = maxY - (maxY - minY) * value; + if (bounce) { + double value = ((particleTickData.getDeg() * multiplication) % 360) / 180; + if (inverted) { + if (value <= 1) { + y = maxY - (maxY - minY) * value; + } else { + y = minY + (maxY - minY) * (value - 1); + } } else { - y = minY + (maxY - minY) * (value - 1); + if (value <= 1) { + y = minY + (maxY - minY) * value; + } else { + y = maxY - (maxY - minY) * (value - 1); + } } } else { - if (value <= 1) { - y = minY + (maxY - minY) * value; + double value = ((particleTickData.getDeg() * multiplication) % 360) / 360; + if (inverted) { + y = maxY - (maxY - minY) * value; } else { - y = maxY - (maxY - minY) * (value - 1); + y = minY + (maxY - minY) * value; } } ParticleTickData current = particleTickData.withLocation(particleTickData.getLocation().clone().add(0, y, 0)); diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/EasterParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/EasterParticle.java index cecd91b9..0d94f2ea 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/particles/EasterParticle.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/particles/EasterParticle.java @@ -21,7 +21,7 @@ public enum EasterParticle implements ParticleEnum { new Always(new Floor(new Sneaking(new SimpleParticle(Particle.GLOW_SQUID_INK, 0.4F, 0.9F, 0.4F, 0.01))))) ), EGG_HUNT_HARD(new ParticleData(Material.RED_CONCRETE_POWDER, "PARTICLE_EGG_HUNT_HARD", ParticleRequirement.EGG_HUNT_HARD, - new Always(new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0.01, 1), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0.01, 1)), 0, 0.5, 0))) + new Always(new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0.01, 1, null), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0.01, 1, null)), 0, 0.5, 0))) ), EGG_HUNT_EXTREME(new ParticleData(Material.PURPLE_CONCRETE_POWDER, "PARTICLE_EGG_HUNT_EXTREME", ParticleRequirement.EGG_HUNT_EXTREME, new Always(new LocationMutator(new SimpleParticle(Particle.FALLING_OBSIDIAN_TEAR, 0.5F, 0.1F, 0.5F, 1, 1), 0, 2.2, 0))) diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/PlayerParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/PlayerParticle.java index f54c516a..bf421bea 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/particles/PlayerParticle.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/particles/PlayerParticle.java @@ -38,7 +38,7 @@ public enum PlayerParticle implements ParticleEnum { new SimpleParticle(Particle.SNOWBALL, 0.2F, 0.2F ,0.2F, 0.01)) ), EFFECT(new ParticleData(Material.GLASS_BOTTLE, "PARTICLE_EFFECT", - new DustParticle(Particle.REDSTONE, 0, 0.2F, 0, 0.01, 5)) + new DustParticle(Particle.REDSTONE, 0, 0.2F, 0, 0.01, 5, null)) ), CAMPFIRE(new ParticleData(Material.CAMPFIRE, "PARTICLE_CAMPFIRE", new SimpleParticle(Particle.CAMPFIRE_COSY_SMOKE, 0, 0.2F ,0, 0.01)) diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java index 0a4206af..55bbf146 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java @@ -1,44 +1,100 @@ package de.steamwar.lobby.particle.particles.custom; -import de.steamwar.lobby.particle.ParticleData; -import de.steamwar.lobby.particle.ParticleEnum; -import de.steamwar.lobby.particle.ParticleRequirement; -import de.steamwar.lobby.particle.WingDesign; +import de.steamwar.lobby.particle.*; import de.steamwar.lobby.particle.elements.*; import de.steamwar.lobby.particle.elements.custom.HearthBeat; import de.steamwar.lobby.particle.elements.custom.NonMoving; import de.steamwar.lobby.particle.elements.custom.PulseShimmer; +import de.steamwar.lobby.particle.elements.custom.YOffset; import lombok.AllArgsConstructor; import lombok.Getter; import org.bukkit.Material; import org.bukkit.Particle; +import java.awt.*; + @AllArgsConstructor public enum CustomEasterParticle implements ParticleEnum { - /* - Lord_Loading(new ParticleData(Material.ENDER_PEARL, "Loading Test", ParticleRequirement.easterEventSpecificPlayer(1063), - new Always(new DoubleCircle(new DoubleCircle(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1), - new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1), 0.5, 4), - new DoubleCircle(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1), - new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1), 0.5, 4), 1.5, 1))) + PLAYER_1063(new ParticleData(Material.ENDER_PEARL, "PARTICLE_PLAYER_1063", ParticleRequirement.easterEventSpecificPlayer(1063), + new Always(new DoubleCircle( + new DoubleCircle( + new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1), + new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1), 0.5, 4), + new DoubleCircle( + new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1), + new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1), 0.5, 4), 1.5, 1) + )) ), - */ - Rongamer99091(new ParticleData(Material.GUNPOWDER, "PARTICLE_PLAYER_RONGAMER99091_AURA", ParticleRequirement.easterEventSpecificPlayer(10697), + PLAYER_10916(new ParticleData(Material.TORCHFLOWER, "PARTICLE_PLAYER_10916_AURA", ParticleRequirement.easterEventSpecificPlayer(10916), + new Always(new NonMoving(new Group( + new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 0.2, 0)), + new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 0.3, 0)), + new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 0.4, 0)), + new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 0.5, 0)), + new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 0.6, 0)), + new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 0.7, 0)), + new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 0.8, 0)), + new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 0.9, 0)), + new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.0, 0)), + new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.1, 0)), + new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.2, 0)), + new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.3, 0)), + new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.4, 0)), + new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.5, 0)), + new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.6, 0)), + new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.7, 0)), + new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.8, 0)), + new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.9, 0)), + new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 2.0, 0)) + )))) + ), + PLAYER_10697(new ParticleData(Material.GUNPOWDER, "PARTICLE_PLAYER_10697_AURA", ParticleRequirement.easterEventSpecificPlayer(10697), new Always(new Sneaking(new Group( new OnlySelf(new Delayed(new SimpleParticle(Particle.EXPLOSION_HUGE, 0, 0, 0, 0.01, 1), 20)), new OnlyOthers(new Delayed(new SimpleParticle(Particle.EXPLOSION_HUGE, 0, 0, 0, 0.01, 1), 2)) )))) ), - Plompa(new ParticleData(Material.PUFFERFISH_BUCKET, "PARTICLE_PLAYER_PLOMPA", ParticleRequirement.specificPlayer(64), + PLAYER_64(new ParticleData(Material.PUFFERFISH_BUCKET, "PARTICLE_PLAYER_64", ParticleRequirement.easterEventSpecificPlayer(64), new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.END_ROD, 0, 0, 0, 0, 1), 0.15, WingDesign.PlompaEasterWings)), 80))) ), - Pulse_EASTER_1(new ParticleData(Material.RED_CANDLE, "PARTICLE_TEAM_PULSE_AURA_1", ParticleRequirement.easterEventSpecificTeam(210), + TEAM_210_1(new ParticleData(Material.RED_CANDLE, "PARTICLE_TEAM_PULSE_AURA", ParticleRequirement.easterEventSpecificTeam(210), new Always(new NonMoving(new PulseShimmer(new SimpleParticle(Particle.FLAME, 0, 0, 0, 0, 1), 80, 2)))) ), - Pulse_EASTER_3(new ParticleData(Material.APPLE, "PARTICLE_TEAM_PULSE_HEART_BEAT", ParticleRequirement.easterEventSpecificTeam(210), + TEAM_210_2(new ParticleData(Material.APPLE, "PARTICLE_TEAM_PULSE_HEART_BEAT", ParticleRequirement.easterEventSpecificTeam(210), new Always(new NonFlying(new HearthBeat(new SimpleParticle(Particle.FLAME, 0, 0, 0, 0, 1), 80)))) ), + PLAYER_153(new ParticleData(Material.OAK_SIGN, "PARTICLE_PLAYER_153", ParticleRequirement.easterEventSpecificPlayer(153), + new Always(new Delayed(new NonFlying(new Group( + new Wing(new SimpleParticle(Particle.VILLAGER_ANGRY, 0, 0, 0, 0, 1), 0.15, WingDesign.ELY_E), + new Wing(new SimpleParticle(Particle.COMPOSTER, 0, 0, 0, 0, 1), 0.15, WingDesign.ELY_L), + new Wing(new SimpleParticle(Particle.CRIT, 0, 0, 0, 0, 1), 0.15, WingDesign.ELY_Y) + )), 80))) + ), + // TODO: Implement zSalos! -> Team + // TODO: Implement GroupXyz! + // TODO: Implement minecrafter_133 1817! + // TODO: Implement TheReaper22122! + // TODO: Implement Bosslar! + // TODO: Implement ATOM65! + PLAYER_3266(new ParticleData(Material.CHORUS_FRUIT, "PARTICLE_PLAYER_3266", ParticleRequirement.easterEventSpecificPlayer(3266), + new Always(new NonFlying(new Cloud(new LocationMutator(new TrippleCircle( + new DustParticle(Particle.REDSTONE, new Gradient(Color.CYAN, Color.BLUE, Color.MAGENTA.darker(), Color.RED, Color.YELLOW, Color.GREEN, Color.CYAN)), + new DustParticle(Particle.REDSTONE, new Gradient(Color.CYAN, Color.BLUE, Color.MAGENTA.darker(), Color.RED, Color.YELLOW, Color.GREEN, Color.CYAN)), + new DustParticle(Particle.REDSTONE, new Gradient(Color.CYAN, Color.BLUE, Color.MAGENTA.darker(), Color.RED, Color.YELLOW, Color.GREEN, Color.CYAN)), + 0.7, + 0.5), location -> location.add(0, 1.2, 0) + ))))) + ), + // TODO: Implement Gehfxhler! + // TODO: Implement SchwarzerFuerst + // TODO: Implement byVallu + TEAM_158_1(new ParticleData(Material.ENCHANTED_BOOK, "PARTICLE_TEAM_158_1", ParticleRequirement.easterEventSpecificTeam(158), + new Always(new NonFlying(new Delayed(new Wing(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0, 1), 0.2, WingDesign.EV), 80)))) + ), + TEAM_158_2(new ParticleData(Material.ENDER_EYE, "PARTICLE_TEAM_158_2", ParticleRequirement.easterEventSpecificTeam(158), + new Always(new NonFlying(new YOffset(new DoubleCircle(new SimpleParticle(Particle.SPORE_BLOSSOM_AIR, 0, 0, 0, 0, 1), new SimpleParticle(Particle.SPORE_BLOSSOM_AIR, 0, 0, 0, 0, 1), 0.5, 1), 1, 0, 2, false, false)))) + ), ; public static ParticleEnum[] particles = values(); diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomPlayerParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomPlayerParticle.java index 3cfe0875..79c42b3b 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomPlayerParticle.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomPlayerParticle.java @@ -16,8 +16,8 @@ public enum CustomPlayerParticle implements ParticleEnum { Haylim_(new ParticleData(Material.WHITE_CANDLE, "PARTICLE_PLAYER_HAYLIM_AURA", ParticleRequirement.specificPlayer(9426), new Always(new NonMoving(new NonFlying(new Group( - new DoubleCircle(new YOffset(new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0, 0, 0, 0.01, 5), 40, 0, 2, false), new YOffset(new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0, 0, 0, 0.0,5), 40, 0, 2, true)), - new DoubleCircle(new YOffset(new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0, 0, 0, 0.01, 5), 40, 0, 2, true), new YOffset(new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0, 0, 0, 0.0,5), 40, 0, 2, false)) + new DoubleCircle(new YOffset(new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0, 0, 0, 0.01, 5), 40, 0, 2, false, false), new YOffset(new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0, 0, 0, 0.0,5), 40, 0, 2, true, false)), + new DoubleCircle(new YOffset(new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0, 0, 0, 0.01, 5), 40, 0, 2, true, false), new YOffset(new SimpleParticle(Particle.ENCHANTMENT_TABLE, 0, 0, 0, 0.0,5), 40, 0, 2, false, false)) ))))) ), ; From b4eab65757a367f677592a7b7bcf925dbff1e377 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Mon, 3 Mar 2025 09:42:39 +0100 Subject: [PATCH 045/124] Hotfix xsome exceptions --- .../de/steamwar/lobby/particle/Gradient.java | 7 +++ .../particle/elements/TrippleCircle.java | 1 + .../custom/CustomEasterParticle.java | 48 +++++++++---------- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/LobbySystem/src/de/steamwar/lobby/particle/Gradient.java b/LobbySystem/src/de/steamwar/lobby/particle/Gradient.java index f7667294..35ffcd72 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/Gradient.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/Gradient.java @@ -32,6 +32,13 @@ public class Gradient { } public Color getColor(double value, double maxValue) { + if (colors.isEmpty()) { + return Color.BLACK; + } + if (colors.size() == 1) { + return colors.get(0); + } + value /= maxValue / (double) (colors.size() - 1); return lerpColor( diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java index 45e8f8a3..8c259f8b 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java @@ -24,6 +24,7 @@ public class TrippleCircle extends Circle { public TrippleCircle(ParticleElement first, ParticleElement second, ParticleElement third, double distance, double speed) { super(first); this.second = second; + this.third = third; this.distance = distance; this.speed = speed; } diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java index 55bbf146..2d243d15 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java @@ -28,25 +28,25 @@ public enum CustomEasterParticle implements ParticleEnum { ), PLAYER_10916(new ParticleData(Material.TORCHFLOWER, "PARTICLE_PLAYER_10916_AURA", ParticleRequirement.easterEventSpecificPlayer(10916), new Always(new NonMoving(new Group( - new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 0.2, 0)), - new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 0.3, 0)), - new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 0.4, 0)), - new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 0.5, 0)), - new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 0.6, 0)), - new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 0.7, 0)), - new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 0.8, 0)), - new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 0.9, 0)), - new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.0, 0)), - new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.1, 0)), - new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.2, 0)), - new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.3, 0)), - new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.4, 0)), - new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.5, 0)), - new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.6, 0)), - new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.7, 0)), - new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.8, 0)), - new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 1.9, 0)), - new LocationMutator(new Circle(new SimpleParticle(Particle.REDSTONE, 0, 0, 0, 0, 1), 0.1, 1), location -> location.add(0, 2.0, 0)) + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 0.2, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 0.3, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 0.4, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 0.5, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 0.6, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 0.7, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 0.8, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 0.9, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.0, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.1, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.2, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.3, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.4, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.5, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.6, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.7, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.8, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.9, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 2.0, 0)) )))) ), PLAYER_10697(new ParticleData(Material.GUNPOWDER, "PARTICLE_PLAYER_10697_AURA", ParticleRequirement.easterEventSpecificPlayer(10697), @@ -66,9 +66,9 @@ public enum CustomEasterParticle implements ParticleEnum { ), PLAYER_153(new ParticleData(Material.OAK_SIGN, "PARTICLE_PLAYER_153", ParticleRequirement.easterEventSpecificPlayer(153), new Always(new Delayed(new NonFlying(new Group( - new Wing(new SimpleParticle(Particle.VILLAGER_ANGRY, 0, 0, 0, 0, 1), 0.15, WingDesign.ELY_E), - new Wing(new SimpleParticle(Particle.COMPOSTER, 0, 0, 0, 0, 1), 0.15, WingDesign.ELY_L), - new Wing(new SimpleParticle(Particle.CRIT, 0, 0, 0, 0, 1), 0.15, WingDesign.ELY_Y) + new Wing(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.DARK_GRAY)), 0.15, WingDesign.ELY_E), + new Wing(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.GREEN)), 0.15, WingDesign.ELY_L), + new Wing(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.GRAY)), 0.15, WingDesign.ELY_Y) )), 80))) ), // TODO: Implement zSalos! -> Team @@ -90,10 +90,10 @@ public enum CustomEasterParticle implements ParticleEnum { // TODO: Implement SchwarzerFuerst // TODO: Implement byVallu TEAM_158_1(new ParticleData(Material.ENCHANTED_BOOK, "PARTICLE_TEAM_158_1", ParticleRequirement.easterEventSpecificTeam(158), - new Always(new NonFlying(new Delayed(new Wing(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0, 1), 0.2, WingDesign.EV), 80)))) + new Always(new NonFlying(new Delayed(new Wing(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0, 1), 0.2, WingDesign.EV), 20)))) ), TEAM_158_2(new ParticleData(Material.ENDER_EYE, "PARTICLE_TEAM_158_2", ParticleRequirement.easterEventSpecificTeam(158), - new Always(new NonFlying(new YOffset(new DoubleCircle(new SimpleParticle(Particle.SPORE_BLOSSOM_AIR, 0, 0, 0, 0, 1), new SimpleParticle(Particle.SPORE_BLOSSOM_AIR, 0, 0, 0, 0, 1), 0.5, 1), 1, 0, 2, false, false)))) + new Always(new NonFlying(new YOffset(new DoubleCircle(new SimpleParticle(Particle.SPORE_BLOSSOM_AIR, 0.01f, 0.01f, 0.01f, 0.1, 1), new SimpleParticle(Particle.SPORE_BLOSSOM_AIR, 0.01f, 0.01f, 0.01f, 0.1, 1), 0.5, 1), 1, 0, 2, false, false)))) ), ; public static ParticleEnum[] particles = values(); From 5f73395b633daa80ac2f85b5c46bae290c5fe160 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Mon, 3 Mar 2025 09:56:12 +0100 Subject: [PATCH 046/124] Hotfix some exceptions --- .../lobby/particle/ParticleElement.java | 2 +- .../particle/elements/TrippleCircle.java | 14 +++--- .../custom/CustomEasterParticle.java | 50 +++++++++---------- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/LobbySystem/src/de/steamwar/lobby/particle/ParticleElement.java b/LobbySystem/src/de/steamwar/lobby/particle/ParticleElement.java index c0039e86..d4bc37ff 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/ParticleElement.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/ParticleElement.java @@ -25,7 +25,7 @@ public interface ParticleElement { } default Particle.DustOptions withColor(int r, int g, int b) { - return new Particle.DustOptions(Color.fromRGB(r, g, b), randomSize()); + return new Particle.DustOptions(Color.fromRGB(r, g, b), RANDOM.nextFloat() / 2); } default void display(Location location, Player root, boolean onlySelf, boolean onlyOther, Consumer consumer) { diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java index 8c259f8b..fdbdf611 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java @@ -48,15 +48,13 @@ public class TrippleCircle extends Circle { Vector vector = new Vector(distance, 0, 0); vector.rotateAroundY((particleTickData.getDeg() * speed) % 360); - ParticleTickData nParticleTickData = particleTickData.withLocation(location.clone().add(vector)); - particleElement.tick(nParticleTickData); - vector.rotateAroundY(120); - nParticleTickData = particleTickData.withLocation(location.clone().add(vector)); - second.tick(nParticleTickData); + particleElement.tick(particleTickData.withLocation(location.clone().add(vector))); - vector.rotateAroundY(120); - nParticleTickData = particleTickData.withLocation(location.clone().add(vector)); - third.tick(nParticleTickData); + vector.rotateAroundY(120 / 180.0); + second.tick(particleTickData.withLocation(location.clone().add(vector))); + + vector.rotateAroundY(120 / 180.0); + third.tick(particleTickData.withLocation(location.clone().add(vector))); } } diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java index 2d243d15..f4a202e2 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java @@ -28,25 +28,25 @@ public enum CustomEasterParticle implements ParticleEnum { ), PLAYER_10916(new ParticleData(Material.TORCHFLOWER, "PARTICLE_PLAYER_10916_AURA", ParticleRequirement.easterEventSpecificPlayer(10916), new Always(new NonMoving(new Group( - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 0.2, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 0.3, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 0.4, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 0.5, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 0.6, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 0.7, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 0.8, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 0.9, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.0, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.1, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.2, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.3, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.4, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.5, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.6, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.7, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.8, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 1.9, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.1, 1), location -> location.add(0, 2.0, 0)) + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.5, 1), location -> location.add(0, 0.2, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.5, 1), location -> location.add(0, 0.3, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.55, 1), location -> location.add(0, 0.4, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.55, 1), location -> location.add(0, 0.5, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.65, 1), location -> location.add(0, 0.6, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.65, 1), location -> location.add(0, 0.7, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.7, 1), location -> location.add(0, 0.8, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.7, 1), location -> location.add(0, 0.9, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.7, 1), location -> location.add(0, 1.0, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.75, 1), location -> location.add(0, 1.1, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.75, 1), location -> location.add(0, 1.2, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.75, 1), location -> location.add(0, 1.3, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.8, 1), location -> location.add(0, 1.4, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.8, 1), location -> location.add(0, 1.5, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.8, 1), location -> location.add(0, 1.6, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.85, 1), location -> location.add(0, 1.7, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.85, 1), location -> location.add(0, 1.8, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.85, 1), location -> location.add(0, 1.9, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.9, 1), location -> location.add(0, 2.0, 0)) )))) ), PLAYER_10697(new ParticleData(Material.GUNPOWDER, "PARTICLE_PLAYER_10697_AURA", ParticleRequirement.easterEventSpecificPlayer(10697), @@ -66,10 +66,10 @@ public enum CustomEasterParticle implements ParticleEnum { ), PLAYER_153(new ParticleData(Material.OAK_SIGN, "PARTICLE_PLAYER_153", ParticleRequirement.easterEventSpecificPlayer(153), new Always(new Delayed(new NonFlying(new Group( - new Wing(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.DARK_GRAY)), 0.15, WingDesign.ELY_E), - new Wing(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.GREEN)), 0.15, WingDesign.ELY_L), - new Wing(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.GRAY)), 0.15, WingDesign.ELY_Y) - )), 80))) + new Wing(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.DARK_GRAY)), 0.2, WingDesign.ELY_E), + new Wing(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.GREEN)), 0.2, WingDesign.ELY_L), + new Wing(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.GRAY)), 0.2, WingDesign.ELY_Y) + )), 20))) ), // TODO: Implement zSalos! -> Team // TODO: Implement GroupXyz! @@ -83,7 +83,7 @@ public enum CustomEasterParticle implements ParticleEnum { new DustParticle(Particle.REDSTONE, new Gradient(Color.CYAN, Color.BLUE, Color.MAGENTA.darker(), Color.RED, Color.YELLOW, Color.GREEN, Color.CYAN)), new DustParticle(Particle.REDSTONE, new Gradient(Color.CYAN, Color.BLUE, Color.MAGENTA.darker(), Color.RED, Color.YELLOW, Color.GREEN, Color.CYAN)), 0.7, - 0.5), location -> location.add(0, 1.2, 0) + 0.5), location -> location.add(0, 0.6, 0) ))))) ), // TODO: Implement Gehfxhler! @@ -93,7 +93,7 @@ public enum CustomEasterParticle implements ParticleEnum { new Always(new NonFlying(new Delayed(new Wing(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0, 1), 0.2, WingDesign.EV), 20)))) ), TEAM_158_2(new ParticleData(Material.ENDER_EYE, "PARTICLE_TEAM_158_2", ParticleRequirement.easterEventSpecificTeam(158), - new Always(new NonFlying(new YOffset(new DoubleCircle(new SimpleParticle(Particle.SPORE_BLOSSOM_AIR, 0.01f, 0.01f, 0.01f, 0.1, 1), new SimpleParticle(Particle.SPORE_BLOSSOM_AIR, 0.01f, 0.01f, 0.01f, 0.1, 1), 0.5, 1), 1, 0, 2, false, false)))) + new Always(new NonFlying(new YOffset(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0.01f, 0.01f, 0.01f, 0.1, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0.01f, 0.01f, 0.01f, 0.1, 1, new Gradient(Color.BLUE)), 0.5, 1), 1, 0, 2, false, false)))) ), ; public static ParticleEnum[] particles = values(); From caee70c07e19641578a5fbf0120e2c8b101c98b5 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Mon, 3 Mar 2025 10:01:56 +0100 Subject: [PATCH 047/124] Hotfix some exceptions --- .../lobby/particle/ParticleElement.java | 2 +- .../particle/elements/TrippleCircle.java | 4 +- .../custom/CustomEasterParticle.java | 40 +++++++++---------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/LobbySystem/src/de/steamwar/lobby/particle/ParticleElement.java b/LobbySystem/src/de/steamwar/lobby/particle/ParticleElement.java index d4bc37ff..33b497f0 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/ParticleElement.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/ParticleElement.java @@ -25,7 +25,7 @@ public interface ParticleElement { } default Particle.DustOptions withColor(int r, int g, int b) { - return new Particle.DustOptions(Color.fromRGB(r, g, b), RANDOM.nextFloat() / 2); + return new Particle.DustOptions(Color.fromRGB(r, g, b), (float) (RANDOM.nextFloat() / 2 + 0.5)); } default void display(Location location, Player root, boolean onlySelf, boolean onlyOther, Consumer consumer) { diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java index fdbdf611..20372aa1 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java @@ -51,10 +51,10 @@ public class TrippleCircle extends Circle { particleElement.tick(particleTickData.withLocation(location.clone().add(vector))); - vector.rotateAroundY(120 / 180.0); + vector.rotateAroundY(Math.toRadians(120)); second.tick(particleTickData.withLocation(location.clone().add(vector))); - vector.rotateAroundY(120 / 180.0); + vector.rotateAroundY(Math.toRadians(120)); third.tick(particleTickData.withLocation(location.clone().add(vector))); } } diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java index f4a202e2..c35d1006 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java @@ -28,25 +28,25 @@ public enum CustomEasterParticle implements ParticleEnum { ), PLAYER_10916(new ParticleData(Material.TORCHFLOWER, "PARTICLE_PLAYER_10916_AURA", ParticleRequirement.easterEventSpecificPlayer(10916), new Always(new NonMoving(new Group( - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.5, 1), location -> location.add(0, 0.2, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.5, 1), location -> location.add(0, 0.3, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.55, 1), location -> location.add(0, 0.4, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.55, 1), location -> location.add(0, 0.5, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.65, 1), location -> location.add(0, 0.6, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.65, 1), location -> location.add(0, 0.7, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.7, 1), location -> location.add(0, 0.8, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.7, 1), location -> location.add(0, 0.9, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.7, 1), location -> location.add(0, 1.0, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.75, 1), location -> location.add(0, 1.1, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.75, 1), location -> location.add(0, 1.2, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.75, 1), location -> location.add(0, 1.3, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.8, 1), location -> location.add(0, 1.4, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.8, 1), location -> location.add(0, 1.5, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.8, 1), location -> location.add(0, 1.6, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.85, 1), location -> location.add(0, 1.7, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.85, 1), location -> location.add(0, 1.8, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.85, 1), location -> location.add(0, 1.9, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.9, 1), location -> location.add(0, 2.0, 0)) + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.5, 10), location -> location.add(0, 0.2, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.5, 10), location -> location.add(0, 0.3, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.55, 10), location -> location.add(0, 0.4, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.55, 10), location -> location.add(0, 0.5, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.65, 10), location -> location.add(0, 0.6, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.65, 10), location -> location.add(0, 0.7, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.7, 10), location -> location.add(0, 0.8, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.7, 10), location -> location.add(0, 0.9, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.7, 10), location -> location.add(0, 1.0, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.75, 10), location -> location.add(0, 1.1, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.75, 10), location -> location.add(0, 1.2, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.75, 10), location -> location.add(0, 1.3, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.8, 10), location -> location.add(0, 1.4, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.8, 10), location -> location.add(0, 1.5, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.8, 10), location -> location.add(0, 1.6, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.85, 10), location -> location.add(0, 1.7, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.85, 10), location -> location.add(0, 1.8, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.85, 10), location -> location.add(0, 1.9, 0)), + new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.9, 10), location -> location.add(0, 2.0, 0)) )))) ), PLAYER_10697(new ParticleData(Material.GUNPOWDER, "PARTICLE_PLAYER_10697_AURA", ParticleRequirement.easterEventSpecificPlayer(10697), @@ -93,7 +93,7 @@ public enum CustomEasterParticle implements ParticleEnum { new Always(new NonFlying(new Delayed(new Wing(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0, 1), 0.2, WingDesign.EV), 20)))) ), TEAM_158_2(new ParticleData(Material.ENDER_EYE, "PARTICLE_TEAM_158_2", ParticleRequirement.easterEventSpecificTeam(158), - new Always(new NonFlying(new YOffset(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0.01f, 0.01f, 0.01f, 0.1, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0.01f, 0.01f, 0.01f, 0.1, 1, new Gradient(Color.BLUE)), 0.5, 1), 1, 0, 2, false, false)))) + new Always(new NonFlying(new YOffset(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0.01f, 0.01f, 0.01f, 0.1, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0.01f, 0.01f, 0.01f, 0.1, 1, new Gradient(Color.BLUE)), 0.5, 1), 10, 0, 2, false, false)))) ), ; public static ParticleEnum[] particles = values(); From f3b5a45f622eaa43856258cd6466f81e975257fe Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Mon, 3 Mar 2025 10:05:08 +0100 Subject: [PATCH 048/124] Fix final things --- .../lobby/particle/elements/DustParticle.java | 2 +- .../custom/CustomEasterParticle.java | 42 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/DustParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/DustParticle.java index 8c143ac2..a7edb3f0 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/elements/DustParticle.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/DustParticle.java @@ -46,7 +46,7 @@ public class DustParticle implements ParticleElement { Location location = particleTickData.getLocation().add(0.0, 0.2, 0.0); Particle.DustOptions dustOptions; if (gradient != null) { - double result = particleTickData.getDeg() % 360; + double result = (particleTickData.getDeg() * 10) % 360; Color color = gradient.getColor(result, 360); dustOptions = withColor(color.getRed(), color.getGreen(), color.getBlue()); } else { diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java index c35d1006..138362a0 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java @@ -28,25 +28,25 @@ public enum CustomEasterParticle implements ParticleEnum { ), PLAYER_10916(new ParticleData(Material.TORCHFLOWER, "PARTICLE_PLAYER_10916_AURA", ParticleRequirement.easterEventSpecificPlayer(10916), new Always(new NonMoving(new Group( - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.5, 10), location -> location.add(0, 0.2, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.5, 10), location -> location.add(0, 0.3, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.55, 10), location -> location.add(0, 0.4, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.55, 10), location -> location.add(0, 0.5, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.65, 10), location -> location.add(0, 0.6, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.65, 10), location -> location.add(0, 0.7, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.7, 10), location -> location.add(0, 0.8, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.7, 10), location -> location.add(0, 0.9, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.7, 10), location -> location.add(0, 1.0, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.75, 10), location -> location.add(0, 1.1, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.75, 10), location -> location.add(0, 1.2, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.75, 10), location -> location.add(0, 1.3, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.8, 10), location -> location.add(0, 1.4, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.8, 10), location -> location.add(0, 1.5, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.8, 10), location -> location.add(0, 1.6, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.85, 10), location -> location.add(0, 1.7, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.85, 10), location -> location.add(0, 1.8, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.85, 10), location -> location.add(0, 1.9, 0)), - new LocationMutator(new Circle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.9, 10), location -> location.add(0, 2.0, 0)) + new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.5, 10), location -> location.add(0, 0.2, 0)), + new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.5, 10), location -> location.add(0, 0.3, 0)), + new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.55, 10), location -> location.add(0, 0.4, 0)), + new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.55, 10), location -> location.add(0, 0.5, 0)), + new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.65, 10), location -> location.add(0, 0.6, 0)), + new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.65, 10), location -> location.add(0, 0.7, 0)), + new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.7, 10), location -> location.add(0, 0.8, 0)), + new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.7, 10), location -> location.add(0, 0.9, 0)), + new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.7, 10), location -> location.add(0, 1.0, 0)), + new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.75, 10), location -> location.add(0, 1.1, 0)), + new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.75, 10), location -> location.add(0, 1.2, 0)), + new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.75, 10), location -> location.add(0, 1.3, 0)), + new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.8, 10), location -> location.add(0, 1.4, 0)), + new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.8, 10), location -> location.add(0, 1.5, 0)), + new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.8, 10), location -> location.add(0, 1.6, 0)), + new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.85, 10), location -> location.add(0, 1.7, 0)), + new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.85, 10), location -> location.add(0, 1.8, 0)), + new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.85, 10), location -> location.add(0, 1.9, 0)), + new LocationMutator(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.9, 10), location -> location.add(0, 2.0, 0)) )))) ), PLAYER_10697(new ParticleData(Material.GUNPOWDER, "PARTICLE_PLAYER_10697_AURA", ParticleRequirement.easterEventSpecificPlayer(10697), @@ -69,7 +69,7 @@ public enum CustomEasterParticle implements ParticleEnum { new Wing(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.DARK_GRAY)), 0.2, WingDesign.ELY_E), new Wing(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.GREEN)), 0.2, WingDesign.ELY_L), new Wing(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.GRAY)), 0.2, WingDesign.ELY_Y) - )), 20))) + )), 10))) ), // TODO: Implement zSalos! -> Team // TODO: Implement GroupXyz! @@ -90,7 +90,7 @@ public enum CustomEasterParticle implements ParticleEnum { // TODO: Implement SchwarzerFuerst // TODO: Implement byVallu TEAM_158_1(new ParticleData(Material.ENCHANTED_BOOK, "PARTICLE_TEAM_158_1", ParticleRequirement.easterEventSpecificTeam(158), - new Always(new NonFlying(new Delayed(new Wing(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0, 1), 0.2, WingDesign.EV), 20)))) + new Always(new NonFlying(new Delayed(new Wing(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0, 1), 0.2, WingDesign.EV), 15)))) ), TEAM_158_2(new ParticleData(Material.ENDER_EYE, "PARTICLE_TEAM_158_2", ParticleRequirement.easterEventSpecificTeam(158), new Always(new NonFlying(new YOffset(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0.01f, 0.01f, 0.01f, 0.1, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0.01f, 0.01f, 0.01f, 0.1, 1, new Gradient(Color.BLUE)), 0.5, 1), 10, 0, 2, false, false)))) From 600c24441cfb3f125dfc93e97104de5450894245 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Mon, 3 Mar 2025 10:09:54 +0100 Subject: [PATCH 049/124] Fix final things --- .../custom/CustomEasterParticle.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java index 138362a0..3c8d43c5 100644 --- a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java +++ b/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java @@ -17,13 +17,14 @@ import java.awt.*; public enum CustomEasterParticle implements ParticleEnum { PLAYER_1063(new ParticleData(Material.ENDER_PEARL, "PARTICLE_PLAYER_1063", ParticleRequirement.easterEventSpecificPlayer(1063), - new Always(new DoubleCircle( + new Always( new DoubleCircle( - new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1), - new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1), 0.5, 4), - new DoubleCircle( - new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1), - new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1), 0.5, 4), 1.5, 1) + new DoubleCircle( + new YOffset(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1), 20, 0, 2, true, true), + new YOffset(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1), 20, 0, 2, false, true), 0.5, 4), + new DoubleCircle( + new YOffset(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1), 20, 0, 2, false, true), + new YOffset(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0.01, 1), 20, 0, 2, true, true), 0.5, 4), 1.5, 1) )) ), PLAYER_10916(new ParticleData(Material.TORCHFLOWER, "PARTICLE_PLAYER_10916_AURA", ParticleRequirement.easterEventSpecificPlayer(10916), @@ -66,9 +67,9 @@ public enum CustomEasterParticle implements ParticleEnum { ), PLAYER_153(new ParticleData(Material.OAK_SIGN, "PARTICLE_PLAYER_153", ParticleRequirement.easterEventSpecificPlayer(153), new Always(new Delayed(new NonFlying(new Group( - new Wing(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.DARK_GRAY)), 0.2, WingDesign.ELY_E), - new Wing(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.GREEN)), 0.2, WingDesign.ELY_L), - new Wing(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.GRAY)), 0.2, WingDesign.ELY_Y) + new Wing(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.DARK_GRAY)), 0.15, WingDesign.ELY_E), + new Wing(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.GREEN)), 0.15, WingDesign.ELY_L), + new Wing(new DustParticle(Particle.REDSTONE, 0, 0, 0, 0, 1, new Gradient(Color.GRAY)), 0.15, WingDesign.ELY_Y) )), 10))) ), // TODO: Implement zSalos! -> Team @@ -93,7 +94,7 @@ public enum CustomEasterParticle implements ParticleEnum { new Always(new NonFlying(new Delayed(new Wing(new SimpleParticle(Particle.CRIT_MAGIC, 0, 0, 0, 0, 1), 0.2, WingDesign.EV), 15)))) ), TEAM_158_2(new ParticleData(Material.ENDER_EYE, "PARTICLE_TEAM_158_2", ParticleRequirement.easterEventSpecificTeam(158), - new Always(new NonFlying(new YOffset(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0.01f, 0.01f, 0.01f, 0.1, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0.01f, 0.01f, 0.01f, 0.1, 1, new Gradient(Color.BLUE)), 0.5, 1), 10, 0, 2, false, false)))) + new Always(new NonFlying(new YOffset(new DoubleCircle(new DustParticle(Particle.REDSTONE, 0.01f, 0.01f, 0.01f, 0.1, 1, new Gradient(Color.RED)), new DustParticle(Particle.REDSTONE, 0.01f, 0.01f, 0.01f, 0.1, 1, new Gradient(Color.BLUE)), 0.7, 1), 40, 0, 2, false, false)))) ), ; public static ParticleEnum[] particles = values(); From f38b85f9cbed9e9d236b143dce17f2e9db54ddbe Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Mon, 3 Mar 2025 11:27:46 +0100 Subject: [PATCH 050/124] Fix TPSSystem in 1.21 and beyond --- .../src/de/steamwar/bausystem/features/tpslimit/TPSSystem.java | 2 ++ 1 file changed, 2 insertions(+) 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 5cb1e1b6..1e25ff18 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 @@ -38,6 +38,7 @@ import de.steamwar.inventory.SWAnvilInv; import de.steamwar.inventory.SWItem; import de.steamwar.linkage.Linked; import de.steamwar.linkage.LinkedInstance; +import de.steamwar.linkage.MaxVersion; import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -51,6 +52,7 @@ import org.bukkit.inventory.ItemStack; import java.util.Arrays; @Linked +@MaxVersion(20) // Hotfix for 1.21 tps limit! -> Backport coming later public class TPSSystem implements Listener { @Getter From 9bc1f8b328d956019c91fa53b99b7cbcbcb40643 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Tue, 4 Mar 2025 21:05:01 +0100 Subject: [PATCH 051/124] Refactor password check and add cache clearance. --- CommonCore/SQL/src/de/steamwar/sql/SteamwarUser.java | 2 +- WebsiteBackend/src/de/steamwar/Application.kt | 1 + WebsiteBackend/src/de/steamwar/routes/Auth.kt | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CommonCore/SQL/src/de/steamwar/sql/SteamwarUser.java b/CommonCore/SQL/src/de/steamwar/sql/SteamwarUser.java index d4bed21c..025e501c 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/SteamwarUser.java +++ b/CommonCore/SQL/src/de/steamwar/sql/SteamwarUser.java @@ -335,7 +335,7 @@ public class SteamwarUser { public boolean verifyPassword(String password) { try { - if (this.password == null) { + if (!hasPassword()) { return false; } diff --git a/WebsiteBackend/src/de/steamwar/Application.kt b/WebsiteBackend/src/de/steamwar/Application.kt index 23fc3066..08cb7dcb 100644 --- a/WebsiteBackend/src/de/steamwar/Application.kt +++ b/WebsiteBackend/src/de/steamwar/Application.kt @@ -48,6 +48,7 @@ fun main() { while (true) { Thread.sleep(1000 * 10) ResponseUser.clearCache() + SteamwarUser.clear() } }.start() embeddedServer(Netty, port = 1337, host = "127.0.0.1", module = Application::module) diff --git a/WebsiteBackend/src/de/steamwar/routes/Auth.kt b/WebsiteBackend/src/de/steamwar/routes/Auth.kt index e76ae47b..1100201d 100644 --- a/WebsiteBackend/src/de/steamwar/routes/Auth.kt +++ b/WebsiteBackend/src/de/steamwar/routes/Auth.kt @@ -61,6 +61,7 @@ fun Route.configureAuth() { post { val request = call.receive() + SteamwarUser.clear() val user = SteamwarUser.get(request.name) val valid = user?.verifyPassword(request.password) ?: false From 29cb1cc5dabb876fd401af652148f51ce9d9e885 Mon Sep 17 00:00:00 2001 From: D4rkr34lm Date: Sat, 8 Mar 2025 01:11:24 +0100 Subject: [PATCH 052/124] Implemented first tracer lib version --- .../features/script/lua/libs/TracerLib.java | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TracerLib.java diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TracerLib.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TracerLib.java new file mode 100644 index 00000000..1e6b005e --- /dev/null +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TracerLib.java @@ -0,0 +1,86 @@ +package de.steamwar.bausystem.features.script.lua.libs; + +import de.steamwar.bausystem.features.tracer.TNTPoint; +import de.steamwar.bausystem.features.tracer.Trace; +import de.steamwar.bausystem.features.tracer.TraceManager; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; +import org.luaj.vm2.LuaError; +import org.luaj.vm2.LuaInteger; +import org.luaj.vm2.LuaTable; +import org.luaj.vm2.LuaValue; +import org.luaj.vm2.lib.OneArgFunction; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public class TracerLib implements LuaLib{ + @Override + public String name() { + return "tracer"; + } + + private LuaTable convertTrace(Trace trace) { + return LuaValue.listOf( + trace.getHistories() + .stream() + .map((history) -> LuaValue.listOf(history.stream().map(this::convertTntPoint).toArray(LuaValue[]::new))) + .toArray(LuaValue[]::new) + ); + } + + private LuaTable convertTntPoint(TNTPoint tntPoint) { + Location pointPos = tntPoint.getLocation(); + LuaTable luaPos = LuaValue.listOf(new LuaValue[] { + LuaValue.valueOf(pointPos.getX()), + LuaValue.valueOf(pointPos.getY()), + LuaValue.valueOf(pointPos.getZ()), + }); + + Vector pointVel = tntPoint.getVelocity(); + LuaTable luaVel = LuaValue.listOf(new LuaValue[] { + LuaValue.valueOf(pointVel.getX()), + LuaValue.valueOf(pointVel.getY()), + LuaValue.valueOf(pointVel.getZ()), + }); + + return LuaValue.tableOf(new LuaValue[] { + LuaValue.valueOf("pos"), luaPos, + LuaValue.valueOf("vel"), luaVel, + LuaValue.valueOf("ticksSinceStart"), LuaValue.valueOf(tntPoint.getTicksSinceStart()), + LuaValue.valueOf("fuse"), LuaValue.valueOf(tntPoint.getFuse()), + LuaValue.valueOf("isExplosion"), LuaValue.valueOf(tntPoint.isExplosion()), + LuaValue.valueOf("isInWater"), LuaValue.valueOf(tntPoint.isInWater()), + LuaValue.valueOf("hasDestroyedBuild"), LuaValue.valueOf(tntPoint.isDestroyedBuildArea()), + LuaValue.valueOf("hasDestroyedTestblock"), LuaValue.valueOf(tntPoint.isDestroyedTestBlock()) + }); + } + + @Override + public LuaTable get(Player player) { + LuaTable rootTable = new LuaTable(); + + rootTable.set("getTrace", new OneArgFunction() { + @Override + public LuaValue call(LuaValue arg) { + int id = arg.checkint(); + + Optional traceResult = TraceManager.instance.get(id); + if(traceResult.isEmpty()) { + throw new LuaError("No trace found with id " + id); + } else { + return convertTrace(traceResult.get()); + } + } + }); + + rootTable.set("getAllTraceIds", getter(() -> LuaValue.listOf(TraceManager.instance.getAllIds() + .stream() + .map((id) -> LuaValue.valueOf(id)).toArray(LuaValue[]::new)) + )); + + return rootTable; + } +} From 644cc9da840b9bbc30a4fc5c36115160aa0c4b08 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Sat, 8 Mar 2025 15:58:50 +0100 Subject: [PATCH 053/124] Fix /arena bugs with event arenas --- VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java b/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java index a6707c45..56620468 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java +++ b/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java @@ -110,7 +110,7 @@ public class ServerStarter { fightMap = eventFight.getMap(); gameMode = eventFight.getSpielmodus(); - String serverName = Team.get(eventFight.getTeamBlue()).getTeamKuerzel() + " vs " + Team.get(eventFight.getTeamRed()).getTeamKuerzel(); + String serverName = Team.get(eventFight.getTeamBlue()).getTeamKuerzel() + "_vs_" + Team.get(eventFight.getTeamRed()).getTeamKuerzel(); serverNameProvider = port -> serverName; worldName = serverToWorldName(serverName + eventFight.getStartTime().toLocalDateTime().format(DateTimeFormatter.ISO_TIME)); return this; From b60111e717c10c345c4bf4d7e4792e725ff866a7 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 8 Mar 2025 17:44:46 +0100 Subject: [PATCH 054/124] Hotfix ShieldPrinting pasting AIR, it should not --- .../bausystem/features/shieldprinting/ShieldPrinting.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java index 28a65a99..780c2bb3 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java @@ -177,6 +177,9 @@ public class ShieldPrinting implements Listener { BlockData worldOriginal = block.getBlockData(); BlockData copied = entry.getValue().clone(); + if (copied.getMaterial().isAir()) { + continue; + } for (BlockDataConfiguration blockDataConfiguration : stateConfigurations) { if (blockDataConfiguration == null) continue; blockDataConfiguration.apply(copied, worldOriginal); From 17eaefe3d0379d951bc0bf49c39ba679ff11b354 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 8 Mar 2025 17:51:41 +0100 Subject: [PATCH 055/124] Hotfix ShieldPrinting pasting AIR, it should not --- .../bausystem/features/shieldprinting/ShieldPrinting.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java index 780c2bb3..329ad9f4 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java @@ -170,13 +170,16 @@ public class ShieldPrinting implements Listener { } BlockDataConfiguration[] stateConfigurations = stateConfiguration.get(entry.getValue().getMaterial()); + BlockData copied = entry.getValue(); if (stateConfigurations == null) { - block.setBlockData(entry.getValue(), false); + if (!copied.getMaterial().isAir()) { + block.setBlockData(copied, false); + } continue; } BlockData worldOriginal = block.getBlockData(); - BlockData copied = entry.getValue().clone(); + copied = copied.clone(); if (copied.getMaterial().isAir()) { continue; } From 82723e4c315a96c5bd9e5f473b8ea59b407461db Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 8 Mar 2025 18:34:22 +0100 Subject: [PATCH 056/124] Hotfix ShieldPrinting pasting AIR, it should not --- .../features/shieldprinting/ShieldPrinting.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java index 329ad9f4..e3b60f1e 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java @@ -160,6 +160,11 @@ public class ShieldPrinting implements Listener { private void paste(Map[]> stateConfiguration) { for (Map.Entry entry : shieldData.entrySet()) { + BlockData copied = entry.getValue(); + if (copied.getMaterial().isAir()) { + continue; + } + Block block = entry.getKey().toLocation(WORLD).getBlock(); if (entry.getValue().getMaterial() != block.getType()) { block.setBlockData(entry.getValue(), false); @@ -170,19 +175,12 @@ public class ShieldPrinting implements Listener { } BlockDataConfiguration[] stateConfigurations = stateConfiguration.get(entry.getValue().getMaterial()); - BlockData copied = entry.getValue(); if (stateConfigurations == null) { - if (!copied.getMaterial().isAir()) { - block.setBlockData(copied, false); - } continue; } BlockData worldOriginal = block.getBlockData(); copied = copied.clone(); - if (copied.getMaterial().isAir()) { - continue; - } for (BlockDataConfiguration blockDataConfiguration : stateConfigurations) { if (blockDataConfiguration == null) continue; blockDataConfiguration.apply(copied, worldOriginal); From 96c25687b64a72fcf131c7ff9b1183130a7d0b31 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 8 Mar 2025 22:16:39 +0100 Subject: [PATCH 057/124] Hotfix SendCommand --- .../de/steamwar/velocitycore/commands/SendCommand.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java index 1a5ba9f5..f1590957 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/SendCommand.java @@ -49,11 +49,15 @@ public class SendCommand extends SWCommand { @Register("to") public void sendCommand(Chatter sender, RegisteredServer toServer, Player... players) { String serverName = toServer.getServerInfo().getName(); + int count = 0; for (Player player : players) { - player.createConnectionRequest(toServer).fireAndForget(); - Chatter.of(player).send(true, null, null, new Message("SEND_MESSAGE", sender.user().getUserName(), serverName)); + if (sender.user().hasPerm(UserPerm.ADMINISTRATION) || check(sender.user(), player.getCurrentServer().map(ServerConnection::getServer).orElse(null))) { + player.createConnectionRequest(toServer).fireAndForget(); + Chatter.of(player).send(true, null, null, new Message("SEND_MESSAGE", sender.user().getUserName(), serverName)); + count++; + } } - sender.send(true, null, null, new Message("SEND_MESSAGE_SELF", players.length, serverName)); + sender.send(true, null, null, new Message("SEND_MESSAGE_SELF", count, serverName)); } private boolean check(SteamwarUser user, RegisteredServer registeredServer) { From 2225b811fa13146a9a78e9b4ba18beea00f15434 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sun, 9 Mar 2025 18:18:13 +0100 Subject: [PATCH 058/124] Update Bossbar of FightSystem --- .../fightsystem/FightSystem.properties | 18 +++++++++--------- .../fightsystem/FightSystem_de.properties | 10 +++++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties index 3d9a9218..dde4e266 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties @@ -176,15 +176,15 @@ UI_WIN={0}Victory {1} UI_DRAW=§7Draw BAR_PRE_LEADER=§7Waiting for team leader -BAR_PRE_SCHEM={1} §7Schematic selection {0} {2} -BAR_PREPARE={1} {3} §7Preparation {0} {4} {2} -BAR_PRE_RUNNING={1} {3} §7Start of fight in {0} {4} {2} -BAR_RUNNING0={1} {3} {0} {4} {2} -BAR_RUNNING1={1} {3} {5} {0} {6} {4} {2} -BAR_RUNNING2={1} {3} {5} {7} {0} {6} {8} {4} {2} -BAR_RUNNING3={1} {3} {5} {7} {9} {0} {6} {8} {10} {4} {2} -BAR_TIE={1} §7Draw {0} {2} -BAR_WIN={1} §7Victory {3} {0} {2} +BAR_PRE_SCHEM = {1} §7Schematic selection {0} {2} +BAR_PREPARE = {1} {3} §7Preparation {0} {4} {2} +BAR_PRE_RUNNING = {1} {3} §7Start of fight in {0} {4} {2} +BAR_RUNNING0 = {1} {3} {0} {4} {2} +BAR_RUNNING1 = {1} {3} {5} {0} {6} {4} {2} +BAR_RUNNING2 = {1} {3} {5} {7} {0} {6} {8} {4} {2} +BAR_RUNNING3 = {1} {3} {5} {7} {9} {0} {6} {8} {10} {4} {2} +BAR_TIE = {1} §7Draw {0} {2} +BAR_WIN = {1} §7Victory {3} {0} {2} BAR_POINTS={0} §8Points BAR_POINTS_OF={0}§8/§7{1} §8Points BAR_PERCENT={0}§8% 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 d45cdfd0..470226a8 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties @@ -161,11 +161,11 @@ UI_WIN={0}Sieg {1} UI_DRAW=§7Unentschieden BAR_PRE_LEADER=§7Warten auf Teamleader -BAR_PRE_SCHEM={1} §7Schemauswahl {0} {2} -BAR_PREPARE={1} {3} §7Vorbereitung {0} {4} {2} -BAR_PRE_RUNNING={1} {3} §7Kampfbeginn in {0} {4} {2} -BAR_TIE={1} §7Unentschieden {0} {2} -BAR_WIN={1} §7Sieg {3} {0} {2} +BAR_PRE_SCHEM = {1} §7Schemauswahl {0} {2} +BAR_PREPARE = {1} {3} §7Vorbereitung {0} {4} {2} +BAR_PRE_RUNNING = {1} {3} §7Kampfbeginn in {0} {4} {2} +BAR_TIE = {1} §7Unentschieden {0} {2} +BAR_WIN = {1} §7Sieg {3} {0} {2} BAR_POINTS={0} §8Punkte BAR_POINTS_OF={0}§8/§7{1} §8Punkte BAR_PERCENT={0}§8% From 3b41cc4ac5a85bed883998ee76cd2b0a11f3a7a4 Mon Sep 17 00:00:00 2001 From: D4rkr34lm Date: Mon, 10 Mar 2025 22:17:05 +0100 Subject: [PATCH 059/124] Improved tracer Lib --- .../features/script/lua/libs/TracerLib.java | 46 +++++++------------ 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TracerLib.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TracerLib.java index 1e6b005e..e18cd84c 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TracerLib.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TracerLib.java @@ -6,15 +6,8 @@ import de.steamwar.bausystem.features.tracer.TraceManager; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import org.luaj.vm2.LuaError; -import org.luaj.vm2.LuaInteger; import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaValue; -import org.luaj.vm2.lib.OneArgFunction; - -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; public class TracerLib implements LuaLib{ @Override @@ -23,12 +16,19 @@ public class TracerLib implements LuaLib{ } private LuaTable convertTrace(Trace trace) { - return LuaValue.listOf( + LuaTable luaTrace = new LuaTable(); + + luaTrace.set("getRecords", getter(() -> LuaValue.listOf( trace.getHistories() - .stream() - .map((history) -> LuaValue.listOf(history.stream().map(this::convertTntPoint).toArray(LuaValue[]::new))) - .toArray(LuaValue[]::new) - ); + .stream() + .map((history) -> LuaValue.listOf(history.stream().map(this::convertTntPoint).toArray(LuaValue[]::new))) + .toArray(LuaValue[]::new) + ))); + + luaTrace.set("getId", getter(() -> TraceManager.instance.getId(trace))); + + + return luaTrace; } private LuaTable convertTntPoint(TNTPoint tntPoint) { @@ -62,23 +62,11 @@ public class TracerLib implements LuaLib{ public LuaTable get(Player player) { LuaTable rootTable = new LuaTable(); - rootTable.set("getTrace", new OneArgFunction() { - @Override - public LuaValue call(LuaValue arg) { - int id = arg.checkint(); - - Optional traceResult = TraceManager.instance.get(id); - if(traceResult.isEmpty()) { - throw new LuaError("No trace found with id " + id); - } else { - return convertTrace(traceResult.get()); - } - } - }); - - rootTable.set("getAllTraceIds", getter(() -> LuaValue.listOf(TraceManager.instance.getAllIds() - .stream() - .map((id) -> LuaValue.valueOf(id)).toArray(LuaValue[]::new)) + rootTable.set("getTraces", getter(() -> + LuaValue.listOf(TraceManager.instance.getAll() + .stream() + .map((trace) -> convertTrace(trace)) + .toArray(LuaValue[]::new)) )); return rootTable; From 1d293b446c10baa8e32f608cbff617c94b68ec1a Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Tue, 11 Mar 2025 18:31:31 +0100 Subject: [PATCH 060/124] Hotfix WhoisCommand for Developers not showing the User ID --- .../src/de/steamwar/velocitycore/commands/WhoisCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/WhoisCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/WhoisCommand.java index 4daa5b78..2fc6f08d 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/commands/WhoisCommand.java +++ b/VelocityCore/src/de/steamwar/velocitycore/commands/WhoisCommand.java @@ -71,7 +71,7 @@ public class WhoisCommand extends SWCommand { if (!sender.user().hasPerm(UserPerm.TEAM)) return; - if (sender.user().hasPerm(UserPerm.MODERATION)) { + if (sender.user().hasPerm(UserPerm.MODERATION) || sender.user().hasPerm(UserPerm.PREFIX_DEVELOPER)) { sender.system("WHOIS_ID", user.getId()); sender.system("WHOIS_UUID", new Message("WHOIS_UUID_HOVER"), ClickEvent.copyToClipboard(user.getUUID().toString()), user.getUUID().toString()); if (user.getDiscordId() != null) From 394591f3028340fee7b3c2164bd392c498df4e43 Mon Sep 17 00:00:00 2001 From: D4rkr34lm Date: Tue, 11 Mar 2025 22:58:03 +0100 Subject: [PATCH 061/124] First impl --- .../features/script/lua/libs/TracerLib.java | 72 ++++++++++++------- BauSystem/sw.def.lua | 34 +++++---- 2 files changed, 65 insertions(+), 41 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TracerLib.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TracerLib.java index e18cd84c..91b510e2 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TracerLib.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TracerLib.java @@ -3,50 +3,65 @@ package de.steamwar.bausystem.features.script.lua.libs; import de.steamwar.bausystem.features.tracer.TNTPoint; import de.steamwar.bausystem.features.tracer.Trace; import de.steamwar.bausystem.features.tracer.TraceManager; +import de.steamwar.linkage.Linked; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.util.Vector; import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaValue; +import org.luaj.vm2.lib.ZeroArgFunction; -public class TracerLib implements LuaLib{ +@Linked +public class TracerLib implements LuaLib { @Override public String name() { return "tracer"; } - private LuaTable convertTrace(Trace trace) { + private static LuaTable convertTrace(Trace trace) { LuaTable luaTrace = new LuaTable(); - luaTrace.set("getRecords", getter(() -> LuaValue.listOf( - trace.getHistories() - .stream() - .map((history) -> LuaValue.listOf(history.stream().map(this::convertTntPoint).toArray(LuaValue[]::new))) - .toArray(LuaValue[]::new) - ))); + luaTrace.set("getRecords", new ZeroArgFunction() { + @Override + public LuaValue call() { + return LuaValue.listOf( + trace.getHistories() + .stream() + .map((history) -> LuaValue.listOf(history + .stream() + .map(TracerLib::convertTntPoint) + .toArray(LuaValue[]::new))) + .toArray(LuaValue[]::new)); + } + }); - luaTrace.set("getId", getter(() -> TraceManager.instance.getId(trace))); + luaTrace.set("getId", new ZeroArgFunction() { + @Override + public LuaValue call() { + return LuaValue.valueOf(trace.getUuid().toString()); + } + }); return luaTrace; } - private LuaTable convertTntPoint(TNTPoint tntPoint) { + private static LuaTable convertTntPoint(TNTPoint tntPoint) { Location pointPos = tntPoint.getLocation(); - LuaTable luaPos = LuaValue.listOf(new LuaValue[] { - LuaValue.valueOf(pointPos.getX()), - LuaValue.valueOf(pointPos.getY()), - LuaValue.valueOf(pointPos.getZ()), + LuaTable luaPos = LuaValue.tableOf(new LuaValue[]{ + LuaValue.valueOf("x"), LuaValue.valueOf(pointPos.getX()), + LuaValue.valueOf("y"), LuaValue.valueOf(pointPos.getY()), + LuaValue.valueOf("z"), LuaValue.valueOf(pointPos.getZ()), }); Vector pointVel = tntPoint.getVelocity(); - LuaTable luaVel = LuaValue.listOf(new LuaValue[] { - LuaValue.valueOf(pointVel.getX()), - LuaValue.valueOf(pointVel.getY()), - LuaValue.valueOf(pointVel.getZ()), + LuaTable luaVel = LuaValue.tableOf(new LuaValue[]{ + LuaValue.valueOf("x"), LuaValue.valueOf(pointVel.getX()), + LuaValue.valueOf("y"), LuaValue.valueOf(pointVel.getY()), + LuaValue.valueOf("z"), LuaValue.valueOf(pointVel.getZ()), }); - return LuaValue.tableOf(new LuaValue[] { + return LuaValue.tableOf(new LuaValue[]{ LuaValue.valueOf("pos"), luaPos, LuaValue.valueOf("vel"), luaVel, LuaValue.valueOf("ticksSinceStart"), LuaValue.valueOf(tntPoint.getTicksSinceStart()), @@ -60,14 +75,19 @@ public class TracerLib implements LuaLib{ @Override public LuaTable get(Player player) { - LuaTable rootTable = new LuaTable(); + LuaTable rootTable = LuaValue.tableOf(); - rootTable.set("getTraces", getter(() -> - LuaValue.listOf(TraceManager.instance.getAll() - .stream() - .map((trace) -> convertTrace(trace)) - .toArray(LuaValue[]::new)) - )); + rootTable.set("getTraces", new ZeroArgFunction() { + @Override + public LuaValue call() { + return LuaValue.listOf(TraceManager.instance.getAll() + .stream() + .map(TracerLib::convertTrace) + .toArray(LuaValue[]::new)); + } + } + + ); return rootTable; } diff --git a/BauSystem/sw.def.lua b/BauSystem/sw.def.lua index 613437a1..4503239c 100644 --- a/BauSystem/sw.def.lua +++ b/BauSystem/sw.def.lua @@ -200,21 +200,6 @@ function tnt.onlyTb() return nil end ---@return boolean function tnt.onlyBuild() return nil end ----@class trace -local trace = {} - ----@return boolean -function trace.active() return nil end - ----@return boolean -function trace.auto() return nil end - ----@return string -function trace.status() return nil end - ----@return number -function trace.time() return nil end - ---@param name string ---@return iregion function region.get(name) return nil end @@ -222,6 +207,25 @@ function region.get(name) return nil end ---@return iregion[] function region.list() return nil end +---@class tracerLib +tracer = {} + +---@class TraceRecord +---@field pos Position +---@field vel Position +---@field ticksSinceStart number +---@field fuse number +---@field isExplosion boolean +---@field isInWater boolean +---@field hasDestroyedBuild boolean +---@field hasDestroyedTestblock boolean + +---@class Tracer +---@field getId fun(): string +---@field getRecords fun(): {[number]: TraceRecord} + +function tracer.getTraces() return nil end + ---@class Position ---@field x number ---@field y number From 522cd850a203e485c153b4c0c73a33fa45aa7ed2 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 12 Mar 2025 08:45:01 +0100 Subject: [PATCH 062/124] Add copyright and usage note! --- .../src/de/steamwar/entity/RBlockDisplay.java | 22 +++++++++++++++++++ .../src/de/steamwar/entity/RDisplay.java | 22 +++++++++++++++++++ .../src/de/steamwar/entity/RItemDisplay.java | 22 +++++++++++++++++++ .../src/de/steamwar/entity/RTextDisplay.java | 22 +++++++++++++++++++ 4 files changed, 88 insertions(+) diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java index c01fdea2..5f4c4d50 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RBlockDisplay.java @@ -1,3 +1,22 @@ +/* + * 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.entity; import de.steamwar.Reflection; @@ -11,6 +30,9 @@ import org.bukkit.entity.EntityType; import java.util.function.BiConsumer; import java.util.function.Consumer; +/** + * !! This class cannot be used in Versions lower than or equal to 1.19.4 !! + */ @Getter public class RBlockDisplay extends RDisplay { diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java index 3be30b12..863dc658 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RDisplay.java @@ -1,3 +1,22 @@ +/* + * 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.entity; import de.steamwar.core.BountifulWrapper; @@ -16,6 +35,9 @@ import java.util.List; import java.util.function.BiConsumer; import java.util.function.Consumer; +/** + * !! This class cannot be used in Versions lower than or equal to 1.19.4 !! + */ @Getter public abstract class RDisplay extends REntity { diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java index 4ed1a4dc..52cbfc31 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RItemDisplay.java @@ -1,3 +1,22 @@ +/* + * 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.entity; import de.steamwar.core.BountifulWrapper; @@ -12,6 +31,9 @@ import org.bukkit.inventory.ItemStack; import java.util.function.BiConsumer; import java.util.function.Consumer; +/** + * !! This class cannot be used in Versions lower than or equal to 1.19.4 !! + */ @Getter public class RItemDisplay extends RDisplay { diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java index 3abf9f18..605b6770 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/entity/RTextDisplay.java @@ -1,3 +1,22 @@ +/* + * 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.entity; import de.steamwar.Reflection; @@ -11,6 +30,9 @@ import org.bukkit.entity.TextDisplay; import java.util.function.BiConsumer; import java.util.function.Consumer; +/** + * !! This class cannot be used in Versions lower than or equal to 1.19.4 !! + */ @Getter public class RTextDisplay extends RDisplay { From c94d67660afeee7ba2a420e757138e2ce031d986 Mon Sep 17 00:00:00 2001 From: D4rkr34lm Date: Wed, 12 Mar 2025 19:13:47 +0100 Subject: [PATCH 063/124] Fixed doc --- BauSystem/sw.def.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BauSystem/sw.def.lua b/BauSystem/sw.def.lua index 4503239c..50095a2d 100644 --- a/BauSystem/sw.def.lua +++ b/BauSystem/sw.def.lua @@ -222,7 +222,7 @@ tracer = {} ---@class Tracer ---@field getId fun(): string ----@field getRecords fun(): {[number]: TraceRecord} +---@field getRecords fun(): {[number]: {[number]: TraceRecord}} function tracer.getTraces() return nil end From 30cb09c127a508fc581c761135594a64cc42cd7f Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 13 Mar 2025 16:36:34 +0100 Subject: [PATCH 064/124] Hotfix ELO on leave --- MissileWars/src/de/steamwar/misslewars/MWTeam.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MissileWars/src/de/steamwar/misslewars/MWTeam.java b/MissileWars/src/de/steamwar/misslewars/MWTeam.java index 7d4224dc..8abc5bc9 100644 --- a/MissileWars/src/de/steamwar/misslewars/MWTeam.java +++ b/MissileWars/src/de/steamwar/misslewars/MWTeam.java @@ -185,7 +185,6 @@ 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; if (stack.getType() == Material.AIR) continue; @@ -196,9 +195,11 @@ public class MWTeam { p.getInventory().clear(); p.setDisplayName("§7" + p.getName()); - sbteam.removePlayer(p); if (players.isEmpty() && MissileWars.getFightState() == FightState.FIGHTING) MissileWars.end(WinReasons.NO_ENEMY, enemy()); + + players.remove(p); + sbteam.removePlayer(p); } public void reset() { From 34e4cd706033720066d11316794efef13f6270cf Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 13 Mar 2025 16:53:37 +0100 Subject: [PATCH 065/124] Add click on SimulatorMaterialGui to change material --- .../features/simulator/gui/SimulatorMaterialGui.java | 10 ++++++++++ .../features/simulator/gui/base/SimulatorBaseGui.java | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorMaterialGui.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorMaterialGui.java index 84f1e682..f081374d 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorMaterialGui.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorMaterialGui.java @@ -53,6 +53,16 @@ public class SimulatorMaterialGui extends SimulatorPageGui { this.back = back; } + @Override + public boolean shouldOpen() { + if (player.getItemOnCursor().getType().isAir()) { + return true; + } + change.accept(player.getItemOnCursor().getType()); + SimulatorWatcher.update(simulator); + return false; + } + @Override public String baseTitle() { return "Material"; 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 e3ddd797..6fa35d4c 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 @@ -46,6 +46,8 @@ public abstract class SimulatorBaseGui { } public final void open() { + if (!shouldOpen()) return; + String newTitle = title(); String originalTitle = player.getOpenInventory().getTitle(); @@ -86,6 +88,10 @@ public abstract class SimulatorBaseGui { inventory.open(); } + public boolean shouldOpen() { + return true; + } + private void setup() { for (int i = 0; i < 9; i++) { inventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§8", clickType -> { From 9eca9ab9904b6ba85a5993531160932157ef918c Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 13 Mar 2025 17:04:59 +0100 Subject: [PATCH 066/124] Add DepthCommand to toggle Depth Counter --- .../BauSystem_Main/src/BauSystem.properties | 2 + .../src/BauSystem_de.properties | 2 + .../features/cannon/depth/Depth.java | 5 ++- .../features/cannon/depth/DepthCommand.java | 45 +++++++++++++++++++ 4 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/DepthCommand.java diff --git a/BauSystem/BauSystem_Main/src/BauSystem.properties b/BauSystem/BauSystem_Main/src/BauSystem.properties index 929d0c67..e4dc1b27 100644 --- a/BauSystem/BauSystem_Main/src/BauSystem.properties +++ b/BauSystem/BauSystem_Main/src/BauSystem.properties @@ -406,6 +406,8 @@ BLOCK_COUNTER_MESSAGE_SECOND=§7Damage §8> §e{0} §7Blocks §e{1} §7TNT §e BLOCK_COUNTER_ENABLE=§7BlockCounter activated BLOCK_COUNTER_DISABLE=§7BlockCounter deactivated # DepthCounter +DEPTH_COUNTER_DISABLE=§7Depth Counter disabled +DEPTH_COUNTER_ENABLE=§7Depth Counter enabled DEPTH_COUNTER_MESSAGE=§7Depth §8> §7 DEPTH_COUNTER_COUNT={0}{1}§8×{2}{3}§8×{4}{5} DEPTH_COUNTER_HOVER=§7X§8×§7Y§8×§7Z diff --git a/BauSystem/BauSystem_Main/src/BauSystem_de.properties b/BauSystem/BauSystem_Main/src/BauSystem_de.properties index 4cb20d95..ea6826ed 100644 --- a/BauSystem/BauSystem_Main/src/BauSystem_de.properties +++ b/BauSystem/BauSystem_Main/src/BauSystem_de.properties @@ -369,6 +369,8 @@ BLOCK_COUNTER_MESSAGE_SECOND=§7Schaden §8> §e{0} §7Blöcke §e{1} §7TNT BLOCK_COUNTER_ENABLE=§7BlockCounter angemacht BLOCK_COUNTER_DISABLE=§7BlockCounter ausgemacht # DepthCounter +DEPTH_COUNTER_DISABLE=§7Depth Counter deaktiviert +DEPTH_COUNTER_ENABLE=§7Depth Counter aktiviert DEPTH_COUNTER_MESSAGE=§7Tiefe §8> §7 # TPSLimit TPSLIMIT_FREEZE_HELP=§8/§etpslimit 0 §8-§7 Friere TPS ein 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 a13d6250..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 @@ -20,6 +20,7 @@ package de.steamwar.bausystem.features.cannon.depth; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.configplayer.Config; import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.region.RegionUtils; import de.steamwar.bausystem.region.utils.RegionExtensionType; @@ -65,7 +66,9 @@ public class Depth { dimensions.setZ(Math.abs(dimensions.getZ())); RegionUtils.message(region, player -> { - player.spigot().sendMessage(getMessage(player, dimensions.getBlockX() + 1, dimensions.getBlockY() + 1, dimensions.getBlockZ() + 1, tntCount)); + if (Config.getInstance().get(player).getPlainValueOrDefault("depth_message", true)) { + player.spigot().sendMessage(getMessage(player, dimensions.getBlockX() + 1, dimensions.getBlockY() + 1, dimensions.getBlockZ() + 1, tntCount)); + } }); } diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/DepthCommand.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/DepthCommand.java new file mode 100644 index 00000000..b7426fd7 --- /dev/null +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/cannon/depth/DepthCommand.java @@ -0,0 +1,45 @@ +/* + * 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.cannon.depth; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.configplayer.Config; +import de.steamwar.command.SWCommand; +import de.steamwar.linkage.Linked; +import org.bukkit.entity.Player; + +@Linked +public class DepthCommand extends SWCommand { + + public DepthCommand() { + super("depth"); + } + + @Register + public void toggle(Player player) { + if (Config.getInstance().get(player).getPlainValueOrDefault("depth_message", true)) { + Config.getInstance().get(player).put("depth_message", false); + BauSystem.MESSAGE.send("DEPTH_COUNTER_DISABLE", player); + } else { + Config.getInstance().get(player).put("depth_message", true); + BauSystem.MESSAGE.send("DEPTH_COUNTER_ENABLE", player); + } + } +} From 50b69473121d51dfa9ce9fe1699eb8db7f967ef0 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 13 Mar 2025 17:14:17 +0100 Subject: [PATCH 067/124] Hotfix DiscordChatRoom --- VelocityCore/src/de/steamwar/messages/Chatter.java | 8 ++++++-- .../velocitycore/discord/channels/DiscordChatRoom.java | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/VelocityCore/src/de/steamwar/messages/Chatter.java b/VelocityCore/src/de/steamwar/messages/Chatter.java index 2e67354c..607b4fd2 100644 --- a/VelocityCore/src/de/steamwar/messages/Chatter.java +++ b/VelocityCore/src/de/steamwar/messages/Chatter.java @@ -213,10 +213,14 @@ public interface Chatter { } static Chatter of(SteamwarUser user) { - return of(user.getUUID()); + return of(user.getUUID(), false); } static Chatter of(UUID uuid) { + return of(uuid, false); + } + + static Chatter of(UUID uuid, boolean playerlessChatShown) { Player player = VelocityCore.getProxy().getPlayer(uuid).orElse(null); if(player != null) return Chatter.of(player); @@ -229,7 +233,7 @@ public interface Chatter { @Override public boolean chatShown() { - return false; + return playerlessChatShown; } @Override diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChatRoom.java b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChatRoom.java index ce54b2d5..7b05357c 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChatRoom.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChatRoom.java @@ -47,6 +47,6 @@ public class DiscordChatRoom extends DiscordChannel { return; } - ChatListener.sendChat(Chatter.of(user), target.get(), format, null, event.getMessage().getContentDisplay().replace('§', '&').replace('\n', ' ')); + ChatListener.sendChat(Chatter.of(user.getUUID(), true), target.get(), format, null, event.getMessage().getContentDisplay().replace('§', '&').replace('\n', ' ')); } } From 9467291020ecb84ab8a7e40ddbccf26988e5b9e1 Mon Sep 17 00:00:00 2001 From: D4rkr34lm Date: Tue, 18 Mar 2025 21:33:34 +0100 Subject: [PATCH 068/124] Add license header to tracer lib --- .../features/script/lua/libs/TracerLib.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TracerLib.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TracerLib.java index 91b510e2..5178bdf9 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TracerLib.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TracerLib.java @@ -1,3 +1,22 @@ +/* + * 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.bausystem.features.script.lua.libs; import de.steamwar.bausystem.features.tracer.TNTPoint; From eca9963653ed7b403cb72da2f7c7f145c7f6c184 Mon Sep 17 00:00:00 2001 From: D4rkr34lm Date: Fri, 21 Mar 2025 18:49:49 +0100 Subject: [PATCH 069/124] Add example hotkey script --- BauSystem/hotkeys.lua | 89 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 BauSystem/hotkeys.lua diff --git a/BauSystem/hotkeys.lua b/BauSystem/hotkeys.lua new file mode 100644 index 00000000..91f8b7de --- /dev/null +++ b/BauSystem/hotkeys.lua @@ -0,0 +1,89 @@ +-- This file is a part of the SteamWar software. +-- +-- Copyright (C) 2021 SteamWar.de-Serverteam +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU Affero General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Affero General Public License for more details. +-- +-- You should have received a copy of the GNU Affero General Public License +-- along with this program. If not, see . + +--- +--- This serves both as an example and a quick start to the Stewamwar Script Api +--- + +hotkey("ctrl+g", hotkeys_freeze) +hotkey("ctrl+c", hotkeys_rgc) +hotkey("ctrl+v", hotkeys_rgp) +hotkey("ctrl+x", hotkeys_tick_step) +hotkey("shift+x", hotkeys_cycle_trace_view) +hotkey("ctrl+y", hotkeys_tb) +hotkey("ctrl+alt", hotkeys_trace_delete) +hotkey("ctrl+h", hotkeys_trace_delete) + + +function hotkeys_freeze(pressed) + if pressed then + exec("/freeze") + end +end + +function hotkeys_rgc(pressed) + if pressed then + exec("/rgc") + end +end + +function hotkeys_rgp(pressed) + if pressed then + exec("/rgp") + end +end + +trace_cycle_counter = 0; +function hotkeys_cycle_trace_view(pressed) + if not pressed then + return + end + trace_cycle = (trace_cycle + 1) % 3 + trace_commands = {"trace hide", "trace show", "trace show -e -c"} + exec(trace_commands[trace_cycle + 1]) +end + +function hotkeys_tick_step(pressed) + if pressed then + exec("tick step") + end +end + +function hotkeys_tpslimit(pressed) + if not pressed then + return + end + if tps.limit() == 20 then + exec("tpslimit 200") + else + exec("tpslimit 20") + end +end + +function hotkeys_tb(pressed) + if pressed then + exec("tb -e") + end +end + +function hotkeys_trace_delete(pressed) + if pressed then + exec("trace delete") + end +end + + From d22b01f5e6dbe84a6bee3fcca27ad5cfd79bf7e8 Mon Sep 17 00:00:00 2001 From: D4rkr34lm Date: Tue, 25 Mar 2025 21:54:03 +0100 Subject: [PATCH 070/124] Updated copyright --- BauSystem/hotkeys.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BauSystem/hotkeys.lua b/BauSystem/hotkeys.lua index 91f8b7de..7d9df865 100644 --- a/BauSystem/hotkeys.lua +++ b/BauSystem/hotkeys.lua @@ -1,6 +1,6 @@ -- This file is a part of the SteamWar software. -- --- Copyright (C) 2021 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 From 16f2eaad529cd26e0bea60c06a02401c1dab1760 Mon Sep 17 00:00:00 2001 From: D4rkr34lm Date: Tue, 25 Mar 2025 22:03:52 +0100 Subject: [PATCH 071/124] fixed Script ordering --- BauSystem/hotkeys.lua | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/BauSystem/hotkeys.lua b/BauSystem/hotkeys.lua index 7d9df865..f1182e7a 100644 --- a/BauSystem/hotkeys.lua +++ b/BauSystem/hotkeys.lua @@ -19,16 +19,6 @@ --- This serves both as an example and a quick start to the Stewamwar Script Api --- -hotkey("ctrl+g", hotkeys_freeze) -hotkey("ctrl+c", hotkeys_rgc) -hotkey("ctrl+v", hotkeys_rgp) -hotkey("ctrl+x", hotkeys_tick_step) -hotkey("shift+x", hotkeys_cycle_trace_view) -hotkey("ctrl+y", hotkeys_tb) -hotkey("ctrl+alt", hotkeys_trace_delete) -hotkey("ctrl+h", hotkeys_trace_delete) - - function hotkeys_freeze(pressed) if pressed then exec("/freeze") @@ -86,4 +76,12 @@ function hotkeys_trace_delete(pressed) end end +hotkey("ctrl+g", hotkeys_freeze) +hotkey("ctrl+c", hotkeys_rgc) +hotkey("ctrl+v", hotkeys_rgp) +hotkey("ctrl+x", hotkeys_tick_step) +hotkey("shift+x", hotkeys_cycle_trace_view) +hotkey("ctrl+y", hotkeys_tb) +hotkey("ctrl+alt", hotkeys_trace_delete) +hotkey("ctrl+h", hotkeys_trace_delete) From 4c8a03ac9c42698719263a76cb90e69a7b322ab8 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 29 Mar 2025 19:53:09 +0100 Subject: [PATCH 072/124] Add 30 seconds EndCountdown for TowerRun --- TowerRun/src/de/steamwar/towerrun/countdowns/EndCountdown.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TowerRun/src/de/steamwar/towerrun/countdowns/EndCountdown.java b/TowerRun/src/de/steamwar/towerrun/countdowns/EndCountdown.java index dbe0d40d..0162ba53 100644 --- a/TowerRun/src/de/steamwar/towerrun/countdowns/EndCountdown.java +++ b/TowerRun/src/de/steamwar/towerrun/countdowns/EndCountdown.java @@ -41,7 +41,7 @@ public class EndCountdown extends Countdown { @Override int defaultTime() { - return 10; + return 30; } @Override From 98cc09a7d388056808da551b9d9142e7d1fc5c14 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 30 Mar 2025 11:11:01 +0200 Subject: [PATCH 073/124] Trigger Rebuild --- CommonCore/SQL/src/de/steamwar/sql/NodeDownload.java | 2 +- SpigotCore/SpigotCore_Main/src/de/steamwar/sql/PersonalKit.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CommonCore/SQL/src/de/steamwar/sql/NodeDownload.java b/CommonCore/SQL/src/de/steamwar/sql/NodeDownload.java index 71cf83f4..b56a5994 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/NodeDownload.java +++ b/CommonCore/SQL/src/de/steamwar/sql/NodeDownload.java @@ -1,7 +1,7 @@ /* * This file is a part of the SteamWar software. * - * Copyright (C) 2021 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/SpigotCore/SpigotCore_Main/src/de/steamwar/sql/PersonalKit.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/sql/PersonalKit.java index fcc5a092..36e31490 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/sql/PersonalKit.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/sql/PersonalKit.java @@ -1,7 +1,7 @@ /* This file is a part of the SteamWar software. - Copyright (C) 2020 SteamWar.de-Serverteam + 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 From f6a18dffcc2b1edc98cbf6cfd7cc1f3450a6b2e8 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 30 Mar 2025 11:14:20 +0200 Subject: [PATCH 074/124] Trigger Rebuild --- .../SpigotCore_Main/src/de/steamwar/sql/SchematicData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/sql/SchematicData.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/sql/SchematicData.java index 62f00369..5ab944dc 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/sql/SchematicData.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/sql/SchematicData.java @@ -1,7 +1,7 @@ /* * This file is a part of the SteamWar software. * - * Copyright (C) 2022 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 From 1a356da6e005c39239b0512598c96d7a54bcf359 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sun, 30 Mar 2025 11:17:27 +0200 Subject: [PATCH 075/124] Trigger Rebuild --- CommonCore/SQL/src/de/steamwar/sql/NodeData.java | 1 - 1 file changed, 1 deletion(-) diff --git a/CommonCore/SQL/src/de/steamwar/sql/NodeData.java b/CommonCore/SQL/src/de/steamwar/sql/NodeData.java index a8d7c099..08179979 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/NodeData.java +++ b/CommonCore/SQL/src/de/steamwar/sql/NodeData.java @@ -30,7 +30,6 @@ import java.util.zip.GZIPInputStream; @AllArgsConstructor @Getter public class NodeData { - static { new SqlTypeMapper<>(PipedInputStream.class, "BLOB", (rs, identifier) -> { throw new SecurityException("PipedInputStream is write only datatype"); }, PreparedStatement::setBinaryStream); new SqlTypeMapper<>(ByteArrayInputStream.class, "BLOB", (rs, identifier) -> { throw new SecurityException("ByteArrayInputStream is write only datatype"); }, PreparedStatement::setBinaryStream); From c4e9f80315d8f61ebbb81ba5e6781b82d87e6df7 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Mon, 31 Mar 2025 19:56:36 +0200 Subject: [PATCH 076/124] Fix leader not changeable during events --- .../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 3a6a12a2..3c834fd1 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java @@ -73,7 +73,6 @@ public class FightTeam { if(ArenaMode.VariableTeams.contains(Config.mode)){ notReadyKit.setItem(2, "REQUESTS", new ItemBuilder(Material.PAPER).build(), GUI::chooseJoinRequests); - notReadyKit.setItem(3, "MANAGE_PLAYERS", SWItem.getPlayerSkull("AdmiralSeekrank").getItemStack(), GUI::managePlayers); if(!AIManager.availableAIs().isEmpty()) notReadyKit.setItem(6, "ADD_AI", new ItemBuilder(Material.REDSTONE).build(), GUI::addAI); } @@ -81,6 +80,7 @@ public class FightTeam { if(Config.test()) notReadyKit.setItem(5, "CHOOSE_SCHEMATIC", new ItemBuilder(SWItem.getMaterial("CAULDRON_ITEM")).enchant().build(), GUI::preSchemDialog); + notReadyKit.setItem(3, "MANAGE_PLAYERS", SWItem.getPlayerSkull("AdmiralSeekrank").getItemStack(), GUI::managePlayers); notReadyKit.setItem(4, "TEAM_NOT_READY", new ItemBuilder(SWItem.getDye(10), (short) 10).enchant().build(), player -> Objects.requireNonNull(Fight.getPlayerTeam(player)).setReady(true)); } private static final HotbarKit chooseSchemKit = new HotbarKit(notReadyKit); From b37ded3a8dafc2cafbfbffed97c82daef8fae976 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Mon, 31 Mar 2025 22:37:55 +0200 Subject: [PATCH 077/124] Add Alu-Hut --- LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java b/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java index 3ca809c1..dd7fcb8f 100644 --- a/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java +++ b/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java @@ -46,6 +46,7 @@ public class PlayerSpawn extends BasicListener { public static final ItemStack PARTICLE = new ItemBuilder(Material.NAME_TAG).setDisplayName("§6Partikel").setUnbreakable(true).removeAllAttributes().build(); private static final ItemStack ELYTRA = new ItemBuilder(Material.ELYTRA).setDisplayName("§5Elytra").setUnbreakable(true).removeAllAttributes().build(); public static final ItemStack NETHER_STAR = new ItemBuilder(Material.NETHER_STAR).setDisplayName("§5Teleporter").setUnbreakable(true).removeAllAttributes().build(); + public static final ItemStack ALU_HUT = new ItemBuilder(Material.CHAINMAIL_HELMET).setDisplayName("§8ALU Hut").setUnbreakable(true).removeAllAttributes().build(); @EventHandler(priority = EventPriority.HIGH) public void onJoin(PlayerJoinEvent e) { @@ -71,6 +72,7 @@ public class PlayerSpawn extends BasicListener { inventory.clear(); inventory.setItem(EquipmentSlot.CHEST, ELYTRA); + inventory.setItem(EquipmentSlot.HEAD, ALU_HUT); int offset = 0; if (AdventsCalendar.active()) { From 87f0765506aa0054c3d8755bae83604dfa4e7f6a Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Mon, 31 Mar 2025 22:44:01 +0200 Subject: [PATCH 078/124] Fix Realtime --- Realtime/src/de/steamwar/realtime/Realtime.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Realtime/src/de/steamwar/realtime/Realtime.java b/Realtime/src/de/steamwar/realtime/Realtime.java index cb2492ef..688cc185 100644 --- a/Realtime/src/de/steamwar/realtime/Realtime.java +++ b/Realtime/src/de/steamwar/realtime/Realtime.java @@ -42,6 +42,7 @@ public class Realtime extends JavaPlugin implements Listener { Bukkit.getScheduler().scheduleSyncRepeatingTask(this, () -> { Date date = new Date(); long time = date.getHours() * 1000 + (long)(date.getMinutes() * 16.66666666666667) + (long)(date.getSeconds() * 0.1666666666666667) - 6000; + time = 24000 - time; for(World world : Bukkit.getWorlds()) world.setTime(time); From 1dcd2f102cef283a3c38d9d496becdfbca135d74 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Tue, 1 Apr 2025 20:56:33 +0200 Subject: [PATCH 079/124] Allow edit of Lobby --- LobbySystem/src/de/steamwar/lobby/LobbySystem.java | 2 +- LobbySystem/src/de/steamwar/lobby/command/ModifyCommand.java | 2 +- LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java | 4 ++-- LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/LobbySystem/src/de/steamwar/lobby/LobbySystem.java b/LobbySystem/src/de/steamwar/lobby/LobbySystem.java index 4d198d4b..7449b5bc 100644 --- a/LobbySystem/src/de/steamwar/lobby/LobbySystem.java +++ b/LobbySystem/src/de/steamwar/lobby/LobbySystem.java @@ -70,7 +70,7 @@ public class LobbySystem extends JavaPlugin { new DoubleJumpListener(); new ParticleListener(); new InventoryInteraction(); - new WorldInteraction(); + // new WorldInteraction(); new PlayerSeatListener(); new MapsRotateListener(); new TeleporterListener(); diff --git a/LobbySystem/src/de/steamwar/lobby/command/ModifyCommand.java b/LobbySystem/src/de/steamwar/lobby/command/ModifyCommand.java index d782112d..78a9281e 100644 --- a/LobbySystem/src/de/steamwar/lobby/command/ModifyCommand.java +++ b/LobbySystem/src/de/steamwar/lobby/command/ModifyCommand.java @@ -60,7 +60,7 @@ public class ModifyCommand extends SWCommand implements Listener { LobbySystem.getEntityServer(true).removePlayer(player); player.setGameMode(GameMode.ADVENTURE); player.setOp(false); - PlayerSpawn.giveItems(player); + // PlayerSpawn.giveItems(player); }else { modifying.add(player); LobbySystem.getEntityServer(true).addPlayer(player); diff --git a/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java b/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java index f8ce3338..15fcc500 100644 --- a/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java +++ b/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java @@ -169,8 +169,8 @@ public class JumpAndRun extends BasicListener { } public static void reset(Player player) { - PlayerSpawn.giveItems(player); - player.setAllowFlight(true); + // PlayerSpawn.giveItems(player); + // player.setAllowFlight(true); CURRENT_POS.remove(player); START.remove(player); FAILS.remove(player); diff --git a/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java b/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java index dd7fcb8f..6ab111e8 100644 --- a/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java +++ b/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java @@ -53,12 +53,12 @@ public class PlayerSpawn extends BasicListener { Player player = e.getPlayer(); e.setJoinMessage(null); - player.setGameMode(GameMode.ADVENTURE); + player.setGameMode(GameMode.SURVIVAL); player.setWalkSpeed(0.5f); player.teleport(Bukkit.getWorlds().get(0).getSpawnLocation().clone().add(0.5, 0, 0.5)); player.setHealth(20); player.setFoodLevel(20); - giveItems(player); + // giveItems(player); LobbySystem.getEntityServer(false).addPlayer(player); BoatRace.boatNpcServer.addPlayer(player); From f62af55d39196c8cf7b85db48b14e6d94361b820 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Tue, 1 Apr 2025 20:58:10 +0200 Subject: [PATCH 080/124] Allow edit of Lobby --- LobbySystem/src/de/steamwar/lobby/LobbySystem.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LobbySystem/src/de/steamwar/lobby/LobbySystem.java b/LobbySystem/src/de/steamwar/lobby/LobbySystem.java index 7449b5bc..c593d205 100644 --- a/LobbySystem/src/de/steamwar/lobby/LobbySystem.java +++ b/LobbySystem/src/de/steamwar/lobby/LobbySystem.java @@ -69,7 +69,7 @@ public class LobbySystem extends JavaPlugin { new PlayerSpawn(); new DoubleJumpListener(); new ParticleListener(); - new InventoryInteraction(); + // new InventoryInteraction(); // new WorldInteraction(); new PlayerSeatListener(); new MapsRotateListener(); From 47c8cb1701b4af94ae3bedee967912fcddf50cdc Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Tue, 1 Apr 2025 23:19:24 +0200 Subject: [PATCH 081/124] Update difficulty --- LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java b/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java index 6ab111e8..ecf79056 100644 --- a/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java +++ b/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java @@ -26,6 +26,7 @@ import de.steamwar.lobby.util.ItemBuilder; import de.steamwar.network.NetworkSender; import de.steamwar.network.packets.client.ImALobbyPacket; import org.bukkit.Bukkit; +import org.bukkit.Difficulty; import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -52,6 +53,7 @@ public class PlayerSpawn extends BasicListener { public void onJoin(PlayerJoinEvent e) { Player player = e.getPlayer(); e.setJoinMessage(null); + player.getWorld().setDifficulty(Difficulty.HARD); player.setGameMode(GameMode.SURVIVAL); player.setWalkSpeed(0.5f); From 81c310c946a295156703ef1c32500ab0846a7b21 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Tue, 1 Apr 2025 23:32:32 +0200 Subject: [PATCH 082/124] Update difficulty --- .../src/de/steamwar/lobby/listener/PlayerSpawn.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java b/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java index ecf79056..5efdcd9a 100644 --- a/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java +++ b/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java @@ -25,10 +25,7 @@ import de.steamwar.lobby.special.advent.AdventsCalendar; import de.steamwar.lobby.util.ItemBuilder; import de.steamwar.network.NetworkSender; import de.steamwar.network.packets.client.ImALobbyPacket; -import org.bukkit.Bukkit; -import org.bukkit.Difficulty; -import org.bukkit.GameMode; -import org.bukkit.Material; +import org.bukkit.*; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -53,7 +50,12 @@ public class PlayerSpawn extends BasicListener { public void onJoin(PlayerJoinEvent e) { Player player = e.getPlayer(); e.setJoinMessage(null); - player.getWorld().setDifficulty(Difficulty.HARD); + Bukkit.getWorlds().forEach(world -> { + world.setDifficulty(Difficulty.HARD); + world.setGameRule(GameRule.MOB_GRIEFING, true); + world.setGameRule(GameRule.MOB_GRIEFING, true); + world.setGameRule(GameRule.DO_MOB_LOOT, true); + }); player.setGameMode(GameMode.SURVIVAL); player.setWalkSpeed(0.5f); From f533e850072b4715b1337c04e673524f4c4163ba Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 2 Apr 2025 08:58:42 +0200 Subject: [PATCH 083/124] Revert "Update difficulty" This reverts commit 81c310c946a295156703ef1c32500ab0846a7b21. --- .../src/de/steamwar/lobby/listener/PlayerSpawn.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java b/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java index 5efdcd9a..ecf79056 100644 --- a/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java +++ b/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java @@ -25,7 +25,10 @@ import de.steamwar.lobby.special.advent.AdventsCalendar; import de.steamwar.lobby.util.ItemBuilder; import de.steamwar.network.NetworkSender; import de.steamwar.network.packets.client.ImALobbyPacket; -import org.bukkit.*; +import org.bukkit.Bukkit; +import org.bukkit.Difficulty; +import org.bukkit.GameMode; +import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -50,12 +53,7 @@ public class PlayerSpawn extends BasicListener { public void onJoin(PlayerJoinEvent e) { Player player = e.getPlayer(); e.setJoinMessage(null); - Bukkit.getWorlds().forEach(world -> { - world.setDifficulty(Difficulty.HARD); - world.setGameRule(GameRule.MOB_GRIEFING, true); - world.setGameRule(GameRule.MOB_GRIEFING, true); - world.setGameRule(GameRule.DO_MOB_LOOT, true); - }); + player.getWorld().setDifficulty(Difficulty.HARD); player.setGameMode(GameMode.SURVIVAL); player.setWalkSpeed(0.5f); From b32d6e9c6942bcc1950171605bfde93d0884d95d Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 2 Apr 2025 08:58:42 +0200 Subject: [PATCH 084/124] Revert "Update difficulty" This reverts commit 47c8cb1701b4af94ae3bedee967912fcddf50cdc. --- LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java b/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java index ecf79056..6ab111e8 100644 --- a/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java +++ b/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java @@ -26,7 +26,6 @@ import de.steamwar.lobby.util.ItemBuilder; import de.steamwar.network.NetworkSender; import de.steamwar.network.packets.client.ImALobbyPacket; import org.bukkit.Bukkit; -import org.bukkit.Difficulty; import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -53,7 +52,6 @@ public class PlayerSpawn extends BasicListener { public void onJoin(PlayerJoinEvent e) { Player player = e.getPlayer(); e.setJoinMessage(null); - player.getWorld().setDifficulty(Difficulty.HARD); player.setGameMode(GameMode.SURVIVAL); player.setWalkSpeed(0.5f); From 5907648462db24a4d2a92c79c0a8bee0761592a4 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 2 Apr 2025 08:58:42 +0200 Subject: [PATCH 085/124] Revert "Allow edit of Lobby" This reverts commit f62af55d39196c8cf7b85db48b14e6d94361b820. --- LobbySystem/src/de/steamwar/lobby/LobbySystem.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LobbySystem/src/de/steamwar/lobby/LobbySystem.java b/LobbySystem/src/de/steamwar/lobby/LobbySystem.java index c593d205..7449b5bc 100644 --- a/LobbySystem/src/de/steamwar/lobby/LobbySystem.java +++ b/LobbySystem/src/de/steamwar/lobby/LobbySystem.java @@ -69,7 +69,7 @@ public class LobbySystem extends JavaPlugin { new PlayerSpawn(); new DoubleJumpListener(); new ParticleListener(); - // new InventoryInteraction(); + new InventoryInteraction(); // new WorldInteraction(); new PlayerSeatListener(); new MapsRotateListener(); From e7c4c998a0d887f65da40b6308df7e828f289618 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 2 Apr 2025 08:58:42 +0200 Subject: [PATCH 086/124] Revert "Allow edit of Lobby" This reverts commit 1dcd2f102cef283a3c38d9d496becdfbca135d74. --- LobbySystem/src/de/steamwar/lobby/LobbySystem.java | 2 +- LobbySystem/src/de/steamwar/lobby/command/ModifyCommand.java | 2 +- LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java | 4 ++-- LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/LobbySystem/src/de/steamwar/lobby/LobbySystem.java b/LobbySystem/src/de/steamwar/lobby/LobbySystem.java index 7449b5bc..4d198d4b 100644 --- a/LobbySystem/src/de/steamwar/lobby/LobbySystem.java +++ b/LobbySystem/src/de/steamwar/lobby/LobbySystem.java @@ -70,7 +70,7 @@ public class LobbySystem extends JavaPlugin { new DoubleJumpListener(); new ParticleListener(); new InventoryInteraction(); - // new WorldInteraction(); + new WorldInteraction(); new PlayerSeatListener(); new MapsRotateListener(); new TeleporterListener(); diff --git a/LobbySystem/src/de/steamwar/lobby/command/ModifyCommand.java b/LobbySystem/src/de/steamwar/lobby/command/ModifyCommand.java index 78a9281e..d782112d 100644 --- a/LobbySystem/src/de/steamwar/lobby/command/ModifyCommand.java +++ b/LobbySystem/src/de/steamwar/lobby/command/ModifyCommand.java @@ -60,7 +60,7 @@ public class ModifyCommand extends SWCommand implements Listener { LobbySystem.getEntityServer(true).removePlayer(player); player.setGameMode(GameMode.ADVENTURE); player.setOp(false); - // PlayerSpawn.giveItems(player); + PlayerSpawn.giveItems(player); }else { modifying.add(player); LobbySystem.getEntityServer(true).addPlayer(player); diff --git a/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java b/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java index 15fcc500..f8ce3338 100644 --- a/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java +++ b/LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java @@ -169,8 +169,8 @@ public class JumpAndRun extends BasicListener { } public static void reset(Player player) { - // PlayerSpawn.giveItems(player); - // player.setAllowFlight(true); + PlayerSpawn.giveItems(player); + player.setAllowFlight(true); CURRENT_POS.remove(player); START.remove(player); FAILS.remove(player); diff --git a/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java b/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java index 6ab111e8..dd7fcb8f 100644 --- a/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java +++ b/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java @@ -53,12 +53,12 @@ public class PlayerSpawn extends BasicListener { Player player = e.getPlayer(); e.setJoinMessage(null); - player.setGameMode(GameMode.SURVIVAL); + player.setGameMode(GameMode.ADVENTURE); player.setWalkSpeed(0.5f); player.teleport(Bukkit.getWorlds().get(0).getSpawnLocation().clone().add(0.5, 0, 0.5)); player.setHealth(20); player.setFoodLevel(20); - // giveItems(player); + giveItems(player); LobbySystem.getEntityServer(false).addPlayer(player); BoatRace.boatNpcServer.addPlayer(player); From 3b7e38aceb49f6b74a34bb4380d0208336ec7aeb Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 2 Apr 2025 08:58:42 +0200 Subject: [PATCH 087/124] Revert "Fix Realtime" This reverts commit 87f0765506aa0054c3d8755bae83604dfa4e7f6a. --- Realtime/src/de/steamwar/realtime/Realtime.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Realtime/src/de/steamwar/realtime/Realtime.java b/Realtime/src/de/steamwar/realtime/Realtime.java index 688cc185..cb2492ef 100644 --- a/Realtime/src/de/steamwar/realtime/Realtime.java +++ b/Realtime/src/de/steamwar/realtime/Realtime.java @@ -42,7 +42,6 @@ public class Realtime extends JavaPlugin implements Listener { Bukkit.getScheduler().scheduleSyncRepeatingTask(this, () -> { Date date = new Date(); long time = date.getHours() * 1000 + (long)(date.getMinutes() * 16.66666666666667) + (long)(date.getSeconds() * 0.1666666666666667) - 6000; - time = 24000 - time; for(World world : Bukkit.getWorlds()) world.setTime(time); From 8c374663120ae1490885c215211595bed0caf5c4 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 2 Apr 2025 08:58:42 +0200 Subject: [PATCH 088/124] Revert "Add Alu-Hut" This reverts commit b37ded3a8dafc2cafbfbffed97c82daef8fae976. --- LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java b/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java index dd7fcb8f..3ca809c1 100644 --- a/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java +++ b/LobbySystem/src/de/steamwar/lobby/listener/PlayerSpawn.java @@ -46,7 +46,6 @@ public class PlayerSpawn extends BasicListener { public static final ItemStack PARTICLE = new ItemBuilder(Material.NAME_TAG).setDisplayName("§6Partikel").setUnbreakable(true).removeAllAttributes().build(); private static final ItemStack ELYTRA = new ItemBuilder(Material.ELYTRA).setDisplayName("§5Elytra").setUnbreakable(true).removeAllAttributes().build(); public static final ItemStack NETHER_STAR = new ItemBuilder(Material.NETHER_STAR).setDisplayName("§5Teleporter").setUnbreakable(true).removeAllAttributes().build(); - public static final ItemStack ALU_HUT = new ItemBuilder(Material.CHAINMAIL_HELMET).setDisplayName("§8ALU Hut").setUnbreakable(true).removeAllAttributes().build(); @EventHandler(priority = EventPriority.HIGH) public void onJoin(PlayerJoinEvent e) { @@ -72,7 +71,6 @@ public class PlayerSpawn extends BasicListener { inventory.clear(); inventory.setItem(EquipmentSlot.CHEST, ELYTRA); - inventory.setItem(EquipmentSlot.HEAD, ALU_HUT); int offset = 0; if (AdventsCalendar.active()) { From c9a1528dfe748d5cfacd666ee6349262f528972a Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 2 Apr 2025 10:21:03 +0200 Subject: [PATCH 089/124] Update UserElo for better distribution --- .../SQL/src/de/steamwar/sql/UserElo.java | 58 ++++++++----------- 1 file changed, 24 insertions(+), 34 deletions(-) diff --git a/CommonCore/SQL/src/de/steamwar/sql/UserElo.java b/CommonCore/SQL/src/de/steamwar/sql/UserElo.java index 235fc302..055b0669 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/UserElo.java +++ b/CommonCore/SQL/src/de/steamwar/sql/UserElo.java @@ -112,27 +112,23 @@ public class UserElo { public static String getEmblemProgression(String gameMode, int userId) { switch (getProgression(userId, gameMode)) { case -1: - return "§f/ §8∨ ∧ ∨ ∧ ∨ ∧ ❂ III II I"; + return "§f/ §8❱❱❱❱ ❂"; case 0: - return "§8/ §6∨ §8∧ ∨ ∧ ∨ ∧ ❂ III II I"; + return "§8/ §e❱§8❱❱❱ ❂"; case 1: - return "§8/ ∨ §6∧ §8∨ ∧ ∨ ∧ ❂ III II I"; + return "§8/ §e❱❱§8❱❱ ❂"; case 2: - return "§8/ ∨ ∧ §7∨ §8∧ ∨ ∧ ❂ III II I"; + return "§8/ §e❱❱❱§8❱ ❂"; case 3: - return "§8/ ∨ ∧ ∨ §7∧ §8∨ ∧ ❂ III II I"; + return "§8/ §e❱❱❱❱§8 ❂"; case 4: - return "§8/ ∨ ∧ ∨ ∧ §e∨ §8∧ ❂ III II I"; + return "§8/ §8❱❱❱❱ §5❂"; case 5: - return "§8/ ∨ ∧ ∨ ∧ ∨ §e∧ §8❂ III II I"; + return "§8/ §8❱❱❱❱ §5III"; case 6: - return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ §5❂ §8III II I"; + return "§8/ §8❱❱❱❱ §5II"; case 7: - return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ ❂ §5III §8II I"; - case 8: - return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ ❂ III §5II §8I"; - case 9: - return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ ❂ III II §5I"; + return "§8/ §8❱❱❱❱ §5I"; default: throw new SecurityException("Progression is not in range"); } @@ -142,19 +138,17 @@ public class UserElo { int elo = getElo(userId, gameMode).orElse(-1); if (elo < 0) return -1; - if (elo <= 100) return 0; - if (elo <= 200) return 1; - if (elo <= 400) return 2; - if (elo <= 600) return 3; - if (elo <= 900) return 4; - if (elo <= 1200) return 5; + if (elo < 150) return 0; + if (elo < 350) return 1; + if (elo < 600) return 2; + if (elo < 900) return 3; int placement = getPlacement(elo, gameMode); - if (placement == 1) return 9; - if (placement == 2) return 8; - if (placement == 3) return 7; + if (placement == 1) return 7; + if (placement == 2) return 6; + if (placement == 3) return 5; - return 6; + return 4; } public static String toEmblem(int progression) { @@ -162,24 +156,20 @@ public class UserElo { case -1: return ""; case 0: - return "§6∨ "; + return "§e❱ "; case 1: - return "§6∧ "; + return "§e❱❱ "; case 2: - return "§7∨ "; + return "§e❱❱❱ "; case 3: - return "§7∧ "; + return "§e❱❱❱❱ "; case 4: - return "§e∨ "; - case 5: - return "§e∧ "; - case 6: return "§5❂ "; - case 7: + case 5: return "§5III "; - case 8: + case 6: return "§5II "; - case 9: + case 7: return "§5I "; default: throw new SecurityException("Progression out of range"); From 764dec99f471f567d35fe23f47cb2f3415f230ba Mon Sep 17 00:00:00 2001 From: Lixfel Date: Wed, 2 Apr 2025 19:05:27 +0200 Subject: [PATCH 090/124] Remove display name cleansing in direct tablist handling --- VelocityCore/src/de/steamwar/velocitycore/tablist/Tablist.java | 1 - 1 file changed, 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/tablist/Tablist.java b/VelocityCore/src/de/steamwar/velocitycore/tablist/Tablist.java index f15bc79c..6195bd73 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/tablist/Tablist.java +++ b/VelocityCore/src/de/steamwar/velocitycore/tablist/Tablist.java @@ -185,7 +185,6 @@ public class Tablist extends ChannelInboundHandlerAdapter { if(msg instanceof UpsertPlayerInfoPacket packet) { packet.getActions().remove(UpsertPlayerInfoPacket.Action.INITIALIZE_CHAT); packet.getActions().remove(UpsertPlayerInfoPacket.Action.UPDATE_LATENCY); - packet.getActions().remove(UpsertPlayerInfoPacket.Action.UPDATE_DISPLAY_NAME); packet.getActions().remove(UpsertPlayerInfoPacket.Action.UPDATE_LISTED); if(packet.getActions().isEmpty()) { ReferenceCountUtil.release(msg); From 9248c9fa519a7b71e4cd08577e91b5e3d546efe0 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 3 Apr 2025 17:56:19 +0200 Subject: [PATCH 091/124] Remove first second and third in master rank --- .../SQL/src/de/steamwar/sql/UserElo.java | 38 +++---------------- 1 file changed, 6 insertions(+), 32 deletions(-) diff --git a/CommonCore/SQL/src/de/steamwar/sql/UserElo.java b/CommonCore/SQL/src/de/steamwar/sql/UserElo.java index 055b0669..d9876c4c 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/UserElo.java +++ b/CommonCore/SQL/src/de/steamwar/sql/UserElo.java @@ -75,15 +75,7 @@ public class UserElo { public static void setElo(int userId, String gameMode, int elo) { emblemCache.remove(userId); - - int oldPlacement = getPlacement(getElo(userId, gameMode).orElse(0), gameMode); - int newPlacement = getPlacement(elo, gameMode); - gameModeUserEloCache.getOrDefault(gameMode, Collections.emptyMap()).remove(userId); - if (oldPlacement <= 3 || newPlacement <= 3) { - emblemCache.clear(); - } - setElo.update(Season.getSeason(), gameMode, userId, elo); } @@ -112,23 +104,17 @@ public class UserElo { public static String getEmblemProgression(String gameMode, int userId) { switch (getProgression(userId, gameMode)) { case -1: - return "§f/ §8❱❱❱❱ ❂"; + return "§8❱❱❱❱ ❂"; case 0: - return "§8/ §e❱§8❱❱❱ ❂"; + return "§e❱§8❱❱❱ ❂"; case 1: - return "§8/ §e❱❱§8❱❱ ❂"; + return "§e❱❱§8❱❱ ❂"; case 2: - return "§8/ §e❱❱❱§8❱ ❂"; + return "§e❱❱❱§8❱ ❂"; case 3: - return "§8/ §e❱❱❱❱§8 ❂"; + return "§e❱❱❱❱§8 ❂"; case 4: - return "§8/ §8❱❱❱❱ §5❂"; - case 5: - return "§8/ §8❱❱❱❱ §5III"; - case 6: - return "§8/ §8❱❱❱❱ §5II"; - case 7: - return "§8/ §8❱❱❱❱ §5I"; + return "§8❱❱❱❱ §5❂"; default: throw new SecurityException("Progression is not in range"); } @@ -142,12 +128,6 @@ public class UserElo { if (elo < 350) return 1; if (elo < 600) return 2; if (elo < 900) return 3; - - int placement = getPlacement(elo, gameMode); - if (placement == 1) return 7; - if (placement == 2) return 6; - if (placement == 3) return 5; - return 4; } @@ -165,12 +145,6 @@ public class UserElo { return "§e❱❱❱❱ "; case 4: return "§5❂ "; - case 5: - return "§5III "; - case 6: - return "§5II "; - case 7: - return "§5I "; default: throw new SecurityException("Progression out of range"); } From dafe838a8a2cab1c5a6dcfa3fe88c1a96d3b5c39 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 4 Apr 2025 10:49:01 +0200 Subject: [PATCH 092/124] Improve DiscordChannel on discord! --- .../discord/channels/DiscordChannel.java | 56 +++++++++++++++++-- 1 file changed, 51 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 b420f601..e1dc9912 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java @@ -26,10 +26,13 @@ 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.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.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; @@ -61,12 +64,55 @@ public class DiscordChannel extends Chatter.PlayerlessChatter { } public void send(String message) { + message = message + .replace("&", "") + .replace("@everyone", "`@everyone`") + .replace("@here", "`@here`") + .replaceAll("<[@#]!?\\d+>", "`$0`"); + + if (getChannel() instanceof TextChannel && message.contains("»")) { + String[] strings = message.split("»", 2); + String userName = strings[0]; + message = strings[1]; + strings = userName.split(" "); + + String ingameName = strings[strings.length - 1]; + + SteamwarUser user = SteamwarUser.get(ingameName); + if (user != null) { + send(new MessageCreateBuilder() + .setContent(message)); + return; + } + + ImageProxy avatarUrl; + if (user.getDiscordId() != null) { + avatarUrl = DiscordBot.getGuild().retrieveMemberById(user.getDiscordId()).complete().getEffectiveAvatar(); + } else { + avatarUrl = DiscordBot.getInstance().getJda().getSelfUser().getAvatar(); + } + + TextChannel textChannel = (TextChannel) getChannel(); + String finalMessage = message; + try { + textChannel.createWebhook(userName) + .setAvatar(Icon.from(avatarUrl.download(128).get())) + .onSuccess(webhook -> { + webhook.sendMessage(finalMessage) + .onSuccess(__ -> { + webhook.delete().queue(); + }) + .queue(); + }) + .queue(); + return; + } catch (Exception e) { + // Ignore and send message as normal! + } + } + send(new MessageCreateBuilder() - .setContent(message - .replace("&", "") - .replace("@everyone", "`@everyone`") - .replace("@here", "`@here`") - .replaceAll("<[@#]!?\\d+>", "`$0`"))); + .setContent(message)); } public void send(MessageCreateBuilder builder) { From bfdc9c118a79ea2b5289733394b312405b9fabb9 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 4 Apr 2025 10:52:37 +0200 Subject: [PATCH 093/124] Hopefully fix it --- .../velocitycore/discord/channels/DiscordChannel.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java index e1dc9912..07e0527c 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java @@ -73,12 +73,13 @@ public class DiscordChannel extends Chatter.PlayerlessChatter { if (getChannel() instanceof TextChannel && message.contains("»")) { String[] strings = message.split("»", 2); String userName = strings[0]; - message = strings[1]; + String sendMessage = strings[1]; strings = userName.split(" "); String ingameName = strings[strings.length - 1]; SteamwarUser user = SteamwarUser.get(ingameName); + System.out.println(ingameName + " " + user); if (user != null) { send(new MessageCreateBuilder() .setContent(message)); @@ -93,12 +94,11 @@ public class DiscordChannel extends Chatter.PlayerlessChatter { } TextChannel textChannel = (TextChannel) getChannel(); - String finalMessage = message; try { textChannel.createWebhook(userName) .setAvatar(Icon.from(avatarUrl.download(128).get())) .onSuccess(webhook -> { - webhook.sendMessage(finalMessage) + webhook.sendMessage(sendMessage) .onSuccess(__ -> { webhook.delete().queue(); }) @@ -107,6 +107,7 @@ public class DiscordChannel extends Chatter.PlayerlessChatter { .queue(); return; } catch (Exception e) { + e.printStackTrace(); // Ignore and send message as normal! } } From 57ea1470e2510fcfbd96ecfc6f01d33b006112c1 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 4 Apr 2025 10:54:06 +0200 Subject: [PATCH 094/124] Fix for real! --- .../velocitycore/discord/channels/DiscordChannel.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java index 07e0527c..7092aeb4 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/DiscordChannel.java @@ -79,8 +79,7 @@ public class DiscordChannel extends Chatter.PlayerlessChatter { String ingameName = strings[strings.length - 1]; SteamwarUser user = SteamwarUser.get(ingameName); - System.out.println(ingameName + " " + user); - if (user != null) { + if (user == null) { send(new MessageCreateBuilder() .setContent(message)); return; @@ -107,7 +106,6 @@ public class DiscordChannel extends Chatter.PlayerlessChatter { .queue(); return; } catch (Exception e) { - e.printStackTrace(); // Ignore and send message as normal! } } From 2686ab285beb94f55a4d1a6f87da3d916462c91f Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 4 Apr 2025 11:16:12 +0200 Subject: [PATCH 095/124] Improve WaitTime in ChecklistChannel --- .../velocitycore/discord/channels/ChecklistChannel.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/ChecklistChannel.java b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/ChecklistChannel.java index 2e6de441..52377976 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/ChecklistChannel.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/ChecklistChannel.java @@ -23,6 +23,7 @@ import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SteamwarUser; import de.steamwar.velocitycore.commands.CheckCommand; +import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -41,7 +42,8 @@ public class ChecklistChannel extends DiscordChannel { schems.removeIf(schem -> lastSchematics.contains(schem.getId())); for(SchematicNode schem : schems) { - system("CHECK_LIST_TO_CHECK", CheckCommand.getWaitTime(schem), schem.getSchemtype().getKuerzel(), SteamwarUser.get(schem.getOwner()).getUserName(), schem.getName()); + String waitTime = ""; + system("CHECK_LIST_TO_CHECK", waitTime, schem.getSchemtype().getKuerzel(), SteamwarUser.get(schem.getOwner()).getUserName(), schem.getName()); lastSchematics.add(schem.getId()); } } From a6c46d02708540788e569d73274290e58013d41c Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 4 Apr 2025 11:21:54 +0200 Subject: [PATCH 096/124] Use combinedIds to hide in TechHider.iBlockDataHidden --- .../src/de/steamwar/techhider/TechHider.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java index 03063eb8..3c9e3677 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java @@ -49,10 +49,9 @@ public class TechHider { public static final Class craftMagicNumbers = Reflection.getClass("org.bukkit.craftbukkit.util.CraftMagicNumbers"); private static final Reflection.Method getBlockByMaterial = Reflection.getTypedMethod(craftMagicNumbers, "getBlock", block, Material.class); - private static final Reflection.Method getBlockByBlockData = Reflection.getTypedMethod(iBlockData, null, block); - private static final Reflection.Method getMaterialByBlock = Reflection.getTypedMethod(craftMagicNumbers, "getMaterial", Material.class, block); + private static final Reflection.Method getCombinedIdByIBlockData = Reflection.getTypedMethod(block, null, int.class, iBlockData); public boolean iBlockDataHidden(Object iBlockData) { - return obfuscate.contains((Material) getMaterialByBlock.invoke(null, getBlockByBlockData.invoke(iBlockData))); + return obfuscateIds.contains(getCombinedIdByIBlockData.invoke(null, iBlockData)); } public static final Object AIR = getBlockDataByBlock.invoke(getBlockByMaterial.invoke(null, Material.AIR)); @@ -66,15 +65,12 @@ public class TechHider { @Getter private final int obfuscationTargetId; @Getter - private final Set obfuscate; - @Getter private final Set obfuscateIds; @Getter private final Set hiddenBlockEntities; public TechHider(LocationEvaluator locationEvaluator, Material obfuscationTarget, Set obfuscate, Set hiddenBlockEntities) { this.locationEvaluator = locationEvaluator; - this.obfuscate = obfuscate; this.obfuscateIds = obfuscate.stream().flatMap(m -> BlockIds.impl.materialToAllIds(m).stream()).collect(Collectors.toSet()); this.hiddenBlockEntities = hiddenBlockEntities; this.obfuscationTarget = getBlockDataByBlock.invoke(getBlockByMaterial.invoke(null, obfuscationTarget)); From 446cd5deae41c4f9e2ea4dc1d17a56f9ebad4a57 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 4 Apr 2025 11:23:51 +0200 Subject: [PATCH 097/124] Fixup ChecklistChannel --- .../velocitycore/discord/channels/ChecklistChannel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/ChecklistChannel.java b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/ChecklistChannel.java index 52377976..6f19f34e 100644 --- a/VelocityCore/src/de/steamwar/velocitycore/discord/channels/ChecklistChannel.java +++ b/VelocityCore/src/de/steamwar/velocitycore/discord/channels/ChecklistChannel.java @@ -42,7 +42,7 @@ public class ChecklistChannel extends DiscordChannel { schems.removeIf(schem -> lastSchematics.contains(schem.getId())); for(SchematicNode schem : schems) { - String waitTime = ""; + String waitTime = ""; system("CHECK_LIST_TO_CHECK", waitTime, schem.getSchemtype().getKuerzel(), SteamwarUser.get(schem.getOwner()).getUserName(), schem.getName()); lastSchematics.add(schem.getId()); } From fd220d7fd47eec77b4d930fdf65626b5c8b0c1a9 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Fri, 4 Apr 2025 13:57:09 +0200 Subject: [PATCH 098/124] Fix maven url --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 87430368..9fdaa60e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -46,7 +46,7 @@ dependencyResolutionManagement { if (isInCi) { url = URI("file:///var/www/maven/") } else { - url = URI("https://steamwar.de/maven/") + url = URI("https://maven.steamwar.de/") credentials { val swProps = Properties() swProps.load(rootDir.resolve("steamwar.properties").inputStream()) From 812e78d277f78d086a13787eb57801b6cbcb2859 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Sat, 5 Apr 2025 18:02:48 +0200 Subject: [PATCH 099/124] Make it 1.8 compatible --- .../SpigotCore_14/src/de/steamwar/techhider/BlockIds14.java | 4 ++-- .../SpigotCore_8/src/de/steamwar/techhider/BlockIds8.java | 6 ++++++ .../SpigotCore_Main/src/de/steamwar/techhider/BlockIds.java | 4 ++++ .../src/de/steamwar/techhider/TechHider.java | 3 +-- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/SpigotCore/SpigotCore_14/src/de/steamwar/techhider/BlockIds14.java b/SpigotCore/SpigotCore_14/src/de/steamwar/techhider/BlockIds14.java index ebf5e952..6e2c0397 100644 --- a/SpigotCore/SpigotCore_14/src/de/steamwar/techhider/BlockIds14.java +++ b/SpigotCore/SpigotCore_14/src/de/steamwar/techhider/BlockIds14.java @@ -66,8 +66,8 @@ public class BlockIds14 implements BlockIds { return getBlock.invoke(null, material); } - private static final Reflection.Method getCombinedId = Reflection.getTypedMethod(TechHider.block, null, int.class, TechHider.iBlockData); - private int getCombinedId(Object blockData) { + @Override + public int getCombinedId(Object blockData) { return (int) getCombinedId.invoke(null, blockData); } } diff --git a/SpigotCore/SpigotCore_8/src/de/steamwar/techhider/BlockIds8.java b/SpigotCore/SpigotCore_8/src/de/steamwar/techhider/BlockIds8.java index 538e8dbd..64ac6c41 100644 --- a/SpigotCore/SpigotCore_8/src/de/steamwar/techhider/BlockIds8.java +++ b/SpigotCore/SpigotCore_8/src/de/steamwar/techhider/BlockIds8.java @@ -25,6 +25,12 @@ import java.util.Collections; import java.util.Set; public class BlockIds8 implements BlockIds { + @Override + public int getCombinedId(Object iBlockData) { + int id = (int) getCombinedId.invoke(null, iBlockData); // blockState << 12 | blockId + return (id & 4095) | (id >> 12); + } + @Override @SuppressWarnings("deprecation") public int materialToId(Material material) { diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/BlockIds.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/BlockIds.java index 8e129a1d..fa2f7f6e 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/BlockIds.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/BlockIds.java @@ -19,6 +19,7 @@ package de.steamwar.techhider; +import de.steamwar.Reflection; import de.steamwar.core.Core; import de.steamwar.core.VersionDependent; import org.bukkit.Material; @@ -28,6 +29,9 @@ import java.util.Set; public interface BlockIds { BlockIds impl = VersionDependent.getVersionImpl(Core.getInstance()); + Reflection.Method getCombinedId = Reflection.getTypedMethod(TechHider.block, null, int.class, TechHider.iBlockData); + + int getCombinedId(Object iBlockData); int materialToId(Material material); Set materialToAllIds(Material material); } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java index 3c9e3677..021d2fe4 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/techhider/TechHider.java @@ -49,9 +49,8 @@ public class TechHider { public static final Class craftMagicNumbers = Reflection.getClass("org.bukkit.craftbukkit.util.CraftMagicNumbers"); private static final Reflection.Method getBlockByMaterial = Reflection.getTypedMethod(craftMagicNumbers, "getBlock", block, Material.class); - private static final Reflection.Method getCombinedIdByIBlockData = Reflection.getTypedMethod(block, null, int.class, iBlockData); public boolean iBlockDataHidden(Object iBlockData) { - return obfuscateIds.contains(getCombinedIdByIBlockData.invoke(null, iBlockData)); + return obfuscateIds.contains(BlockIds.impl.getCombinedId(iBlockData)); } public static final Object AIR = getBlockDataByBlock.invoke(getBlockByMaterial.invoke(null, Material.AIR)); From 9c3f7526ff2f878d279df73aeba67a96bbb39a19 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Mon, 7 Apr 2025 19:37:23 +0200 Subject: [PATCH 100/124] Add techhiderbug command. --- FightSystem/FightSystem_Core/build.gradle.kts | 1 + .../de/steamwar/fightsystem/FightSystem.java | 1 + .../commands/TechhiderbugCommand.java | 71 +++++++++++++++++++ .../fightsystem/states/FightState.java | 1 + .../de/steamwar/fightsystem/utils/Hull.java | 1 + .../steamwar/fightsystem/utils/HullHider.java | 2 + .../de/steamwar/fightsystem/utils/Region.java | 5 ++ .../fightsystem/utils/TechHiderWrapper.java | 2 + FightSystem/FightSystem_Core/src/plugin.yml | 1 + .../comphenix/tinyprotocol/TinyProtocol.java | 5 +- 10 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/TechhiderbugCommand.java diff --git a/FightSystem/FightSystem_Core/build.gradle.kts b/FightSystem/FightSystem_Core/build.gradle.kts index 2f044447..93dd59c4 100644 --- a/FightSystem/FightSystem_Core/build.gradle.kts +++ b/FightSystem/FightSystem_Core/build.gradle.kts @@ -29,4 +29,5 @@ dependencies { compileOnly(libs.worldedit15) compileOnly(libs.fastutil) compileOnly(libs.authlib) + compileOnly(libs.netty) } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java index 57400063..23e2bb0c 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java @@ -156,6 +156,7 @@ public class FightSystem extends JavaPlugin { new LockschemCommand(); new StateCommand(); new SkipCommand(); + new TechhiderbugCommand(); new TPSWarpCommand(); new UnrankCommand(); new WinCommand(); diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/TechhiderbugCommand.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/TechhiderbugCommand.java new file mode 100644 index 00000000..4a3bf47f --- /dev/null +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/commands/TechhiderbugCommand.java @@ -0,0 +1,71 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2025 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.fightsystem.commands; + +import com.comphenix.tinyprotocol.TinyProtocol; +import de.steamwar.fightsystem.ArenaMode; +import de.steamwar.fightsystem.Config; +import de.steamwar.fightsystem.FightSystem; +import de.steamwar.fightsystem.fight.Fight; +import de.steamwar.fightsystem.states.FightState; +import de.steamwar.fightsystem.states.StateDependentCommand; +import de.steamwar.sql.SWException; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +import java.io.StringWriter; +import java.util.Arrays; + +public class TechhiderbugCommand implements CommandExecutor { + + public TechhiderbugCommand() { + new StateDependentCommand(ArenaMode.All, FightState.All, "techhiderbug", this); + } + + @Override + 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'); + + 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("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')); + + SWException.log("Techhider-Bug reported by " + sender.getName() + ": " + Arrays.toString(args), writer.toString()); + return false; + } +} diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/states/FightState.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/states/FightState.java index 1d5acf35..cadcec66 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/states/FightState.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/states/FightState.java @@ -49,6 +49,7 @@ public enum FightState { public static final Set AntiIngame = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(PRE_RUNNING, RUNNING))); public static final Set AntiSpectate = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(SPECTATE))); + @Getter private static final Map stateDependentFeatures = new HashMap<>(); @Getter private static FightState fightState = PRE_LEADER_SETUP; diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java index a67c6d5d..caf39e79 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java @@ -45,6 +45,7 @@ public class Hull { return material.isOccluding() || Config.HiddenBlocks.contains(material); } + @Getter private final Region region; private final boolean groundVisible; private final IntVector[] directions; diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHider.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHider.java index 455b960d..c050656d 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHider.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHider.java @@ -33,6 +33,7 @@ import de.steamwar.fightsystem.states.StateDependent; import de.steamwar.fightsystem.states.StateDependentListener; import de.steamwar.fightsystem.states.StateDependentTask; import de.steamwar.techhider.TechHider; +import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; @@ -56,6 +57,7 @@ import java.util.function.Function; public class HullHider implements Listener { + @Getter private final Map hullMap = new HashMap<>(); private final Hull[] hulls; private final Map, BiFunction> packetHiders = new HashMap<>(); diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Region.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Region.java index 6a559799..60d37be8 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Region.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Region.java @@ -159,4 +159,9 @@ public class Region { public interface TriConsumer{ void accept(T x, V y, U z); } + + @Override + public String toString() { + return minX + "," + minY + "," + minZ + "->" + maxX + "," + maxY + "," + maxZ; + } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java index c45d7ab6..bf890168 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/TechHiderWrapper.java @@ -32,6 +32,7 @@ import de.steamwar.fightsystem.states.StateDependent; import de.steamwar.fightsystem.states.StateDependentListener; import de.steamwar.sql.SteamwarUser; import de.steamwar.techhider.TechHider; +import lombok.Getter; import org.bukkit.GameMode; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -51,6 +52,7 @@ public class TechHiderWrapper extends StateDependent implements TechHider.Locati public static final boolean ENABLED = !Config.OnlyPublicSchematics && !Config.test() && Config.TechhiderActive; + @Getter private final ConcurrentHashMap hiddenRegion = new ConcurrentHashMap<>(); private final ConcurrentHashMap patterns = new ConcurrentHashMap<>(); private final TechHider techHider; diff --git a/FightSystem/FightSystem_Core/src/plugin.yml b/FightSystem/FightSystem_Core/src/plugin.yml index 64ece716..6925bf69 100644 --- a/FightSystem/FightSystem_Core/src/plugin.yml +++ b/FightSystem/FightSystem_Core/src/plugin.yml @@ -27,4 +27,5 @@ commands: resettb: tpslimit: tpswarp: + techhiderbug: unrank: \ No newline at end of file diff --git a/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java b/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java index 7cca9c95..af318d83 100644 --- a/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java +++ b/SpigotCore/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java @@ -23,6 +23,7 @@ import de.steamwar.Reflection; import de.steamwar.Reflection.Field; import de.steamwar.core.Core; import io.netty.channel.*; +import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -67,6 +68,7 @@ public class TinyProtocol implements Listener { private boolean closed; private final Map, List>> packetFilters = new HashMap<>(); + @Getter private final Map playerInterceptors = new HashMap<>(); private TinyProtocol(final Plugin plugin) { @@ -136,8 +138,9 @@ public class TinyProtocol implements Listener { private static final Field getChannel = Reflection.getField(networkManager, Channel.class, 0); private static final Field getUUID = Reflection.getField(networkManager, UUID.class, 0); - private final class PacketInterceptor extends ChannelDuplexHandler { + public final class PacketInterceptor extends ChannelDuplexHandler { private final Player player; + @Getter private final Channel channel; private PacketInterceptor(Player player) { From 4c6ab2c1a0e71bac024c399bc49ff6a682f7f1a9 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Tue, 8 Apr 2025 20:52:54 +0200 Subject: [PATCH 101/124] 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 d1d1679c0a84bcf5edd907d75e9e437f746747aa Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Tue, 8 Apr 2025 20:54:48 +0200 Subject: [PATCH 102/124] Add /skull shorthand for own skull --- .../de/steamwar/bausystem/features/util/SkullCommand.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/SkullCommand.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/SkullCommand.java index 1f50a2ae..55ea2c05 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/SkullCommand.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/SkullCommand.java @@ -42,6 +42,11 @@ public class SkullCommand extends SWCommand { super("skull", "head"); } + @Register + public void giveCommand(@Validator Player p) { + giveCommand(p, p.getName()); + } + @Register(description = "SKULL_HELP") public void giveCommand(@Validator Player p, @Mapper("player") @ErrorMessage("SKULL_INVALID") String skull) { ItemStack is = SWItem.getPlayerSkull(skull).getItemStack(); From d9493c7474f48367f31d428351e3116f0523206b Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Tue, 8 Apr 2025 20:58:23 +0200 Subject: [PATCH 103/124] Dont show bedrock players and send an error for getting your own skull as a bedrock player --- .../de/steamwar/bausystem/features/util/SkullCommand.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/SkullCommand.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/SkullCommand.java index 55ea2c05..e7da48d1 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/SkullCommand.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/util/SkullCommand.java @@ -44,6 +44,10 @@ public class SkullCommand extends SWCommand { @Register public void giveCommand(@Validator Player p) { + if (p.getName().startsWith(".")) { + BauSystem.MESSAGE.send("SKULL_INVALID", p); + return; + } giveCommand(p, p.getName()); } @@ -68,7 +72,7 @@ public class SkullCommand extends SWCommand { @Override public List tabCompletes(CommandSender commandSender, PreviousArguments previousArguments, String s) { - return Bukkit.getOnlinePlayers().stream().map(Player::getName).filter(s1 -> !s1.endsWith("⍇")).collect(Collectors.toList()); + return Bukkit.getOnlinePlayers().stream().map(Player::getName).filter(s1 -> !s1.startsWith(".")).collect(Collectors.toList()); } }; } From 2405c5e6205f87a16dc8d3c3929625a2f54105b7 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Tue, 8 Apr 2025 21:31:47 +0200 Subject: [PATCH 104/124] Fix spectator handling --- .../de/steamwar/fightsystem/FightSystem.java | 1 + .../de/steamwar/fightsystem/fight/Fight.java | 34 ------ .../steamwar/fightsystem/fight/FightTeam.java | 10 +- .../fightsystem/listener/LeaveableArena.java | 2 +- .../fightsystem/listener/Permanent.java | 6 +- .../fightsystem/listener/Spectator.java | 102 ++++++++++++++++++ .../fightsystem/listener/TeamArea.java | 44 ++------ 7 files changed, 118 insertions(+), 81 deletions(-) create mode 100644 FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Spectator.java diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java index 23e2bb0c..b32a41b9 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java @@ -97,6 +97,7 @@ public class FightSystem extends JavaPlugin { new PrepareSchem(); new TestJoin(); new NormalJoin(); + new Spectator(); new RunningWorldInteraction(); new PersonalKitCreator(); new ArrowStopper(); diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java index 5b8f62f9..1f205122 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java @@ -104,40 +104,6 @@ public class Fight { return null; } - @SuppressWarnings("deprecation") - public static void setPlayerGamemode(Player player, GameMode gameMode) { - player.setGameMode(gameMode); - - if(gameMode == GameMode.SPECTATOR) { - for(Player currentPlayer : Bukkit.getServer().getOnlinePlayers()) { - if(currentPlayer.getUniqueId() != player.getUniqueId() && currentPlayer.getGameMode() == GameMode.SPECTATOR) { - currentPlayer.hidePlayer(player); - player.hidePlayer(currentPlayer); - } - } - - if(Config.test() || Config.isReferee(player)) - return; - - Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> { - if(!player.isOnline()) - return; - pseudoSpectator(player, true); - }, 1); - }else if(gameMode == GameMode.SURVIVAL) { - for(Player currentPlayer : Bukkit.getServer().getOnlinePlayers()) { - if(currentPlayer.getUniqueId() != player.getUniqueId() && currentPlayer.getGameMode() == GameMode.SPECTATOR) { - currentPlayer.showPlayer(player); - player.showPlayer(currentPlayer); - } - } - } - } - - public static void pseudoSpectator(Player player, boolean enable) { - TinyProtocol.instance.sendPacket(player, ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.GAMEMODE, new GameProfile(player.getUniqueId(), player.getName()), enable ? GameMode.CREATIVE : GameMode.SPECTATOR)); - } - public static boolean publicOnly() { if (Config.OnlyPublicSchematics) { return true; 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 3c834fd1..0cb68f71 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java @@ -282,9 +282,9 @@ public class FightTeam { FightSystem.getHullHider().updatePlayer(player); if(FightState.Spectate.contains(FightState.getFightState())) { - Fight.setPlayerGamemode(player, GameMode.SPECTATOR); + player.setGameMode(GameMode.SPECTATOR); } else { - Fight.setPlayerGamemode(player, GameMode.SURVIVAL); + player.setGameMode(GameMode.SURVIVAL); (FightState.ingame() ? fightPlayer.getKit() : memberKit).loadToPlayer(player); } }); @@ -317,7 +317,7 @@ public class FightTeam { entity.teleport(Config.SpecSpawn); fightPlayer.ifPlayer(player -> { - Fight.setPlayerGamemode(player, GameMode.SPECTATOR); + player.setGameMode(GameMode.SPECTATOR); player.getInventory().clear(); if(player.isOnline()){ @@ -517,14 +517,14 @@ public class FightTeam { @Override public void enable() { players.values().forEach(fightPlayer -> { - fightPlayer.ifPlayer(player -> Fight.setPlayerGamemode(player, GameMode.SPECTATOR)); + fightPlayer.ifPlayer(player -> player.setGameMode(GameMode.SPECTATOR)); fightPlayer.getEntity().teleport(FightTeam.this.spawn); }); } @Override public void disable() { - players.values().forEach(fightPlayer -> fightPlayer.ifPlayer(player -> Fight.setPlayerGamemode(player, GameMode.SURVIVAL))); + players.values().forEach(fightPlayer -> fightPlayer.ifPlayer(player -> player.setGameMode(GameMode.SURVIVAL))); } } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/LeaveableArena.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/LeaveableArena.java index 9d0bb4e2..36a5a189 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/LeaveableArena.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/LeaveableArena.java @@ -84,6 +84,6 @@ public class LeaveableArena implements Listener { private void markInArena(Player player) { spectatorsInArena.put(player, player.getGameMode()); - Fight.setPlayerGamemode(player, GameMode.SPECTATOR); + player.setGameMode(GameMode.SPECTATOR); } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java index 2f3138ec..4976463c 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java @@ -74,7 +74,7 @@ public class Permanent implements Listener { public void handlePlayerRespawn(PlayerRespawnEvent event){ Player player = event.getPlayer(); if(Fight.fighting(player)) { - Fight.setPlayerGamemode(player, GameMode.SPECTATOR); + player.setGameMode(GameMode.SPECTATOR); FightTeam team = Fight.getPlayerTeam(player); event.setRespawnLocation(team == null ? Config.SpecSpawn : team.getSpawn()); @@ -98,11 +98,11 @@ public class Permanent implements Listener { FightPlayer fp = Fight.getFightPlayer(player); if (!Config.ArenaLeaveable && fp == null) { - Fight.setPlayerGamemode(player, GameMode.SPECTATOR); + player.setGameMode(GameMode.SPECTATOR); spectatorTeam.addEntry(player.getName()); player.teleport(Config.SpecSpawn); } else if(fp != null && !fp.isLiving()) { - Fight.setPlayerGamemode(player, GameMode.SPECTATOR); + player.setGameMode(GameMode.SPECTATOR); player.teleport(fp.getTeam().getSpawn()); } } diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Spectator.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Spectator.java new file mode 100644 index 00000000..cdd034a1 --- /dev/null +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Spectator.java @@ -0,0 +1,102 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2025 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.fightsystem.listener; + +import java.util.HashSet; +import java.util.Set; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerGameModeChangeEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import com.comphenix.tinyprotocol.TinyProtocol; +import com.mojang.authlib.GameProfile; + +import de.steamwar.core.ProtocolWrapper; +import de.steamwar.fightsystem.ArenaMode; +import de.steamwar.fightsystem.Config; +import de.steamwar.fightsystem.fight.Fight; +import de.steamwar.fightsystem.fight.FightPlayer; +import de.steamwar.fightsystem.states.FightState; +import de.steamwar.fightsystem.states.StateDependentListener; +import de.steamwar.fightsystem.states.StateDependentTask; + + +public class Spectator implements Listener { + + private final Set pseudoSpectator = new HashSet<>(); + + public Spectator() { + new StateDependentListener(ArenaMode.All, FightState.All, this); + new StateDependentTask(ArenaMode.AntiTest, FightState.All, this::pseudoSpectatorCheck, 1, 1); + } + + @EventHandler + @SuppressWarnings("deprecation") + public void onGameModeChange(PlayerGameModeChangeEvent e) { + Player player = e.getPlayer(); + + if (e.getNewGameMode() == GameMode.SPECTATOR) { + for(Player currentPlayer : Bukkit.getServer().getOnlinePlayers()) { + if(currentPlayer.getUniqueId() != player.getUniqueId()) + currentPlayer.hidePlayer(player); + } + } else { + for(Player currentPlayer : Bukkit.getServer().getOnlinePlayers()) { + if(currentPlayer.getUniqueId() != player.getUniqueId()) + currentPlayer.showPlayer(player); + } + } + } + + @EventHandler + public void playerQuit(PlayerQuitEvent e) { + pseudoSpectator.remove(e.getPlayer()); + } + + private void pseudoSpectatorCheck() { + for (Player player : Bukkit.getOnlinePlayers()) { + if (player.getGameMode() != GameMode.SPECTATOR) { + pseudoSpectator.remove(player); + continue; + } + + if (Config.isReferee(player)) + continue; + + FightPlayer fightPlayer = Fight.getFightPlayer(player); + if (fightPlayer == null || !fightPlayer.getTeam().getExtendRegion().playerInRegion(player.getLocation())) { + if (pseudoSpectator.add(player)) + pseudoSpectator(player, true); + } else { + if (pseudoSpectator.remove(player)) + pseudoSpectator(player, false); + } + } + } + + private static void pseudoSpectator(Player player, boolean enable) { + TinyProtocol.instance.sendPacket(player, ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.GAMEMODE, new GameProfile(player.getUniqueId(), player.getName()), enable ? GameMode.CREATIVE : GameMode.SPECTATOR)); + } +} diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/TeamArea.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/TeamArea.java index 2720b25c..2f888452 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/TeamArea.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/TeamArea.java @@ -19,9 +19,14 @@ package de.steamwar.fightsystem.listener; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + import de.steamwar.fightsystem.ArenaMode; import de.steamwar.fightsystem.Config; -import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.events.BoardingEvent; import de.steamwar.fightsystem.events.TeamDeathEvent; import de.steamwar.fightsystem.events.TeamLeaveEvent; @@ -32,23 +37,12 @@ import de.steamwar.fightsystem.fight.FightTeam; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.OneShotStateDependent; import de.steamwar.fightsystem.states.StateDependentListener; -import de.steamwar.fightsystem.states.StateDependentTask; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; - -import java.util.HashSet; -import java.util.Set; public class TeamArea implements Listener { private final FightTeam team; private final Border spectatorBorder; private final Border bordingBorder; - private final Set realSpectator = new HashSet<>(); public TeamArea(FightTeam team) { this.team = team; @@ -56,7 +50,6 @@ public class TeamArea implements Listener { this.bordingBorder = new Border(team.getExtendRegion().to2d(), true, 1, "NO_ENTERN", team.getName() + ".boardingBorder"); new StateDependentListener(ArenaMode.AntiTest, FightState.All, this); - new StateDependentTask(ArenaMode.AntiTest, FightState.TeamFix, this::realSpectatorCheck, 1, 1); new OneShotStateDependent(ArenaMode.AntiTest, FightState.Spectate, () -> Fight.teams().forEach(t -> t.getPlayers().forEach(this::teamSpectator))); } @@ -114,30 +107,5 @@ public class TeamArea implements Listener { Player player = e.getPlayer(); spectatorBorder.removePlayer(player); bordingBorder.removePlayer(player); - realSpectator.remove(player); - } - - private void realSpectatorCheck() { - for(FightPlayer fightPlayer : team.getPlayers()) { - if(fightPlayer.isLiving()) - continue; - - fightPlayer.ifPlayer(player -> { - boolean inRegion = team.getExtendRegion().playerInRegion(player.getLocation()); - if(inRegion && !realSpectator.contains(player)) { - realSpectator.add(player); - - //Later to prevent race condition with Fight.setSpecatator() during respawn - Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> { - if(!player.isOnline()) - return; - Fight.pseudoSpectator(player, false); - }, 2); - }else if(!inRegion && realSpectator.contains(player)) { - Fight.pseudoSpectator(player, true); - realSpectator.remove(player); - } - }); - } } } From f2d8c9c02b8809cf5bd37ac20b1a4b426af3a079 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Tue, 8 Apr 2025 21:34:41 +0200 Subject: [PATCH 105/124] Only AntiTest --- .../src/de/steamwar/fightsystem/listener/Spectator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Spectator.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Spectator.java index cdd034a1..405f2b0d 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Spectator.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Spectator.java @@ -48,7 +48,7 @@ public class Spectator implements Listener { private final Set pseudoSpectator = new HashSet<>(); public Spectator() { - new StateDependentListener(ArenaMode.All, FightState.All, this); + new StateDependentListener(ArenaMode.AntiTest, FightState.All, this); new StateDependentTask(ArenaMode.AntiTest, FightState.All, this::pseudoSpectatorCheck, 1, 1); } From 038f54c3b31d9dbab3e0d00d0340728d01297bd1 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 9 Apr 2025 09:03:07 +0200 Subject: [PATCH 106/124] 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 107/124] 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 cf4ac95c2f4d55c3caf47babea81ce695581a3fe Mon Sep 17 00:00:00 2001 From: Lixfel Date: Wed, 9 Apr 2025 21:04:28 +0200 Subject: [PATCH 108/124] Bugfix after testing --- .../fightsystem/listener/Spectator.java | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Spectator.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Spectator.java index 405f2b0d..399970ca 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Spectator.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Spectator.java @@ -26,8 +26,10 @@ import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerGameModeChangeEvent; +import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import com.comphenix.tinyprotocol.TinyProtocol; @@ -52,20 +54,30 @@ public class Spectator implements Listener { new StateDependentTask(ArenaMode.AntiTest, FightState.All, this::pseudoSpectatorCheck, 1, 1); } - @EventHandler - @SuppressWarnings("deprecation") - public void onGameModeChange(PlayerGameModeChangeEvent e) { + @EventHandler(priority = EventPriority.MONITOR) + public void handlePlayerJoin(PlayerJoinEvent e) { Player player = e.getPlayer(); - if (e.getNewGameMode() == GameMode.SPECTATOR) { - for(Player currentPlayer : Bukkit.getServer().getOnlinePlayers()) { - if(currentPlayer.getUniqueId() != player.getUniqueId()) - currentPlayer.hidePlayer(player); + if(player.getGameMode() == GameMode.SPECTATOR) + gameModeChange(player, GameMode.SPECTATOR); + } + + @EventHandler + public void onGameModeChange(PlayerGameModeChangeEvent e) { + gameModeChange(e.getPlayer(), e.getNewGameMode()); + } + + @SuppressWarnings("deprecation") + private void gameModeChange(Player player, GameMode gameMode) { + if (gameMode == GameMode.SPECTATOR) { + for(Player p : Bukkit.getServer().getOnlinePlayers()) { + if(p.getUniqueId() != player.getUniqueId()) + p.hidePlayer(player); } } else { - for(Player currentPlayer : Bukkit.getServer().getOnlinePlayers()) { - if(currentPlayer.getUniqueId() != player.getUniqueId()) - currentPlayer.showPlayer(player); + for(Player p : Bukkit.getServer().getOnlinePlayers()) { + if(p.getUniqueId() != player.getUniqueId()) + p.showPlayer(player); } } } From 130404850982f3a6fbb4ffb64b3b60fbcbd849a1 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Fri, 11 Apr 2025 00:07:53 +0200 Subject: [PATCH 109/124] Refactors SchematicNode queries for efficiency --- .../src/de/steamwar/sql/SchematicNode.java | 136 +++++++++++------- 1 file changed, 88 insertions(+), 48 deletions(-) diff --git a/CommonCore/SQL/src/de/steamwar/sql/SchematicNode.java b/CommonCore/SQL/src/de/steamwar/sql/SchematicNode.java index bece8549..87b7cac4 100644 --- a/CommonCore/SQL/src/de/steamwar/sql/SchematicNode.java +++ b/CommonCore/SQL/src/de/steamwar/sql/SchematicNode.java @@ -31,10 +31,13 @@ public class SchematicNode { static { SchematicType.Normal.name(); // Ensure SchematicType is loaded. - new SqlTypeMapper<>(SchematicNode.class, null, (rs, identifier) -> { throw new SecurityException("SchematicNode cannot be used as type (recursive select)"); }, (st, index, value) -> st.setInt(index, value.nodeId)); + new SqlTypeMapper<>(SchematicNode.class, null, (rs, identifier) -> { + throw new SecurityException("SchematicNode cannot be used as type (recursive select)"); + }, (st, index, value) -> st.setInt(index, value.nodeId)); } private static final Map>> TAB_CACHE = new HashMap<>(); + public static void clear() { TAB_CACHE.clear(); } @@ -42,39 +45,60 @@ public class SchematicNode { private static final String nodeSelector = "SELECT NodeId, NodeOwner, NodeOwner AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode "; private static final Table table = new Table<>(SchematicNode.class); - private static final Statement create = table.insertFields(true, "NodeOwner", "NodeName", "ParentNode", "NodeItem", "NodeType"); - private static final Statement update = table.update(Table.PRIMARY, "NodeName", "ParentNode", "NodeItem", "NodeType", "NodeRank", "ReplaceColor", "AllowReplay"); + private static final Statement create = table.insertFields(true, "NodeOwner", "NodeName", "ParentNode", "NodeItem", + "NodeType"); + private static final Statement update = table.update(Table.PRIMARY, "NodeName", "ParentNode", "NodeItem", + "NodeType", "NodeRank", "ReplaceColor", "AllowReplay"); private static final Statement delete = table.delete(Table.PRIMARY); - private static final SelectStatement byId = new SelectStatement<>(table, nodeSelector + "WHERE NodeId = ?"); - private static final SelectStatement byOwnerNameParent = new SelectStatement<>(table, nodeSelector + "WHERE NodeOwner = ? AND NodeName = ? AND ParentNode " + Statement.NULL_SAFE_EQUALS + "?"); - private static final SelectStatement byParent = new SelectStatement<>(table, nodeSelector + "WHERE ParentNode" + Statement.NULL_SAFE_EQUALS + "? ORDER BY NodeName"); - private static final SelectStatement dirsByParent = new SelectStatement<>(table, nodeSelector + "WHERE ParentNode" + Statement.NULL_SAFE_EQUALS + "? AND NodeType is NULL ORDER BY NodeName"); - private static final SelectStatement byOwnerType = new SelectStatement<>(table, nodeSelector + "WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName"); - private static final SelectStatement byType = new SelectStatement<>(table, nodeSelector + "WHERE NodeType = ? ORDER BY NodeName"); - private static final SelectStatement all = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? ORDER BY NodeName"); - private static final SelectStatement list = new SelectStatement<>(table, "SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId " + Statement.NULL_SAFE_EQUALS + "? AND NM.UserId = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE (? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?) ORDER BY NodeName"); - private static final SelectStatement byParentName = new SelectStatement<>(table, "SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId " + Statement.NULL_SAFE_EQUALS + "? AND NM.UserId = ? AND SchematicNode.NodeName = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE ((? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?)) AND NodeName = ?"); - private static final SelectStatement schematicAccessibleForUser = new SelectStatement<>(table, "SELECT COUNT(DISTINCT NodeId) FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND NodeId = ?"); - private static final SelectStatement accessibleByUserTypeInParent = new SelectStatement<>(table, "WITH RECURSIVE RSASN AS(WITH RECURSIVE RSAN AS (WITH RSANH AS (WITH RECURSIVE RSA AS (SELECT SN.NodeId, NM.ParentId FROM SchematicNode SN LEFT JOIN NodeMember NM on SN.NodeId = NM.NodeId WHERE NM.UserId = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN INNER JOIN RSA ON RSA.NodeId = SN.ParentNode) SELECT * FROM RSA UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?) SELECT * FROM RSANH UNION SELECT SN.NodeId, SN.ParentNode FROM RSANH JOIN SchematicNode SN ON SN.ParentNode = RSANH.NodeId) SELECT RSAN.NodeId, RSAN.ParentId FROM RSAN JOIN SchematicNode SN ON SN.NodeId = RSAN.NodeId WHERE NodeType = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN JOIN RSASN ON SN.NodeId = RSASN.ParentId) SELECT SN.*, ? as EffectiveOwner, RSASN.ParentId AS ParentNode FROM RSASN JOIN SchematicNode SN ON SN.NodeId = RSASN.NodeId WHERE RSASN.ParentId" + Statement.NULL_SAFE_EQUALS + "? ORDER BY NodeName"); - private static final SelectStatement accessibleByUserType = new SelectStatement<>(table, "WITH RECURSIVE Nodes AS (SELECT NodeId, ParentId as ParentNode FROM NodeMember WHERE UserId = ? UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?), RSN AS ( SELECT NodeId, ParentNode FROM Nodes UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSN WHERE SN.ParentNode = RSN.NodeId ) SELECT SN.*, ? AS EffectiveOwner FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE NodeType = ?"); - private static final SelectStatement byIdAndUser = new SelectStatement<>(table, "SELECT NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE NodeId = ?"); - private static final SelectStatement allParentsOfNode = new SelectStatement<>(table, "WITH RECURSIVE R AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeId = ? AND EffectiveOwner = ? UNION SELECT E.NodeId, E.ParentNode FROM R, EffectiveSchematicNode E WHERE R.ParentNode = E.NodeId AND E.EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, R.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank, SN.ReplaceColor, SN.AllowReplay FROM R INNER JOIN SchematicNode SN ON SN.NodeId = R.NodeId"); + private static final SelectStatement byId = new SelectStatement<>(table, + nodeSelector + "WHERE NodeId = ?"); + private static final SelectStatement byOwnerNameParent = new SelectStatement<>(table, + nodeSelector + "WHERE NodeOwner = ? AND NodeName = ? AND ParentNode " + Statement.NULL_SAFE_EQUALS + "?"); + private static final SelectStatement byParent = new SelectStatement<>(table, + nodeSelector + "WHERE ParentNode" + Statement.NULL_SAFE_EQUALS + "? ORDER BY NodeName"); + private static final SelectStatement dirsByParent = new SelectStatement<>(table, nodeSelector + + "WHERE ParentNode" + Statement.NULL_SAFE_EQUALS + "? AND NodeType is NULL ORDER BY NodeName"); + private static final SelectStatement byOwnerType = new SelectStatement<>(table, + nodeSelector + "WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName"); + private static final SelectStatement byType = new SelectStatement<>(table, + nodeSelector + "WHERE NodeType = ? ORDER BY NodeName"); + private static final SelectStatement all = new SelectStatement<>(table, + "WITH RECURSIVE Nodes AS (SELECT NodeId, ParentId as ParentNode FROM NodeMember WHERE UserId = ? UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?), RSN AS ( SELECT NodeId, ParentNode FROM Nodes UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSN WHERE SN.ParentNode = RSN.NodeId ) SELECT SN.*, ? AS EffectiveOwner FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId"); + private static final SelectStatement list = new SelectStatement<>(table, + "SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId " + + Statement.NULL_SAFE_EQUALS + + "? AND NM.UserId = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE (? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?) ORDER BY NodeName"); + private static final SelectStatement byParentName = new SelectStatement<>(table, + "SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId " + + Statement.NULL_SAFE_EQUALS + + "? AND NM.UserId = ? AND SchematicNode.NodeName = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE ((? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?)) AND NodeName = ?"); + private static final SelectStatement schematicAccessibleForUser = new SelectStatement<>(table, + "WITH RECURSIVE Nodes AS (SELECT NodeId, ParentId as ParentNode FROM NodeMember WHERE UserId = ? UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?), RSN AS ( SELECT NodeId, ParentNode FROM Nodes UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSN WHERE SN.ParentNode = RSN.NodeId ) SELECT SN.*, ? AS EffectiveOwner FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE NodeId = ?"); + private static final SelectStatement accessibleByUserTypeInParent = new SelectStatement<>(table, + "WITH RECURSIVE RSASN AS(WITH RECURSIVE RSAN AS (WITH RSANH AS (WITH RECURSIVE RSA AS (SELECT SN.NodeId, NM.ParentId FROM SchematicNode SN LEFT JOIN NodeMember NM on SN.NodeId = NM.NodeId WHERE NM.UserId = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN INNER JOIN RSA ON RSA.NodeId = SN.ParentNode) SELECT * FROM RSA UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?) SELECT * FROM RSANH UNION SELECT SN.NodeId, SN.ParentNode FROM RSANH JOIN SchematicNode SN ON SN.ParentNode = RSANH.NodeId) SELECT RSAN.NodeId, RSAN.ParentId FROM RSAN JOIN SchematicNode SN ON SN.NodeId = RSAN.NodeId WHERE NodeType = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN JOIN RSASN ON SN.NodeId = RSASN.ParentId) SELECT SN.*, ? as EffectiveOwner, RSASN.ParentId AS ParentNode FROM RSASN JOIN SchematicNode SN ON SN.NodeId = RSASN.NodeId WHERE RSASN.ParentId" + + Statement.NULL_SAFE_EQUALS + "? ORDER BY NodeName"); + private static final SelectStatement accessibleByUserType = new SelectStatement<>(table, + "WITH RECURSIVE Nodes AS (SELECT NodeId, ParentId as ParentNode FROM NodeMember WHERE UserId = ? UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?), RSN AS ( SELECT NodeId, ParentNode FROM Nodes UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSN WHERE SN.ParentNode = RSN.NodeId ) SELECT SN.*, ? AS EffectiveOwner FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE NodeType = ?"); + private static final SelectStatement byIdAndUser = new SelectStatement<>(table, + "SELECT NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE NodeId = ?"); + private static final SelectStatement allParentsOfNode = new SelectStatement<>(table, + "WITH RECURSIVE R AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeId = ? AND EffectiveOwner = ? UNION SELECT E.NodeId, E.ParentNode FROM R, EffectiveSchematicNode E WHERE R.ParentNode = E.NodeId AND E.EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, R.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank, SN.ReplaceColor, SN.AllowReplay FROM R INNER JOIN SchematicNode SN ON SN.NodeId = R.NodeId"); static { NodeMember.init(); } - @Field(keys = {Table.PRIMARY}, autoincrement = true) + @Field(keys = { Table.PRIMARY }, autoincrement = true) private final int nodeId; - @Field(keys = {"OwnerNameParent"}) + @Field(keys = { "OwnerNameParent" }) private final int nodeOwner; @Field(def = "0") @Getter private final int effectiveOwner; - @Field(keys = {"OwnerNameParent"}) + @Field(keys = { "OwnerNameParent" }) private String nodeName; - @Field(keys = {"OwnerNameParent"}, nullable = true) + @Field(keys = { "OwnerNameParent" }, nullable = true) private Integer parentNode; @Field(def = "CURRENT_TIMESTAMP") private Timestamp lastUpdate; @@ -102,8 +126,7 @@ public class SchematicNode { SchematicType nodeType, int nodeRank, boolean replaceColor, - boolean allowReplay - ) { + boolean allowReplay) { this.nodeId = nodeId; this.nodeOwner = nodeOwner; this.effectiveOwner = effectiveOwner; @@ -118,7 +141,7 @@ public class SchematicNode { } public static List getAll(SteamwarUser user) { - return all.listSelect(user); + return all.listSelect(user, user, user); } public static Map> getAllMap(SteamwarUser user) { @@ -130,7 +153,8 @@ public class SchematicNode { } public static SchematicNode byParentName(SteamwarUser user, Integer schematicId, String name) { - return byParentName.select(user, schematicId, user, name, user, schematicId, user, schematicId, schematicId, name); + return byParentName.select(user, schematicId, user, name, user, schematicId, user, schematicId, schematicId, + name); } public static List accessibleByUserType(SteamwarUser user, SchematicType type) { @@ -142,10 +166,11 @@ public class SchematicNode { } public static boolean schematicAccessibleForUser(SteamwarUser user, Integer schematicId) { - return schematicAccessibleForUser.select(user, schematicId) != null; + return schematicAccessibleForUser.select(user, user, user, schematicId) != null; } - public static List accessibleByUserTypeParent(SteamwarUser user, SchematicType type, Integer parentId) { + public static List accessibleByUserTypeParent(SteamwarUser user, SchematicType type, + Integer parentId) { return accessibleByUserTypeInParent.listSelect(user, user, type, user, parentId); } @@ -160,7 +185,8 @@ public class SchematicNode { private static Map> map(List in) { Map> map = new HashMap<>(); for (SchematicNode effectiveSchematicNode : in) { - map.computeIfAbsent(effectiveSchematicNode.getOptionalParent().orElse(0), k -> new ArrayList<>()).add(effectiveSchematicNode); + map.computeIfAbsent(effectiveSchematicNode.getOptionalParent().orElse(0), k -> new ArrayList<>()) + .add(effectiveSchematicNode); } return map; } @@ -218,7 +244,8 @@ public class SchematicNode { return byId.select(id); } - public static List getAccessibleSchematicsOfTypeInParent(int owner, String schemType, Integer parent) { + public static List getAccessibleSchematicsOfTypeInParent(int owner, String schemType, + Integer parent) { return accessibleByUserTypeParent(SteamwarUser.get(owner), SchematicType.fromDB(schemType), parent); } @@ -283,10 +310,12 @@ public class SchematicNode { } if (s.contains("/")) { String[] layers = s.split("/"); - Optional currentNode = Optional.ofNullable(SchematicNode.byParentName(user, null, layers[0])); + Optional currentNode = Optional + .ofNullable(SchematicNode.byParentName(user, null, layers[0])); for (int i = 1; i < layers.length; i++) { int finalI = i; - Optional node = currentNode.map(effectiveSchematicNode -> SchematicNode.byParentName(user, effectiveSchematicNode.getId(), layers[finalI])); + Optional node = currentNode.map(effectiveSchematicNode -> SchematicNode + .byParentName(user, effectiveSchematicNode.getId(), layers[finalI])); if (!node.isPresent()) { return null; } else { @@ -365,7 +394,7 @@ public class SchematicNode { @Deprecated public void setType(String type) { - if(isDir()) + if (isDir()) throw new SecurityException("Node is Directory"); this.nodeType = SchematicType.fromDB(type); updateDB(); @@ -376,13 +405,13 @@ public class SchematicNode { } public String getFileEnding() { - if(isDir()) + if (isDir()) throw new SecurityException("Node is Directory"); return NodeData.get(this).getNodeFormat().getFileEnding(); } public int getRank() { - if(isDir()) + if (isDir()) throw new SecurityException("Node is Directory"); return nodeRank; } @@ -393,19 +422,19 @@ public class SchematicNode { } public void setRank(int rank) { - if(isDir()) + if (isDir()) throw new SecurityException("Node is Directory"); this.nodeRank = rank; } public SchematicType getSchemtype() { - if(isDir()) + if (isDir()) throw new SecurityException("Is Directory"); return nodeType; } public void setSchemtype(SchematicType type) { - if(isDir()) + if (isDir()) throw new SecurityException("Is Directory"); this.nodeType = type; updateDB(); @@ -416,7 +445,7 @@ public class SchematicNode { } public void setReplaceColor(boolean replaceColor) { - if(isDir()) + if (isDir()) throw new SecurityException("Is Directory"); this.replaceColor = replaceColor; updateDB(); @@ -427,14 +456,15 @@ public class SchematicNode { } public void setAllowReplay(boolean allowReplay) { - if(isDir()) + if (isDir()) throw new SecurityException("Is Directory"); this.allowReplay = allowReplay; updateDB(); } public SchematicNode getParentNode() { - if(parentNode == null) return null; + if (parentNode == null) + return null; return SchematicNode.getSchematicNode(parentNode); } @@ -486,7 +516,7 @@ public class SchematicNode { } public String generateBreadcrumbs() { - if(brCache == null) { + if (brCache == null) { brCache = generateBreadcrumbs("/"); } return brCache; @@ -495,11 +525,15 @@ public class SchematicNode { public String generateBreadcrumbs(String split) { StringBuilder builder = new StringBuilder(getName()); Optional currentNode = Optional.of(this); - if(currentNode.map(SchematicNode::isDir).orElse(false)) { + if (currentNode.map(SchematicNode::isDir).orElse(false)) { builder.append(split); } while (currentNode.isPresent()) { - currentNode = currentNode.flatMap(schematicNode -> Optional.ofNullable(NodeMember.getNodeMember(schematicNode.getId(), effectiveOwner)).map(NodeMember::getParent).orElse(schematicNode.getOptionalParent())).map(SchematicNode::getSchematicNode); + currentNode = currentNode + .flatMap(schematicNode -> Optional + .ofNullable(NodeMember.getNodeMember(schematicNode.getId(), effectiveOwner)) + .map(NodeMember::getParent).orElse(schematicNode.getOptionalParent())) + .map(SchematicNode::getSchematicNode); currentNode.ifPresent(node -> builder.insert(0, split).insert(0, node.getName())); } return builder.toString(); @@ -508,17 +542,22 @@ public class SchematicNode { public List> generateBreadcrumbsMap(SteamwarUser user) { List> map = new ArrayList<>(); Optional currentNode = Optional.of(this); - if(currentNode.map(SchematicNode::isDir).orElse(false)) { + if (currentNode.map(SchematicNode::isDir).orElse(false)) { map.add(new AbstractMap.SimpleEntry<>(getName(), getId())); } while (currentNode.isPresent()) { - currentNode = currentNode.flatMap(schematicNode -> Optional.ofNullable(NodeMember.getNodeMember(schematicNode.getId(), effectiveOwner)).map(NodeMember::getParent).orElse(schematicNode.getOptionalParent())).map(SchematicNode::getSchematicNode); + currentNode = currentNode + .flatMap(schematicNode -> Optional + .ofNullable(NodeMember.getNodeMember(schematicNode.getId(), effectiveOwner)) + .map(NodeMember::getParent).orElse(schematicNode.getOptionalParent())) + .map(SchematicNode::getSchematicNode); currentNode.ifPresent(node -> map.add(0, new AbstractMap.SimpleEntry<>(node.getName(), node.getId()))); } return map; } private static final List FORBIDDEN_NAMES = Collections.unmodifiableList(Arrays.asList("public")); + public static boolean invalidSchemName(String[] layers) { for (String layer : layers) { if (layer.isEmpty()) { @@ -535,7 +574,7 @@ public class SchematicNode { layer.contains(" ")) { return true; } - if(FORBIDDEN_NAMES.contains(layer.toLowerCase())) { + if (FORBIDDEN_NAMES.contains(layer.toLowerCase())) { return true; } } @@ -549,14 +588,15 @@ public class SchematicNode { } int index = s.lastIndexOf("/"); String cacheKey = index == -1 ? "" : s.substring(0, index); - if(TAB_CACHE.containsKey(user.getId()) && TAB_CACHE.get(user.getId()).containsKey(cacheKey)) { + if (TAB_CACHE.containsKey(user.getId()) && TAB_CACHE.get(user.getId()).containsKey(cacheKey)) { return new ArrayList<>(TAB_CACHE.get(user.getId()).get(cacheKey)); } List list = new ArrayList<>(); if (s.contains("/")) { String preTab = s.substring(0, s.lastIndexOf("/") + 1); SchematicNode pa = SchematicNode.getNodeFromPath(user, preTab); - if (pa == null) return new ArrayList<>(); + if (pa == null) + return new ArrayList<>(); List nodes = SchematicNode.list(user, pa.getId()); String br = pa.generateBreadcrumbs(); nodes.forEach(node -> list.add((sws ? "/" : "") + br + node.getName() + (node.isDir() ? "/" : ""))); From f573771355a185dc132c8304e7ba44d19d7af523 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sat, 12 Apr 2025 19:03:32 +0200 Subject: [PATCH 110/124] Hotfix: Double Creation of //copy Schematics in //download command --- .../schematicsystem/commands/DownloadCommand.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/DownloadCommand.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/DownloadCommand.java index ff797b67..b62c5c50 100644 --- a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/DownloadCommand.java +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/DownloadCommand.java @@ -35,10 +35,10 @@ public class DownloadCommand extends SWCommand { @Register(help = true) public void genericCommand(Player player, String... args) { SteamwarUser user = SteamwarUser.get(player.getUniqueId()); - SchematicNode copyNode = SchematicNode.getSchematicNode(user.getId(), "//copy", 0); + SchematicNode copyNode = SchematicNode.getSchematicNode(user.getId(), "//copy", null); boolean newSchem = false; - if(copyNode == null) { - copyNode = SchematicNode.createSchematicNode(user.getId(), "//copy", 0, SchematicType.Normal.toDB(), ""); + if (copyNode == null) { + copyNode = SchematicNode.createSchematicNode(user.getId(), "//copy", null, SchematicType.Normal.toDB(), ""); newSchem = true; } @@ -46,13 +46,13 @@ public class DownloadCommand extends SWCommand { new SchematicData(copyNode).saveFromPlayer(player); } catch (IOException e) { SchematicSystem.MESSAGE.send("DOWNLOAD_ERROR", player); - if(newSchem) { + if (newSchem) { copyNode.delete(); } throw new SecurityException(e); } catch (NoClipboardException e) { SchematicSystem.MESSAGE.send("COMMAND_SAVE_CLIPBOARD_EMPTY", player); - if(newSchem) { + if (newSchem) { copyNode.delete(); } return; From c9e4b57f12db06f6fc8dab834e0dba61cd5aaf89 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sat, 12 Apr 2025 19:10:18 +0200 Subject: [PATCH 111/124] Fix: Explicitly cast null to Integer in DownloadCommand --- .../de/steamwar/schematicsystem/commands/DownloadCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/DownloadCommand.java b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/DownloadCommand.java index b62c5c50..31c29bd0 100644 --- a/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/DownloadCommand.java +++ b/SchematicSystem/SchematicSystem_Core/src/de/steamwar/schematicsystem/commands/DownloadCommand.java @@ -35,7 +35,7 @@ public class DownloadCommand extends SWCommand { @Register(help = true) public void genericCommand(Player player, String... args) { SteamwarUser user = SteamwarUser.get(player.getUniqueId()); - SchematicNode copyNode = SchematicNode.getSchematicNode(user.getId(), "//copy", null); + SchematicNode copyNode = SchematicNode.getSchematicNode(user.getId(), "//copy", (Integer) null); boolean newSchem = false; if (copyNode == null) { copyNode = SchematicNode.createSchematicNode(user.getId(), "//copy", null, SchematicType.Normal.toDB(), ""); From e1bcdd59baf94934d283e17cfab50fbe7eaa50a5 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Mon, 14 Apr 2025 09:14:04 +0200 Subject: [PATCH 112/124] 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 113/124] 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 114/124] 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 115/124] 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 116/124] 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 117/124] 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 118/124] 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 119/124] 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 120/124] 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 121/124] 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 122/124] 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 424c80ec81201f7dc1bbe5059d79bca1ee90361b Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 17 Apr 2025 16:09:29 +0200 Subject: [PATCH 123/124] 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 124/124] 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;