From 4d531ea7b5d3bc3c5dca7c0866a1285a5b402dce Mon Sep 17 00:00:00 2001 From: Len <40720638+destro174@users.noreply.github.com> Date: Thu, 20 Nov 2025 20:41:15 +0100 Subject: [PATCH] Refactor PlayerShopCommand to use Brigadier. --- .../com/alttd/playershops/PlayerShops.java | 14 +- .../commands/PlayerShopCommand.java | 211 +++++++----------- .../commands/PlayerShopCommands.java | 58 ----- .../playershops/commands/Subcommand.java | 19 -- .../arguments/OfflinePlayerArgument.java | 49 ++++ .../subcommands/CheckStockCommand.java | 74 +----- .../commands/subcommands/ReloadCommand.java | 19 -- .../subcommands/TransferShopsCommand.java | 50 ----- .../playershops/config/MessageConfig.java | 2 + .../playershops/handler/ShopHandler.java | 23 ++ .../alttd/playershops/shop/PlayerShop.java | 3 +- .../com/alttd/playershops/utils/Pair.java | 5 + 12 files changed, 183 insertions(+), 344 deletions(-) delete mode 100644 src/main/java/com/alttd/playershops/commands/PlayerShopCommands.java delete mode 100644 src/main/java/com/alttd/playershops/commands/Subcommand.java create mode 100644 src/main/java/com/alttd/playershops/commands/arguments/OfflinePlayerArgument.java delete mode 100644 src/main/java/com/alttd/playershops/commands/subcommands/ReloadCommand.java delete mode 100644 src/main/java/com/alttd/playershops/commands/subcommands/TransferShopsCommand.java create mode 100644 src/main/java/com/alttd/playershops/utils/Pair.java diff --git a/src/main/java/com/alttd/playershops/PlayerShops.java b/src/main/java/com/alttd/playershops/PlayerShops.java index c06cde7..d050fca 100644 --- a/src/main/java/com/alttd/playershops/PlayerShops.java +++ b/src/main/java/com/alttd/playershops/PlayerShops.java @@ -1,6 +1,6 @@ package com.alttd.playershops; -import com.alttd.playershops.commands.PlayerShopCommands; +import com.alttd.playershops.commands.PlayerShopCommand; import com.alttd.playershops.config.Config; import com.alttd.playershops.config.DatabaseConfig; import com.alttd.playershops.config.MessageConfig; @@ -10,12 +10,18 @@ import com.alttd.playershops.listener.*; import com.alttd.playershops.shop.ShopType; import com.alttd.playershops.storage.database.DatabaseManager; import com.alttd.playershops.storage.database.DatabaseHelper; +import io.papermc.paper.command.brigadier.Commands; +import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; +import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents; import lombok.Getter; import net.milkbowl.vault.economy.Economy; import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.java.JavaPlugin; +import java.util.List; + public class PlayerShops extends JavaPlugin { @Getter @@ -107,7 +113,11 @@ public class PlayerShops extends JavaPlugin { } private void registerCommands() { - PlayerShopCommands.registerCommands(); + LifecycleEventManager manager = this.getLifecycleManager(); + manager.registerEventHandler(LifecycleEvents.COMMANDS, event -> { + final Commands commands = event.registrar(); + commands.register(new PlayerShopCommand().command(), null, List.of("shop", "shops")); + }); } public void reloadConfigs() { diff --git a/src/main/java/com/alttd/playershops/commands/PlayerShopCommand.java b/src/main/java/com/alttd/playershops/commands/PlayerShopCommand.java index 14b1a98..b703647 100644 --- a/src/main/java/com/alttd/playershops/commands/PlayerShopCommand.java +++ b/src/main/java/com/alttd/playershops/commands/PlayerShopCommand.java @@ -1,147 +1,96 @@ package com.alttd.playershops.commands; +import com.alttd.playershops.PlayerShops; +import com.alttd.playershops.commands.arguments.OfflinePlayerArgument; import com.alttd.playershops.commands.subcommands.CheckStockCommand; -import com.alttd.playershops.commands.subcommands.ReloadCommand; -import com.alttd.playershops.commands.subcommands.TransferShopsCommand; import com.alttd.playershops.gui.HomeGui; -import com.alttd.playershops.utils.Util; -import it.unimi.dsi.fastutil.Pair; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.tree.LiteralCommandNode; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.command.brigadier.Commands; +import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; -import org.bukkit.permissions.Permission; -import org.bukkit.permissions.PermissionDefault; -import org.bukkit.plugin.PluginManager; -import org.checkerframework.checker.nullness.qual.Nullable; import org.jetbrains.annotations.NotNull; -import java.util.*; -import java.util.stream.Collectors; +public class PlayerShopCommand { -import static net.kyori.adventure.text.Component.text; -import static net.kyori.adventure.text.format.NamedTextColor.RED; + public static final String BASE_PERM = "playershops.command"; -public class PlayerShopCommand extends Command { + public @NotNull LiteralCommandNode command() { + final LiteralArgumentBuilder builder = + Commands.literal("playershop") + .requires( + commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM) + && commandSourceStack.getSender() instanceof Player + ) + .executes((source) -> { + if (!(source.getSource().getSender() instanceof Player player)) + return 1; - public static final String BASE_PERM = "playershops.command"; // TODO load from config + // TODO -- DIALOG + HomeGui gui = new HomeGui(player.getUniqueId()); + gui.open(); + return 1; + }) + .then( + Commands.literal("reload") + .requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + "reload")) + .executes(source -> { + PlayerShops.getInstance().reloadConfigs(); + return 1; + }) + ) + .then( + Commands.literal("checkstock") + .requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + "checkstock") + && commandSourceStack.getSender() instanceof Player) + .then( + Commands.argument("range", IntegerArgumentType.integer(1, 100)) + .executes(source -> { + if (!(source.getSource().getSender() instanceof Player player)) + return 1; - // subcommand label -> subcommand - private static final Map SUBCOMMANDS = PlayerShopCommands.make(() -> { - final Map, Subcommand> commands = new HashMap<>(); + int range = source.getArgument("range", Integer.class); + int stock = -1; + CheckStockCommand.doStockCheck(player, range, stock); + return 1; + }) + .then( + Commands.argument("stock", IntegerArgumentType.integer()) + .executes(source -> { + if (!(source.getSource().getSender() instanceof Player player)) + return 1; - commands.put(Set.of("reload"), new ReloadCommand()); - commands.put(Set.of("checkstock"), new CheckStockCommand()); - commands.put(Set.of("transfershops"), new TransferShopsCommand()); + int range = source.getArgument("range", Integer.class); + int stock = source.getArgument("stock", Integer.class); + CheckStockCommand.doStockCheck(player, range, stock); + return 1; + }) + ) + ) + ) + .then( + Commands.literal("transfershops") + .requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + "transfershops")) + .then( + Commands.argument("old", new OfflinePlayerArgument()) + .then( + Commands.argument("new", new OfflinePlayerArgument()) + ) + .executes( + source -> { + OfflinePlayer oldOwner = source.getArgument("old", OfflinePlayer.class); + OfflinePlayer newOwner = source.getArgument("new", OfflinePlayer.class); + PlayerShops.getInstance().getShopHandler().transferShops(source.getSource().getSender(), oldOwner, newOwner); - return commands.entrySet().stream() - .flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue()))) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - }); - // alias -> subcommand label - private static final Map ALIASES = PlayerShopCommands.make(() -> { - final Map> aliases = new HashMap<>(); - - aliases.put("reload", Set.of("reloadconfig")); - - return aliases.entrySet().stream() - .flatMap(entry -> entry.getValue().stream().map(s -> Map.entry(s, entry.getKey()))) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - }); - - public PlayerShopCommand() { - super("playershop"); - this.description = "PlayerShop related commands"; - this.usageMessage = "/playershop [" + String.join(" | ", SUBCOMMANDS.keySet()) + "]"; - this.setAliases(List.of("shop", "shops")); - final List permissions = new ArrayList<>(); - permissions.add(BASE_PERM); - permissions.addAll(SUBCOMMANDS.keySet().stream().map(s -> BASE_PERM + "." + s).toList()); - this.setPermission(String.join(";", permissions)); - final PluginManager pluginManager = Bukkit.getServer().getPluginManager(); - for (final String perm : permissions) { - pluginManager.addPermission(new Permission(perm, PermissionDefault.OP)); - } + return 1; + } + ) + ) + ) + ; + return builder.build(); } - private static boolean testPermission(final CommandSender sender, final String permission) { - if (sender.hasPermission(BASE_PERM + "." + permission)) { - return true; - } - sender.sendMessage(Bukkit.permissionMessage()); - return false; - } - - @Override - public @NotNull List tabComplete( - final @NotNull CommandSender sender, - final @NotNull String alias, - final String[] args, - final @Nullable Location location - ) throws IllegalArgumentException { - if (args.length <= 1) { - return PlayerShopCommands.getListMatchingLast(sender, args, SUBCOMMANDS.keySet(), BASE_PERM); - } - - final @Nullable Pair subCommand = resolveCommand(args[0]); - if (subCommand != null) { - return subCommand.second().tabComplete(sender, subCommand.first(), Arrays.copyOfRange(args, 1, args.length)); - } - - return Collections.emptyList(); - } - - @Override - public boolean execute( - final @NotNull CommandSender sender, - final @NotNull String commandLabel, - final String[] args - ) { - if (!testPermission(sender)) { - return true; - } - - if (args.length == 0) { - if (!(sender instanceof Player player)) { - sender.sendMessage(Util.parseMiniMessage("Only players can use this command.")); - return false; - } - HomeGui gui = new HomeGui(player.getUniqueId()); - gui.open(); - return true; - } - final @Nullable Pair subCommand = resolveCommand(args[0]); - - if (subCommand == null) { - sender.sendMessage(text("Usage: " + this.usageMessage, RED)); - return false; - } - - if (!testPermission(sender, subCommand.first())) { - return true; - } - final String[] choppedArgs = Arrays.copyOfRange(args, 1, args.length); - return subCommand.second().execute(sender, subCommand.first(), choppedArgs); - } - - private static @Nullable Pair resolveCommand(String label) { - label = label.toLowerCase(Locale.ENGLISH); - @Nullable Subcommand subCommand = SUBCOMMANDS.get(label); - if (subCommand == null) { - final @Nullable String command = ALIASES.get(label); - if (command != null) { - label = command; - subCommand = SUBCOMMANDS.get(command); - } - } - - if (subCommand != null) { - return Pair.of(label, subCommand); - } - - return null; - } - - } diff --git a/src/main/java/com/alttd/playershops/commands/PlayerShopCommands.java b/src/main/java/com/alttd/playershops/commands/PlayerShopCommands.java deleted file mode 100644 index 90e9569..0000000 --- a/src/main/java/com/alttd/playershops/commands/PlayerShopCommands.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.alttd.playershops.commands; - -import com.google.common.base.Functions; -import com.google.common.collect.Lists; -import org.bukkit.Bukkit; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; - -import java.util.*; -import java.util.function.Supplier; - -public class PlayerShopCommands { - - private PlayerShopCommands() { - } - - private static final Map COMMANDS = new HashMap<>(); - static { - COMMANDS.put("playershop", new PlayerShopCommand()); - } - - public static void registerCommands() { - COMMANDS.forEach((s, command) -> { - Bukkit.getCommandMap().register(s, command.getName(), command); - }); - } - - // Code from Mojang - copyright them | Altered to fit our needs - public static List getListMatchingLast(final CommandSender sender, final String[] args, final String basePermission, final String... matches) { - return getListMatchingLast(sender, args, Arrays.asList(matches), basePermission); - } - - public static boolean matches(final String s, final String s1) { - return s1.regionMatches(true, 0, s, 0, s.length()); - } - - public static List getListMatchingLast(final CommandSender sender, final String[] strings, final Collection collection, final String basePermission) { - String last = strings[strings.length - 1]; - ArrayList results = Lists.newArrayList(); - - if (!collection.isEmpty()) { - - for (String s1 : collection.stream().map(Functions.toStringFunction()).toList()) { - if (matches(last, s1) && (sender.hasPermission(basePermission + "." + s1))) { - results.add(s1); - } - } - - } - - return results; - } - - public static T make(Supplier factory) { - return factory.get(); - } - // end copy stuff -} diff --git a/src/main/java/com/alttd/playershops/commands/Subcommand.java b/src/main/java/com/alttd/playershops/commands/Subcommand.java deleted file mode 100644 index 25261af..0000000 --- a/src/main/java/com/alttd/playershops/commands/Subcommand.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.alttd.playershops.commands; - -import org.bukkit.command.CommandSender; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.framework.qual.DefaultQualifier; - -import java.util.Collections; -import java.util.List; - -@DefaultQualifier(NonNull.class) -public interface Subcommand { - - boolean execute(CommandSender sender, String subCommand, String[] args); - - default List tabComplete(final CommandSender sender, final String subCommand, final String[] args) { - return Collections.emptyList(); - } - -} diff --git a/src/main/java/com/alttd/playershops/commands/arguments/OfflinePlayerArgument.java b/src/main/java/com/alttd/playershops/commands/arguments/OfflinePlayerArgument.java new file mode 100644 index 0000000..06bd0a1 --- /dev/null +++ b/src/main/java/com/alttd/playershops/commands/arguments/OfflinePlayerArgument.java @@ -0,0 +1,49 @@ +package com.alttd.playershops.commands.arguments; + +import com.mojang.brigadier.Message; +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import io.papermc.paper.command.brigadier.MessageComponentSerializer; +import io.papermc.paper.command.brigadier.argument.CustomArgumentType; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.Locale; +import java.util.concurrent.CompletableFuture; + +public class OfflinePlayerArgument implements CustomArgumentType.Converted { + + @Override + public @NotNull OfflinePlayer convert(String nativeType) throws CommandSyntaxException { + try { + return Bukkit.getOfflinePlayer(nativeType); + } catch (Exception e) { + Message message = MessageComponentSerializer.message().serialize(Component.text("Invalid PlayerName %s!".formatted(nativeType), NamedTextColor.RED)); + + throw new CommandSyntaxException(new SimpleCommandExceptionType(message), message); + } + } + + @Override + public @NotNull ArgumentType getNativeType() { + return StringArgumentType.word(); + } + + @Override + public @NotNull CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { + Bukkit.getOnlinePlayers().stream() + .map(Player::getName) + .filter(name -> name.toLowerCase(Locale.ROOT).startsWith(builder.getRemainingLowerCase())) + .forEach(builder::suggest); + return builder.buildFuture(); + } +} \ No newline at end of file diff --git a/src/main/java/com/alttd/playershops/commands/subcommands/CheckStockCommand.java b/src/main/java/com/alttd/playershops/commands/subcommands/CheckStockCommand.java index 6ba493f..722719a 100644 --- a/src/main/java/com/alttd/playershops/commands/subcommands/CheckStockCommand.java +++ b/src/main/java/com/alttd/playershops/commands/subcommands/CheckStockCommand.java @@ -2,8 +2,7 @@ package com.alttd.playershops.commands.subcommands; import com.alttd.playershops.PlayerShops; import com.alttd.playershops.commands.PlayerShopCommand; -import com.alttd.playershops.commands.PlayerShopCommands; -import com.alttd.playershops.commands.Subcommand; +import com.alttd.playershops.config.MessageConfig; import com.alttd.playershops.shop.PlayerShop; import com.alttd.playershops.utils.ShopUtil; import com.alttd.playershops.utils.Util; @@ -13,78 +12,26 @@ import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.bukkit.Location; import org.bukkit.Particle; -import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.framework.qual.DefaultQualifier; -import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @DefaultQualifier(NonNull.class) -public class CheckStockCommand implements Subcommand { +public class CheckStockCommand { - @Override - public boolean execute(CommandSender sender, String subCommand, String[] args) { - return this.doStockCheck(sender, args); - } - - @Override - public List tabComplete(final CommandSender sender, final String subCommand, final String[] args) { - // TODO give some default tab completions - if (args.length == 1) { - return PlayerShopCommands.getListMatchingLast(sender, args, PlayerShopCommand.BASE_PERM + ".checkstock", "help"); - } else if (args.length == 2) { -// return PlayerShopCommands.getListMatchingLast(sender, args, "radius"); - return Collections.emptyList(); - } - return Collections.emptyList(); - } - - private int minimumStock = -1; - - public boolean doStockCheck(final CommandSender sender, final String[] args) { - if (!(sender instanceof Player player)) { - sender.sendRichMessage("Only players can use this command."); - return false; - } - if (args.length != 1 && args.length != 2) { - player.sendRichMessage("Invalid command syntax, use /checkstock [minimum stock]"); - return false; - } - - int radius; - try { - radius = Integer.parseInt(args[0]); - } catch (NumberFormatException e) { - player.sendRichMessage("radius has to be a valid number, use /checkstock [minimum stock]"); - return false; - } - - if (radius > 100 || radius <= 0) { - player.sendRichMessage("Please keep the radius between 1 and 100"); - return false; - } - - if (args.length == 2) { - try { - minimumStock = Integer.parseInt(args[1]); - } catch (NumberFormatException e) { - player.sendRichMessage("minimum stock has to be a valid number, use /checkstock [minimum stock]"); - return false; - } - } - List stockList = checkStock(player.getLocation().getBlockX(), player.getLocation().getBlockZ(), radius, player); - sendStockMessage(player, stockList); + public static void doStockCheck(final Player player, int radius, int minimumStock) { + List stockList = checkStock(player.getLocation().getBlockX(), player.getLocation().getBlockZ(), radius, player, minimumStock); + sendStockMessage(player, stockList, minimumStock); highlightLowStock(player, stockList); - return true; } //Stole this code from AlttdUtility by ___Kappa___ and reworked it slightly - private void highlightLowStock(Player player, List stockList) { + private static void highlightLowStock(Player player, List stockList) { ParticleBuilder particleBuilder = new ParticleBuilder(Particle.DUST); particleBuilder.color(255, 255, 255); particleBuilder.receivers(player); @@ -139,7 +86,7 @@ public class CheckStockCommand implements Subcommand { * @param caller Player who is checking for stock, can only see the stock from their shops unless they have base_perm.checkstock.bypass * @return A list of Stock that the player is allowed to see */ - private List checkStock(int x, int z, int radius, Player caller) { + private static List checkStock(int x, int z, int radius, Player caller, int minimumStock) { List shops = PlayerShops.getInstance().getShopHandler().getShopsInRadius(x, z, radius); Stream playerShopStream = shops.stream(); if (minimumStock != -1) @@ -157,8 +104,7 @@ public class CheckStockCommand implements Subcommand { }).collect(Collectors.toList()); } - private static final String putInConfig = " '>[] left in stock"; - private void sendStockMessage(Player player, List stockList) { + private static void sendStockMessage(Player player, List stockList, int minimumStock) { Component component = null; for (Stock stock : stockList) { TagResolver resolver = TagResolver.resolver( @@ -169,9 +115,9 @@ public class CheckStockCommand implements Subcommand { Placeholder.parsed("amount", stock.stock + "") ); if (component == null) - component = Util.parseMiniMessage(putInConfig, resolver); + component = Util.parseMiniMessage(MessageConfig.SHOP_STOCK_CHECK, resolver); else - component = component.append(Component.newline()).append(Util.parseMiniMessage(putInConfig, resolver)); + component = component.append(Component.newline()).append(Util.parseMiniMessage(MessageConfig.SHOP_STOCK_CHECK, resolver)); } if (component == null) if (minimumStock == -1) diff --git a/src/main/java/com/alttd/playershops/commands/subcommands/ReloadCommand.java b/src/main/java/com/alttd/playershops/commands/subcommands/ReloadCommand.java deleted file mode 100644 index a918416..0000000 --- a/src/main/java/com/alttd/playershops/commands/subcommands/ReloadCommand.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.alttd.playershops.commands.subcommands; - -import com.alttd.playershops.PlayerShops; -import com.alttd.playershops.commands.Subcommand; -import org.bukkit.command.CommandSender; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.framework.qual.DefaultQualifier; - -@DefaultQualifier(NonNull.class) -public class ReloadCommand implements Subcommand { - - @Override - public boolean execute(final CommandSender sender, final String subCommand, final String[] args) { - PlayerShops.getInstance().reloadConfigs(); - // Todo message when config is reloaded - return true; - } - -} diff --git a/src/main/java/com/alttd/playershops/commands/subcommands/TransferShopsCommand.java b/src/main/java/com/alttd/playershops/commands/subcommands/TransferShopsCommand.java deleted file mode 100644 index 0a7bc1f..0000000 --- a/src/main/java/com/alttd/playershops/commands/subcommands/TransferShopsCommand.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.alttd.playershops.commands.subcommands; - -import com.alttd.playershops.PlayerShops; -import com.alttd.playershops.commands.Subcommand; -import com.alttd.playershops.shop.PlayerShop; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.framework.qual.DefaultQualifier; - -import java.util.List; -import java.util.UUID; - -@DefaultQualifier(NonNull.class) -public class TransferShopsCommand implements Subcommand { - - @Override - public boolean execute(CommandSender sender, String subCommand, String[] args) { - if (!(sender instanceof Player player)) { - sender.sendRichMessage("Only players can use this command."); - return false; - } - if (args.length != 1 && args.length != 2) { - player.sendRichMessage("Invalid command syntax, use /transfershops "); - return false; - } - OfflinePlayer oldOfflinePlayer = Bukkit.getOfflinePlayer(args[0]); - if (!oldOfflinePlayer.hasPlayedBefore()) { - player.sendRichMessage("" + args[0] + " has not joined this server before."); - return false; - } - Player newShopOwner = Bukkit.getPlayer(args[1]); - if (newShopOwner == null) { - player.sendRichMessage("" + args[1] + " is not online and has to be online for this process."); - return false; - } - UUID oldUUID = oldOfflinePlayer.getUniqueId(); - List playerShops = PlayerShops.getInstance().getShopHandler().getShops(oldUUID); - sender.sendRichMessage("Starting the transfer process now, this might lag the server."); - for (PlayerShop playerShop : playerShops) { - playerShop.setOwner(newShopOwner); - } - newShopOwner.sendRichMessage(playerShops.size() + " have been transferred to you."); - sender.sendRichMessage(playerShops.size() + " have been transferred to " + args[1] + "."); - return true; - } - -} diff --git a/src/main/java/com/alttd/playershops/config/MessageConfig.java b/src/main/java/com/alttd/playershops/config/MessageConfig.java index 56f95d0..8b825b3 100644 --- a/src/main/java/com/alttd/playershops/config/MessageConfig.java +++ b/src/main/java/com/alttd/playershops/config/MessageConfig.java @@ -143,9 +143,11 @@ public class MessageConfig { public static String SHOP_INFO = "This shop for ."; public static String SHOP_STOCK_INFO = "This shop has stock."; + public static String SHOP_STOCK_CHECK = " '>[] left in stock"; private static void otherMessages() { SHOP_INFO = getString("messages.shop-info", SHOP_INFO); SHOP_STOCK_INFO = getString("messages.shop-stock-info", SHOP_STOCK_INFO); + SHOP_STOCK_CHECK = getString("messages.shop-stock-check", SHOP_STOCK_CHECK); } public static String CHANGE_PRICE_PROMPT = "What should the price be? Type cancel to cancel this action."; diff --git a/src/main/java/com/alttd/playershops/handler/ShopHandler.java b/src/main/java/com/alttd/playershops/handler/ShopHandler.java index 7fb8f97..0954a70 100644 --- a/src/main/java/com/alttd/playershops/handler/ShopHandler.java +++ b/src/main/java/com/alttd/playershops/handler/ShopHandler.java @@ -11,9 +11,11 @@ import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.OfflinePlayer; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.DoubleChest; +import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.InventoryHolder; @@ -178,4 +180,25 @@ public class ShopHandler { return playerSettings.computeIfAbsent(uuid, PlayerSettings::loadFromFile); } + public void transferShops(CommandSender sender, OfflinePlayer oldOwner, OfflinePlayer newOwner) { + if (!oldOwner.hasPlayedBefore()) { + sender.sendRichMessage("" + oldOwner.getName() + " has not joined this server before."); + return; + } + + if (!newOwner.hasPlayedBefore()) { + sender.sendRichMessage("" + newOwner.getName() + " has not joined this server before."); + return; + } + + List playerShops = PlayerShops.getInstance().getShopHandler().getShops(oldOwner.getUniqueId()); + sender.sendRichMessage("Starting the transfer process now, this might lag the server."); + for (PlayerShop playerShop : playerShops) { + playerShop.setOwner(newOwner); + } + if (newOwner.isOnline() && newOwner.getPlayer() != null) { + newOwner.getPlayer().sendRichMessage(playerShops.size() + " have been transferred to you."); + } + sender.sendRichMessage(playerShops.size() + " from " + oldOwner.getName() + " have been transferred to " + newOwner.getName() + "."); + } } diff --git a/src/main/java/com/alttd/playershops/shop/PlayerShop.java b/src/main/java/com/alttd/playershops/shop/PlayerShop.java index a7be8a7..40bb1bd 100644 --- a/src/main/java/com/alttd/playershops/shop/PlayerShop.java +++ b/src/main/java/com/alttd/playershops/shop/PlayerShop.java @@ -10,6 +10,7 @@ import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.OfflinePlayer; import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; @@ -134,7 +135,7 @@ public class PlayerShop { } } - public void setOwner(Player player) { + public void setOwner(OfflinePlayer player) { ownerUUID = player.getUniqueId(); ownerName = player.getName(); update(); diff --git a/src/main/java/com/alttd/playershops/utils/Pair.java b/src/main/java/com/alttd/playershops/utils/Pair.java new file mode 100644 index 0000000..536fcb6 --- /dev/null +++ b/src/main/java/com/alttd/playershops/utils/Pair.java @@ -0,0 +1,5 @@ +package com.alttd.playershops.utils; + +public record Pair(X x, Y y) { + +}