feat: chat channel system (/join /leave /channel)
- config-driven channels in config/channels.yml (global, local, staff, trade) with emoji, colors, prefix, radius, cooldowns, permissions and aliases - Channel record + ChannelConfig loader wired into ConfigManager (reload supported) - ChannelService (api) + ConcurrentHashMap-backed ChannelServiceImpl, joined in ServiceRegistry; default channel join treated as 'not in channel' - JoinChannelCommand / LeaveChannelCommand / ChannelCommand (+ tab completion), registered in CommandManager; plugin.yml commands + permissions - ChatEventListener routes AsyncChatEvent to the active channel: per-channel cooldown, local-radius viewer filtering, channel-aware renderer - EnhancedChatRenderer supports Channel overload (emojiFor/prefixText/channelColor) - ChannelServiceImplTest covering join/leave/permissions/aliases
This commit is contained in:
parent
689ab1a9ae
commit
a822c91637
17 changed files with 821 additions and 12 deletions
120
src/main/java/com/loki/lochat/commands/chat/ChannelCommand.java
Normal file
120
src/main/java/com/loki/lochat/commands/chat/ChannelCommand.java
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
package com.loki.lochat.commands.chat;
|
||||
|
||||
import com.loki.lochat.LoChat;
|
||||
import com.loki.lochat.api.service.ChannelService;
|
||||
import com.loki.lochat.channel.Channel;
|
||||
import com.loki.lochat.commands.base.PlayerCommand;
|
||||
import com.loki.lochat.utils.format.ChatFormatter;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* /channel — инфо о текущем канале со списком доступных.
|
||||
* /channel <канал> — переключиться. /channel off — выйти.
|
||||
* /channel list — список каналов.
|
||||
*/
|
||||
public class ChannelCommand extends PlayerCommand {
|
||||
|
||||
public ChannelCommand(LoChat plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean executePlayerCommand(@NotNull Player player, @NotNull Command command,
|
||||
@NotNull String label, @NotNull String[] args) {
|
||||
ChannelService channels = plugin.getServiceRegistry().get(ChannelService.class);
|
||||
if (!channels.isEnabled()) {
|
||||
player.sendMessage(ChatFormatter.parse("&#CF6679Система каналов отключена"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length == 0) {
|
||||
showCurrent(player, channels);
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (args[0].toLowerCase(Locale.ROOT)) {
|
||||
case "off", "leave" -> {
|
||||
if (channels.isInChannel(player)) {
|
||||
channels.leave(player);
|
||||
player.sendMessage(ChatFormatter.parse("⚖C9Вы вышли из канала"));
|
||||
} else {
|
||||
player.sendMessage(ChatFormatter.parse("&#B798A8Вы не находитесь в канале"));
|
||||
}
|
||||
}
|
||||
case "list" -> listChannels(player, channels);
|
||||
default -> joinChannel(player, channels, args[0]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void showCurrent(Player player, ChannelService channels) {
|
||||
Channel active = channels.getActive(player).orElse(null);
|
||||
if (active == null) {
|
||||
Channel def = channels.getDefault();
|
||||
player.sendMessage(ChatFormatter.parse("&#B798A8Вы в дефолтном канале [ẲE9"
|
||||
+ (def == null ? "?" : def.display() + "&8 " + def.prefix()) + "&#B798A8]"));
|
||||
} else {
|
||||
player.sendMessage(ChatFormatter.parse("⚖C9Вы в канале [ẲE9"
|
||||
+ active.display() + "&8 " + active.prefix() + "⚖C9]"));
|
||||
}
|
||||
player.sendMessage(ChatFormatter.parse("&#B798A8/join <канал> ⚖C9— войти, "
|
||||
+ "&#B798A8/channel list ⚖C9— все каналы"));
|
||||
}
|
||||
|
||||
private void listChannels(Player player, ChannelService channels) {
|
||||
player.sendMessage(ChatFormatter.parse("&#B798A8Доступные каналы:"));
|
||||
for (Channel c : channels.getChannels()) {
|
||||
boolean canUse = channels.canUse(player, c);
|
||||
boolean active = c.equals(channels.getActive(player).orElse(null));
|
||||
player.sendMessage(ChatFormatter.parse((canUse ? "⚖C9" : "&#CF6679")
|
||||
+ (active ? "\u25B8 " : "\u25AA ") + c.display() + "&8 " + c.prefix()
|
||||
+ (canUse ? "" : " &#CF6679(нет прав)")
|
||||
+ " &#B798A8— " + (c.isGlobalScope() ? "глобальный" : "локальный, " + c.radius() + "б")));
|
||||
}
|
||||
}
|
||||
|
||||
private void joinChannel(Player player, ChannelService channels, String name) {
|
||||
Channel channel = channels.find(name);
|
||||
if (channel == null) {
|
||||
player.sendMessage(ChatFormatter.parse("&#CF6679Канал ẲE9" + name + " &#CF6679не найден"));
|
||||
return;
|
||||
}
|
||||
if (!channels.canUse(player, channel)) {
|
||||
player.sendMessage(ChatFormatter.parse(
|
||||
plugin.getConfigManager().getMessagesConfig().getNoPermission()));
|
||||
return;
|
||||
}
|
||||
Channel active = channels.getActive(player).orElse(null);
|
||||
channels.join(player, channel);
|
||||
if (channel.equals(active)) {
|
||||
player.sendMessage(ChatFormatter.parse("&#B798A8Вы уже в канале [ẲE9"
|
||||
+ channel.display() + "&8 " + channel.prefix() + "&#B798A8]"));
|
||||
} else {
|
||||
player.sendMessage(ChatFormatter.parse("⚖C9Вы вошли в канал [ẲE9"
|
||||
+ channel.display() + "&8 " + channel.prefix() + "⚖C9]"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull Command command,
|
||||
@NotNull String alias, @NotNull String[] args) {
|
||||
if (args.length != 1) {
|
||||
return null;
|
||||
}
|
||||
ChannelService channels = plugin.getServiceRegistry().get(ChannelService.class);
|
||||
String input = args[0].toLowerCase(Locale.ROOT);
|
||||
return java.util.stream.Stream.concat(
|
||||
java.util.stream.Stream.of("list", "off"),
|
||||
channels.getChannels().stream().map(Channel::id))
|
||||
.filter(s -> s.startsWith(input))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue