From e015bbb3561e6604313a591f06fd51bc36a866cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Sat, 13 Dec 2025 15:00:48 +0100 Subject: [PATCH] added `unsuspectedKick` and `crashKick` features to `Kick` appliance; updated `AcInform` to include related commands --- .../appliances/tooling/acInform/AcInform.java | 22 +++++++++--- .../common/appliances/tooling/kick/Kick.java | 34 ++++++++++++++++++- .../tooling/kick/KickCrashCommand.java | 31 +++++++++++++++++ .../tooling/kick/KickUnsuspectedCommand.java | 31 +++++++++++++++++ .../spawn/core/util/entity/PlayerUtils.java | 32 +++++++++++++++++ 5 files changed, 145 insertions(+), 5 deletions(-) create mode 100644 common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/tooling/kick/KickCrashCommand.java create mode 100644 common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/tooling/kick/KickUnsuspectedCommand.java diff --git a/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/tooling/acInform/AcInform.java b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/tooling/acInform/AcInform.java index a721ad3..72f855d 100644 --- a/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/tooling/acInform/AcInform.java +++ b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/tooling/acInform/AcInform.java @@ -110,28 +110,42 @@ public class AcInform extends Appliance { Component.newline() .append(Component.text("⊥ ", NamedTextColor.GRAY)) .append(Component.text("[", NamedTextColor.GRAY)) - .append(Component.text("Report", NamedTextColor.GOLD)) + .append(Component.text("\uD83D\uDCD6", NamedTextColor.GOLD)) .append(Component.text("]", NamedTextColor.GRAY)) .clickEvent(ClickEvent.suggestCommand(String.format("/report %s anticheat %s flagged %s", playerName, anticheatName, checkName))) ); component.append( Component.text(" [", NamedTextColor.GRAY) - .append(Component.text("Kick", NamedTextColor.GOLD)) + .append(Component.text("\u23F1", NamedTextColor.GOLD)) .append(Component.text("]", NamedTextColor.GRAY)) .clickEvent(ClickEvent.suggestCommand(String.format("/kick %s", playerName))) ); component.append( Component.text(" [", NamedTextColor.GRAY) - .append(Component.text("Panic Ban", NamedTextColor.GOLD)) + .append(Component.text("\uD83E\uDDB6", NamedTextColor.GOLD)) + .append(Component.text("]", NamedTextColor.GRAY)) + .clickEvent(ClickEvent.suggestCommand(String.format("/kickunsuspected %s", playerName))) + ); + + component.append( + Component.text(" [", NamedTextColor.GRAY) + .append(Component.text("\u2623", NamedTextColor.GOLD)) + .append(Component.text("]", NamedTextColor.GRAY)) + .clickEvent(ClickEvent.suggestCommand(String.format("/kickcrash %s", playerName))) + ); + + component.append( + Component.text(" [", NamedTextColor.GRAY) + .append(Component.text("\uD83D\uDD12", NamedTextColor.GOLD)) .append(Component.text("]", NamedTextColor.GRAY)) .clickEvent(ClickEvent.suggestCommand(String.format("/panicban %s", playerName))) ); component.append( Component.text(" [", NamedTextColor.GRAY) - .append(Component.text("Spectate/Teleport", NamedTextColor.GOLD)) + .append(Component.text("\uD83D\uDC41", NamedTextColor.GOLD)) .append(Component.text("]", NamedTextColor.GRAY)) .clickEvent(ClickEvent.suggestCommand(String.format("/grim spectate %s", playerName))) ); diff --git a/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/tooling/kick/Kick.java b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/tooling/kick/Kick.java index c9b1389..9bc67e9 100644 --- a/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/tooling/kick/Kick.java +++ b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/tooling/kick/Kick.java @@ -1,9 +1,14 @@ package eu.mhsl.craftattack.spawn.common.appliances.tooling.kick; +import eu.mhsl.craftattack.spawn.core.Main; import eu.mhsl.craftattack.spawn.core.appliance.Appliance; import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand; +import eu.mhsl.craftattack.spawn.core.util.entity.PlayerUtils; import eu.mhsl.craftattack.spawn.core.util.text.DisconnectInfo; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.util.Ticks; import org.bukkit.Bukkit; +import org.bukkit.Material; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -25,9 +30,36 @@ public class Kick extends Appliance { ).applyKick(player); } + public void unsuspectedKick(@NotNull String playerName) { + Player player = Bukkit.getPlayer(playerName); + + if(player == null) + throw new ApplianceCommand.Error("Player not found"); + + String material = Material.values()[(int)(Math.random() * Material.values().length)].name(); + player.kick(Component.text("java.lang.IllegalStateException: Failed to create model for minecraft:%s".formatted(material))); + } + + public void crashKick(@NotNull String playerName) { + Player player = Bukkit.getPlayer(playerName); + + if(player == null) + throw new ApplianceCommand.Error("Player not found"); + + Bukkit.getScheduler().runTaskAsynchronously(Main.instance(), () -> { + PlayerUtils.sendCube(player, 100, Material.ENCHANTING_TABLE.createBlockData()); + PlayerUtils.sendCube(player, 5, Material.DIRT.createBlockData()); + }); + Bukkit.getScheduler().runTaskLater(Main.instance(), () -> player.kick(Component.empty()), Ticks.TICKS_PER_SECOND * 15); + } + @Override @NotNull protected List> commands() { - return List.of(new KickCommand()); + return List.of( + new KickCommand(), + new KickUnsuspectedCommand(), + new KickCrashCommand() + ); } } diff --git a/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/tooling/kick/KickCrashCommand.java b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/tooling/kick/KickCrashCommand.java new file mode 100644 index 0000000..79025f1 --- /dev/null +++ b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/tooling/kick/KickCrashCommand.java @@ -0,0 +1,31 @@ +package eu.mhsl.craftattack.spawn.common.appliances.tooling.kick; + +import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class KickCrashCommand extends ApplianceCommand { + public KickCrashCommand() { + super("kickCrash"); + } + + @Override + protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception { + if(args.length < 1) throw new Error("Es muss ein Spielername angegeben werden!"); + this.getAppliance().crashKick(args[0]); + } + + @Override + public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + return super.tabCompleteReducer( + Bukkit.getOnlinePlayers().stream().map(Player::getName).toList(), + args + ); + } +} diff --git a/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/tooling/kick/KickUnsuspectedCommand.java b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/tooling/kick/KickUnsuspectedCommand.java new file mode 100644 index 0000000..f84fa45 --- /dev/null +++ b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/tooling/kick/KickUnsuspectedCommand.java @@ -0,0 +1,31 @@ +package eu.mhsl.craftattack.spawn.common.appliances.tooling.kick; + +import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class KickUnsuspectedCommand extends ApplianceCommand { + public KickUnsuspectedCommand() { + super("kickUnsuspected"); + } + + @Override + protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception { + if(args.length < 1) throw new Error("Es muss ein Spielername angegeben werden!"); + this.getAppliance().unsuspectedKick(args[0]); + } + + @Override + public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + return super.tabCompleteReducer( + Bukkit.getOnlinePlayers().stream().map(Player::getName).toList(), + args + ); + } +} diff --git a/core/src/main/java/eu/mhsl/craftattack/spawn/core/util/entity/PlayerUtils.java b/core/src/main/java/eu/mhsl/craftattack/spawn/core/util/entity/PlayerUtils.java index 41c5914..2994461 100644 --- a/core/src/main/java/eu/mhsl/craftattack/spawn/core/util/entity/PlayerUtils.java +++ b/core/src/main/java/eu/mhsl/craftattack/spawn/core/util/entity/PlayerUtils.java @@ -1,10 +1,16 @@ package eu.mhsl.craftattack.spawn.core.util.entity; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Statistic; +import org.bukkit.World; +import org.bukkit.block.data.BlockData; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; +import java.util.HashMap; +import java.util.Map; + public class PlayerUtils { public static void resetStatistics(Player player) { for(Statistic statistic : Statistic.values()) { @@ -30,4 +36,30 @@ public class PlayerUtils { } } } + + public static void sendCube(Player player, int cubeSize, BlockData fakeBlock) { + Location loc = player.getLocation(); + World world = player.getWorld(); + + int half = cubeSize / 2; + int cx = loc.getBlockX(); + int cy = loc.getBlockY(); + int cz = loc.getBlockZ(); + + int minY = world.getMinHeight(); + int maxY = world.getMaxHeight() - 1; + + Map changes = new HashMap<>(); + + for (int x = cx - half; x <= cx + half; x++) { + for (int y = Math.max(cy - half, minY); y <= Math.min(cy + half, maxY); y++) { + for (int z = cz - half; z <= cz + half; z++) { + changes.put(new Location(world, x, y, z), fakeBlock); + } + } + } + + //noinspection UnstableApiUsage + player.sendMultiBlockChange(changes); + } }