Skip to content
7 changes: 7 additions & 0 deletions api/src/main/java/at/helpch/chatchat/api/channel/Channel.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ public interface Channel {
*/
int radius();

/**
* Check if this channel is cross server.
*
* @return True if this channel is cross server, false otherwise.
*/
boolean crossServer();

/**
* Get a set of {@link ChatUser}s that can see this channel.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ interface Builder<T extends Channel> {
@NotNull final List<String> toggleCommands,
@NotNull final String channelPrefix,
@NotNull final FormatsHolder formats,
final int radius);
final int radius,
final boolean crossServer);
}

/**
Expand Down
26 changes: 26 additions & 0 deletions plugin/src/main/java/at/helpch/chatchat/ChatChatPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
import at.helpch.chatchat.command.WhisperToggleCommand;
import at.helpch.chatchat.api.hook.Hook;
import at.helpch.chatchat.config.ConfigManager;
import at.helpch.chatchat.cs.receiver.BungeeMessageReceiver;
import at.helpch.chatchat.cs.receiver.RemoteMessageReceiver;
import at.helpch.chatchat.cs.sender.BungeeMessageSender;
import at.helpch.chatchat.cs.sender.RemoteMessageSender;
import at.helpch.chatchat.data.base.Database;
import at.helpch.chatchat.data.impl.gson.GsonDatabase;
import at.helpch.chatchat.hooks.HookManagerImpl;
Expand Down Expand Up @@ -53,6 +57,8 @@
import java.util.List;
import java.util.stream.Collectors;

import static at.helpch.chatchat.util.Constants.BUNGEE_CROSS_SERVER_CHANNEL;

@BukkitMain
public final class ChatChatPlugin extends JavaPlugin {

Expand All @@ -76,6 +82,9 @@ public final class ChatChatPlugin extends JavaPlugin {
private @NotNull
final ChatChatAPIImpl api = new ChatChatAPIImpl(this);

private RemoteMessageSender remoteMessageSender;
private RemoteMessageReceiver remoteMessageReceiver;


private static BukkitAudiences audiences;
private BukkitCommandManager<User> commandManager;
Expand All @@ -99,6 +108,12 @@ public void onEnable() {
hookManager.init();
configManager.reload();

// TODO: Make cross server type configurable
remoteMessageSender = new BungeeMessageSender(this);
remoteMessageReceiver = new BungeeMessageReceiver(this);
this.getServer().getMessenger().registerOutgoingPluginChannel(this, BUNGEE_CROSS_SERVER_CHANNEL);
this.getServer().getMessenger().registerIncomingPluginChannel(this, BUNGEE_CROSS_SERVER_CHANNEL, remoteMessageReceiver);

// bStats
Metrics metrics = new Metrics(this, 14781);
metrics.addCustomChart(new SimpleBarChart("channelTypes", () ->
Expand Down Expand Up @@ -142,6 +157,9 @@ public void onEnable() {

@Override
public void onDisable() {
this.getServer().getMessenger().unregisterOutgoingPluginChannel(this);
this.getServer().getMessenger().unregisterIncomingPluginChannel(this);

hookManager().hooks().forEach(Hook::disable);
hookManager().vanishHooks().forEach(Hook::disable);
hookManager().muteHooks().forEach(Hook::disable);
Expand Down Expand Up @@ -205,6 +223,14 @@ public static long cacheDuration() {
return api;
}

public @NotNull RemoteMessageSender remoteMessageSender() {
return remoteMessageSender;
}

public @NotNull RemoteMessageReceiver remoteMessageReceiver() {
return remoteMessageReceiver;
}

private void registerArguments() {
commandManager.registerArgument(PriorityFormat.class, (sender, argument) ->
configManager().formats().formats().get(argument));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,24 @@ public abstract class AbstractChannel implements Channel {

private final int radius;

private final boolean crossServer;

protected AbstractChannel(
@NotNull final String name,
@NotNull final String messagePrefix,
@NotNull final List<String> toggleCommands,
@NotNull final String channelPrefix,
@NotNull final FormatsHolder formats,
final int radius
final int radius,
final boolean crossServer
) {
this.name = name;
this.messagePrefix = messagePrefix;
this.toggleCommands = toggleCommands;
this.channelPrefix = channelPrefix;
this.formats = formats;
this.radius = radius;
this.crossServer = crossServer;
}

@Override
Expand Down Expand Up @@ -68,6 +72,11 @@ public int radius() {
return radius;
}

@Override
public boolean crossServer() {
return crossServer;
}

@Override
public boolean isUsableBy(@NotNull final ChatUser user) {
if (ChatChannel.defaultChannel().equals(this)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ public ChatChannel(
@NotNull final List<String> toggleCommands,
@NotNull final String channelPrefix,
@NotNull final FormatsHolder formats,
final int radius
final int radius,
final boolean crossServer
) {
super(name, messagePrefix, toggleCommands, channelPrefix, formats, radius);
super(name, messagePrefix, toggleCommands, channelPrefix, formats, radius, crossServer);
}

public static @NotNull Channel defaultChannel() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import at.helpch.chatchat.placeholder.MiniPlaceholderContext;
import at.helpch.chatchat.user.ConsoleUser;
import at.helpch.chatchat.util.FormatUtils;
import at.helpch.chatchat.util.MessageProcessor;
import at.helpch.chatchat.processor.LocalToLocalMessageProcessor;
import dev.triumphteam.cmd.bukkit.annotation.Permission;
import dev.triumphteam.cmd.core.annotation.Join;
import dev.triumphteam.cmd.core.annotation.SubCommand;
Expand Down Expand Up @@ -39,7 +39,7 @@ public void testFormat(
format,
sender.player(),
sender.player(),
MessageProcessor.processMessage(plugin, sender, ConsoleUser.INSTANCE, message),
LocalToLocalMessageProcessor.processMessage(plugin, sender, ConsoleUser.INSTANCE, message),
plugin.miniPlaceholdersManager().compileTags(MiniPlaceholderContext.builder().inMessage(false).sender(sender).recipient(sender).build())
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
public final class MainCommand extends ChatChatCommand {

private static final JavaPlugin PLUGIN = JavaPlugin.getProvidingPlugin(ChatChatPlugin.class);
private static final Component TEXT = MessageUtils.parseToMiniMessage(
private static final Component TEXT = MessageUtils.parseFromMiniMessage(
"<aqua><click:open_url:'https://helpch.at'>A Chat Plugin <gray>by <#3dbbe4>Help<#f3af4b>Chat<br><gray>Version: <aqua>" + PLUGIN.getDescription().getVersion());

@Default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import at.helpch.chatchat.ChatChatPlugin;
import at.helpch.chatchat.api.user.ChatUser;
import at.helpch.chatchat.hooks.towny.AbstractTownyChannel;
import at.helpch.chatchat.util.MessageProcessor;
import at.helpch.chatchat.processor.MessageProcessor;
import com.palmergames.bukkit.towny.TownyUniverse;
import com.palmergames.bukkit.towny.object.Resident;
import dev.triumphteam.cmd.core.BaseCommand;
Expand Down Expand Up @@ -57,6 +57,6 @@ public void switchChannel(final ChatUser user, @Join @Optional @NotNull final St
return;
}

MessageProcessor.process(plugin, user, channel, message, false);
MessageProcessor.processMessageEvent(plugin, user, channel, message, false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ public final class DefaultConfigObjects {

public static @NotNull Channel createDefaultChannel() {
return new ChatChannel("default", "",
List.of("global"), "<gray>[<blue>Global<gray>]", new FormatsHolderImpl(), -1);
List.of("global"), "<gray>[<blue>Global<gray>]", new FormatsHolderImpl(), -1, false);
}

public static @NotNull Channel createStaffChannel() {
return new ChatChannel("staff", "@",
List.of("staffchat"), "<gray>[<green>Staff<gray>]", new FormatsHolderImpl(), -1);
List.of("staffchat"), "<gray>[<green>Staff<gray>]", new FormatsHolderImpl(), -1, false);
}

public static @NotNull SimpleFormat createDefaultConsoleFormat() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public final class ChannelMapper implements TypeSerializer<Channel> {
private static final String CHANNEL_PREFIX = "channel-prefix";
private static final String FORMATS = "formats";
private static final String RADIUS = "radius";
private static final String CROSS_SERVER = "cross-server";
private static final String TYPE = "type";
private static final TypeToken<Map<String, PriorityFormat>> FORMATS_MAP_TYPE = new TypeToken<>() {};

Expand Down Expand Up @@ -55,6 +56,7 @@ public Channel deserialize(Type type, ConfigurationNode node) throws Serializati
final var formatsMap = node.node(FORMATS).get(FORMATS_MAP_TYPE, Map.of());
final var formats = new FormatsHolderImpl(formatsMap);
final var radius = node.node(RADIUS).getInt(-1);
final var crossServer = node.node(CROSS_SERVER).getBoolean(false);

final var channelType = node.node(TYPE).getString("default").toLowerCase();

Expand All @@ -63,7 +65,7 @@ public Channel deserialize(Type type, ConfigurationNode node) throws Serializati
throw new SerializationException("Channel " + key + " has unknown channel type " + channelType + ", " +
"ignoring.");
}
return builder.build(key, messagePrefix, commandName, channelPrefix, formats, radius);
return builder.build(key, messagePrefix, commandName, channelPrefix, formats, radius, crossServer);
}

@Override
Expand All @@ -78,5 +80,6 @@ public void serialize(Type type, @Nullable Channel channel, ConfigurationNode ta
target.node(CHANNEL_PREFIX).set(channel.channelPrefix());
target.node(FORMATS).set(channel.formats().formats());
target.node(RADIUS).set(channel.radius());
target.node(CROSS_SERVER).set(channel.crossServer());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package at.helpch.chatchat.cs.receiver;

import at.helpch.chatchat.ChatChatPlugin;
import at.helpch.chatchat.processor.RemoteToLocalMessageProcessor;
import at.helpch.chatchat.util.Constants;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.logging.Level;

import static at.helpch.chatchat.util.Constants.BUNGEE_CROSS_SERVER_CHANNEL;
import static at.helpch.chatchat.util.Constants.CROSS_SERVER_SUB_CHANNEL;

public class BungeeMessageReceiver implements RemoteMessageReceiver {

private final @NotNull ChatChatPlugin plugin;

public BungeeMessageReceiver(final @NotNull ChatChatPlugin plugin) {
this.plugin = plugin;
}

@Override
public void onPluginMessageReceived(final @NotNull String channel, @NotNull Player player, final byte[] message) {
if (!channel.equals(BUNGEE_CROSS_SERVER_CHANNEL)) return;

final ByteArrayDataInput in = ByteStreams.newDataInput(message);
final String subChannel = in.readUTF();

if (!subChannel.equals(CROSS_SERVER_SUB_CHANNEL)) return;

final short length = in.readShort();
final byte[] messageBytes = new byte[length];
in.readFully(messageBytes);

final DataInputStream messageIn = new DataInputStream(new ByteArrayInputStream(messageBytes));
try {
final String messageType = messageIn.readUTF();
if (!messageType.equals(Constants.PUBLIC_MESSAGE_TYPE) && !messageType.equals(Constants.PRIVATE_MESSAGE_TYPE)) {
plugin.getLogger().warning("Got cross server message but the message type was invalid: " + messageType);
return;
}

// TODO: Add private message support

final String channelName = messageIn.readUTF();
final String messageContent = messageIn.readUTF();

RemoteToLocalMessageProcessor.processRemoteMessageEvent(plugin, channelName, messageContent);

} catch (final IOException exception) {
plugin.getLogger().log(Level.WARNING, "Got cross server message but could not read it.", exception);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package at.helpch.chatchat.cs.receiver;

import org.bukkit.plugin.messaging.PluginMessageListener;

public interface RemoteMessageReceiver extends PluginMessageListener {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package at.helpch.chatchat.cs.sender;

import at.helpch.chatchat.ChatChatPlugin;
import at.helpch.chatchat.util.Constants;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.logging.Level;

import static at.helpch.chatchat.util.Constants.BUNGEE_CROSS_SERVER_CHANNEL;
import static at.helpch.chatchat.util.Constants.CROSS_SERVER_SUB_CHANNEL;

public class BungeeMessageSender implements RemoteMessageSender {
private final @NotNull ChatChatPlugin plugin;

public BungeeMessageSender(final @NotNull ChatChatPlugin plugin) {
this.plugin = plugin;
}

@Override
public boolean send(String channel, String message) {
final ByteArrayDataOutput out = ByteStreams.newDataOutput();

out.writeUTF("Forward");
out.writeUTF("ALL");
out.writeUTF(CROSS_SERVER_SUB_CHANNEL);

final ByteArrayOutputStream messageBytes = new ByteArrayOutputStream();
final DataOutputStream messageOut = new DataOutputStream(messageBytes);

try {
messageOut.writeUTF(Constants.PUBLIC_MESSAGE_TYPE);
messageOut.writeUTF(channel);
messageOut.writeUTF(message);
} catch (final IOException exception){
plugin.getLogger().log(Level.WARNING, "Could not write cross server message.", exception);
return false;
}

out.writeShort(messageBytes.toByteArray().length);
out.write(messageBytes.toByteArray());

Bukkit.getServer().sendPluginMessage(plugin, BUNGEE_CROSS_SERVER_CHANNEL, out.toByteArray());
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package at.helpch.chatchat.cs.sender;

public interface RemoteMessageSender {
boolean send(String channel, String message);
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ protected AbstractTownyChannel(@NotNull final String name,
@NotNull final List<String> toggleCommands,
@NotNull final String channelPrefix,
@NotNull final FormatsHolder formats,
final int radius) {
super(name, messagePrefix, toggleCommands, channelPrefix, formats, radius);
final int radius,
final boolean crossServer) {
super(name, messagePrefix, toggleCommands, channelPrefix, formats, radius, crossServer);
if (Bukkit.getPluginManager().getPlugin("Towny") == null) {
throw new RuntimeException("Attempting to use a Towny channel but Towny is not installed.");
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ public TownyNationChannel(@NotNull final String name,
@NotNull final List<String> toggleCommands,
@NotNull final String channelPrefix,
@NotNull final FormatsHolder formats,
final int radius) {
super(name, messagePrefix, toggleCommands, channelPrefix, formats, radius);
final int radius,
final boolean crossServer) {
super(name, messagePrefix, toggleCommands, channelPrefix, formats, radius, crossServer);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ public TownyTownChannel(@NotNull final String name,
@NotNull final List<String> toggleCommands,
@NotNull final String channelPrefix,
@NotNull final FormatsHolder formats,
final int radius) {
super(name, messagePrefix, toggleCommands, channelPrefix, formats, radius);
final int radius,
final boolean crossServer) {
super(name, messagePrefix, toggleCommands, channelPrefix, formats, radius, crossServer);
}

@Override
Expand Down
Loading