Merge pull request #342 from allinkdev/fix/stuff

Big bug fix & some feature additions
This commit is contained in:
Kaboom 2023-04-18 00:34:32 +03:00 committed by GitHub
commit f303dbfc73
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 260 additions and 174 deletions

View file

@ -4,26 +4,27 @@ Extras is a Bukkit plugin that that adds extra functionality to the Kaboom serve
## Commands ## Commands
| Command | Aliases | Permission | Description | | Command | Aliases | Permission | Description |
|-----------------------|----------------------------------------------|-----------------------------|---------------------------------------------------------------| |-----------------------|---------------------|-----------------------------|---------------------------------------------------------|
| /broadcastminimessage | /broadcastmm, /bcmm | extras.broadcastminimessage | Broadcasts a deserialized MiniMessage component | | /broadcastminimessage | /broadcastmm, /bcmm | extras.broadcastminimessage | Broadcasts a deserialized MiniMessage component |
| /broadcastraw | /bcraw, /tellraw | extras.broadcastraw | Broadcasts raw text to the server | | /broadcastraw | /bcraw, /tellraw | extras.broadcastraw | Broadcasts raw text to the server |
| /broadcastvanilla | /bcv | extras.broadcastvanilla | Broadcasts text in vanilla style | | /broadcastvanilla | /bcv | extras.broadcastvanilla | Broadcasts text in vanilla style |
| /clearchat | /cc | extras.clearchat | Clears messages from the chat | | /clearchat | /cc | extras.clearchat | Clears messages from the chat |
| /console | | extras.console | Broadcasts a message as the console | | /console | | extras.console | Broadcasts a message as the console |
| /destroyentities | /de | extras.destroyentities | Destroys all entities in every world | | /destroyentities | /de | extras.destroyentities | Destroys all entities in every world |
| /enchantall | | extras.enchantall | Adds every enchantment to a held item | | /enchantall | | extras.enchantall | Adds every enchantment to a held item |
| /getjson | /gj, /gmm | extras.getjson | Gets the JSON of a deserialized MiniMessage/legacy component | | /getjson | /gj | extras.getjson | Gets the JSON of a deserialized legacy component |
| /jumpscare | /scare | extras.jumpscare | Scares a player | | /getjsonmm | /gmm | extras.getjsonmm | Gets the JSON of a deserialized MiniMessage component |
| /kaboom | | extras.kaboom | I wonder... | | /jumpscare | /scare | extras.jumpscare | Scares a player |
| /ping | /ms, /delay | extras.ping | Gets your ping | | /kaboom | | extras.kaboom | I wonder... |
| /prefix | /rank, /tag | extras.prefix | Changes your tag | | /ping | /ms, /delay | extras.ping | Gets your ping |
| /pumpkin | | extras.pumpkin | Places a pumpkin on a player's head | | /prefix | /rank, /tag | extras.prefix | Changes your tag |
| /serverinfo | /specs | extras.serverinfo | Shows detailed server information | | /pumpkin | | extras.pumpkin | Places a pumpkin on a player's head |
| /skin | | extras.skin | Changes your skin | | /serverinfo | /specs | extras.serverinfo | Shows detailed server information |
| /spawn | | extras.spawn | Teleports you to spawn | | /skin | | extras.skin | Changes your skin |
| /spidey | | extras.spidey | Annoying little spider... | | /spawn | | extras.spawn | Teleports you to spawn |
| /username | | extras.username | Changes your username on the server | | /spidey | | extras.spidey | Annoying little spider... |
| /username | | extras.username | Changes your username on the server |
## Compiling ## Compiling

View file

@ -15,7 +15,7 @@
<dependency> <dependency>
<groupId>io.papermc.paper</groupId> <groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId> <artifactId>paper-api</artifactId>
<version>1.18.2-R0.1-SNAPSHOT</version> <version>1.19.4-R0.1-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View file

