LoChat/src/main/java/com/loki/lochat/commands/chat/ChannelCommand.java
loki5512344 a822c91637
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
2026-08-09 21:31:11 +02:00

120 lines
No EOL
5.3 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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("&#9878C9Вы вышли из канала"));
} 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Вы в дефолтном канале [&#7858E9"
+ (def == null ? "?" : def.display() + "&8 " + def.prefix()) + "&#B798A8]"));
} else {
player.sendMessage(ChatFormatter.parse("&#9878C9Вы в канале [&#7858E9"
+ active.display() + "&8 " + active.prefix() + "&#9878C9]"));
}
player.sendMessage(ChatFormatter.parse("&#B798A8/join <канал> &#9878C9— войти, "
+ "&#B798A8/channel list &#9878C9— все каналы"));
}
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 ? "&#9878C9" : "&#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Канал &#7858E9" + 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Вы уже в канале [&#7858E9"
+ channel.display() + "&8 " + channel.prefix() + "&#B798A8]"));
} else {
player.sendMessage(ChatFormatter.parse("&#9878C9Вы вошли в канал [&#7858E9"
+ channel.display() + "&8 " + channel.prefix() + "&#9878C9]"));
}
}
@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();
}
}