diff --git a/src/main/java/com/loki/lochat/commands/CommandManager.java b/src/main/java/com/loki/lochat/commands/CommandManager.java
index 5f709a9..0625aee 100644
--- a/src/main/java/com/loki/lochat/commands/CommandManager.java
+++ b/src/main/java/com/loki/lochat/commands/CommandManager.java
@@ -1,10 +1,14 @@
package com.loki.lochat.commands;
import com.loki.lochat.LoChat;
-import com.loki.lochat.commands.admin.*;
+import com.loki.lochat.commands.admin.chat.*;
+import com.loki.lochat.commands.admin.system.*;
+import com.loki.lochat.commands.admin.broadcast.*;
import com.loki.lochat.commands.chat.*;
import com.loki.lochat.commands.messaging.*;
-import com.loki.lochat.commands.moderation.*;
+import com.loki.lochat.commands.moderation.ban.*;
+import com.loki.lochat.commands.moderation.mute.*;
+import com.loki.lochat.commands.moderation.warn.*;
import com.loki.lochat.commands.nick.*;
import com.loki.lochat.commands.rp.*;
import org.bukkit.command.PluginCommand;
diff --git a/src/main/java/com/loki/lochat/commands/CustomCommandsCommand.java b/src/main/java/com/loki/lochat/commands/CustomCommandsCommand.java
index 2243fea..6414b68 100644
--- a/src/main/java/com/loki/lochat/commands/CustomCommandsCommand.java
+++ b/src/main/java/com/loki/lochat/commands/CustomCommandsCommand.java
@@ -2,7 +2,7 @@ package com.loki.lochat.commands;
import com.loki.lochat.LoChat;
import com.loki.lochat.managers.CustomCommandManager;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import net.kyori.adventure.text.Component;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
diff --git a/src/main/java/com/loki/lochat/commands/admin/AnnounceCommand.java b/src/main/java/com/loki/lochat/commands/admin/broadcast/AnnounceCommand.java
similarity index 95%
rename from src/main/java/com/loki/lochat/commands/admin/AnnounceCommand.java
rename to src/main/java/com/loki/lochat/commands/admin/broadcast/AnnounceCommand.java
index 6a2fb38..ddfea18 100644
--- a/src/main/java/com/loki/lochat/commands/admin/AnnounceCommand.java
+++ b/src/main/java/com/loki/lochat/commands/admin/broadcast/AnnounceCommand.java
@@ -1,7 +1,7 @@
-package com.loki.lochat.commands.admin;
+package com.loki.lochat.commands.admin.broadcast;
import com.loki.lochat.LoChat;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.title.Title;
import org.bukkit.Bukkit;
diff --git a/src/main/java/com/loki/lochat/commands/admin/DiscordCommand.java b/src/main/java/com/loki/lochat/commands/admin/broadcast/DiscordCommand.java
similarity index 96%
rename from src/main/java/com/loki/lochat/commands/admin/DiscordCommand.java
rename to src/main/java/com/loki/lochat/commands/admin/broadcast/DiscordCommand.java
index e3b7e7d..752f8ff 100644
--- a/src/main/java/com/loki/lochat/commands/admin/DiscordCommand.java
+++ b/src/main/java/com/loki/lochat/commands/admin/broadcast/DiscordCommand.java
@@ -1,8 +1,8 @@
-package com.loki.lochat.commands.admin;
+package com.loki.lochat.commands.admin.broadcast;
import com.loki.lochat.LoChat;
import com.loki.lochat.integrations.DiscordIntegration;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
diff --git a/src/main/java/com/loki/lochat/commands/admin/ChatSpyCommand.java b/src/main/java/com/loki/lochat/commands/admin/chat/ChatSpyCommand.java
similarity index 92%
rename from src/main/java/com/loki/lochat/commands/admin/ChatSpyCommand.java
rename to src/main/java/com/loki/lochat/commands/admin/chat/ChatSpyCommand.java
index af48020..7f12b66 100644
--- a/src/main/java/com/loki/lochat/commands/admin/ChatSpyCommand.java
+++ b/src/main/java/com/loki/lochat/commands/admin/chat/ChatSpyCommand.java
@@ -1,8 +1,8 @@
-package com.loki.lochat.commands.admin;
+package com.loki.lochat.commands.admin.chat;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.MessagingService;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
diff --git a/src/main/java/com/loki/lochat/commands/admin/ClearChatCommand.java b/src/main/java/com/loki/lochat/commands/admin/chat/ClearChatCommand.java
similarity index 91%
rename from src/main/java/com/loki/lochat/commands/admin/ClearChatCommand.java
rename to src/main/java/com/loki/lochat/commands/admin/chat/ClearChatCommand.java
index 9a1adc6..0763832 100644
--- a/src/main/java/com/loki/lochat/commands/admin/ClearChatCommand.java
+++ b/src/main/java/com/loki/lochat/commands/admin/chat/ClearChatCommand.java
@@ -1,7 +1,7 @@
-package com.loki.lochat.commands.admin;
+package com.loki.lochat.commands.admin.chat;
import com.loki.lochat.LoChat;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
diff --git a/src/main/java/com/loki/lochat/commands/admin/ClearChatConfigCommand.java b/src/main/java/com/loki/lochat/commands/admin/chat/ClearChatConfigCommand.java
similarity index 96%
rename from src/main/java/com/loki/lochat/commands/admin/ClearChatConfigCommand.java
rename to src/main/java/com/loki/lochat/commands/admin/chat/ClearChatConfigCommand.java
index 2420910..351f599 100644
--- a/src/main/java/com/loki/lochat/commands/admin/ClearChatConfigCommand.java
+++ b/src/main/java/com/loki/lochat/commands/admin/chat/ClearChatConfigCommand.java
@@ -1,7 +1,7 @@
-package com.loki.lochat.commands.admin;
+package com.loki.lochat.commands.admin.chat;
import com.loki.lochat.LoChat;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
diff --git a/src/main/java/com/loki/lochat/commands/admin/HubCommand.java b/src/main/java/com/loki/lochat/commands/admin/system/HubCommand.java
similarity index 93%
rename from src/main/java/com/loki/lochat/commands/admin/HubCommand.java
rename to src/main/java/com/loki/lochat/commands/admin/system/HubCommand.java
index 7eb5e93..9774994 100644
--- a/src/main/java/com/loki/lochat/commands/admin/HubCommand.java
+++ b/src/main/java/com/loki/lochat/commands/admin/system/HubCommand.java
@@ -1,9 +1,9 @@
-package com.loki.lochat.commands.admin;
+package com.loki.lochat.commands.admin.system;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import com.loki.lochat.LoChat;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
diff --git a/src/main/java/com/loki/lochat/commands/admin/LoChatCommand.java b/src/main/java/com/loki/lochat/commands/admin/system/LoChatCommand.java
similarity index 96%
rename from src/main/java/com/loki/lochat/commands/admin/LoChatCommand.java
rename to src/main/java/com/loki/lochat/commands/admin/system/LoChatCommand.java
index 9faf6e3..ca5002f 100644
--- a/src/main/java/com/loki/lochat/commands/admin/LoChatCommand.java
+++ b/src/main/java/com/loki/lochat/commands/admin/system/LoChatCommand.java
@@ -1,7 +1,7 @@
-package com.loki.lochat.commands.admin;
+package com.loki.lochat.commands.admin.system;
import com.loki.lochat.LoChat;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
diff --git a/src/main/java/com/loki/lochat/commands/admin/ReloadConfigCommand.java b/src/main/java/com/loki/lochat/commands/admin/system/ReloadConfigCommand.java
similarity index 92%
rename from src/main/java/com/loki/lochat/commands/admin/ReloadConfigCommand.java
rename to src/main/java/com/loki/lochat/commands/admin/system/ReloadConfigCommand.java
index 4690deb..c935a18 100644
--- a/src/main/java/com/loki/lochat/commands/admin/ReloadConfigCommand.java
+++ b/src/main/java/com/loki/lochat/commands/admin/system/ReloadConfigCommand.java
@@ -1,7 +1,7 @@
-package com.loki.lochat.commands.admin;
+package com.loki.lochat.commands.admin.system;
import com.loki.lochat.LoChat;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
diff --git a/src/main/java/com/loki/lochat/commands/chat/GlobalChatCommand.java b/src/main/java/com/loki/lochat/commands/chat/GlobalChatCommand.java
index c8c2858..471c5ed 100644
--- a/src/main/java/com/loki/lochat/commands/chat/GlobalChatCommand.java
+++ b/src/main/java/com/loki/lochat/commands/chat/GlobalChatCommand.java
@@ -2,7 +2,7 @@ package com.loki.lochat.commands.chat;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.ChatService;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
diff --git a/src/main/java/com/loki/lochat/commands/chat/LocalChatCommand.java b/src/main/java/com/loki/lochat/commands/chat/LocalChatCommand.java
index 5b89445..5fa8691 100644
--- a/src/main/java/com/loki/lochat/commands/chat/LocalChatCommand.java
+++ b/src/main/java/com/loki/lochat/commands/chat/LocalChatCommand.java
@@ -2,7 +2,7 @@ package com.loki.lochat.commands.chat;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.ChatService;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
diff --git a/src/main/java/com/loki/lochat/commands/messaging/IgnoreCommand.java b/src/main/java/com/loki/lochat/commands/messaging/IgnoreCommand.java
index 78612c6..aefc3f3 100644
--- a/src/main/java/com/loki/lochat/commands/messaging/IgnoreCommand.java
+++ b/src/main/java/com/loki/lochat/commands/messaging/IgnoreCommand.java
@@ -2,7 +2,7 @@ package com.loki.lochat.commands.messaging;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.MessagingService;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
diff --git a/src/main/java/com/loki/lochat/commands/messaging/IgnoreListCommand.java b/src/main/java/com/loki/lochat/commands/messaging/IgnoreListCommand.java
index e674248..12263eb 100644
--- a/src/main/java/com/loki/lochat/commands/messaging/IgnoreListCommand.java
+++ b/src/main/java/com/loki/lochat/commands/messaging/IgnoreListCommand.java
@@ -2,8 +2,8 @@ package com.loki.lochat.commands.messaging;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.MessagingService;
-import com.loki.lochat.utils.ChatFormatter;
-import com.loki.lochat.utils.PlayerUtil;
+import com.loki.lochat.utils.format.ChatFormatter;
+import com.loki.lochat.utils.player.PlayerUtil;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
diff --git a/src/main/java/com/loki/lochat/commands/messaging/MsgCommand.java b/src/main/java/com/loki/lochat/commands/messaging/MsgCommand.java
index dca89af..a1222aa 100644
--- a/src/main/java/com/loki/lochat/commands/messaging/MsgCommand.java
+++ b/src/main/java/com/loki/lochat/commands/messaging/MsgCommand.java
@@ -2,8 +2,8 @@ package com.loki.lochat.commands.messaging;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.MessagingService;
-import com.loki.lochat.utils.ChatFormatter;
-import com.loki.lochat.utils.PlayerUtil;
+import com.loki.lochat.utils.format.ChatFormatter;
+import com.loki.lochat.utils.player.PlayerUtil;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.command.Command;
diff --git a/src/main/java/com/loki/lochat/commands/messaging/ReplyCommand.java b/src/main/java/com/loki/lochat/commands/messaging/ReplyCommand.java
index 70bc232..1664652 100644
--- a/src/main/java/com/loki/lochat/commands/messaging/ReplyCommand.java
+++ b/src/main/java/com/loki/lochat/commands/messaging/ReplyCommand.java
@@ -2,8 +2,8 @@ package com.loki.lochat.commands.messaging;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.MessagingService;
-import com.loki.lochat.utils.ChatFormatter;
-import com.loki.lochat.utils.PlayerUtil;
+import com.loki.lochat.utils.format.ChatFormatter;
+import com.loki.lochat.utils.player.PlayerUtil;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.command.Command;
diff --git a/src/main/java/com/loki/lochat/commands/messaging/UnignoreCommand.java b/src/main/java/com/loki/lochat/commands/messaging/UnignoreCommand.java
index 23d210d..6ee5b96 100644
--- a/src/main/java/com/loki/lochat/commands/messaging/UnignoreCommand.java
+++ b/src/main/java/com/loki/lochat/commands/messaging/UnignoreCommand.java
@@ -2,7 +2,7 @@ package com.loki.lochat.commands.messaging;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.MessagingService;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
diff --git a/src/main/java/com/loki/lochat/commands/moderation/BanCommand.java b/src/main/java/com/loki/lochat/commands/moderation/ban/BanCommand.java
similarity index 97%
rename from src/main/java/com/loki/lochat/commands/moderation/BanCommand.java
rename to src/main/java/com/loki/lochat/commands/moderation/ban/BanCommand.java
index 5afae61..86b4338 100644
--- a/src/main/java/com/loki/lochat/commands/moderation/BanCommand.java
+++ b/src/main/java/com/loki/lochat/commands/moderation/ban/BanCommand.java
@@ -1,12 +1,12 @@
-package com.loki.lochat.commands.moderation;
+package com.loki.lochat.commands.moderation.ban;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.MuteService;
import com.loki.lochat.api.service.PunishmentService;
import com.loki.lochat.config.MessagesConfig;
import com.loki.lochat.data.model.BanRecord;
-import com.loki.lochat.utils.ChatFormatter;
-import com.loki.lochat.utils.PlayerUtil;
+import com.loki.lochat.utils.format.ChatFormatter;
+import com.loki.lochat.utils.player.PlayerUtil;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
diff --git a/src/main/java/com/loki/lochat/commands/moderation/UnbanCommand.java b/src/main/java/com/loki/lochat/commands/moderation/ban/UnbanCommand.java
similarity index 94%
rename from src/main/java/com/loki/lochat/commands/moderation/UnbanCommand.java
rename to src/main/java/com/loki/lochat/commands/moderation/ban/UnbanCommand.java
index e79ca6b..4d4d672 100644
--- a/src/main/java/com/loki/lochat/commands/moderation/UnbanCommand.java
+++ b/src/main/java/com/loki/lochat/commands/moderation/ban/UnbanCommand.java
@@ -1,10 +1,10 @@
-package com.loki.lochat.commands.moderation;
+package com.loki.lochat.commands.moderation.ban;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.PunishmentService;
import com.loki.lochat.config.MessagesConfig;
-import com.loki.lochat.utils.ChatFormatter;
-import com.loki.lochat.utils.PlayerUtil;
+import com.loki.lochat.utils.format.ChatFormatter;
+import com.loki.lochat.utils.player.PlayerUtil;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
diff --git a/src/main/java/com/loki/lochat/commands/moderation/MuteBlameCommand.java b/src/main/java/com/loki/lochat/commands/moderation/mute/MuteBlameCommand.java
similarity index 98%
rename from src/main/java/com/loki/lochat/commands/moderation/MuteBlameCommand.java
rename to src/main/java/com/loki/lochat/commands/moderation/mute/MuteBlameCommand.java
index f11211c..7951555 100644
--- a/src/main/java/com/loki/lochat/commands/moderation/MuteBlameCommand.java
+++ b/src/main/java/com/loki/lochat/commands/moderation/mute/MuteBlameCommand.java
@@ -1,4 +1,4 @@
-package com.loki.lochat.commands.moderation;
+package com.loki.lochat.commands.moderation.mute;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.MuteService;
diff --git a/src/main/java/com/loki/lochat/commands/moderation/MuteCommand.java b/src/main/java/com/loki/lochat/commands/moderation/mute/MuteCommand.java
similarity index 95%
rename from src/main/java/com/loki/lochat/commands/moderation/MuteCommand.java
rename to src/main/java/com/loki/lochat/commands/moderation/mute/MuteCommand.java
index 44ec8de..1dbeac6 100644
--- a/src/main/java/com/loki/lochat/commands/moderation/MuteCommand.java
+++ b/src/main/java/com/loki/lochat/commands/moderation/mute/MuteCommand.java
@@ -1,9 +1,9 @@
-package com.loki.lochat.commands.moderation;
+package com.loki.lochat.commands.moderation.mute;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.MuteService;
import com.loki.lochat.config.MessagesConfig;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@@ -93,12 +93,12 @@ public class MuteCommand implements CommandExecutor, TabCompleter {
return true;
}
- UUID targetUUID = com.loki.lochat.utils.PlayerUtil.findPlayerUUID(targetName);
+ UUID targetUUID = com.loki.lochat.utils.player.PlayerUtil.findPlayerUUID(targetName);
if (targetUUID == null) { sender.sendMessage(plugin.getMessageConfig().getComponent("errors.player-not-found")); return true; }
if (muteService.isMuted(targetUUID)) { sender.sendMessage(ChatFormatter.parse("CF6679Игрок уже замучен!")); return true; }
Player target = Bukkit.getPlayer(targetUUID);
- String finalName = com.loki.lochat.utils.PlayerUtil.getPlayerName(targetUUID);
+ String finalName = com.loki.lochat.utils.player.PlayerUtil.getPlayerName(targetUUID);
String op = sender.getName();
muteService.mute(targetUUID, finalName, duration, reason, op);
diff --git a/src/main/java/com/loki/lochat/commands/moderation/MuteHistoryCommand.java b/src/main/java/com/loki/lochat/commands/moderation/mute/MuteHistoryCommand.java
similarity index 96%
rename from src/main/java/com/loki/lochat/commands/moderation/MuteHistoryCommand.java
rename to src/main/java/com/loki/lochat/commands/moderation/mute/MuteHistoryCommand.java
index e5657b7..8cf30ef 100644
--- a/src/main/java/com/loki/lochat/commands/moderation/MuteHistoryCommand.java
+++ b/src/main/java/com/loki/lochat/commands/moderation/mute/MuteHistoryCommand.java
@@ -1,4 +1,4 @@
-package com.loki.lochat.commands.moderation;
+package com.loki.lochat.commands.moderation.mute;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.MuteService;
@@ -34,7 +34,7 @@ public class MuteHistoryCommand implements CommandExecutor, TabCompleter {
if (!sender.hasPermission("lochat.mutehistory")) { sender.sendMessage(plugin.getMessageConfig().getComponent("errors.no-permission")); return true; }
if (args.length < 1) { sender.sendMessage("CF6679Использование: /lmutehistory <ник>"); return true; }
- UUID uuid = com.loki.lochat.utils.PlayerUtil.findPlayerUUID(args[0]);
+ UUID uuid = com.loki.lochat.utils.player.PlayerUtil.findPlayerUUID(args[0]);
if (uuid == null) uuid = muteService.getUUIDByName(args[0]);
if (uuid == null) { sender.sendMessage(plugin.getMessageConfig().getComponent("errors.player-not-found")); return true; }
diff --git a/src/main/java/com/loki/lochat/commands/moderation/MuteListCommand.java b/src/main/java/com/loki/lochat/commands/moderation/mute/MuteListCommand.java
similarity index 97%
rename from src/main/java/com/loki/lochat/commands/moderation/MuteListCommand.java
rename to src/main/java/com/loki/lochat/commands/moderation/mute/MuteListCommand.java
index d88d1cb..f93c0e0 100644
--- a/src/main/java/com/loki/lochat/commands/moderation/MuteListCommand.java
+++ b/src/main/java/com/loki/lochat/commands/moderation/mute/MuteListCommand.java
@@ -1,4 +1,4 @@
-package com.loki.lochat.commands.moderation;
+package com.loki.lochat.commands.moderation.mute;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.MuteService;
diff --git a/src/main/java/com/loki/lochat/commands/moderation/UnmuteCommand.java b/src/main/java/com/loki/lochat/commands/moderation/mute/UnmuteCommand.java
similarity index 92%
rename from src/main/java/com/loki/lochat/commands/moderation/UnmuteCommand.java
rename to src/main/java/com/loki/lochat/commands/moderation/mute/UnmuteCommand.java
index f4fc81c..9970859 100644
--- a/src/main/java/com/loki/lochat/commands/moderation/UnmuteCommand.java
+++ b/src/main/java/com/loki/lochat/commands/moderation/mute/UnmuteCommand.java
@@ -1,8 +1,8 @@
-package com.loki.lochat.commands.moderation;
+package com.loki.lochat.commands.moderation.mute;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.MuteService;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@@ -42,10 +42,10 @@ public class UnmuteCommand implements CommandExecutor, TabCompleter {
return true;
}
- UUID uuid = com.loki.lochat.utils.PlayerUtil.findPlayerUUID(targetName);
+ UUID uuid = com.loki.lochat.utils.player.PlayerUtil.findPlayerUUID(targetName);
if (uuid == null) { sender.sendMessage(plugin.getMessageConfig().getComponent("errors.player-not-found")); return true; }
- String name = com.loki.lochat.utils.PlayerUtil.getPlayerName(uuid);
+ String name = com.loki.lochat.utils.player.PlayerUtil.getPlayerName(uuid);
Player target = Bukkit.getPlayer(uuid);
String op = sender.getName();
diff --git a/src/main/java/com/loki/lochat/commands/moderation/SilentWarnCommand.java b/src/main/java/com/loki/lochat/commands/moderation/warn/SilentWarnCommand.java
similarity index 95%
rename from src/main/java/com/loki/lochat/commands/moderation/SilentWarnCommand.java
rename to src/main/java/com/loki/lochat/commands/moderation/warn/SilentWarnCommand.java
index fd5190f..594d8c9 100644
--- a/src/main/java/com/loki/lochat/commands/moderation/SilentWarnCommand.java
+++ b/src/main/java/com/loki/lochat/commands/moderation/warn/SilentWarnCommand.java
@@ -1,10 +1,10 @@
-package com.loki.lochat.commands.moderation;
+package com.loki.lochat.commands.moderation.warn;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.PunishmentService;
import com.loki.lochat.config.MessagesConfig;
-import com.loki.lochat.utils.ChatFormatter;
-import com.loki.lochat.utils.PlayerUtil;
+import com.loki.lochat.utils.format.ChatFormatter;
+import com.loki.lochat.utils.player.PlayerUtil;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
diff --git a/src/main/java/com/loki/lochat/commands/moderation/WarnCommand.java b/src/main/java/com/loki/lochat/commands/moderation/warn/WarnCommand.java
similarity index 96%
rename from src/main/java/com/loki/lochat/commands/moderation/WarnCommand.java
rename to src/main/java/com/loki/lochat/commands/moderation/warn/WarnCommand.java
index 1271c2f..ed267d5 100644
--- a/src/main/java/com/loki/lochat/commands/moderation/WarnCommand.java
+++ b/src/main/java/com/loki/lochat/commands/moderation/warn/WarnCommand.java
@@ -1,10 +1,10 @@
-package com.loki.lochat.commands.moderation;
+package com.loki.lochat.commands.moderation.warn;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.PunishmentService;
import com.loki.lochat.config.MessagesConfig;
-import com.loki.lochat.utils.ChatFormatter;
-import com.loki.lochat.utils.PlayerUtil;
+import com.loki.lochat.utils.format.ChatFormatter;
+import com.loki.lochat.utils.player.PlayerUtil;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
diff --git a/src/main/java/com/loki/lochat/commands/nick/NickCommand.java b/src/main/java/com/loki/lochat/commands/nick/NickCommand.java
index 6ddab4d..55dd417 100644
--- a/src/main/java/com/loki/lochat/commands/nick/NickCommand.java
+++ b/src/main/java/com/loki/lochat/commands/nick/NickCommand.java
@@ -2,7 +2,7 @@ package com.loki.lochat.commands.nick;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.NickService;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.Command;
diff --git a/src/main/java/com/loki/lochat/commands/nick/PlayerInfoCommand.java b/src/main/java/com/loki/lochat/commands/nick/PlayerInfoCommand.java
index cbc6cf3..d1ee197 100644
--- a/src/main/java/com/loki/lochat/commands/nick/PlayerInfoCommand.java
+++ b/src/main/java/com/loki/lochat/commands/nick/PlayerInfoCommand.java
@@ -6,8 +6,8 @@ import com.loki.lochat.api.service.PunishmentService;
import com.loki.lochat.data.model.BanRecord;
import com.loki.lochat.data.model.MuteData;
import com.loki.lochat.data.model.WarnEntry;
-import com.loki.lochat.utils.ChatFormatter;
-import com.loki.lochat.utils.PlayerUtil;
+import com.loki.lochat.utils.format.ChatFormatter;
+import com.loki.lochat.utils.player.PlayerUtil;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
diff --git a/src/main/java/com/loki/lochat/commands/rp/DoCommand.java b/src/main/java/com/loki/lochat/commands/rp/DoCommand.java
index 83bd81c..e9dee62 100644
--- a/src/main/java/com/loki/lochat/commands/rp/DoCommand.java
+++ b/src/main/java/com/loki/lochat/commands/rp/DoCommand.java
@@ -3,7 +3,7 @@ package com.loki.lochat.commands.rp;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.PlayerService;
import com.loki.lochat.commands.base.PlayerCommand;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import net.kyori.adventure.text.Component;
import org.bukkit.command.Command;
import org.bukkit.entity.Player;
diff --git a/src/main/java/com/loki/lochat/commands/rp/MeCommand.java b/src/main/java/com/loki/lochat/commands/rp/MeCommand.java
index c4a1bd8..32044c0 100644
--- a/src/main/java/com/loki/lochat/commands/rp/MeCommand.java
+++ b/src/main/java/com/loki/lochat/commands/rp/MeCommand.java
@@ -3,7 +3,7 @@ package com.loki.lochat.commands.rp;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.PlayerService;
import com.loki.lochat.commands.base.PlayerCommand;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import net.kyori.adventure.text.Component;
import org.bukkit.command.Command;
import org.bukkit.entity.Player;
diff --git a/src/main/java/com/loki/lochat/commands/rp/RollCommand.java b/src/main/java/com/loki/lochat/commands/rp/RollCommand.java
index 44ba642..fae0701 100644
--- a/src/main/java/com/loki/lochat/commands/rp/RollCommand.java
+++ b/src/main/java/com/loki/lochat/commands/rp/RollCommand.java
@@ -2,7 +2,8 @@ package com.loki.lochat.commands.rp;
import com.loki.lochat.LoChat;
import com.loki.lochat.commands.base.PlayerCommand;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.config.RatConfig;
+import com.loki.lochat.utils.format.ChatFormatter;
import net.kyori.adventure.text.Component;
import org.bukkit.command.Command;
import org.bukkit.entity.Player;
@@ -20,8 +21,6 @@ import java.util.Random;
public class RollCommand extends PlayerCommand {
private static final Random RANDOM = new Random();
- private static final int DEFAULT_MAX = 100;
- private static final int ABSOLUTE_MAX = 1_000_000;
public RollCommand(LoChat plugin) {
super(plugin);
@@ -32,7 +31,7 @@ public class RollCommand extends PlayerCommand {
@NotNull String label, @NotNull String[] args) {
if (!requirePermission(player, "lochat.rp.roll")) return true;
- int max = DEFAULT_MAX;
+ int max = RatConfig.ROLL_DEFAULT_MAX;
if (args.length >= 1) {
try {
@@ -43,7 +42,7 @@ public class RollCommand extends PlayerCommand {
"Минимальное значение кубика: 2")));
return true;
}
- if (max > ABSOLUTE_MAX) {
+ if (max > RatConfig.ROLL_ABSOLUTE_MAX) {
player.sendMessage(ChatFormatter.parse(
plugin.getConfigManager().getString("rp.roll-max-error",
"Максимальное значение кубика: 1000000")));
diff --git a/src/main/java/com/loki/lochat/commands/rp/RpUtil.java b/src/main/java/com/loki/lochat/commands/rp/RpUtil.java
index dd17b4a..a3036e3 100644
--- a/src/main/java/com/loki/lochat/commands/rp/RpUtil.java
+++ b/src/main/java/com/loki/lochat/commands/rp/RpUtil.java
@@ -1,7 +1,7 @@
package com.loki.lochat.commands.rp;
import com.loki.lochat.LoChat;
-import com.loki.lochat.utils.DistanceUtil;
+import com.loki.lochat.utils.player.DistanceUtil;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.Bukkit;
diff --git a/src/main/java/com/loki/lochat/commands/rp/TryCommand.java b/src/main/java/com/loki/lochat/commands/rp/TryCommand.java
index 81fef88..95d5d1b 100644
--- a/src/main/java/com/loki/lochat/commands/rp/TryCommand.java
+++ b/src/main/java/com/loki/lochat/commands/rp/TryCommand.java
@@ -3,7 +3,7 @@ package com.loki.lochat.commands.rp;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.PlayerService;
import com.loki.lochat.commands.base.PlayerCommand;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import net.kyori.adventure.text.Component;
import org.bukkit.command.Command;
import org.bukkit.entity.Player;
diff --git a/src/main/java/com/loki/lochat/config/ConfigManager.java b/src/main/java/com/loki/lochat/config/ConfigManager.java
index 7408ca9..79813e5 100644
--- a/src/main/java/com/loki/lochat/config/ConfigManager.java
+++ b/src/main/java/com/loki/lochat/config/ConfigManager.java
@@ -1,7 +1,7 @@
package com.loki.lochat.config;
import com.loki.lochat.LoChat;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import org.bukkit.configuration.file.FileConfiguration;
import java.util.List;
diff --git a/src/main/java/com/loki/lochat/config/MessageConfig.java b/src/main/java/com/loki/lochat/config/MessageConfig.java
index f18e12e..e21a8d7 100644
--- a/src/main/java/com/loki/lochat/config/MessageConfig.java
+++ b/src/main/java/com/loki/lochat/config/MessageConfig.java
@@ -1,7 +1,7 @@
package com.loki.lochat.config;
import com.loki.lochat.LoChat;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
diff --git a/src/main/java/com/loki/lochat/config/RatConfig.java b/src/main/java/com/loki/lochat/config/RatConfig.java
new file mode 100644
index 0000000..1da0ed2
--- /dev/null
+++ b/src/main/java/com/loki/lochat/config/RatConfig.java
@@ -0,0 +1,67 @@
+package com.loki.lochat.config;
+
+import java.util.List;
+
+/**
+ * Централизованная конфигурация констант с поддержкой переменных окружения
+ * KISS: все хардкод значения в одном месте
+ */
+public final class RatConfig {
+
+ // ========== Nick validation ==========
+ public static final int NICK_MIN_LENGTH = getEnvOrDefault("LOCHAT_NICK_MIN", 3);
+ public static final int NICK_MAX_LENGTH = getEnvOrDefault("LOCHAT_NICK_MAX", 16);
+
+ // ========== Roll limits ==========
+ public static final int ROLL_DEFAULT_MAX = getEnvOrDefault("LOCHAT_ROLL_DEFAULT", 100);
+ public static final int ROLL_ABSOLUTE_MAX = getEnvOrDefault("LOCHAT_ROLL_MAX", 1_000_000);
+
+ // ========== Mute history ==========
+ public static final int MAX_HISTORY_PER_PLAYER = getEnvOrDefault("LOCHAT_MUTE_HISTORY", 50);
+
+ // ========== Time constants ==========
+ public static final long MILLIS_PER_SECOND = 1000L;
+ public static final int SECONDS_IN_MINUTE = 60;
+ public static final int MINUTES_IN_HOUR = 60;
+ public static final int HOURS_IN_DAY = 24;
+
+ // ========== Folia/Paper compatibility ==========
+ public static final int TICKS_PER_SECOND = 20;
+ public static final int MILLIS_PER_TICK = 50;
+
+ // ========== Math constants ==========
+ public static final int PERCENTAGE_MULTIPLIER = 100;
+
+ // ========== GUI slots ==========
+ public static final int GUI_CONFIRM_SLOT = 11;
+ public static final int GUI_CANCEL_SLOT = 15;
+ public static final int GUI_PREVIEW_SLOT = 13;
+
+ // ========== LuckPerms ==========
+ public static final int LUCKPERMS_PREFIX_PRIORITY = 100;
+
+ // ========== Gradient presets ==========
+ public static final List PRESET_COLORS = List.of(
+ "#FF0000", "#FF7F00", "#FFFF00", "#00FF00",
+ "#0000FF", "#4B0082", "#9400D3", "#FF69B4",
+ "#00FFFF", "#FFD700", "#FFFFFF", "#000000"
+ );
+
+ private RatConfig() {
+ }
+
+ /**
+ * Получить значение из переменной окружения или вернуть дефолт
+ */
+ private static int getEnvOrDefault(String envKey, int defaultValue) {
+ String envValue = System.getenv(envKey);
+ if (envValue != null) {
+ try {
+ return Integer.parseInt(envValue);
+ } catch (NumberFormatException e) {
+ return defaultValue;
+ }
+ }
+ return defaultValue;
+ }
+}
diff --git a/src/main/java/com/loki/lochat/core/factory/ServiceFactory.java b/src/main/java/com/loki/lochat/core/factory/ServiceFactory.java
new file mode 100644
index 0000000..1f406c9
--- /dev/null
+++ b/src/main/java/com/loki/lochat/core/factory/ServiceFactory.java
@@ -0,0 +1,42 @@
+package com.loki.lochat.core.factory;
+
+import com.loki.lochat.api.service.MuteService;
+import com.loki.lochat.core.service.MuteServiceImpl;
+import com.loki.lochat.core.service.mute.MuteDataStorage;
+import com.loki.lochat.core.service.mute.MuteHistoryManager;
+import com.loki.lochat.core.service.mute.strategies.ChatMuteStrategy;
+import com.loki.lochat.core.service.mute.strategies.MuteStrategy;
+import com.loki.lochat.core.service.mute.strategies.VoiceMuteStrategy;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Фабрика для создания сервисов
+ * Factory pattern для инициализации сложных объектов
+ */
+public class ServiceFactory {
+
+ /**
+ * Создать MuteService со всеми зависимостями
+ */
+ public static MuteService createMuteService(JavaPlugin plugin) {
+ // Создаем стратегии
+ List strategies = List.of(
+ new ChatMuteStrategy(),
+ new VoiceMuteStrategy(plugin)
+ );
+
+ // Создаем хранилище данных
+ MuteDataStorage storage = new MuteDataStorage(plugin);
+ storage.load();
+
+ // Создаем менеджер истории
+ File historyFile = new File(plugin.getDataFolder(), "mute-history.json");
+ MuteHistoryManager historyManager = new MuteHistoryManager(historyFile);
+
+ // Собираем сервис
+ return new MuteServiceImpl(plugin, strategies, storage, historyManager);
+ }
+}
diff --git a/src/main/java/com/loki/lochat/core/filter/MuteFilter.java b/src/main/java/com/loki/lochat/core/filter/MuteFilter.java
index ef39912..8c5201c 100644
--- a/src/main/java/com/loki/lochat/core/filter/MuteFilter.java
+++ b/src/main/java/com/loki/lochat/core/filter/MuteFilter.java
@@ -4,7 +4,7 @@ import com.loki.lochat.api.filter.MessageFilter;
import com.loki.lochat.api.service.MuteService;
import com.loki.lochat.config.MessagesConfig;
import com.loki.lochat.data.model.ChatMessage;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
diff --git a/src/main/java/com/loki/lochat/core/registry/ServiceRegistry.java b/src/main/java/com/loki/lochat/core/registry/ServiceRegistry.java
index 967722e..e1d5979 100644
--- a/src/main/java/com/loki/lochat/core/registry/ServiceRegistry.java
+++ b/src/main/java/com/loki/lochat/core/registry/ServiceRegistry.java
@@ -3,6 +3,7 @@ package com.loki.lochat.core.registry;
import com.loki.lochat.api.service.*;
import com.loki.lochat.config.ConfigManager;
import com.loki.lochat.config.MessageConfig;
+import com.loki.lochat.core.factory.ServiceFactory;
import com.loki.lochat.core.service.*;
import org.bukkit.plugin.java.JavaPlugin;
@@ -25,7 +26,7 @@ public class ServiceRegistry {
private void registerServicesWithDeps(ConfigManager configManager, MessageConfig messageConfig) {
register(ChatService.class, new ChatServiceImpl(plugin, this));
- register(MuteService.class, new MuteServiceImpl(plugin));
+ register(MuteService.class, ServiceFactory.createMuteService(plugin));
// ✅ NEW: Объединённый PlayerService (Cooldown + PlayerData)
PlayerService playerService = new PlayerServiceImpl(plugin);
@@ -36,7 +37,7 @@ public class ServiceRegistry {
// ✅ NEW: Объединённый MessagingService (PM + Spy + Ignore)
MessagingService messagingService = new MessagingServiceImpl(plugin, messageConfig);
register(MessagingService.class, messagingService);
-
+
register(MentionService.class, new MentionServiceImpl(configManager));
register(NickService.class, new NickServiceImpl(plugin));
register(PunishmentService.class, new PunishmentServiceImpl(plugin, configManager.getMessagesConfig()));
diff --git a/src/main/java/com/loki/lochat/core/service/ChatServiceImpl.java b/src/main/java/com/loki/lochat/core/service/ChatServiceImpl.java
index cfcbce1..58b6f38 100644
--- a/src/main/java/com/loki/lochat/core/service/ChatServiceImpl.java
+++ b/src/main/java/com/loki/lochat/core/service/ChatServiceImpl.java
@@ -3,9 +3,9 @@ package com.loki.lochat.core.service;
import com.loki.lochat.api.service.ChatService;
import com.loki.lochat.core.registry.ServiceRegistry;
import com.loki.lochat.renderer.EnhancedChatRenderer;
-import com.loki.lochat.utils.DistanceUtil;
-import com.loki.lochat.utils.FoliaUtil;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.player.DistanceUtil;
+import com.loki.lochat.utils.platform.FoliaUtil;
+import com.loki.lochat.utils.format.ChatFormatter;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
diff --git a/src/main/java/com/loki/lochat/core/service/MentionServiceImpl.java b/src/main/java/com/loki/lochat/core/service/MentionServiceImpl.java
index 9d01443..29ea9c7 100644
--- a/src/main/java/com/loki/lochat/core/service/MentionServiceImpl.java
+++ b/src/main/java/com/loki/lochat/core/service/MentionServiceImpl.java
@@ -2,7 +2,7 @@ package com.loki.lochat.core.service;
import com.loki.lochat.api.service.MentionService;
import com.loki.lochat.config.ConfigManager;
-import com.loki.lochat.utils.PlayerUtil;
+import com.loki.lochat.utils.player.PlayerUtil;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
diff --git a/src/main/java/com/loki/lochat/core/service/MessagingServiceImpl.java b/src/main/java/com/loki/lochat/core/service/MessagingServiceImpl.java
index aed7c78..0081090 100644
--- a/src/main/java/com/loki/lochat/core/service/MessagingServiceImpl.java
+++ b/src/main/java/com/loki/lochat/core/service/MessagingServiceImpl.java
@@ -2,218 +2,123 @@ package com.loki.lochat.core.service;
import com.loki.lochat.api.service.MessagingService;
import com.loki.lochat.config.MessageConfig;
-import com.loki.lochat.utils.FoliaUtil;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.core.service.messaging.IgnoreService;
+import com.loki.lochat.core.service.messaging.PrivateMessageService;
+import com.loki.lochat.core.service.messaging.SpyService;
import net.kyori.adventure.text.Component;
-import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
-import org.bukkit.Bukkit;
-import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
-import java.io.File;
-import java.io.IOException;
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
+import java.util.Optional;
+import java.util.Set;
+import java.util.UUID;
/**
- * Объединённая реализация сервиса общения
- * Включает: PM, Spy, Ignore
+ * Фасад для сервисов общения
+ * Делегирует вызовы: PrivateMessageService, SpyService, IgnoreService
*/
public class MessagingServiceImpl implements MessagingService {
-
- private final JavaPlugin plugin;
- private final MessageConfig messageConfig;
- private final File ignoreFile;
-
- // PM state
- private final Map lastConversation = new ConcurrentHashMap<>();
-
- // Spy state
- private final Set spyEnabled = ConcurrentHashMap.newKeySet();
-
- // Ignore state
- private final Map> ignoreMap = new ConcurrentHashMap<>();
-
+
+ private final PrivateMessageService pmService;
+ private final SpyService spyService;
+ private final IgnoreService ignoreService;
+
public MessagingServiceImpl(JavaPlugin plugin, MessageConfig messageConfig) {
- this.plugin = plugin;
- this.messageConfig = messageConfig;
- this.ignoreFile = new File(plugin.getDataFolder(), "ignores.yml");
- load();
+ this.pmService = new PrivateMessageService();
+ this.spyService = new SpyService(messageConfig);
+ this.ignoreService = new IgnoreService(plugin);
}
-
- // ========== PM Implementation ==========
-
+
+ // ========== PM Delegation ==========
+
@Override
public void setLastConversation(UUID player, UUID target) {
- lastConversation.put(player, target);
+ pmService.setLastConversation(player, target);
}
-
+
@Override
public Optional getLastConversation(UUID player) {
- return Optional.ofNullable(lastConversation.get(player));
+ return pmService.getLastConversation(player);
}
-
+
@Override
public void removeConversation(UUID player) {
- lastConversation.remove(player);
+ pmService.removeConversation(player);
}
-
+
@Override
public boolean hasConversation(UUID player) {
- return lastConversation.containsKey(player);
+ return pmService.hasConversation(player);
}
-
- // ========== Spy Implementation ==========
-
+
+ // ========== Spy Delegation ==========
+
@Override
public boolean toggleSpy(UUID player) {
- if (spyEnabled.contains(player)) {
- spyEnabled.remove(player);
- return false;
- } else {
- spyEnabled.add(player);
- return true;
- }
+ return spyService.toggleSpy(player);
}
-
+
@Override
public boolean isSpying(UUID player) {
- return spyEnabled.contains(player);
+ return spyService.isSpying(player);
}
-
+
@Override
public void broadcastPM(Player sender, Player receiver, String message) {
- String format = messageConfig.get("spy.format");
-
- for (UUID spyUuid : spyEnabled) {
- Player spy = Bukkit.getPlayer(spyUuid);
- if (spy != null && spy.isOnline() && !spy.equals(sender) && !spy.equals(receiver)) {
- spy.sendMessage(ChatFormatter.parse(format
- .replace("{sender}", sender.getName())
- .replace("{receiver}", receiver.getName())
- .replace("{message}", message)));
- }
- }
+ spyService.broadcastPM(sender, receiver, message);
}
-
+
@Override
public void sendToSpies(Player sender, Component message, boolean isGlobal) {
- if (spyEnabled.isEmpty()) return;
-
- String chatType = isGlobal ? "Global" : "Local";
- String plainMessage = PlainTextComponentSerializer.plainText().serialize(message);
- String format = messageConfig.get("spy.chat-format",
- "§7[SPY] §e{type} §7{sender}: §f{message}");
-
- for (UUID spyUuid : spyEnabled) {
- Player spy = Bukkit.getPlayer(spyUuid);
- if (spy != null && spy.isOnline() && !spy.equals(sender)) {
- spy.sendMessage(ChatFormatter.parse(format
- .replace("{type}", chatType)
- .replace("{sender}", sender.getName())
- .replace("{message}", plainMessage)));
- }
- }
+ spyService.sendToSpies(sender, message, isGlobal);
}
-
+
@Override
public void removeSpy(UUID player) {
- spyEnabled.remove(player);
+ spyService.removeSpy(player);
}
-
- // ========== Ignore Implementation ==========
-
+
+ // ========== Ignore Delegation ==========
+
@Override
public boolean isIgnoring(UUID player, UUID target) {
- Set ignored = ignoreMap.get(player);
- return ignored != null && ignored.contains(target);
+ return ignoreService.isIgnoring(player, target);
}
-
+
@Override
public boolean addIgnore(UUID player, UUID target) {
- Set ignored = ignoreMap.computeIfAbsent(player, k -> ConcurrentHashMap.newKeySet());
- boolean added = ignored.add(target);
- if (added) saveAsync();
- return added;
+ return ignoreService.addIgnore(player, target);
}
-
+
@Override
public boolean removeIgnore(UUID player, UUID target) {
- Set ignored = ignoreMap.get(player);
- if (ignored == null) return false;
- boolean removed = ignored.remove(target);
- if (removed) saveAsync();
- return removed;
+ return ignoreService.removeIgnore(player, target);
}
-
+
@Override
public Set getIgnoredPlayers(UUID player) {
- return ignoreMap.getOrDefault(player, Collections.emptySet());
+ return ignoreService.getIgnoredPlayers(player);
}
-
+
@Override
public int getIgnoredCount(UUID player) {
- Set ignored = ignoreMap.get(player);
- return ignored == null ? 0 : ignored.size();
+ return ignoreService.getIgnoredCount(player);
}
-
+
@Override
public void clearIgnores(UUID player) {
- ignoreMap.remove(player);
- saveAsync();
+ ignoreService.clearIgnores(player);
}
-
+
// ========== Persistence ==========
-
+
@Override
public void load() {
- if (!ignoreFile.exists()) return;
-
- YamlConfiguration config = YamlConfiguration.loadConfiguration(ignoreFile);
- for (String key : config.getKeys(false)) {
- try {
- UUID uuid = UUID.fromString(key);
- List ignoredList = config.getStringList(key);
- Set ignored = ConcurrentHashMap.newKeySet();
-
- for (String ignoredStr : ignoredList) {
- try {
- ignored.add(UUID.fromString(ignoredStr));
- } catch (Exception e) {
- // Ignore invalid UUID
- }
- }
-
- if (!ignored.isEmpty()) {
- ignoreMap.put(uuid, ignored);
- }
- } catch (Exception e) {
- // Ignore invalid entry
- }
- }
+ ignoreService.load();
}
-
+
@Override
public void save() {
- YamlConfiguration config = new YamlConfiguration();
-
- for (Map.Entry> entry : ignoreMap.entrySet()) {
- List ignoredList = new ArrayList<>();
- for (UUID ignored : entry.getValue()) {
- ignoredList.add(ignored.toString());
- }
- config.set(entry.getKey().toString(), ignoredList);
- }
-
- try {
- config.save(ignoreFile);
- } catch (IOException e) {
- plugin.getLogger().severe("Не удалось сохранить игноры: " + e.getMessage());
- }
- }
-
- private void saveAsync() {
- FoliaUtil.runAsync(plugin, this::save);
+ ignoreService.save();
}
}
diff --git a/src/main/java/com/loki/lochat/core/service/MuteServiceImpl.java b/src/main/java/com/loki/lochat/core/service/MuteServiceImpl.java
index ed8a748..8443a2f 100644
--- a/src/main/java/com/loki/lochat/core/service/MuteServiceImpl.java
+++ b/src/main/java/com/loki/lochat/core/service/MuteServiceImpl.java
@@ -1,48 +1,36 @@
package com.loki.lochat.core.service;
import com.loki.lochat.api.service.MuteService;
+import com.loki.lochat.core.service.mute.MuteDataStorage;
+import com.loki.lochat.core.service.mute.MuteHistoryManager;
+import com.loki.lochat.core.service.mute.MutePermissionChecker;
+import com.loki.lochat.core.service.mute.strategies.MuteStrategy;
import com.loki.lochat.data.model.MuteData;
-import com.loki.lochat.utils.FoliaUtil;
-import com.loki.lochat.utils.TimeFormatter;
-import org.bukkit.Bukkit;
+import com.loki.lochat.utils.format.TimeFormatter;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.*;
/**
- * Сервис мутов с интеграцией Simple Voice Chat
+ * Сервис мутов с использованием Strategy pattern
+ * Разделен на: стратегии мута, хранилище данных, история, проверка прав
*/
public class MuteServiceImpl implements MuteService {
private final JavaPlugin plugin;
- private final Map mutes = new HashMap<>();
- private final Map> history = new HashMap<>();
- private Object voicechatService; // Используем Object для опциональной зависимости
+ private final List strategies;
+ private final MuteDataStorage storage;
+ private final MuteHistoryManager historyManager;
+ private final MutePermissionChecker permissionChecker;
- public MuteServiceImpl(JavaPlugin plugin) {
+ public MuteServiceImpl(JavaPlugin plugin, List strategies,
+ MuteDataStorage storage, MuteHistoryManager historyManager) {
this.plugin = plugin;
- initVoiceChat();
- load();
- }
-
- private void initVoiceChat() {
- if (Bukkit.getPluginManager().isPluginEnabled("voicechat")) {
- try {
- // Проверяем наличие класса через рефлексию
- Class.forName("de.maxhenkel.voicechat.api.BukkitVoicechatService");
- voicechatService = Bukkit.getServicesManager().load(
- Class.forName("de.maxhenkel.voicechat.api.BukkitVoicechatService")
- );
- if (voicechatService != null) {
- plugin.getLogger().info("Simple Voice Chat integration enabled!");
- }
- } catch (ClassNotFoundException e) {
- plugin.getLogger().info("VoiceChat API not found, voice mute disabled");
- } catch (Exception e) {
- plugin.getLogger().warning("Failed to hook into Simple Voice Chat: " + e.getMessage());
- }
- }
+ this.strategies = strategies;
+ this.storage = storage;
+ this.historyManager = historyManager;
+ this.permissionChecker = new MutePermissionChecker();
}
@Override
@@ -51,20 +39,21 @@ public class MuteServiceImpl implements MuteService {
plugin.getLogger().warning("Attempted to mute player with invalid data");
return;
}
-
+
long endTime = duration > 0 ? System.currentTimeMillis() + duration : 0;
MuteData data = new MuteData(uuid, playerName, endTime, reason, mutedBy);
-
- mutes.put(uuid, data);
- addToHistory(uuid, playerName, duration, reason, mutedBy);
-
- // Мутим в голосовом чате
- muteVoiceChat(uuid, true);
-
- saveAsync();
-
- plugin.getLogger().info("Player " + playerName + " muted by " + mutedBy +
- " for " + (duration > 0 ? formatTime(duration) : "permanent") +
+
+ storage.save(data);
+ historyManager.addEntry(uuid, playerName, duration, reason, mutedBy);
+
+ // Применяем все стратегии мута
+ strategies.forEach(strategy -> {
+ strategy.apply(uuid);
+ plugin.getLogger().fine(strategy.getName() + " mute applied to " + playerName);
+ });
+
+ plugin.getLogger().info("Player " + playerName + " muted by " + mutedBy +
+ " for " + (duration > 0 ? formatTime(duration) : "permanent") +
(reason != null ? " (reason: " + reason + ")" : ""));
}
@@ -74,15 +63,17 @@ public class MuteServiceImpl implements MuteService {
plugin.getLogger().warning("Attempted to unmute player with null UUID");
return false;
}
-
- MuteData removed = mutes.remove(uuid);
+
+ MuteData removed = storage.remove(uuid);
if (removed != null) {
- updateUnmuteInHistory(uuid, unmutedBy);
-
- // Размутим в голосовом чате
- muteVoiceChat(uuid, false);
-
- saveAsync();
+ historyManager.updateUnmute(uuid, unmutedBy);
+
+ // Снимаем все стратегии мута
+ strategies.forEach(strategy -> {
+ strategy.remove(uuid);
+ plugin.getLogger().fine(strategy.getName() + " mute removed from " + removed.getPlayerName());
+ });
+
plugin.getLogger().info("Player " + removed.getPlayerName() + " unmuted by " + unmutedBy);
return true;
}
@@ -93,26 +84,26 @@ public class MuteServiceImpl implements MuteService {
public boolean isMuted(UUID uuid) {
if (uuid == null) return false;
- MuteData data = mutes.get(uuid);
+ MuteData data = storage.get(uuid);
if (data == null) return false;
if (!isExpired(data)) return true;
- mutes.remove(uuid);
- muteVoiceChat(uuid, false);
- saveAsync();
+ // Мут истек - удаляем
+ storage.remove(uuid);
+ strategies.forEach(strategy -> strategy.remove(uuid));
plugin.getLogger().info("Mute expired for player " + data.getPlayerName());
return false;
}
@Override
public MuteData getMuteData(UUID uuid) {
- return isMuted(uuid) ? mutes.get(uuid) : null;
+ return isMuted(uuid) ? storage.get(uuid) : null;
}
@Override
public long getRemainingTime(UUID uuid) {
- MuteData data = mutes.get(uuid);
+ MuteData data = storage.get(uuid);
if (data == null) return 0;
if (data.getEndTime() == 0) return -1;
return Math.max(0, data.getEndTime() - System.currentTimeMillis());
@@ -130,62 +121,32 @@ public class MuteServiceImpl implements MuteService {
@Override
public long getMaxDuration(Player player) {
- if (player.hasPermission("lochat.mute.dur.perm")) return 0;
-
- String[] durations = {"30d", "14d", "7d", "3d", "1d", "12h", "6h", "1h", "30m", "10m"};
- for (String dur : durations) {
- if (player.hasPermission("lochat.mute.dur." + dur)) {
- return parseTime(dur);
- }
- }
- return -1;
+ return permissionChecker.getMaxDuration(player);
}
@Override
public boolean canMuteForDuration(Player player, long duration) {
- if (player.hasPermission("lochat.mute.dur.perm")) return true;
- if (duration == 0) return false;
-
- long maxDuration = getMaxDuration(player);
- if (maxDuration == -1) return false;
- if (maxDuration == 0) return true;
-
- return duration <= maxDuration;
+ return permissionChecker.canMuteForDuration(player, duration);
}
@Override
public List getPlayerHistory(UUID uuid) {
- return history.getOrDefault(uuid, new ArrayList<>());
+ return historyManager.getHistory(uuid);
}
@Override
public List getMutesByOperator(String operatorName) {
- List result = new ArrayList<>();
- history.values().forEach(entries ->
- entries.stream()
- .filter(e -> e.mutedBy != null && e.mutedBy.equalsIgnoreCase(operatorName))
- .forEach(result::add)
- );
- result.sort((a, b) -> Long.compare(b.mutedAt, a.mutedAt));
- return result;
+ return historyManager.getMutesByOperator(operatorName);
}
@Override
public UUID getUUIDByName(String name) {
- for (Map.Entry> entry : history.entrySet()) {
- for (MuteData.MuteHistoryEntry e : entry.getValue()) {
- if (e.playerName != null && e.playerName.equalsIgnoreCase(name)) {
- return entry.getKey();
- }
- }
- }
- return null;
+ return historyManager.getUUIDByName(name);
}
@Override
public Map getActiveMutes() {
- mutes.entrySet().removeIf(e -> isExpired(e.getValue()));
- return new HashMap<>(mutes);
+ return storage.getActiveMutes();
}
@Override
@@ -199,63 +160,11 @@ public class MuteServiceImpl implements MuteService {
@Override
public void save() {
- // TODO: Implement save to file
+ storage.saveToFile();
+ historyManager.save();
}
- // ========== Voice Chat Integration ==========
-
- private void muteVoiceChat(UUID uuid, boolean mute) {
- if (voicechatService == null) return;
-
- try {
- Player player = Bukkit.getPlayer(uuid);
- if (player != null && player.isOnline()) {
- // Используем рефлексию для вызова метода
- voicechatService.getClass()
- .getMethod("getVoicechat")
- .invoke(voicechatService)
- .getClass()
- .getMethod("setMuted", UUID.class, boolean.class)
- .invoke(voicechatService.getClass().getMethod("getVoicechat").invoke(voicechatService),
- player.getUniqueId(), mute);
- }
- } catch (Exception e) {
- plugin.getLogger().warning("Failed to " + (mute ? "mute" : "unmute") +
- " player in voice chat: " + e.getMessage());
- }
- }
-
- // ========== Private Methods ==========
-
private boolean isExpired(MuteData data) {
return data.getEndTime() > 0 && System.currentTimeMillis() > data.getEndTime();
}
-
- private void addToHistory(UUID uuid, String playerName, long duration, String reason, String mutedBy) {
- List entries = history.computeIfAbsent(uuid, k -> new ArrayList<>());
- entries.add(new MuteData.MuteHistoryEntry(
- playerName, duration, reason, mutedBy, System.currentTimeMillis(), false, null, 0
- ));
- }
-
- private void updateUnmuteInHistory(UUID uuid, String unmutedBy) {
- List entries = history.get(uuid);
- if (entries != null && !entries.isEmpty()) {
- MuteData.MuteHistoryEntry last = entries.get(entries.size() - 1);
- if (!last.unmuted) {
- entries.set(entries.size() - 1, new MuteData.MuteHistoryEntry(
- last.playerName, last.duration, last.reason, last.mutedBy, last.mutedAt,
- true, unmutedBy, System.currentTimeMillis()
- ));
- }
- }
- }
-
- private void load() {
- // TODO: Implement load from file
- }
-
- private void saveAsync() {
- FoliaUtil.runAsync(plugin, this::save);
- }
}
diff --git a/src/main/java/com/loki/lochat/core/service/NickServiceImpl.java b/src/main/java/com/loki/lochat/core/service/NickServiceImpl.java
index adcc964..8b8f947 100644
--- a/src/main/java/com/loki/lochat/core/service/NickServiceImpl.java
+++ b/src/main/java/com/loki/lochat/core/service/NickServiceImpl.java
@@ -1,7 +1,8 @@
package com.loki.lochat.core.service;
import com.loki.lochat.api.service.NickService;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.config.RatConfig;
+import com.loki.lochat.utils.format.ChatFormatter;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.Bukkit;
@@ -21,9 +22,6 @@ import java.util.concurrent.ConcurrentHashMap;
* Реализация сервиса кастомных ников
*/
public class NickServiceImpl implements NickService {
- // Настройки
- private static final int MIN_LENGTH = 3;
- private static final int MAX_LENGTH = 16;
private final JavaPlugin plugin;
private final Map nicknames = new ConcurrentHashMap<>();
private final File dataFile;
@@ -150,7 +148,7 @@ public class NickServiceImpl implements NickService {
String cleanNick = stripColors(nickname);
// Проверка длины
- if (cleanNick.length() < MIN_LENGTH || cleanNick.length() > MAX_LENGTH) {
+ if (cleanNick.length() < RatConfig.NICK_MIN_LENGTH || cleanNick.length() > RatConfig.NICK_MAX_LENGTH) {
return false;
}
diff --git a/src/main/java/com/loki/lochat/core/service/PlayerServiceImpl.java b/src/main/java/com/loki/lochat/core/service/PlayerServiceImpl.java
index 060f846..f52a180 100644
--- a/src/main/java/com/loki/lochat/core/service/PlayerServiceImpl.java
+++ b/src/main/java/com/loki/lochat/core/service/PlayerServiceImpl.java
@@ -1,7 +1,7 @@
package com.loki.lochat.core.service;
import com.loki.lochat.api.service.PlayerService;
-import com.loki.lochat.utils.FoliaUtil;
+import com.loki.lochat.utils.platform.FoliaUtil;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
diff --git a/src/main/java/com/loki/lochat/core/service/PunishmentServiceImpl.java b/src/main/java/com/loki/lochat/core/service/PunishmentServiceImpl.java
index 030b86c..8bb6d3f 100644
--- a/src/main/java/com/loki/lochat/core/service/PunishmentServiceImpl.java
+++ b/src/main/java/com/loki/lochat/core/service/PunishmentServiceImpl.java
@@ -7,9 +7,9 @@ import com.loki.lochat.api.service.PunishmentService;
import com.loki.lochat.config.MessagesConfig;
import com.loki.lochat.data.model.BanRecord;
import com.loki.lochat.data.model.WarnEntry;
-import com.loki.lochat.utils.FoliaUtil;
-import com.loki.lochat.utils.ChatFormatter;
-import com.loki.lochat.utils.TimeFormatter;
+import com.loki.lochat.utils.platform.FoliaUtil;
+import com.loki.lochat.utils.format.ChatFormatter;
+import com.loki.lochat.utils.format.TimeFormatter;
import net.kyori.adventure.text.Component;
import org.bukkit.plugin.java.JavaPlugin;
diff --git a/src/main/java/com/loki/lochat/core/service/messaging/IgnoreService.java b/src/main/java/com/loki/lochat/core/service/messaging/IgnoreService.java
new file mode 100644
index 0000000..f914d62
--- /dev/null
+++ b/src/main/java/com/loki/lochat/core/service/messaging/IgnoreService.java
@@ -0,0 +1,110 @@
+package com.loki.lochat.core.service.messaging;
+
+import com.loki.lochat.utils.platform.FoliaUtil;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Сервис игнорирования игроков
+ * Управляет списками игнорируемых игроков
+ */
+public class IgnoreService {
+
+ private final JavaPlugin plugin;
+ private final Map> ignoreMap = new ConcurrentHashMap<>();
+ private final File ignoreFile;
+
+ public IgnoreService(JavaPlugin plugin) {
+ this.plugin = plugin;
+ this.ignoreFile = new File(plugin.getDataFolder(), "ignores.yml");
+ load();
+ }
+
+ public boolean isIgnoring(UUID player, UUID target) {
+ Set ignored = ignoreMap.get(player);
+ return ignored != null && ignored.contains(target);
+ }
+
+ public boolean addIgnore(UUID player, UUID target) {
+ Set ignored = ignoreMap.computeIfAbsent(player, k -> ConcurrentHashMap.newKeySet());
+ boolean added = ignored.add(target);
+ if (added) saveAsync();
+ return added;
+ }
+
+ public boolean removeIgnore(UUID player, UUID target) {
+ Set ignored = ignoreMap.get(player);
+ if (ignored == null) return false;
+ boolean removed = ignored.remove(target);
+ if (removed) saveAsync();
+ return removed;
+ }
+
+ public Set getIgnoredPlayers(UUID player) {
+ return ignoreMap.getOrDefault(player, Collections.emptySet());
+ }
+
+ public int getIgnoredCount(UUID player) {
+ Set ignored = ignoreMap.get(player);
+ return ignored == null ? 0 : ignored.size();
+ }
+
+ public void clearIgnores(UUID player) {
+ ignoreMap.remove(player);
+ saveAsync();
+ }
+
+ public void load() {
+ if (!ignoreFile.exists()) return;
+
+ YamlConfiguration config = YamlConfiguration.loadConfiguration(ignoreFile);
+ for (String key : config.getKeys(false)) {
+ try {
+ UUID uuid = UUID.fromString(key);
+ List ignoredList = config.getStringList(key);
+ Set ignored = ConcurrentHashMap.newKeySet();
+
+ for (String ignoredStr : ignoredList) {
+ try {
+ ignored.add(UUID.fromString(ignoredStr));
+ } catch (Exception e) {
+ // Ignore invalid UUID
+ }
+ }
+
+ if (!ignored.isEmpty()) {
+ ignoreMap.put(uuid, ignored);
+ }
+ } catch (Exception e) {
+ // Ignore invalid entry
+ }
+ }
+ }
+
+ public void save() {
+ YamlConfiguration config = new YamlConfiguration();
+
+ for (Map.Entry> entry : ignoreMap.entrySet()) {
+ List ignoredList = new ArrayList<>();
+ for (UUID ignored : entry.getValue()) {
+ ignoredList.add(ignored.toString());
+ }
+ config.set(entry.getKey().toString(), ignoredList);
+ }
+
+ try {
+ config.save(ignoreFile);
+ } catch (IOException e) {
+ plugin.getLogger().severe("Не удалось сохранить игноры: " + e.getMessage());
+ }
+ }
+
+ private void saveAsync() {
+ FoliaUtil.runAsync(plugin, this::save);
+ }
+}
diff --git a/src/main/java/com/loki/lochat/core/service/messaging/PrivateMessageService.java b/src/main/java/com/loki/lochat/core/service/messaging/PrivateMessageService.java
new file mode 100644
index 0000000..21281d9
--- /dev/null
+++ b/src/main/java/com/loki/lochat/core/service/messaging/PrivateMessageService.java
@@ -0,0 +1,31 @@
+package com.loki.lochat.core.service.messaging;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Сервис личных сообщений (PM)
+ * Отслеживает последние диалоги между игроками
+ */
+public class PrivateMessageService {
+
+ private final Map lastConversation = new ConcurrentHashMap<>();
+
+ public void setLastConversation(UUID player, UUID target) {
+ lastConversation.put(player, target);
+ }
+
+ public Optional getLastConversation(UUID player) {
+ return Optional.ofNullable(lastConversation.get(player));
+ }
+
+ public void removeConversation(UUID player) {
+ lastConversation.remove(player);
+ }
+
+ public boolean hasConversation(UUID player) {
+ return lastConversation.containsKey(player);
+ }
+}
diff --git a/src/main/java/com/loki/lochat/core/service/messaging/SpyService.java b/src/main/java/com/loki/lochat/core/service/messaging/SpyService.java
new file mode 100644
index 0000000..b38a8c3
--- /dev/null
+++ b/src/main/java/com/loki/lochat/core/service/messaging/SpyService.java
@@ -0,0 +1,77 @@
+package com.loki.lochat.core.service.messaging;
+
+import com.loki.lochat.config.MessageConfig;
+import com.loki.lochat.utils.format.ChatFormatter;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Сервис шпионажа за личными сообщениями
+ * Позволяет админам видеть PM других игроков
+ */
+public class SpyService {
+
+ private final Set spyEnabled = ConcurrentHashMap.newKeySet();
+ private final MessageConfig messageConfig;
+
+ public SpyService(MessageConfig messageConfig) {
+ this.messageConfig = messageConfig;
+ }
+
+ public boolean toggleSpy(UUID player) {
+ if (spyEnabled.contains(player)) {
+ spyEnabled.remove(player);
+ return false;
+ } else {
+ spyEnabled.add(player);
+ return true;
+ }
+ }
+
+ public boolean isSpying(UUID player) {
+ return spyEnabled.contains(player);
+ }
+
+ public void broadcastPM(Player sender, Player receiver, String message) {
+ String format = messageConfig.get("spy.format");
+
+ for (UUID spyUuid : spyEnabled) {
+ Player spy = Bukkit.getPlayer(spyUuid);
+ if (spy != null && spy.isOnline() && !spy.equals(sender) && !spy.equals(receiver)) {
+ spy.sendMessage(ChatFormatter.parse(format
+ .replace("{sender}", sender.getName())
+ .replace("{receiver}", receiver.getName())
+ .replace("{message}", message)));
+ }
+ }
+ }
+
+ public void sendToSpies(Player sender, Component message, boolean isGlobal) {
+ if (spyEnabled.isEmpty()) return;
+
+ String chatType = isGlobal ? "Global" : "Local";
+ String plainMessage = PlainTextComponentSerializer.plainText().serialize(message);
+ String format = messageConfig.get("spy.chat-format",
+ "§7[SPY] §e{type} §7{sender}: §f{message}");
+
+ for (UUID spyUuid : spyEnabled) {
+ Player spy = Bukkit.getPlayer(spyUuid);
+ if (spy != null && spy.isOnline() && !spy.equals(sender)) {
+ spy.sendMessage(ChatFormatter.parse(format
+ .replace("{type}", chatType)
+ .replace("{sender}", sender.getName())
+ .replace("{message}", plainMessage)));
+ }
+ }
+ }
+
+ public void removeSpy(UUID player) {
+ spyEnabled.remove(player);
+ }
+}
diff --git a/src/main/java/com/loki/lochat/core/service/mute/MuteDataStorage.java b/src/main/java/com/loki/lochat/core/service/mute/MuteDataStorage.java
index 2986777..53eb99a 100644
--- a/src/main/java/com/loki/lochat/core/service/mute/MuteDataStorage.java
+++ b/src/main/java/com/loki/lochat/core/service/mute/MuteDataStorage.java
@@ -4,7 +4,7 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.loki.lochat.data.model.MuteData;
-import com.loki.lochat.utils.FoliaUtil;
+import com.loki.lochat.utils.platform.FoliaUtil;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.*;
@@ -27,40 +27,24 @@ public class MuteDataStorage {
this.dataFile = new File(plugin.getDataFolder(), "mutes.json");
}
- public void addMute(UUID uuid, MuteData data) {
- mutes.put(uuid, data);
+ public void save(MuteData data) {
+ mutes.put(data.getUuid(), data);
saveAsync();
}
-
- public MuteData removeMute(UUID uuid) {
+
+ public MuteData remove(UUID uuid) {
MuteData removed = mutes.remove(uuid);
if (removed != null) {
saveAsync();
}
return removed;
}
-
- public boolean isMuted(UUID uuid) {
- if (uuid == null) return false;
- MuteData data = mutes.get(uuid);
- if (data == null) return false;
-
- if (!isExpired(data)) return true;
-
- boolean removed = mutes.remove(uuid, data);
- if (removed) {
- saveAsync();
- plugin.getLogger().info("Mute expired for player " + data.getPlayerName());
- }
- return false;
- }
-
- public MuteData getMute(UUID uuid) {
+ public MuteData get(UUID uuid) {
return mutes.get(uuid);
}
-
- public Map getAllMutes() {
+
+ public Map getActiveMutes() {
mutes.entrySet().removeIf(entry -> isExpired(entry.getValue()));
return new HashMap<>(mutes);
}
@@ -90,7 +74,11 @@ public class MuteDataStorage {
}
}
- public void save() {
+ public void saveToFile() {
+ save();
+ }
+
+ private void save() {
try {
ensureDataFolderExists();
diff --git a/src/main/java/com/loki/lochat/core/service/MuteHistoryManager.java b/src/main/java/com/loki/lochat/core/service/mute/MuteHistoryManager.java
similarity index 73%
rename from src/main/java/com/loki/lochat/core/service/MuteHistoryManager.java
rename to src/main/java/com/loki/lochat/core/service/mute/MuteHistoryManager.java
index e07119a..43cad9a 100644
--- a/src/main/java/com/loki/lochat/core/service/MuteHistoryManager.java
+++ b/src/main/java/com/loki/lochat/core/service/mute/MuteHistoryManager.java
@@ -1,8 +1,9 @@
-package com.loki.lochat.core.service;
+package com.loki.lochat.core.service.mute;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
+import com.loki.lochat.config.RatConfig;
import com.loki.lochat.data.model.MuteData;
import java.io.File;
@@ -15,9 +16,6 @@ import java.util.concurrent.ConcurrentHashMap;
public class MuteHistoryManager {
- // ✅ FIX: Ограничиваем размер истории для предотвращения утечки памяти
- private static final int MAX_HISTORY_PER_PLAYER = 50;
-
private final Map> history = new ConcurrentHashMap<>();
private final File historyFile;
private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
@@ -41,7 +39,7 @@ public class MuteHistoryManager {
));
// ✅ FIX: Удаляем старые записи если превышен лимит
- if (entries.size() > MAX_HISTORY_PER_PLAYER) {
+ if (entries.size() > RatConfig.MAX_HISTORY_PER_PLAYER) {
entries.remove(0); // Удаляем самую старую запись
}
}
@@ -62,6 +60,28 @@ public class MuteHistoryManager {
return history.getOrDefault(uuid, Collections.emptyList());
}
+ public List getMutesByOperator(String operatorName) {
+ List result = new ArrayList<>();
+ history.values().forEach(entries ->
+ entries.stream()
+ .filter(e -> e.mutedBy != null && e.mutedBy.equalsIgnoreCase(operatorName))
+ .forEach(result::add)
+ );
+ result.sort((a, b) -> Long.compare(b.mutedAt, a.mutedAt));
+ return result;
+ }
+
+ public UUID getUUIDByName(String name) {
+ for (Map.Entry> entry : history.entrySet()) {
+ for (MuteData.MuteHistoryEntry e : entry.getValue()) {
+ if (e.playerName != null && e.playerName.equalsIgnoreCase(name)) {
+ return entry.getKey();
+ }
+ }
+ }
+ return null;
+ }
+
public void save() {
try (FileWriter writer = new FileWriter(historyFile)) {
gson.toJson(history, writer);
diff --git a/src/main/java/com/loki/lochat/core/service/mute/MutePermissionChecker.java b/src/main/java/com/loki/lochat/core/service/mute/MutePermissionChecker.java
index e66a53f..8eae26d 100644
--- a/src/main/java/com/loki/lochat/core/service/mute/MutePermissionChecker.java
+++ b/src/main/java/com/loki/lochat/core/service/mute/MutePermissionChecker.java
@@ -1,6 +1,6 @@
package com.loki.lochat.core.service.mute;
-import com.loki.lochat.utils.TimeFormatter;
+import com.loki.lochat.utils.format.TimeFormatter;
import org.bukkit.entity.Player;
/**
diff --git a/src/main/java/com/loki/lochat/core/service/mute/strategies/ChatMuteStrategy.java b/src/main/java/com/loki/lochat/core/service/mute/strategies/ChatMuteStrategy.java
new file mode 100644
index 0000000..464e6af
--- /dev/null
+++ b/src/main/java/com/loki/lochat/core/service/mute/strategies/ChatMuteStrategy.java
@@ -0,0 +1,27 @@
+package com.loki.lochat.core.service.mute.strategies;
+
+import java.util.UUID;
+
+/**
+ * Стратегия мута в чате
+ * Базовая реализация - мут проверяется через MuteService.isMuted()
+ */
+public class ChatMuteStrategy implements MuteStrategy {
+
+ @Override
+ public void apply(UUID playerUuid) {
+ // Чат мут работает через проверку в фильтрах
+ // Не требует дополнительных действий при применении
+ }
+
+ @Override
+ public void remove(UUID playerUuid) {
+ // Чат мут работает через проверку в фильтрах
+ // Не требует дополнительных действий при снятии
+ }
+
+ @Override
+ public String getName() {
+ return "Chat";
+ }
+}
diff --git a/src/main/java/com/loki/lochat/core/service/mute/strategies/MuteStrategy.java b/src/main/java/com/loki/lochat/core/service/mute/strategies/MuteStrategy.java
new file mode 100644
index 0000000..2c0f660
--- /dev/null
+++ b/src/main/java/com/loki/lochat/core/service/mute/strategies/MuteStrategy.java
@@ -0,0 +1,25 @@
+package com.loki.lochat.core.service.mute.strategies;
+
+import java.util.UUID;
+
+/**
+ * Стратегия применения мута
+ * Strategy pattern для разных типов мутов (чат, голос)
+ */
+public interface MuteStrategy {
+
+ /**
+ * Применить мут к игроку
+ */
+ void apply(UUID playerUuid);
+
+ /**
+ * Снять мут с игрока
+ */
+ void remove(UUID playerUuid);
+
+ /**
+ * Название стратегии для логирования
+ */
+ String getName();
+}
diff --git a/src/main/java/com/loki/lochat/core/service/mute/strategies/VoiceMuteStrategy.java b/src/main/java/com/loki/lochat/core/service/mute/strategies/VoiceMuteStrategy.java
new file mode 100644
index 0000000..689635f
--- /dev/null
+++ b/src/main/java/com/loki/lochat/core/service/mute/strategies/VoiceMuteStrategy.java
@@ -0,0 +1,78 @@
+package com.loki.lochat.core.service.mute.strategies;
+
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import java.util.UUID;
+
+/**
+ * Стратегия мута в голосовом чате (Simple Voice Chat)
+ */
+public class VoiceMuteStrategy implements MuteStrategy {
+
+ private final JavaPlugin plugin;
+ private final Object voicechatService;
+
+ public VoiceMuteStrategy(JavaPlugin plugin) {
+ this.plugin = plugin;
+ this.voicechatService = initVoiceChat();
+ }
+
+ private Object initVoiceChat() {
+ if (!Bukkit.getPluginManager().isPluginEnabled("voicechat")) {
+ return null;
+ }
+
+ try {
+ Class.forName("de.maxhenkel.voicechat.api.BukkitVoicechatService");
+ Object service = Bukkit.getServicesManager().load(
+ Class.forName("de.maxhenkel.voicechat.api.BukkitVoicechatService")
+ );
+ if (service != null) {
+ plugin.getLogger().info("Simple Voice Chat integration enabled!");
+ }
+ return service;
+ } catch (ClassNotFoundException e) {
+ plugin.getLogger().info("VoiceChat API not found, voice mute disabled");
+ } catch (Exception e) {
+ plugin.getLogger().warning("Failed to hook into Simple Voice Chat: " + e.getMessage());
+ }
+ return null;
+ }
+
+ @Override
+ public void apply(UUID playerUuid) {
+ muteVoiceChat(playerUuid, true);
+ }
+
+ @Override
+ public void remove(UUID playerUuid) {
+ muteVoiceChat(playerUuid, false);
+ }
+
+ @Override
+ public String getName() {
+ return "Voice";
+ }
+
+ private void muteVoiceChat(UUID uuid, boolean mute) {
+ if (voicechatService == null) return;
+
+ try {
+ Player player = Bukkit.getPlayer(uuid);
+ if (player != null && player.isOnline()) {
+ voicechatService.getClass()
+ .getMethod("getVoicechat")
+ .invoke(voicechatService)
+ .getClass()
+ .getMethod("setMuted", UUID.class, boolean.class)
+ .invoke(voicechatService.getClass().getMethod("getVoicechat").invoke(voicechatService),
+ player.getUniqueId(), mute);
+ }
+ } catch (Exception e) {
+ plugin.getLogger().warning("Failed to " + (mute ? "mute" : "unmute") +
+ " player in voice chat: " + e.getMessage());
+ }
+ }
+}
diff --git a/src/main/java/com/loki/lochat/gradient/commands/GradientAdminCommand.java b/src/main/java/com/loki/lochat/gradient/commands/GradientAdminCommand.java
index fb31a20..63613df 100644
--- a/src/main/java/com/loki/lochat/gradient/commands/GradientAdminCommand.java
+++ b/src/main/java/com/loki/lochat/gradient/commands/GradientAdminCommand.java
@@ -1,12 +1,13 @@
package com.loki.lochat.gradient.commands;
+import com.loki.lochat.config.RatConfig;
import com.loki.lochat.gradient.GradientModule;
import com.loki.lochat.gradient.commands.handlers.ColorCommandHandler;
import com.loki.lochat.gradient.commands.handlers.PrefixCommandHandler;
import com.loki.lochat.gradient.config.GradientMessages;
import com.loki.lochat.gradient.data.GradientPlayerData;
import com.loki.lochat.gradient.util.DisplayNameUtil;
-import com.loki.lochat.utils.FoliaUtil;
+import com.loki.lochat.utils.platform.FoliaUtil;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
@@ -26,10 +27,6 @@ import java.util.List;
*/
public class GradientAdminCommand implements CommandExecutor, TabCompleter {
- private static final List PRESET_COLORS = Arrays.asList(
- "#FF0000", "#FF7F00", "#FFFF00", "#00FF00", "#0000FF", "#4B0082", "#9400D3"
- );
-
private final GradientModule module;
private final ColorCommandHandler colorHandler;
private final PrefixCommandHandler prefixHandler;
@@ -149,7 +146,7 @@ public class GradientAdminCommand implements CommandExecutor, TabCompleter {
}
if (args.length >= 3 && args[0].equalsIgnoreCase("setcolor")) {
- return PRESET_COLORS.stream()
+ return RatConfig.PRESET_COLORS.stream()
.filter(s -> s.toLowerCase().startsWith(args[args.length - 1].toLowerCase()))
.toList();
}
diff --git a/src/main/java/com/loki/lochat/gradient/commands/GradientColorCommand.java b/src/main/java/com/loki/lochat/gradient/commands/GradientColorCommand.java
index cc54351..4c6b15a 100644
--- a/src/main/java/com/loki/lochat/gradient/commands/GradientColorCommand.java
+++ b/src/main/java/com/loki/lochat/gradient/commands/GradientColorCommand.java
@@ -1,13 +1,13 @@
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.FoliaUtil;
-import com.loki.lochat.gradient.util.GradientConstants;
+import com.loki.lochat.utils.platform.FoliaUtil;
import com.loki.lochat.gradient.util.GradientUtil;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
@@ -26,10 +26,6 @@ import java.util.function.BiFunction;
*/
public class GradientColorCommand implements CommandExecutor, TabCompleter {
- private static final List PRESET_COLORS = List.of(
- "#FF0000", "#FF7F00", "#FFFF00", "#00FF00", "#0000FF", "#4B0082", "#9400D3",
- "#FF69B4", "#00FFFF", "#FFD700", "#FFFFFF", "#000000"
- );
private static final Set SUB_COMMANDS = Set.of("on", "off", "reset", "copy");
private final GradientModule module;
private final Map> subCommands = new HashMap<>();
@@ -197,10 +193,10 @@ public class GradientColorCommand implements CommandExecutor, TabCompleter {
}
private boolean checkCooldown(Player player, int cooldownSec, long lastChange) {
- long cooldownMs = cooldownSec * GradientConstants.MILLIS_PER_SECOND;
+ long cooldownMs = cooldownSec * RatConfig.MILLIS_PER_SECOND;
long timePassed = System.currentTimeMillis() - lastChange;
if (timePassed < cooldownMs) {
- long remaining = (cooldownMs - timePassed) / GradientConstants.MILLIS_PER_SECOND;
+ long remaining = (cooldownMs - timePassed) / RatConfig.MILLIS_PER_SECOND;
module.getMessages().send(player, "cooldown", "time", String.valueOf(remaining));
return false;
}
@@ -233,7 +229,7 @@ public class GradientColorCommand implements CommandExecutor, TabCompleter {
if (args.length == 1) {
String input = args[0].toLowerCase();
List completions = new ArrayList<>(SUB_COMMANDS);
- completions.addAll(PRESET_COLORS);
+ completions.addAll(RatConfig.PRESET_COLORS);
return completions.stream().filter(s -> s.toLowerCase().startsWith(input)).toList();
}
@@ -245,7 +241,7 @@ public class GradientColorCommand implements CommandExecutor, TabCompleter {
}
if (!SUB_COMMANDS.contains(firstArg) && args.length <= module.getConfig().getMaxColors()) {
- return PRESET_COLORS.stream()
+ return RatConfig.PRESET_COLORS.stream()
.filter(s -> s.toLowerCase().startsWith(args[args.length - 1].toLowerCase()))
.toList();
}
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 d383b50..6b90335 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,13 @@
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.FoliaUtil;
-import com.loki.lochat.gradient.util.GradientConstants;
+import com.loki.lochat.utils.platform.FoliaUtil;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@@ -169,10 +169,10 @@ public class GradientPrefixCommand implements CommandExecutor, TabCompleter {
}
private boolean checkCooldown(Player player, int cooldownSec, long lastChange) {
- long cooldownMs = cooldownSec * GradientConstants.MILLIS_PER_SECOND;
+ long cooldownMs = cooldownSec * RatConfig.MILLIS_PER_SECOND;
long timePassed = System.currentTimeMillis() - lastChange;
if (timePassed < cooldownMs) {
- long remaining = (cooldownMs - timePassed) / GradientConstants.MILLIS_PER_SECOND;
+ long remaining = (cooldownMs - timePassed) / RatConfig.MILLIS_PER_SECOND;
module.getMessages().send(player, "cooldown", "time", String.valueOf(remaining));
return false;
}
diff --git a/src/main/java/com/loki/lochat/gradient/commands/handlers/ColorCommandHandler.java b/src/main/java/com/loki/lochat/gradient/commands/handlers/ColorCommandHandler.java
index 79036f1..8f4314e 100644
--- a/src/main/java/com/loki/lochat/gradient/commands/handlers/ColorCommandHandler.java
+++ b/src/main/java/com/loki/lochat/gradient/commands/handlers/ColorCommandHandler.java
@@ -5,7 +5,7 @@ import com.loki.lochat.gradient.config.GradientMessages;
import com.loki.lochat.gradient.data.GradientPlayerData;
import com.loki.lochat.gradient.util.DisplayNameUtil;
import com.loki.lochat.gradient.util.GradientUtil;
-import com.loki.lochat.utils.FoliaUtil;
+import com.loki.lochat.utils.platform.FoliaUtil;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
diff --git a/src/main/java/com/loki/lochat/gradient/commands/handlers/PrefixCommandHandler.java b/src/main/java/com/loki/lochat/gradient/commands/handlers/PrefixCommandHandler.java
index fca72d6..dab72b8 100644
--- a/src/main/java/com/loki/lochat/gradient/commands/handlers/PrefixCommandHandler.java
+++ b/src/main/java/com/loki/lochat/gradient/commands/handlers/PrefixCommandHandler.java
@@ -4,7 +4,7 @@ import com.loki.lochat.gradient.GradientModule;
import com.loki.lochat.gradient.config.GradientMessages;
import com.loki.lochat.gradient.data.GradientPlayerData;
import com.loki.lochat.gradient.util.DisplayNameUtil;
-import com.loki.lochat.utils.FoliaUtil;
+import com.loki.lochat.utils.platform.FoliaUtil;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
diff --git a/src/main/java/com/loki/lochat/gradient/config/GradientMessages.java b/src/main/java/com/loki/lochat/gradient/config/GradientMessages.java
index abfd4ef..2541deb 100644
--- a/src/main/java/com/loki/lochat/gradient/config/GradientMessages.java
+++ b/src/main/java/com/loki/lochat/gradient/config/GradientMessages.java
@@ -1,6 +1,6 @@
package com.loki.lochat.gradient.config;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
diff --git a/src/main/java/com/loki/lochat/gradient/gui/GradientConfirmGUI.java b/src/main/java/com/loki/lochat/gradient/gui/GradientConfirmGUI.java
index 1c6ba5f..b50c213 100644
--- a/src/main/java/com/loki/lochat/gradient/gui/GradientConfirmGUI.java
+++ b/src/main/java/com/loki/lochat/gradient/gui/GradientConfirmGUI.java
@@ -1,7 +1,7 @@
package com.loki.lochat.gradient.gui;
+import com.loki.lochat.config.RatConfig;
import com.loki.lochat.gradient.GradientModule;
-import com.loki.lochat.gradient.util.GradientConstants;
import com.loki.lochat.gradient.util.GradientUtil;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
@@ -81,7 +81,7 @@ public final class GradientConfirmGUI implements InventoryHolder {
}
skullMeta.lore(lore);
head.setItemMeta(skullMeta);
- inventory.setItem(GradientConstants.GUI_PREVIEW_SLOT, head);
+ inventory.setItem(RatConfig.GUI_PREVIEW_SLOT, head);
ItemStack confirm = createItem(Material.LIME_WOOL, "§a§lПодтвердить");
ItemMeta confirmMeta = confirm.getItemMeta();
@@ -91,7 +91,7 @@ public final class GradientConfirmGUI implements InventoryHolder {
.decoration(TextDecoration.ITALIC, false));
confirmMeta.lore(confirmLore);
confirm.setItemMeta(confirmMeta);
- inventory.setItem(GradientConstants.GUI_CONFIRM_SLOT, confirm);
+ inventory.setItem(RatConfig.GUI_CONFIRM_SLOT, confirm);
ItemStack cancel = createItem(Material.RED_WOOL, "§c§lОтменить");
ItemMeta cancelMeta = cancel.getItemMeta();
@@ -101,7 +101,7 @@ public final class GradientConfirmGUI implements InventoryHolder {
.decoration(TextDecoration.ITALIC, false));
cancelMeta.lore(cancelLore);
cancel.setItemMeta(cancelMeta);
- inventory.setItem(GradientConstants.GUI_CANCEL_SLOT, cancel);
+ inventory.setItem(RatConfig.GUI_CANCEL_SLOT, cancel);
}
private String buildPreview() {
diff --git a/src/main/java/com/loki/lochat/gradient/listeners/GradientGUIListener.java b/src/main/java/com/loki/lochat/gradient/listeners/GradientGUIListener.java
index feee460..19742bd 100644
--- a/src/main/java/com/loki/lochat/gradient/listeners/GradientGUIListener.java
+++ b/src/main/java/com/loki/lochat/gradient/listeners/GradientGUIListener.java
@@ -1,12 +1,12 @@
package com.loki.lochat.gradient.listeners;
+import com.loki.lochat.config.RatConfig;
import com.loki.lochat.gradient.GradientModule;
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.FoliaUtil;
-import com.loki.lochat.gradient.util.GradientConstants;
+import com.loki.lochat.utils.platform.FoliaUtil;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -38,8 +38,8 @@ public class GradientGUIListener implements Listener {
if (!(event.getWhoClicked() instanceof Player player) || !player.equals(gui.getPlayer())) return;
switch (event.getRawSlot()) {
- case GradientConstants.GUI_CONFIRM_SLOT -> handleConfirm(player, gui);
- case GradientConstants.GUI_CANCEL_SLOT -> handleCancel(player);
+ case RatConfig.GUI_CONFIRM_SLOT -> handleConfirm(player, gui);
+ case RatConfig.GUI_CANCEL_SLOT -> handleCancel(player);
}
}
diff --git a/src/main/java/com/loki/lochat/gradient/listeners/GradientPlayerListener.java b/src/main/java/com/loki/lochat/gradient/listeners/GradientPlayerListener.java
index a125a28..485a42f 100644
--- a/src/main/java/com/loki/lochat/gradient/listeners/GradientPlayerListener.java
+++ b/src/main/java/com/loki/lochat/gradient/listeners/GradientPlayerListener.java
@@ -1,7 +1,7 @@
package com.loki.lochat.gradient.listeners;
import com.loki.lochat.gradient.GradientModule;
-import com.loki.lochat.utils.FoliaUtil;
+import com.loki.lochat.utils.platform.FoliaUtil;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
diff --git a/src/main/java/com/loki/lochat/gradient/util/GradientConstants.java b/src/main/java/com/loki/lochat/gradient/util/GradientConstants.java
deleted file mode 100644
index 931bc58..0000000
--- a/src/main/java/com/loki/lochat/gradient/util/GradientConstants.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.loki.lochat.gradient.util;
-
-/**
- * Константы для градиентного модуля
- */
-public final class GradientConstants {
-
- public static final long MILLIS_PER_SECOND = 1000L;
- // GUI слоты
- public static final int GUI_CONFIRM_SLOT = 11;
- public static final int GUI_CANCEL_SLOT = 15;
- public static final int GUI_PREVIEW_SLOT = 13;
- // LuckPerms
- public static final int LUCKPERMS_PREFIX_PRIORITY = 100;
-
- private GradientConstants() {
- }
-}
diff --git a/src/main/java/com/loki/lochat/integrations/discord/DiscordMessageService.java b/src/main/java/com/loki/lochat/integrations/discord/DiscordMessageService.java
index 54ba337..8732614 100644
--- a/src/main/java/com/loki/lochat/integrations/discord/DiscordMessageService.java
+++ b/src/main/java/com/loki/lochat/integrations/discord/DiscordMessageService.java
@@ -1,7 +1,7 @@
package com.loki.lochat.integrations.discord;
import com.loki.lochat.integrations.DiscordWebhook;
-import com.loki.lochat.utils.FoliaUtil;
+import com.loki.lochat.utils.platform.FoliaUtil;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
diff --git a/src/main/java/com/loki/lochat/listener/ChatEventListener.java b/src/main/java/com/loki/lochat/listener/ChatEventListener.java
index 9b5a11a..1170b34 100644
--- a/src/main/java/com/loki/lochat/listener/ChatEventListener.java
+++ b/src/main/java/com/loki/lochat/listener/ChatEventListener.java
@@ -6,7 +6,7 @@ import com.loki.lochat.core.filter.AdvancedMessageFilter;
import com.loki.lochat.core.filter.FilterResult;
import com.loki.lochat.core.registry.ServiceRegistry;
import com.loki.lochat.renderer.EnhancedChatRenderer;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import io.papermc.paper.event.player.AsyncChatEvent;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
@@ -124,7 +124,7 @@ public class ChatEventListener implements Listener {
event.viewers().removeIf(v -> {
if (!(v instanceof Player p)) return false;
try {
- return !com.loki.lochat.utils.DistanceUtil.isInRange(sender, p, radius);
+ return !com.loki.lochat.utils.player.DistanceUtil.isInRange(sender, p, radius);
} catch (Exception e) {
return false;
}
diff --git a/src/main/java/com/loki/lochat/listener/PlayerEventListener.java b/src/main/java/com/loki/lochat/listener/PlayerEventListener.java
index 2b52675..4503e81 100644
--- a/src/main/java/com/loki/lochat/listener/PlayerEventListener.java
+++ b/src/main/java/com/loki/lochat/listener/PlayerEventListener.java
@@ -7,7 +7,7 @@ import com.loki.lochat.api.service.PlayerService;
import com.loki.lochat.config.ConfigManager;
import com.loki.lochat.core.filter.AdvancedMessageFilter;
import com.loki.lochat.core.registry.ServiceRegistry;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import net.kyori.adventure.text.Component;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
diff --git a/src/main/java/com/loki/lochat/managers/AutoMessageManager.java b/src/main/java/com/loki/lochat/managers/AutoMessageManager.java
index 4781b03..110adab 100644
--- a/src/main/java/com/loki/lochat/managers/AutoMessageManager.java
+++ b/src/main/java/com/loki/lochat/managers/AutoMessageManager.java
@@ -1,8 +1,8 @@
package com.loki.lochat.managers;
import com.loki.lochat.LoChat;
-import com.loki.lochat.utils.FoliaUtil;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.platform.FoliaUtil;
+import com.loki.lochat.utils.format.ChatFormatter;
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
diff --git a/src/main/java/com/loki/lochat/managers/CustomCommandManager.java b/src/main/java/com/loki/lochat/managers/CustomCommandManager.java
index c8980de..6afec15 100644
--- a/src/main/java/com/loki/lochat/managers/CustomCommandManager.java
+++ b/src/main/java/com/loki/lochat/managers/CustomCommandManager.java
@@ -4,7 +4,7 @@ import com.loki.lochat.LoChat;
import com.loki.lochat.commands.CustomCommand;
import com.loki.lochat.managers.commands.MessageSender;
import com.loki.lochat.managers.commands.PlaceholderProcessor;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandMap;
import org.bukkit.configuration.ConfigurationSection;
diff --git a/src/main/java/com/loki/lochat/managers/commands/MessageSender.java b/src/main/java/com/loki/lochat/managers/commands/MessageSender.java
index 492933b..c17335f 100644
--- a/src/main/java/com/loki/lochat/managers/commands/MessageSender.java
+++ b/src/main/java/com/loki/lochat/managers/commands/MessageSender.java
@@ -1,6 +1,6 @@
package com.loki.lochat.managers.commands;
-import com.loki.lochat.utils.ChatFormatter;
+import com.loki.lochat.utils.format.ChatFormatter;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.title.Title;
import org.bukkit.Bukkit;
diff --git a/src/main/java/com/loki/lochat/renderer/EnhancedChatRenderer.java b/src/main/java/com/loki/lochat/renderer/EnhancedChatRenderer.java
index c93eb58..6313d1f 100644
--- a/src/main/java/com/loki/lochat/renderer/EnhancedChatRenderer.java
+++ b/src/main/java/com/loki/lochat/renderer/EnhancedChatRenderer.java
@@ -1,8 +1,8 @@
package com.loki.lochat.renderer;
import com.loki.lochat.renderer.components.*;
-import com.loki.lochat.utils.MentionHandler;
-import com.loki.lochat.utils.TextFormatter;
+import com.loki.lochat.utils.player.MentionHandler;
+import com.loki.lochat.utils.format.TextFormatter;
import io.papermc.paper.chat.ChatRenderer;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component;
@@ -112,7 +112,7 @@ public class EnhancedChatRenderer implements ChatRenderer {
if (gradientModule != null && gradientModule.isEnabled()) {
String prefix = gradientModule.getPrefix(player);
if (!prefix.isEmpty()) {
- return com.loki.lochat.utils.ChatFormatter.parse(prefix);
+ return com.loki.lochat.utils.format.ChatFormatter.parse(prefix);
}
}
@@ -126,7 +126,7 @@ public class EnhancedChatRenderer implements ChatRenderer {
if (gradientModule != null && gradientModule.isEnabled()) {
String suffix = gradientModule.getSuffix(player);
if (!suffix.isEmpty()) {
- return com.loki.lochat.utils.ChatFormatter.parse(suffix);
+ return com.loki.lochat.utils.format.ChatFormatter.parse(suffix);
}
}
@@ -184,7 +184,7 @@ public class EnhancedChatRenderer implements ChatRenderer {
.replace("{health}", String.valueOf(Math.round(player.getHealth())))
.replace("{food}", String.valueOf(player.getFoodLevel()));
- hoverBuilder.append(com.loki.lochat.utils.ChatFormatter.parse(line));
+ hoverBuilder.append(com.loki.lochat.utils.format.ChatFormatter.parse(line));
if (i < hoverLines.size() - 1) hoverBuilder.append(Component.newline());
}
diff --git a/src/main/java/com/loki/lochat/utils/Constants.java b/src/main/java/com/loki/lochat/utils/Constants.java
deleted file mode 100644
index 70f48f3..0000000
--- a/src/main/java/com/loki/lochat/utils/Constants.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.loki.lochat.utils;
-
-/**
- * Константы плагина (только неизменяемые системные значения)
- */
-public final class Constants {
-
- // Время (системные константы)
- public static final long MILLIS_IN_SECOND = 1000L;
- public static final int SECONDS_IN_MINUTE = 60;
- public static final int MINUTES_IN_HOUR = 60;
- public static final int HOURS_IN_DAY = 24;
-
- // Folia/Paper совместимость (системные константы)
- public static final int TICKS_PER_SECOND = 20;
- public static final int MILLIS_PER_TICK = 50;
-
- // Математические константы
- public static final int PERCENTAGE_MULTIPLIER = 100;
-
- // LuckPerms приоритет (системная константа)
- public static final int LUCKPERMS_PREFIX_PRIORITY = 100;
-
- private Constants() {
- }
-}
diff --git a/src/main/java/com/loki/lochat/utils/ChatFormatter.java b/src/main/java/com/loki/lochat/utils/format/ChatFormatter.java
similarity index 99%
rename from src/main/java/com/loki/lochat/utils/ChatFormatter.java
rename to src/main/java/com/loki/lochat/utils/format/ChatFormatter.java
index 47e4616..dc8c5fa 100644
--- a/src/main/java/com/loki/lochat/utils/ChatFormatter.java
+++ b/src/main/java/com/loki/lochat/utils/format/ChatFormatter.java
@@ -1,4 +1,4 @@
-package com.loki.lochat.utils;
+package com.loki.lochat.utils.format;
import com.loki.lochat.utils.color.ColorConverter;
import net.kyori.adventure.text.Component;
diff --git a/src/main/java/com/loki/lochat/utils/TextFormatter.java b/src/main/java/com/loki/lochat/utils/format/TextFormatter.java
similarity index 99%
rename from src/main/java/com/loki/lochat/utils/TextFormatter.java
rename to src/main/java/com/loki/lochat/utils/format/TextFormatter.java
index 2f7858f..1329ef0 100644
--- a/src/main/java/com/loki/lochat/utils/TextFormatter.java
+++ b/src/main/java/com/loki/lochat/utils/format/TextFormatter.java
@@ -1,4 +1,4 @@
-package com.loki.lochat.utils;
+package com.loki.lochat.utils.format;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
diff --git a/src/main/java/com/loki/lochat/utils/TimeFormatter.java b/src/main/java/com/loki/lochat/utils/format/TimeFormatter.java
similarity index 98%
rename from src/main/java/com/loki/lochat/utils/TimeFormatter.java
rename to src/main/java/com/loki/lochat/utils/format/TimeFormatter.java
index 54c3469..e4ecc2c 100644
--- a/src/main/java/com/loki/lochat/utils/TimeFormatter.java
+++ b/src/main/java/com/loki/lochat/utils/format/TimeFormatter.java
@@ -1,4 +1,4 @@
-package com.loki.lochat.utils;
+package com.loki.lochat.utils.format;
public final class TimeFormatter {
diff --git a/src/main/java/com/loki/lochat/utils/AdventureManager.java b/src/main/java/com/loki/lochat/utils/platform/AdventureManager.java
similarity index 98%
rename from src/main/java/com/loki/lochat/utils/AdventureManager.java
rename to src/main/java/com/loki/lochat/utils/platform/AdventureManager.java
index 102f56f..631ecca 100644
--- a/src/main/java/com/loki/lochat/utils/AdventureManager.java
+++ b/src/main/java/com/loki/lochat/utils/platform/AdventureManager.java
@@ -1,4 +1,4 @@
-package com.loki.lochat.utils;
+package com.loki.lochat.utils.platform;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
diff --git a/src/main/java/com/loki/lochat/utils/FoliaUtil.java b/src/main/java/com/loki/lochat/utils/platform/FoliaUtil.java
similarity index 98%
rename from src/main/java/com/loki/lochat/utils/FoliaUtil.java
rename to src/main/java/com/loki/lochat/utils/platform/FoliaUtil.java
index 3f93ae7..f9f8aae 100644
--- a/src/main/java/com/loki/lochat/utils/FoliaUtil.java
+++ b/src/main/java/com/loki/lochat/utils/platform/FoliaUtil.java
@@ -1,4 +1,4 @@
-package com.loki.lochat.utils;
+package com.loki.lochat.utils.platform;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
diff --git a/src/main/java/com/loki/lochat/utils/DistanceUtil.java b/src/main/java/com/loki/lochat/utils/player/DistanceUtil.java
similarity index 91%
rename from src/main/java/com/loki/lochat/utils/DistanceUtil.java
rename to src/main/java/com/loki/lochat/utils/player/DistanceUtil.java
index 0e4e34b..6557328 100644
--- a/src/main/java/com/loki/lochat/utils/DistanceUtil.java
+++ b/src/main/java/com/loki/lochat/utils/player/DistanceUtil.java
@@ -1,4 +1,4 @@
-package com.loki.lochat.utils;
+package com.loki.lochat.utils.player;
import org.bukkit.entity.Player;
diff --git a/src/main/java/com/loki/lochat/utils/MentionHandler.java b/src/main/java/com/loki/lochat/utils/player/MentionHandler.java
similarity index 97%
rename from src/main/java/com/loki/lochat/utils/MentionHandler.java
rename to src/main/java/com/loki/lochat/utils/player/MentionHandler.java
index e60c659..f4b19d5 100644
--- a/src/main/java/com/loki/lochat/utils/MentionHandler.java
+++ b/src/main/java/com/loki/lochat/utils/player/MentionHandler.java
@@ -1,6 +1,6 @@
-package com.loki.lochat.utils;
+package com.loki.lochat.utils.player;
-import com.loki.lochat.utils.FoliaUtil;
+import com.loki.lochat.utils.platform.FoliaUtil;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
diff --git a/src/main/java/com/loki/lochat/utils/PlayerUtil.java b/src/main/java/com/loki/lochat/utils/player/PlayerUtil.java
similarity index 98%
rename from src/main/java/com/loki/lochat/utils/PlayerUtil.java
rename to src/main/java/com/loki/lochat/utils/player/PlayerUtil.java
index cb4a0c7..b64dd2c 100644
--- a/src/main/java/com/loki/lochat/utils/PlayerUtil.java
+++ b/src/main/java/com/loki/lochat/utils/player/PlayerUtil.java
@@ -1,4 +1,4 @@
-package com.loki.lochat.utils;
+package com.loki.lochat.utils.player;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
diff --git a/src/test/java/com/loki/lochat/gradient/util/GradientConstantsTest.java b/src/test/java/com/loki/lochat/gradient/util/GradientConstantsTest.java
index fc6d841..c9fbd18 100644
--- a/src/test/java/com/loki/lochat/gradient/util/GradientConstantsTest.java
+++ b/src/test/java/com/loki/lochat/gradient/util/GradientConstantsTest.java
@@ -1,5 +1,6 @@
package com.loki.lochat.gradient.util;
+import com.loki.lochat.config.RatConfig;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -8,18 +9,18 @@ class GradientConstantsTest {
@Test
void millisPerSecond() {
- assertEquals(1000L, GradientConstants.MILLIS_PER_SECOND);
+ assertEquals(1000L, RatConfig.MILLIS_PER_SECOND);
}
@Test
void guiSlots() {
- assertEquals(11, GradientConstants.GUI_CONFIRM_SLOT);
- assertEquals(15, GradientConstants.GUI_CANCEL_SLOT);
- assertEquals(13, GradientConstants.GUI_PREVIEW_SLOT);
+ assertEquals(11, RatConfig.GUI_CONFIRM_SLOT);
+ assertEquals(15, RatConfig.GUI_CANCEL_SLOT);
+ assertEquals(13, RatConfig.GUI_PREVIEW_SLOT);
}
@Test
void luckPermsPriority() {
- assertEquals(100, GradientConstants.LUCKPERMS_PREFIX_PRIORITY);
+ assertEquals(100, RatConfig.LUCKPERMS_PREFIX_PRIORITY);
}
}
diff --git a/src/test/java/com/loki/lochat/utils/ChatFormatterTest.java b/src/test/java/com/loki/lochat/utils/ChatFormatterTest.java
index 5ed24f9..1819e29 100644
--- a/src/test/java/com/loki/lochat/utils/ChatFormatterTest.java
+++ b/src/test/java/com/loki/lochat/utils/ChatFormatterTest.java
@@ -1,5 +1,7 @@
package com.loki.lochat.utils;
+import com.loki.lochat.utils.format.ChatFormatter;
+
import net.kyori.adventure.text.Component;
import org.junit.jupiter.api.Test;