@ -1,50 +1,27 @@
package pw.kaboom.extras; package pw.kaboom.extras;
import java.io.File;
import java.util.Collections;
import org.bukkit.WorldCreator; import org.bukkit.WorldCreator;
import org.bukkit.WorldType; import org.bukkit.WorldType;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import pw.kaboom.extras.commands.CommandBroadcastMM; import pw.kaboom.extras.commands.*;
import pw.kaboom.extras.commands.CommandBroadcastVanilla;
import pw.kaboom.extras.commands.CommandClearChat;
import pw.kaboom.extras.commands.CommandConsole;
import pw.kaboom.extras.commands.CommandDestroyEntities;
import pw.kaboom.extras.commands.CommandEnchantAll;
import pw.kaboom.extras.commands.CommandGetJSON;
import pw.kaboom.extras.commands.CommandJumpscare;
import pw.kaboom.extras.commands.CommandKaboom;
import pw.kaboom.extras.commands.CommandPing;
import pw.kaboom.extras.commands.CommandPrefix;
import pw.kaboom.extras.commands.CommandPumpkin;
import pw.kaboom.extras.commands.CommandServerInfo;
import pw.kaboom.extras.commands.CommandSkin;
import pw.kaboom.extras.commands.CommandSpawn;
import pw.kaboom.extras.commands.CommandSpidey;
import pw.kaboom.extras.commands.CommandTellraw;
import pw.kaboom.extras.commands.CommandUsername;
import pw.kaboom.extras.modules.block.BlockCheck; import pw.kaboom.extras.modules.block.BlockCheck;
import pw.kaboom.extras.modules.block.BlockPhysics; import pw.kaboom.extras.modules.block.BlockPhysics;
import pw.kaboom.extras.modules.entity.EntityExplosion; import pw.kaboom.extras.modules.entity.EntityExplosion;
import pw.kaboom.extras.modules.entity.EntityKnockback; import pw.kaboom.extras.modules.entity.EntityKnockback;
import pw.kaboom.extras.modules.entity.EntitySpawn; import pw.kaboom.extras.modules.entity.EntitySpawn;
import pw.kaboom.extras.modules.entity.EntityTeleport; import pw.kaboom.extras.modules.entity.EntityTeleport;
import pw.kaboom.extras.modules.player.PlayerChat; import pw.kaboom.extras.modules.player.*;
import pw.kaboom.extras.modules.player.PlayerCommand;
import pw.kaboom.extras.modules.player.PlayerConnection;
import pw.kaboom.extras.modules.player.PlayerDamage;
import pw.kaboom.extras.modules.player.PlayerInteract;
import pw.kaboom.extras.modules.player.PlayerPrefix;
import pw.kaboom.extras.modules.player.PlayerRecipe;
import pw.kaboom.extras.modules.player.PlayerTeleport;
import pw.kaboom.extras.modules.server.ServerCommand; import pw.kaboom.extras.modules.server.ServerCommand;
import pw.kaboom.extras.modules.server.ServerGameRule; import pw.kaboom.extras.modules.server.ServerGameRule;
import pw.kaboom.extras.modules.server.ServerTabComplete; import pw.kaboom.extras.modules.server.ServerTabComplete;
import pw.kaboom.extras.modules.server.ServerTick; import pw.kaboom.extras.modules.server.ServerTick;
import java.io.File;
import java.util.Collections;
public final class Main extends JavaPlugin { public final class Main extends JavaPlugin {
private File prefixConfigFile; private File prefixConfigFile;
private FileConfiguration prefixConfig; private FileConfiguration prefixConfig;
@ -80,6 +57,7 @@ public final class Main extends JavaPlugin {
this.getCommand("destroyentities").setExecutor(new CommandDestroyEntities()); this.getCommand("destroyentities").setExecutor(new CommandDestroyEntities());
this.getCommand("enchantall").setExecutor(new CommandEnchantAll()); this.getCommand("enchantall").setExecutor(new CommandEnchantAll());
this.getCommand("getjson").setExecutor(new CommandGetJSON()); this.getCommand("getjson").setExecutor(new CommandGetJSON());
this.getCommand("getjsonmm").setExecutor(new CommandGetJSONMM());
this.getCommand("jumpscare").setExecutor(new CommandJumpscare()); this.getCommand("jumpscare").setExecutor(new CommandJumpscare());
this.getCommand("kaboom").setExecutor(new CommandKaboom()); this.getCommand("kaboom").setExecutor(new CommandKaboom());
this.getCommand("ping").setExecutor(new CommandPing()); this.getCommand("ping").setExecutor(new CommandPing());

View file

@ -10,7 +10,7 @@ import org.bukkit.command.CommandSender;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class CommandBroadcastMM implements CommandExecutor { public final class CommandBroadcastMM implements CommandExecutor {
private static final MiniMessage MINI_MESSAGE = MiniMessage.miniMessage(); private static final MiniMessage MINI_MESSAGE = MiniMessage.miniMessage();
public boolean onCommand(final @Nonnull CommandSender sender, public boolean onCommand(final @Nonnull CommandSender sender,

View file

@ -2,14 +2,23 @@ package pw.kaboom.extras.commands;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.ChatColor; import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.Collection;
public final class CommandBroadcastVanilla implements CommandExecutor { public final class CommandBroadcastVanilla implements CommandExecutor {
private static final LegacyComponentSerializer LEGACY_COMPONENT_SERIALIZER =
LegacyComponentSerializer
.legacyAmpersand();
public boolean onCommand(final @Nonnull CommandSender sender, public boolean onCommand(final @Nonnull CommandSender sender,
final @Nonnull Command command, final @Nonnull Command command,
final @Nonnull String label, final @Nonnull String label,
@ -21,8 +30,29 @@ public final class CommandBroadcastVanilla implements CommandExecutor {
return true; return true;
} }
Command.broadcastCommandMessage(sender, ChatColor.translateAlternateColorCodes( final Component senderName = sender.name();
'&', String.join(" ", args))); final String input = String.join(" ", args);
final Component component = LEGACY_COMPONENT_SERIALIZER.deserialize(input);
final Component broadcastComponent = Component.translatable("chat.type.admin")
.decorate(TextDecoration.ITALIC)
.color(NamedTextColor.GRAY)
.args(senderName, component);
sender.sendMessage(component);
final Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers();
for (final Player onlinePlayer : onlinePlayers) {
if (onlinePlayer.equals(sender)) {
continue;
}
onlinePlayer.sendMessage(broadcastComponent);
}
final ConsoleCommandSender consoleCommandSender = Bukkit.getConsoleSender();
consoleCommandSender.sendMessage(broadcastComponent);
return true; return true;
} }
} }

View file

@ -5,7 +5,6 @@ import org.bukkit.Material;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -17,13 +16,12 @@ public final class CommandEnchantAll implements CommandExecutor {
final @Nonnull Command command, final @Nonnull Command command,
final @Nonnull String label, final @Nonnull String label,
final String[] args) { final String[] args) {
if (sender instanceof ConsoleCommandSender) { if (!(sender instanceof final Player player)) {
sender.sendMessage(Component sender.sendMessage(Component
.text("Command has to be run by a player")); .text("Command has to be run by a player"));
return true; return true;
} }
final Player player = (Player) sender;
final ItemStack item = player.getInventory().getItemInMainHand(); final ItemStack item = player.getInventory().getItemInMainHand();
if (Material.AIR.equals(item.getType())) { if (Material.AIR.equals(item.getType())) {

View file

@ -1,6 +1,5 @@
package pw.kaboom.extras.commands; package pw.kaboom.extras.commands;
import javax.annotation.Nonnull;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
@ -10,7 +9,9 @@ import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
public class CommandGetJSON implements CommandExecutor { import javax.annotation.Nonnull;
public final class CommandGetJSON implements CommandExecutor {
public boolean onCommand(final @Nonnull CommandSender sender, public boolean onCommand(final @Nonnull CommandSender sender,
final @Nonnull Command command, final @Nonnull Command command,
final @Nonnull String label, final @Nonnull String label,

View file

@ -0,0 +1,40 @@
package pw.kaboom.extras.commands;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import javax.annotation.Nonnull;
public final class CommandGetJSONMM implements CommandExecutor {
public boolean onCommand(final @Nonnull CommandSender sender,
final @Nonnull Command command,
final @Nonnull String label,
final String[] args) {
if (args.length == 0) {
sender.sendMessage(Component
.text("Usage: /" + label + " <message ..>", NamedTextColor.RED));
return true;
}
final String message = String.join(" ", args);
Component createdComponent = MiniMessage.miniMessage()
.deserialize(message);
String asJson = GsonComponentSerializer.gson()
.serialize(createdComponent);
Component feedback = Component.empty()
.append(Component.text("Your component as JSON (click to copy): "))
.append(Component.text(asJson, NamedTextColor.GREEN))
.clickEvent(ClickEvent.copyToClipboard(asJson));
sender.sendMessage(feedback);
return true;
}
}

View file

@ -19,7 +19,12 @@ public final class CommandKaboom implements CommandExecutor {
final @Nonnull Command command, final @Nonnull Command command,
final @Nonnull String label, final @Nonnull String label,
final String[] args) { final String[] args) {
final Player player = (Player) sender; if (!(sender instanceof final Player player)) {
sender.sendMessage(Component
.text("Command has to be run by a player"));
return true;
}
boolean explode = ThreadLocalRandom.current().nextBoolean(); boolean explode = ThreadLocalRandom.current().nextBoolean();
if (explode) { if (explode) {

View file

@ -1,15 +1,15 @@
package pw.kaboom.extras.commands; package pw.kaboom.extras.commands;
import javax.annotation.Nonnull;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import pw.kaboom.extras.modules.player.PlayerPrefix; import pw.kaboom.extras.modules.player.PlayerPrefix;
import javax.annotation.Nonnull;
public final class CommandPrefix implements CommandExecutor { public final class CommandPrefix implements CommandExecutor {
@ -17,14 +17,12 @@ public final class CommandPrefix implements CommandExecutor {
final @Nonnull Command cmd, final @Nonnull Command cmd,
final @Nonnull String label, final @Nonnull String label,
final String[] args) { final String[] args) {
if (sender instanceof ConsoleCommandSender) { if (!(sender instanceof final Player player)) {
sender.sendMessage(Component sender.sendMessage(Component
.text("Command has to be run by a player")); .text("Command has to be run by a player"));
return true; return true;
} }
final Player player = (Player) sender;
if (args.length == 0) { if (args.length == 0) {
player.sendMessage(Component player.sendMessage(Component
.text("Usage: /" + label + " <prefix|off>", .text("Usage: /" + label + " <prefix|off>",

View file

@ -1,17 +1,16 @@
package pw.kaboom.extras.commands; package pw.kaboom.extras.commands;
import java.util.HashMap;
import java.util.Map;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import pw.kaboom.extras.skin.SkinManager; import pw.kaboom.extras.skin.SkinManager;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.HashMap;
import java.util.Map;
public final class CommandSkin implements CommandExecutor { public final class CommandSkin implements CommandExecutor {
private final Map<Player, Long> lastUsedMillis = new HashMap<>(); private final Map<Player, Long> lastUsedMillis = new HashMap<>();
@ -21,13 +20,12 @@ public final class CommandSkin implements CommandExecutor {
final @Nonnull Command command, final @Nonnull Command command,
final @Nonnull String label, final @Nonnull String label,
final String[] args) { final String[] args) {
if (sender instanceof ConsoleCommandSender) { if (!(sender instanceof final Player player)) {
sender.sendMessage(Component sender.sendMessage(Component
.text("Command has to be run by a player")); .text("Command has to be run by a player"));
return true; return true;
} }
final Player player = (Player) sender;
final long millis = lastUsedMillis.getOrDefault(player, 0L); final long millis = lastUsedMillis.getOrDefault(player, 0L);
final long millisDifference = System.currentTimeMillis() - millis; final long millisDifference = System.currentTimeMillis() - millis;

View file

@ -9,7 +9,6 @@ import org.bukkit.block.BlockFace;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -19,13 +18,12 @@ public final class CommandSpawn implements CommandExecutor {
final @Nonnull Command command, final @Nonnull Command command,
final @Nonnull String label, final @Nonnull String label,
final String[] args) { final String[] args) {
if (sender instanceof ConsoleCommandSender) { if (!(sender instanceof final Player player)) {
sender.sendMessage(Component sender.sendMessage(Component
.text("Command has to be run by a player")); .text("Command has to be run by a player"));
return true; return true;
} }
final Player player = (Player) sender;
final World defaultWorld = Bukkit.getWorld("world"); final World defaultWorld = Bukkit.getWorld("world");
final World world = (defaultWorld == null) ? Bukkit.getWorlds().get(0) : defaultWorld; final World world = (defaultWorld == null) ? Bukkit.getWorlds().get(0) : defaultWorld;
final Location spawnLocation = world.getSpawnLocation(); final Location spawnLocation = world.getSpawnLocation();

View file

@ -6,7 +6,6 @@ import org.bukkit.World;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.util.BlockIterator; import org.bukkit.util.BlockIterator;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
@ -18,13 +17,12 @@ public final class CommandSpidey implements CommandExecutor {
final @Nonnull Command command, final @Nonnull Command command,
final @Nonnull String label, final @Nonnull String label,
final String[] args) { final String[] args) {
if (sender instanceof ConsoleCommandSender) { if (!(sender instanceof final Player player)) {
sender.sendMessage(Component sender.sendMessage(Component
.text("Command has to be run by a player")); .text("Command has to be run by a player"));
return true; return true;
} }
final Player player = (Player) sender;
final World world = player.getWorld(); final World world = player.getWorld();
final Vector start = player.getEyeLocation().toVector(); final Vector start = player.getEyeLocation().toVector();
final Vector direction = player.getEyeLocation().getDirection(); final Vector direction = player.getEyeLocation().getDirection();

View file

@ -1,8 +1,6 @@
package pw.kaboom.extras.commands; package pw.kaboom.extras.commands;
import com.destroystokyo.paper.profile.PlayerProfile; import com.destroystokyo.paper.profile.PlayerProfile;
import java.util.HashMap;
import java.util.Map;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -10,10 +8,11 @@ import org.bukkit.ChatColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.HashMap;
import java.util.Map;
public final class CommandUsername implements CommandExecutor { public final class CommandUsername implements CommandExecutor {
private final Map<Player, Long> lastUsedMillis = new HashMap<>(); private final Map<Player, Long> lastUsedMillis = new HashMap<>();
@ -23,13 +22,12 @@ public final class CommandUsername implements CommandExecutor {
final @Nonnull Command command, final @Nonnull Command command,
final @Nonnull String label, final @Nonnull String label,
final String[] args) { final String[] args) {
if (sender instanceof ConsoleCommandSender) { if (!(sender instanceof final Player player)) {
sender.sendMessage(Component sender.sendMessage(Component
.text("Command has to be run by a player")); .text("Command has to be run by a player"));
return true; return true;
} }
final Player player = (Player) sender;
final String nameColor = ChatColor.translateAlternateColorCodes( final String nameColor = ChatColor.translateAlternateColorCodes(
'&', String.join(" ", args)); '&', String.join(" ", args));
final String name = nameColor.substring(0, Math.min(16, nameColor.length())); final String name = nameColor.substring(0, Math.min(16, nameColor.length()));
@ -56,7 +54,7 @@ public final class CommandUsername implements CommandExecutor {
} }
for (Player other : Bukkit.getOnlinePlayers()) { for (Player other : Bukkit.getOnlinePlayers()) {
if (!other.getName().equals(name)) continue; if (!other.getName().equalsIgnoreCase(name)) continue;
player.sendMessage(Component player.sendMessage(Component
.text("A player with that username is already logged in.")); .text("A player with that username is already logged in."));

View file

@ -2,18 +2,24 @@ package pw.kaboom.extras.modules.player;
import io.papermc.paper.chat.ChatRenderer; import io.papermc.paper.chat.ChatRenderer;
import io.papermc.paper.event.player.AsyncChatEvent; import io.papermc.paper.event.player.AsyncChatEvent;
import java.io.IOException;
import java.util.UUID;
import javax.annotation.Nonnull;
import net.kyori.adventure.audience.Audience; import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.util.UUID;
import java.util.regex.Pattern;
public final class PlayerChat implements Listener { public final class PlayerChat implements Listener {
private static final PlayerChatRenderer CHAT_RENDERER = new PlayerChatRenderer(); private static final PlayerChatRenderer CHAT_RENDERER = new PlayerChatRenderer();
@ -39,6 +45,43 @@ public final class PlayerChat implements Listener {
} }
public static class PlayerChatRenderer implements ChatRenderer { public static class PlayerChatRenderer implements ChatRenderer {
private static final TextReplacementConfig URL_REPLACEMENT_CONFIG =
TextReplacementConfig
.builder()
.match(Pattern
.compile("((https?://(ww(w|\\d)\\.)?|ww(w|\\d))[-a-zA-Z0-9@:%._+~#=]{1,256}"
+ "\\.[a-zA-Z0-9]{2,6}\\b([-a-zA-Z0-9@:%_+.~#?&/=]*))"))
.replacement((b, c) -> {
if (c == null) {
return null;
}
if (b.groupCount() < 1) {
return null;
}
final String content = b.group(1);
final String url;
/*
Minecraft doesn't accept "www.google.com" as a URL
in click events
*/
if (content.contains("://")) {
url = content;
} else {
url = "https://" + content;
}
return Component.text(content, NamedTextColor.BLUE)
.decorate(TextDecoration.UNDERLINED)
.clickEvent(ClickEvent.openUrl(url));
})
.build();
private static final LegacyComponentSerializer LEGACY_COMPONENT_SERIALIZER =
LegacyComponentSerializer
.legacyAmpersand();
@Override @Override
public @Nonnull Component render(@Nonnull Player player, public @Nonnull Component render(@Nonnull Player player,
@ -65,10 +108,12 @@ public final class PlayerChat implements Listener {
.append(Component.text(":")) .append(Component.text(":"))
.append(Component.space()); .append(Component.space());
return newComponent.append(LegacyComponentSerializer final Component messageWithColorCodes = LEGACY_COMPONENT_SERIALIZER
.legacyAmpersand() .deserialize(message);
.deserialize(message) final Component completedMessage = messageWithColorCodes
); .replaceText(URL_REPLACEMENT_CONFIG);
return newComponent.append(completedMessage);
} }
} }
} }

View file

@ -1,9 +1,8 @@
package pw.kaboom.extras.modules.player; package pw.kaboom.extras.modules.player;
import java.util.HashSet; import com.destroystokyo.paper.event.profile.PreLookupProfileEvent;
import java.util.UUID; import com.destroystokyo.paper.profile.ProfileProperty;
import java.util.concurrent.ThreadLocalRandom; import com.google.common.base.Charsets;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Server; import org.bukkit.Server;
@ -11,26 +10,19 @@ import org.bukkit.World;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent; import org.bukkit.event.player.*;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerLoginEvent.Result; import org.bukkit.event.player.PlayerLoginEvent.Result;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.spigotmc.event.player.PlayerSpawnLocationEvent; import org.spigotmc.event.player.PlayerSpawnLocationEvent;
import com.destroystokyo.paper.event.profile.PreLookupProfileEvent;
import com.destroystokyo.paper.profile.ProfileProperty;
import com.google.common.base.Charsets;
import pw.kaboom.extras.Main; import pw.kaboom.extras.Main;
import pw.kaboom.extras.modules.server.ServerTabComplete; import pw.kaboom.extras.modules.server.ServerTabComplete;
import pw.kaboom.extras.skin.SkinManager; import pw.kaboom.extras.skin.SkinManager;
import pw.kaboom.extras.util.Utility;
import java.util.HashSet;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
public final class PlayerConnection implements Listener { public final class PlayerConnection implements Listener {
private static final FileConfiguration CONFIG = JavaPlugin.getPlugin(Main.class).getConfig(); private static final FileConfiguration CONFIG = JavaPlugin.getPlugin(Main.class).getConfig();
@ -50,8 +42,9 @@ public final class PlayerConnection implements Listener {
@EventHandler @EventHandler
void onAsyncPlayerPreLogin(final AsyncPlayerPreLoginEvent event) { void onAsyncPlayerPreLogin(final AsyncPlayerPreLoginEvent event) {
if (Bukkit.getPlayer(event.getName()) != null final Player player = Utility.getPlayerExactIgnoreCase(event.getName());
&& Bukkit.getPlayer(event.getName()).isOnline()) {
if (player != null) {
event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER,
"A player with that username is already logged in"); "A player with that username is already logged in");
} }

View file

@ -1,11 +1,5 @@
package pw.kaboom.extras.modules.player; package pw.kaboom.extras.modules.player;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -21,15 +15,22 @@ import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scheduler.BukkitScheduler;
import pw.kaboom.extras.Main; import pw.kaboom.extras.Main;
public class PlayerPrefix implements Listener { import java.io.File;
private static final Main plugin = JavaPlugin.getPlugin(Main.class); import java.io.IOException;
private static final File PREFIX_CONFIG_FILE = plugin.getPrefixConfigFile(); import java.util.Collection;
private static final FileConfiguration PREFIX_CONFIG = plugin.getPrefixConfig(); import java.util.HashMap;
private static final FileConfiguration PLUGIN_CONFIGURATION = plugin.getConfig(); import java.util.Map;
private static final Component opTag; import java.util.UUID;
private static final Component deOpTag;
private static final Map<Player, Boolean> opMap = new HashMap<>(); public final class PlayerPrefix implements Listener {
private static final Map<Player, Component> displayNameMap = new HashMap<>(); private static final Main PLUGIN = JavaPlugin.getPlugin(Main.class);
private static final File PREFIX_CONFIG_FILE = PLUGIN.getPrefixConfigFile();
private static final FileConfiguration PREFIX_CONFIG = PLUGIN.getPrefixConfig();
private static final FileConfiguration PLUGIN_CONFIGURATION = PLUGIN.getConfig();
private static final Component OP_TAG;
private static final Component DE_OP_TAG;
private static final Map<Player, Boolean> OP_MAP = new HashMap<>();
private static final Map<Player, Component> DISPLAY_NAME_MAP = new HashMap<>();
static { static {
final String legacyOpTag = PLUGIN_CONFIGURATION.getString("opTag"); final String legacyOpTag = PLUGIN_CONFIGURATION.getString("opTag");
@ -39,14 +40,14 @@ public class PlayerPrefix implements Listener {
throw new RuntimeException("Invalid plugin configuration!"); throw new RuntimeException("Invalid plugin configuration!");
} }
opTag = LegacyComponentSerializer.legacySection().deserialize(legacyOpTag); OP_TAG = LegacyComponentSerializer.legacySection().deserialize(legacyOpTag);
deOpTag = LegacyComponentSerializer.legacySection().deserialize(legacyDeOpTag); DE_OP_TAG = LegacyComponentSerializer.legacySection().deserialize(legacyDeOpTag);
final BukkitScheduler scheduler = Bukkit.getScheduler(); final BukkitScheduler scheduler = Bukkit.getScheduler();
scheduler.runTaskTimerAsynchronously(plugin, PlayerPrefix::checkOpStatus, scheduler.runTaskTimerAsynchronously(PLUGIN, PlayerPrefix::checkOpStatus,
0L, 1L); 0L, 1L);
scheduler.runTaskTimerAsynchronously(plugin, PlayerPrefix::checkDisplayNames, scheduler.runTaskTimerAsynchronously(PLUGIN, PlayerPrefix::checkDisplayNames,
0L, 1L); 0L, 1L);
} }
@ -79,7 +80,7 @@ public class PlayerPrefix implements Listener {
final String legacyPrefix = PREFIX_CONFIG.getString(stringifiedUUID); final String legacyPrefix = PREFIX_CONFIG.getString(stringifiedUUID);
if (legacyPrefix == null) { if (legacyPrefix == null) {
return player.isOp() ? opTag : deOpTag; return player.isOp() ? OP_TAG : DE_OP_TAG;
} }
return LegacyComponentSerializer.legacyAmpersand() return LegacyComponentSerializer.legacyAmpersand()
@ -88,7 +89,7 @@ public class PlayerPrefix implements Listener {
} }
public static Component getDefaultPrefix(Player player) { public static Component getDefaultPrefix(Player player) {
return player.isOp() ? opTag : deOpTag; return player.isOp() ? OP_TAG : DE_OP_TAG;
} }
private static void onUpdate(Player player) throws IOException { private static void onUpdate(Player player) throws IOException {
@ -104,8 +105,8 @@ public class PlayerPrefix implements Listener {
final Player player = event.getPlayer(); final Player player = event.getPlayer();
final boolean isOp = player.isOp(); final boolean isOp = player.isOp();
opMap.put(player, isOp); OP_MAP.put(player, isOp);
displayNameMap.put(player, player.displayName()); DISPLAY_NAME_MAP.put(player, player.displayName());
onUpdate(player); onUpdate(player);
} }
@ -113,8 +114,8 @@ public class PlayerPrefix implements Listener {
public void onPlayerQuitEvent(PlayerQuitEvent event) { public void onPlayerQuitEvent(PlayerQuitEvent event) {
final Player player = event.getPlayer(); final Player player = event.getPlayer();
opMap.remove(player); OP_MAP.remove(player);
displayNameMap.remove(player); DISPLAY_NAME_MAP.remove(player);
} }
private static void checkOpStatus() { private static void checkOpStatus() {
@ -124,17 +125,17 @@ public class PlayerPrefix implements Listener {
for (Player player : players) { for (Player player : players) {
final boolean isOp = player.isOp(); final boolean isOp = player.isOp();
if (!opMap.containsKey(player)) { if (!OP_MAP.containsKey(player)) {
return; return;
} }
final boolean storedOp = opMap.get(player); final boolean storedOp = OP_MAP.get(player);
if (isOp == storedOp) { if (isOp == storedOp) {
continue; continue;
} }
opMap.put(player, isOp); OP_MAP.put(player, isOp);
try { try {
onUpdate(player); onUpdate(player);
@ -151,17 +152,17 @@ public class PlayerPrefix implements Listener {
for (Player player : players) { for (Player player : players) {
final Component displayName = player.displayName(); final Component displayName = player.displayName();
if (!displayNameMap.containsKey(player)) { if (!DISPLAY_NAME_MAP.containsKey(player)) {
return; return;
} }
final Component storedDisplayName = displayNameMap.get(player); final Component storedDisplayName = DISPLAY_NAME_MAP.get(player);
if (displayName.equals(storedDisplayName)) { if (displayName.equals(storedDisplayName)) {
continue; continue;
} }
displayNameMap.put(player, displayName); DISPLAY_NAME_MAP.put(player, displayName);
try { try {
onUpdate(player); onUpdate(player);

View file

@ -1,11 +1,5 @@
package pw.kaboom.extras.modules.server; package pw.kaboom.extras.modules.server;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.block.CommandBlock; import org.bukkit.block.CommandBlock;
import org.bukkit.command.BlockCommandSender; import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -14,9 +8,14 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.server.ServerCommandEvent; import org.bukkit.event.server.ServerCommandEvent;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import pw.kaboom.extras.Main; import pw.kaboom.extras.Main;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class ServerCommand implements Listener { public final class ServerCommand implements Listener {
private static final Pattern AS_AT_PATTERN = Pattern.compile( private static final Pattern AS_AT_PATTERN = Pattern.compile(
"\\b(as|at|facing entity) @[ae]\\b"); "\\b(as|at|facing entity) @[ae]\\b");
@ -45,6 +44,9 @@ public final class ServerCommand implements Listener {
|| "tm".equalsIgnoreCase(cmd) || "tm".equalsIgnoreCase(cmd)
|| "tp".equalsIgnoreCase(cmd) || "tp".equalsIgnoreCase(cmd)
|| "w".equalsIgnoreCase(cmd) || "w".equalsIgnoreCase(cmd)
|| "place".equalsIgnoreCase(cmd)
|| "fillbiome".equalsIgnoreCase(cmd)
|| "ride".equalsIgnoreCase(cmd)
); );
} }
@ -102,6 +104,9 @@ public final class ServerCommand implements Listener {
} }
for (int i = 1; i < arr.length; i++) { for (int i = 1; i < arr.length; i++) {
if ("summon".equalsIgnoreCase(arr[i])) {
return "cancel";
}
if (!"run".equalsIgnoreCase(arr[i])) { if (!"run".equalsIgnoreCase(arr[i])) {
continue; continue;
} }
@ -117,7 +122,7 @@ public final class ServerCommand implements Listener {
String.join(" ", executeCommand), true, depth + 1); String.join(" ", executeCommand), true, depth + 1);
if (result == null) { if (result == null) {
continue; continue;
} else if (result == "cancel") { } else if (result.equals("cancel")) {
return "cancel"; return "cancel";
} }
final String pureExecute = String.join( final String pureExecute = String.join(
@ -208,11 +213,6 @@ public final class ServerCommand implements Listener {
// Do nothing // Do nothing
} }
if (command.contains("distance")) {
return command.replace("distance=", "]").replace("\"distance\"=", "]")
.replace("'distance'=", "]");
}
return null; return null;
} }

View file

@ -1,11 +1,10 @@
package pw.kaboom.extras.modules.server; package pw.kaboom.extras.modules.server;
import io.papermc.paper.event.world.WorldGameRuleChangeEvent;
import org.bukkit.GameRule; import org.bukkit.GameRule;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import io.papermc.paper.event.world.WorldGameRuleChangeEvent;
public final class ServerGameRule implements Listener { public final class ServerGameRule implements Listener {
@EventHandler @EventHandler
void onGameRuleChange(final WorldGameRuleChangeEvent event) { void onGameRuleChange(final WorldGameRuleChangeEvent event) {
@ -14,7 +13,9 @@ public final class ServerGameRule implements Listener {
if ((gameRule == GameRule.RANDOM_TICK_SPEED if ((gameRule == GameRule.RANDOM_TICK_SPEED
&& Integer.parseInt(event.getValue()) > 6) && Integer.parseInt(event.getValue()) > 6)
|| (event.getGameRule() == GameRule.SPAWN_RADIUS || (event.getGameRule() == GameRule.SPAWN_RADIUS
&& Integer.parseInt(event.getValue()) > 100)) { && Integer.parseInt(event.getValue()) > 100)
|| (event.getGameRule() == GameRule.COMMAND_MODIFICATION_BLOCK_LIMIT
&& Integer.parseInt(event.getValue()) > 32768)) {
event.setCancelled(true); event.setCancelled(true);
} }
} }

View file

@ -1,20 +1,3 @@
package pw.kaboom.extras.skin.response; package pw.kaboom.extras.skin.response;
public class ProfileResponse { public record ProfileResponse(String name, String id) {}
public ProfileResponse(String name, String id) {
this.name = name;
this.id = id;
}
private final String name;
private final String id;
public String name() {
return name;
}
public String id() {
return id;
}
}

View file

@ -0,0 +1,16 @@
package pw.kaboom.extras.util;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import javax.annotation.Nullable;
public final class Utility {
public static @Nullable Player getPlayerExactIgnoreCase(final String username) {
return Bukkit.getOnlinePlayers()
.stream()
.filter(p -> p.getName().equalsIgnoreCase(username))
.findFirst()
.orElse(null);
}
}

View file

@ -32,9 +32,13 @@ commands:
description: Adds every enchantment to a held item description: Adds every enchantment to a held item
permission: extras.enchantall permission: extras.enchantall
getjson: getjson:
aliases: [ gj, gmm ] aliases: [ gj ]
description: Gets the JSON of a deserialized MiniMessage/legacy component description: Gets the JSON of a deserialized legacy component
permission: extras.getjson permission: extras.getjson
getjsonmm:
aliases: [ gmm ]
description: Gets the JSON of a deserialized MiniMessage component
permission: extras.getjsonmm
jumpscare: jumpscare:
aliases: scare aliases: scare
description: Scares a player description: Scares a player