From 410773101457299eed0575f74192fa1bb68e2a83 Mon Sep 17 00:00:00 2001 From: loki5512344 Date: Tue, 7 Apr 2026 12:57:06 +0200 Subject: [PATCH] =?UTF-8?q?refactor(gradient):=20=D1=80=D0=B0=D0=B7=D0=B1?= =?UTF-8?q?=D0=B8=D1=82=D1=8C=20GradientPrefixCommand=20=D1=87=D0=B5=D1=80?= =?UTF-8?q?=D0=B5=D0=B7=20Command=20pattern=20(212=E2=86=9264=20=D1=81?= =?UTF-8?q?=D1=82=D1=80=D0=BE=D0=BA=D0=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Применен Command pattern с handlers: - PrefixSubCommandHandler: интерфейс для обработчиков - PrefixOnHandler: включение префикса (40 строк) - PrefixOffHandler: выключение префикса (35 строк) - PrefixResetHandler: сброс префикса (40 строк) - PrefixSetHandler: установка префикса (110 строк) Структура: + gradient/commands/handlers/prefix/PrefixSubCommandHandler.java + gradient/commands/handlers/prefix/PrefixOnHandler.java + gradient/commands/handlers/prefix/PrefixOffHandler.java + gradient/commands/handlers/prefix/PrefixResetHandler.java + gradient/commands/handlers/prefix/PrefixSetHandler.java ~ gradient/commands/GradientPrefixCommand.java (212→64 строки) Результат: - GradientPrefixCommand уменьшен с 212 до 64 строк - Каждый handler отвечает за одну подкоманду - Улучшена тестируемость и расширяемость - Все god-классы разбиты, директории оптимизированы --- .../commands/GradientPrefixCommand.java | 166 ++---------------- .../handlers/prefix/PrefixOffHandler.java | 35 ++++ .../handlers/prefix/PrefixOnHandler.java | 41 +++++ .../handlers/prefix/PrefixResetHandler.java | 42 +++++ .../handlers/prefix/PrefixSetHandler.java | 110 ++++++++++++ .../prefix/PrefixSubCommandHandler.java | 17 ++ 6 files changed, 260 insertions(+), 151 deletions(-) create mode 100644 src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixOffHandler.java create mode 100644 src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixOnHandler.java create mode 100644 src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixResetHandler.java create mode 100644 src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixSetHandler.java create mode 100644 src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixSubCommandHandler.java diff --git a/src/main/java/com/loki/lochat/gradient/commands/GradientPrefixCommand.java b/src/main/java/com/loki/lochat/gradient/commands/GradientPrefixCommand.java index 6b90335..541138e 100644 --- a/src/main/java/com/loki/lochat/gradient/commands/GradientPrefixCommand.java +++ b/src/main/java/com/loki/lochat/gradient/commands/GradientPrefixCommand.java @@ -1,13 +1,7 @@ package com.loki.lochat.gradient.commands; -import com.loki.lochat.config.RatConfig; import com.loki.lochat.gradient.GradientModule; -import com.loki.lochat.gradient.config.GradientConfig; -import com.loki.lochat.gradient.config.GradientMessages; -import com.loki.lochat.gradient.data.GradientPlayerData; -import com.loki.lochat.gradient.gui.GradientConfirmGUI; -import com.loki.lochat.gradient.util.DisplayNameUtil; -import com.loki.lochat.utils.platform.FoliaUtil; +import com.loki.lochat.gradient.commands.handlers.prefix.*; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -16,34 +10,29 @@ import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.BiFunction; -import java.util.regex.Pattern; +import java.util.*; /** * Команда /prefix для установки кастомного префикса + * Делегирует обработку подкоманд соответствующим handlers */ public class GradientPrefixCommand implements CommandExecutor, TabCompleter { - private static final Pattern COLOR_CODE_PATTERN = Pattern.compile( - "(?i)(&[0-9a-fk-or]|§[0-9a-fk-or]|#[0-9a-f]{6}|&#[0-9a-f]{6}|<#[0-9a-f]{6}>)"); - private static final Pattern ALLOWED_PREFIX_PATTERN = Pattern.compile("^[a-zA-Zа-яА-ЯёЁ0-9 _\\-]+$"); private static final Set SUB_COMMANDS = Set.of("on", "off", "reset"); private final GradientModule module; - private final Map> subCommands = new HashMap<>(); + private final Map handlers = new HashMap<>(); + private final PrefixSetHandler setHandler; public GradientPrefixCommand(GradientModule module) { this.module = module; - registerSubCommands(); + this.setHandler = new PrefixSetHandler(module); + registerHandlers(); } - private void registerSubCommands() { - subCommands.put("on", this::handleOn); - subCommands.put("off", this::handleOff); - subCommands.put("reset", this::handleReset); + private void registerHandlers() { + handlers.put("on", new PrefixOnHandler(module)); + handlers.put("off", new PrefixOffHandler(module)); + handlers.put("reset", new PrefixResetHandler(module)); } @Override @@ -65,138 +54,13 @@ public class GradientPrefixCommand implements CommandExecutor, TabCompleter { } String subCommand = args[0].toLowerCase(); - var handler = subCommands.get(subCommand); + PrefixSubCommandHandler handler = handlers.get(subCommand); + if (handler != null) { - return handler.apply(player, args); + return handler.handle(player, args); } - return handleSetPrefix(player, args); - } - - private boolean handleOn(Player player, String[] args) { - GradientPlayerData data = module.getDataManager().getPlayerData(player.getUniqueId()); - GradientMessages msg = module.getMessages(); - - if (!data.hasPrefix()) { - msg.send(player, "prefix-no-prefix"); - return true; - } - - data.setPrefixEnabled(true); - saveAndUpdate(player, data); - msg.send(player, "prefix-enabled"); - return true; - } - - private boolean handleOff(Player player, String[] args) { - GradientPlayerData data = module.getDataManager().getPlayerData(player.getUniqueId()); - data.setPrefixEnabled(false); - saveAndUpdate(player, data); - module.getMessages().send(player, "prefix-disabled"); - return true; - } - - private boolean handleReset(Player player, String[] args) { - GradientPlayerData data = module.getDataManager().getPlayerData(player.getUniqueId()); - GradientMessages msg = module.getMessages(); - - if (!data.hasPrefix()) { - msg.send(player, "prefix-no-prefix"); - return true; - } - - data.setPrefix(null); - data.setPrefixEnabled(false); - saveAndUpdate(player, data); - msg.send(player, "prefix-reset-success"); - return true; - } - - private boolean handleSetPrefix(Player player, String[] args) { - GradientMessages msg = module.getMessages(); - GradientConfig cfg = module.getConfig(); - String prefix = String.join(" ", args); - - if (prefix.trim().isEmpty()) { - msg.send(player, "prefix-help"); - return true; - } - - if (COLOR_CODE_PATTERN.matcher(prefix).find()) { - msg.send(player, "prefix-no-colors"); - return true; - } - - if (!ALLOWED_PREFIX_PATTERN.matcher(prefix).matches()) { - msg.send(player, "prefix-invalid-chars"); - return true; - } - - if (cfg.isPrefixBlacklisted(prefix)) { - msg.send(player, "prefix-blacklisted"); - return true; - } - - if (prefix.length() > cfg.getMaxPrefixLength()) { - msg.send(player, "prefix-too-long", "max", String.valueOf(cfg.getMaxPrefixLength())); - return true; - } - - GradientPlayerData data = module.getDataManager().getPlayerData(player.getUniqueId()); - - if (!player.hasPermission("gradient.bypass.cooldown") && - !checkCooldown(player, cfg.getPrefixCooldown(), data.getLastPrefixChange())) { - return true; - } - - int price = calculatePrice(player, cfg, data); - - if (price > 0 && !checkBalance(player, price)) { - return true; - } - - GradientConfirmGUI gui = new GradientConfirmGUI(module, player, - GradientConfirmGUI.ConfirmType.PREFIX, - data.hasColors() && data.isColorEnabled() ? data.getColors() : null, - prefix, price); - FoliaUtil.runEntityTask(module.getPlugin(), player, gui::open); - return true; - } - - private int calculatePrice(Player player, GradientConfig cfg, GradientPlayerData data) { - if (player.hasPermission("gradient.bypass.cost")) return 0; - return (cfg.isPrefixOneTimePurchase() && data.isPrefixPurchased()) ? 0 : cfg.getPrefixPrice(); - } - - private boolean checkCooldown(Player player, int cooldownSec, long lastChange) { - long cooldownMs = cooldownSec * RatConfig.MILLIS_PER_SECOND; - long timePassed = System.currentTimeMillis() - lastChange; - if (timePassed < cooldownMs) { - long remaining = (cooldownMs - timePassed) / RatConfig.MILLIS_PER_SECOND; - module.getMessages().send(player, "cooldown", "time", String.valueOf(remaining)); - return false; - } - return true; - } - - private boolean checkBalance(Player player, int price) { - if (!module.hasPlayerPoints()) { - player.sendMessage("§cPlayerPoints не установлен!"); - return false; - } - int balance = module.getPlayerPointsAPI().look(player.getUniqueId()); - if (balance < price) { - module.getMessages().send(player, "not-enough-points-prefix", "price", String.valueOf(price)); - return false; - } - return true; - } - - private void saveAndUpdate(Player player, GradientPlayerData data) { - FoliaUtil.runEntityTask(module.getPlugin(), player, - () -> DisplayNameUtil.updateDisplayName(module, player, data)); - FoliaUtil.runAsync(module.getPlugin(), - () -> module.getDataManager().savePlayerData(player.getUniqueId())); + return setHandler.handle(player, args); } @Override diff --git a/src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixOffHandler.java b/src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixOffHandler.java new file mode 100644 index 0000000..efff579 --- /dev/null +++ b/src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixOffHandler.java @@ -0,0 +1,35 @@ +package com.loki.lochat.gradient.commands.handlers.prefix; + +import com.loki.lochat.gradient.GradientModule; +import com.loki.lochat.gradient.data.GradientPlayerData; +import com.loki.lochat.gradient.util.DisplayNameUtil; +import com.loki.lochat.utils.platform.FoliaUtil; +import org.bukkit.entity.Player; + +/** + * Обработчик команды /prefix off + */ +public class PrefixOffHandler implements PrefixSubCommandHandler { + + private final GradientModule module; + + public PrefixOffHandler(GradientModule module) { + this.module = module; + } + + @Override + public boolean handle(Player player, String[] args) { + GradientPlayerData data = module.getDataManager().getPlayerData(player.getUniqueId()); + data.setPrefixEnabled(false); + saveAndUpdate(player, data); + module.getMessages().send(player, "prefix-disabled"); + return true; + } + + private void saveAndUpdate(Player player, GradientPlayerData data) { + FoliaUtil.runEntityTask(module.getPlugin(), player, + () -> DisplayNameUtil.updateDisplayName(module, player, data)); + FoliaUtil.runAsync(module.getPlugin(), + () -> module.getDataManager().savePlayerData(player.getUniqueId())); + } +} diff --git a/src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixOnHandler.java b/src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixOnHandler.java new file mode 100644 index 0000000..c262d11 --- /dev/null +++ b/src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixOnHandler.java @@ -0,0 +1,41 @@ +package com.loki.lochat.gradient.commands.handlers.prefix; + +import com.loki.lochat.gradient.GradientModule; +import com.loki.lochat.gradient.data.GradientPlayerData; +import com.loki.lochat.gradient.util.DisplayNameUtil; +import com.loki.lochat.utils.platform.FoliaUtil; +import org.bukkit.entity.Player; + +/** + * Обработчик команды /prefix on + */ +public class PrefixOnHandler implements PrefixSubCommandHandler { + + private final GradientModule module; + + public PrefixOnHandler(GradientModule module) { + this.module = module; + } + + @Override + public boolean handle(Player player, String[] args) { + GradientPlayerData data = module.getDataManager().getPlayerData(player.getUniqueId()); + + if (!data.hasPrefix()) { + module.getMessages().send(player, "prefix-no-prefix"); + return true; + } + + data.setPrefixEnabled(true); + saveAndUpdate(player, data); + module.getMessages().send(player, "prefix-enabled"); + return true; + } + + private void saveAndUpdate(Player player, GradientPlayerData data) { + FoliaUtil.runEntityTask(module.getPlugin(), player, + () -> DisplayNameUtil.updateDisplayName(module, player, data)); + FoliaUtil.runAsync(module.getPlugin(), + () -> module.getDataManager().savePlayerData(player.getUniqueId())); + } +} diff --git a/src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixResetHandler.java b/src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixResetHandler.java new file mode 100644 index 0000000..ed60267 --- /dev/null +++ b/src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixResetHandler.java @@ -0,0 +1,42 @@ +package com.loki.lochat.gradient.commands.handlers.prefix; + +import com.loki.lochat.gradient.GradientModule; +import com.loki.lochat.gradient.data.GradientPlayerData; +import com.loki.lochat.gradient.util.DisplayNameUtil; +import com.loki.lochat.utils.platform.FoliaUtil; +import org.bukkit.entity.Player; + +/** + * Обработчик команды /prefix reset + */ +public class PrefixResetHandler implements PrefixSubCommandHandler { + + private final GradientModule module; + + public PrefixResetHandler(GradientModule module) { + this.module = module; + } + + @Override + public boolean handle(Player player, String[] args) { + GradientPlayerData data = module.getDataManager().getPlayerData(player.getUniqueId()); + + if (!data.hasPrefix()) { + module.getMessages().send(player, "prefix-no-prefix"); + return true; + } + + data.setPrefix(null); + data.setPrefixEnabled(false); + saveAndUpdate(player, data); + module.getMessages().send(player, "prefix-reset-success"); + return true; + } + + private void saveAndUpdate(Player player, GradientPlayerData data) { + FoliaUtil.runEntityTask(module.getPlugin(), player, + () -> DisplayNameUtil.updateDisplayName(module, player, data)); + FoliaUtil.runAsync(module.getPlugin(), + () -> module.getDataManager().savePlayerData(player.getUniqueId())); + } +} diff --git a/src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixSetHandler.java b/src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixSetHandler.java new file mode 100644 index 0000000..ba9ef38 --- /dev/null +++ b/src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixSetHandler.java @@ -0,0 +1,110 @@ +package com.loki.lochat.gradient.commands.handlers.prefix; + +import com.loki.lochat.config.RatConfig; +import com.loki.lochat.gradient.GradientModule; +import com.loki.lochat.gradient.config.GradientConfig; +import com.loki.lochat.gradient.config.GradientMessages; +import com.loki.lochat.gradient.data.GradientPlayerData; +import com.loki.lochat.gradient.gui.GradientConfirmGUI; +import com.loki.lochat.utils.platform.FoliaUtil; +import org.bukkit.entity.Player; + +import java.util.regex.Pattern; + +/** + * Обработчик команды /prefix <текст> + * Устанавливает кастомный префикс + */ +public class PrefixSetHandler implements PrefixSubCommandHandler { + + private static final Pattern COLOR_CODE_PATTERN = Pattern.compile( + "(?i)(&[0-9a-fk-or]|§[0-9a-fk-or]|#[0-9a-f]{6}|&#[0-9a-f]{6}|<#[0-9a-f]{6}>)"); + private static final Pattern ALLOWED_PREFIX_PATTERN = Pattern.compile("^[a-zA-Zа-яА-ЯёЁ0-9 _\\-]+$"); + + private final GradientModule module; + + public PrefixSetHandler(GradientModule module) { + this.module = module; + } + + @Override + public boolean handle(Player player, String[] args) { + GradientMessages msg = module.getMessages(); + GradientConfig cfg = module.getConfig(); + String prefix = String.join(" ", args); + + if (prefix.trim().isEmpty()) { + msg.send(player, "prefix-help"); + return true; + } + + if (COLOR_CODE_PATTERN.matcher(prefix).find()) { + msg.send(player, "prefix-no-colors"); + return true; + } + + if (!ALLOWED_PREFIX_PATTERN.matcher(prefix).matches()) { + msg.send(player, "prefix-invalid-chars"); + return true; + } + + if (cfg.isPrefixBlacklisted(prefix)) { + msg.send(player, "prefix-blacklisted"); + return true; + } + + if (prefix.length() > cfg.getMaxPrefixLength()) { + msg.send(player, "prefix-too-long", "max", String.valueOf(cfg.getMaxPrefixLength())); + return true; + } + + GradientPlayerData data = module.getDataManager().getPlayerData(player.getUniqueId()); + + if (!player.hasPermission("gradient.bypass.cooldown") && + !checkCooldown(player, cfg.getPrefixCooldown(), data.getLastPrefixChange())) { + return true; + } + + int price = calculatePrice(player, cfg, data); + + if (price > 0 && !checkBalance(player, price)) { + return true; + } + + GradientConfirmGUI gui = new GradientConfirmGUI(module, player, + GradientConfirmGUI.ConfirmType.PREFIX, + data.hasColors() && data.isColorEnabled() ? data.getColors() : null, + prefix, price); + FoliaUtil.runEntityTask(module.getPlugin(), player, gui::open); + return true; + } + + private int calculatePrice(Player player, GradientConfig cfg, GradientPlayerData data) { + if (player.hasPermission("gradient.bypass.cost")) return 0; + return (cfg.isPrefixOneTimePurchase() && data.isPrefixPurchased()) ? 0 : cfg.getPrefixPrice(); + } + + private boolean checkCooldown(Player player, int cooldownSec, long lastChange) { + long cooldownMs = cooldownSec * RatConfig.MILLIS_PER_SECOND; + long timePassed = System.currentTimeMillis() - lastChange; + if (timePassed < cooldownMs) { + long remaining = (cooldownMs - timePassed) / RatConfig.MILLIS_PER_SECOND; + module.getMessages().send(player, "cooldown", "time", String.valueOf(remaining)); + return false; + } + return true; + } + + private boolean checkBalance(Player player, int price) { + if (!module.hasPlayerPoints()) { + player.sendMessage("§cPlayerPoints не установлен!"); + return false; + } + int balance = module.getPlayerPointsAPI().look(player.getUniqueId()); + if (balance < price) { + module.getMessages().send(player, "not-enough-points-prefix", "price", String.valueOf(price)); + return false; + } + return true; + } +} diff --git a/src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixSubCommandHandler.java b/src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixSubCommandHandler.java new file mode 100644 index 0000000..aab2877 --- /dev/null +++ b/src/main/java/com/loki/lochat/gradient/commands/handlers/prefix/PrefixSubCommandHandler.java @@ -0,0 +1,17 @@ +package com.loki.lochat.gradient.commands.handlers.prefix; + +import org.bukkit.entity.Player; + +/** + * Интерфейс для обработчиков подкоманд /prefix + */ +public interface PrefixSubCommandHandler { + + /** + * Обрабатывает подкоманду + * @param player игрок, выполнивший команду + * @param args аргументы команды + * @return true если команда обработана успешно + */ + boolean handle(Player player, String[] args); +}