diff --git a/src/main/java/me/oskar3123/staffchat/spigot/Main.java b/src/main/java/me/oskar3123/staffchat/spigot/Main.java index dc82487..1dfb350 100644 --- a/src/main/java/me/oskar3123/staffchat/spigot/Main.java +++ b/src/main/java/me/oskar3123/staffchat/spigot/Main.java @@ -1,12 +1,17 @@ package me.oskar3123.staffchat.spigot; +import github.scarsz.discordsrv.DiscordSRV; import java.util.Optional; import me.clip.placeholderapi.PlaceholderAPI; import me.oskar3123.staffchat.spigot.command.StaffChatCommand; +import me.oskar3123.staffchat.spigot.handler.StaffChatHandler; import me.oskar3123.staffchat.spigot.listener.ChatListener; +import me.oskar3123.staffchat.spigot.listener.DiscordSrvListener; +import me.oskar3123.staffchat.spigot.listener.StaffChatPml; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.NotNull; public class Main extends JavaPlugin { @@ -14,15 +19,20 @@ public class Main extends JavaPlugin { public final String seePerm = "staffchat.see"; public final String commandPerm = "staffchat.command"; public final String reloadPerm = "staffchat.reload"; - public final ChatListener chatListener = new ChatListener(this); + public final StaffChatHandler staffChatHandler = new StaffChatHandler(this); + public final ChatListener chatListener = new ChatListener(staffChatHandler); + public final StaffChatPml staffChatPml = new StaffChatPml(staffChatHandler); public void onEnable() { getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); - getServer().getMessenger().registerIncomingPluginChannel(this, "BungeeCord", chatListener); + getServer().getMessenger().registerIncomingPluginChannel(this, "BungeeCord", staffChatPml); new MetricsLite(this); saveDefaultConfig(); registerCommands(); registerEvents(); + if (Bukkit.getPluginManager().isPluginEnabled("DiscordSRV")) { + DiscordSRV.api.subscribe(new DiscordSrvListener(this)); + } } @Override @@ -45,7 +55,7 @@ public class Main extends JavaPlugin { return Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI"); } - public String replacePlaceholders(Player player, String string) { + public @NotNull String replacePlaceholders(Player player, String string) { if (!isPlaceholderApiEnabled()) { return string; } diff --git a/src/main/java/me/oskar3123/staffchat/spigot/command/StaffChatCommand.java b/src/main/java/me/oskar3123/staffchat/spigot/command/StaffChatCommand.java index cf4d2f2..d835c73 100644 --- a/src/main/java/me/oskar3123/staffchat/spigot/command/StaffChatCommand.java +++ b/src/main/java/me/oskar3123/staffchat/spigot/command/StaffChatCommand.java @@ -86,7 +86,7 @@ public class StaffChatCommand implements CommandExecutor { playerOnly(sender); return; } - boolean toggled = plugin.chatListener.togglePlayer(((Player) sender).getUniqueId()); + boolean toggled = plugin.staffChatHandler.togglePlayer(((Player) sender).getUniqueId()); String state = toggled ? config.getString("messages.onstring") : config.getString("messages.offstring"); sender.sendMessage( diff --git a/src/main/java/me/oskar3123/staffchat/spigot/handler/StaffChatHandler.java b/src/main/java/me/oskar3123/staffchat/spigot/handler/StaffChatHandler.java new file mode 100644 index 0000000..dfb363d --- /dev/null +++ b/src/main/java/me/oskar3123/staffchat/spigot/handler/StaffChatHandler.java @@ -0,0 +1,167 @@ +package me.oskar3123.staffchat.spigot.handler; + +import com.google.common.io.ByteArrayDataInput; +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; +import github.scarsz.discordsrv.DiscordSRV; +import github.scarsz.discordsrv.util.DiscordUtil; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import me.oskar3123.staffchat.spigot.Main; +import me.oskar3123.staffchat.spigot.event.StaffChatEvent; +import me.oskar3123.staffchat.util.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.jetbrains.annotations.NotNull; + +public class StaffChatHandler { + + private final Main plugin; + private final Set toggledPlayers = new HashSet<>(); + + public StaffChatHandler(Main plugin) { + this.plugin = plugin; + } + + public void onChatEvent(@NotNull AsyncPlayerChatEvent event) { + if (!event.getPlayer().hasPermission(plugin.usePerm)) { + return; + } + + FileConfiguration config = plugin.getConfig(); + String character = Objects.requireNonNull(config.getString("settings.character", "@")); + boolean isToggled = toggledPlayers.contains(event.getPlayer().getUniqueId()); + if (!event.getMessage().startsWith(character) && !isToggled) { + return; + } + + String format = Objects.requireNonNull(config.getString("settings.format", "")); + String message = event.getMessage().substring(isToggled ? 0 : character.length()).trim(); + if (config.getBoolean("settings.replaceplaceholdersinmessage")) { + message = plugin.replacePlaceholders(event.getPlayer(), message); + } + + StaffChatEvent chatEvent = + new StaffChatEvent(event.isAsynchronous(), event.getPlayer(), format, message); + Bukkit.getServer().getPluginManager().callEvent(chatEvent); + if (chatEvent.isCancelled()) { + return; + } + format = chatEvent.getFormat(); + message = chatEvent.getMessage(); + + format = plugin.replacePlaceholders(event.getPlayer(), format); + + sendStaffChatMessage(format, event.getPlayer().getName(), message); + + if (plugin.getConfig().getBoolean("discordsrv.enable")) { + sendDiscordMessage(event.getPlayer(), message); + } + + event.setCancelled(true); + } + + public void sendStaffChatMessage(String format, String name, String message) { + format = format.replaceAll("\\{NAME}", StringUtils.sanitize(name)); + format = ChatColor.translateAlternateColorCodes('&', format); + format = format.replaceAll("\\{MESSAGE}", StringUtils.sanitize(message)); + final String finalMessage = format; + + if (plugin.getConfig().getBoolean("settings.sendmessagestoallservers")) { + // Find any player and send using that object + // (which player sends the plugin message is not important) + Bukkit.getOnlinePlayers().stream() + .findAny() + .ifPresent(player -> sendForwardPluginMessage(player, finalMessage)); + } + sendStaffChatMessage(finalMessage); + } + + public void onPluginMessageReceived(@NotNull String channel, byte[] message) { + if (!channel.equals("BungeeCord")) { + return; + } + ByteArrayDataInput in = ByteStreams.newDataInput(message); + String subChannel = in.readUTF(); + if (!subChannel.equals("StaffChat")) { + return; + } + short len = in.readShort(); + byte[] msgbytes = new byte[len]; + in.readFully(msgbytes); + + DataInputStream msgin = new DataInputStream(new ByteArrayInputStream(msgbytes)); + String actualMessage; + try { + actualMessage = msgin.readUTF(); + } catch (IOException e) { + e.printStackTrace(); + plugin.getLogger().severe("Failed to read plugin message from bungeecord"); + return; + } + sendStaffChatMessage(actualMessage); + } + + private void sendForwardPluginMessage(@NotNull Player player, @NotNull String message) { + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + out.writeUTF("Forward"); + out.writeUTF("ONLINE"); + out.writeUTF("StaffChat"); + ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); + DataOutputStream dataStream = new DataOutputStream(byteStream); + try { + dataStream.writeUTF(message); + } catch (IOException e) { + e.printStackTrace(); + plugin.getLogger().severe("Failed to send plugin message to bungeecord"); + return; + } + byte[] data = byteStream.toByteArray(); + out.writeShort(data.length); + out.write(data); + player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray()); + } + + private void sendStaffChatMessage(@NotNull String message) { + Bukkit.getOnlinePlayers().stream() + .filter(p -> p.hasPermission(plugin.seePerm)) + .forEach(p -> p.sendMessage(message)); + plugin.getLogger().info(ChatColor.stripColor(message)); + } + + private void sendDiscordMessage(Player player, String message) { + if (Bukkit.getPluginManager().isPluginEnabled("DiscordSRV")) { + String format = + plugin + .replacePlaceholders( + player, + plugin.getConfig().getString("discordsrv.minecraft-to-discord-format", "")) + .replaceAll("\\{NAME}", StringUtils.sanitize(player.getName())) + .replaceAll("\\{MESSAGE}", StringUtils.sanitize(message)); + DiscordUtil.sendMessage( + DiscordSRV.getPlugin() + .getOptionalTextChannel( + plugin.getConfig().getString("discordsrv.channel", "staffchat")), + format); + } + } + + public boolean togglePlayer(@NotNull UUID player) { + if (toggledPlayers.contains(player)) { + toggledPlayers.remove(player); + return false; + } + toggledPlayers.add(player); + return true; + } +} diff --git a/src/main/java/me/oskar3123/staffchat/spigot/listener/ChatListener.java b/src/main/java/me/oskar3123/staffchat/spigot/listener/ChatListener.java index b1808d2..a6d53b5 100644 --- a/src/main/java/me/oskar3123/staffchat/spigot/listener/ChatListener.java +++ b/src/main/java/me/oskar3123/staffchat/spigot/listener/ChatListener.java @@ -1,161 +1,21 @@ package me.oskar3123.staffchat.spigot.listener; -import com.google.common.io.ByteArrayDataInput; -import com.google.common.io.ByteArrayDataOutput; -import com.google.common.io.ByteStreams; -import github.scarsz.discordsrv.DiscordSRV; -import github.scarsz.discordsrv.util.DiscordUtil; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; -import java.util.UUID; -import me.oskar3123.staffchat.spigot.Main; -import me.oskar3123.staffchat.spigot.event.StaffChatEvent; -import me.oskar3123.staffchat.util.StringUtils; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; +import me.oskar3123.staffchat.spigot.handler.StaffChatHandler; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.AsyncPlayerChatEvent; -import org.bukkit.plugin.messaging.PluginMessageListener; import org.jetbrains.annotations.NotNull; -public class ChatListener implements Listener, PluginMessageListener { +public class ChatListener implements Listener { - private final Main plugin; - private final Set toggledPlayers = new HashSet<>(); + private final StaffChatHandler staffChatHandler; - public ChatListener(@NotNull Main plugin) { - this.plugin = plugin; + public ChatListener(@NotNull StaffChatHandler staffChatHandler) { + this.staffChatHandler = staffChatHandler; } @EventHandler public void chat(@NotNull AsyncPlayerChatEvent event) { - if (!event.getPlayer().hasPermission(plugin.usePerm)) { - return; - } - - FileConfiguration config = plugin.getConfig(); - String character = Objects.requireNonNull(config.getString("settings.character", "@")); - boolean isToggled = toggledPlayers.contains(event.getPlayer().getUniqueId()); - if (!event.getMessage().startsWith(character) && !isToggled) { - return; - } - - String format = Objects.requireNonNull(config.getString("settings.format", "")); - String message = event.getMessage().substring(isToggled ? 0 : character.length()).trim(); - if (config.getBoolean("settings.replaceplaceholdersinmessage")) { - message = plugin.replacePlaceholders(event.getPlayer(), message); - } - - StaffChatEvent chatEvent = - new StaffChatEvent(event.isAsynchronous(), event.getPlayer(), format, message); - Bukkit.getServer().getPluginManager().callEvent(chatEvent); - if (chatEvent.isCancelled()) { - return; - } - format = chatEvent.getFormat(); - message = chatEvent.getMessage(); - - format = plugin.replacePlaceholders(event.getPlayer(), format); - format = format.replaceAll("\\{NAME}", StringUtils.sanitize(event.getPlayer().getName())); - format = ChatColor.translateAlternateColorCodes('&', format); - format = format.replaceAll("\\{MESSAGE}", StringUtils.sanitize(message)); - final String finalMessage = format; - - if (plugin.getConfig().getBoolean("discordsrv.enable")) { - sendDiscordMessage(event.getPlayer(), message); - } - if (plugin.getConfig().getBoolean("settings.sendmessagestoallservers")) { - sendForwardPluginMessage(event.getPlayer(), finalMessage); - } - sendStaffChatMessage(finalMessage); - - event.setCancelled(true); - } - - @Override - public void onPluginMessageReceived( - @NotNull String channel, @NotNull Player player, byte[] message) { - if (!channel.equals("BungeeCord")) { - return; - } - ByteArrayDataInput in = ByteStreams.newDataInput(message); - String subChannel = in.readUTF(); - if (!subChannel.equals("StaffChat")) { - return; - } - short len = in.readShort(); - byte[] msgbytes = new byte[len]; - in.readFully(msgbytes); - - DataInputStream msgin = new DataInputStream(new ByteArrayInputStream(msgbytes)); - String actualMessage; - try { - actualMessage = msgin.readUTF(); - } catch (IOException e) { - e.printStackTrace(); - plugin.getLogger().severe("Failed to read plugin message from bungeecord"); - return; - } - sendStaffChatMessage(actualMessage); - } - - private void sendStaffChatMessage(@NotNull String message) { - Bukkit.getOnlinePlayers().stream() - .filter(p -> p.hasPermission(plugin.seePerm)) - .forEach(p -> p.sendMessage(message)); - plugin.getLogger().info(ChatColor.stripColor(message)); - } - - private void sendForwardPluginMessage(@NotNull Player player, @NotNull String message) { - ByteArrayDataOutput out = ByteStreams.newDataOutput(); - out.writeUTF("Forward"); - out.writeUTF("ONLINE"); - out.writeUTF("StaffChat"); - ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); - DataOutputStream dataStream = new DataOutputStream(byteStream); - try { - dataStream.writeUTF(message); - } catch (IOException e) { - e.printStackTrace(); - plugin.getLogger().severe("Failed to send plugin message to bungeecord"); - return; - } - byte[] data = byteStream.toByteArray(); - out.writeShort(data.length); - out.write(data); - player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray()); - } - - private void sendDiscordMessage(Player player, String message) { - if (Bukkit.getPluginManager().isPluginEnabled("DiscordSRV")) { - String format = - plugin - .replacePlaceholders(player, plugin.getConfig().getString("discordsrv.format", "")) - .replaceAll("\\{NAME}", StringUtils.sanitize(player.getName())) - .replaceAll("\\{MESSAGE}", StringUtils.sanitize(message)); - DiscordUtil.sendMessage( - DiscordSRV.getPlugin() - .getOptionalTextChannel( - plugin.getConfig().getString("discordsrv.channel", "staffchat")), - format); - } - } - - public boolean togglePlayer(@NotNull UUID player) { - if (toggledPlayers.contains(player)) { - toggledPlayers.remove(player); - return false; - } - toggledPlayers.add(player); - return true; + staffChatHandler.onChatEvent(event); } } diff --git a/src/main/java/me/oskar3123/staffchat/spigot/listener/DiscordSrvListener.java b/src/main/java/me/oskar3123/staffchat/spigot/listener/DiscordSrvListener.java new file mode 100644 index 0000000..9919d46 --- /dev/null +++ b/src/main/java/me/oskar3123/staffchat/spigot/listener/DiscordSrvListener.java @@ -0,0 +1,57 @@ +package me.oskar3123.staffchat.spigot.listener; + +import github.scarsz.discordsrv.DiscordSRV; +import github.scarsz.discordsrv.api.ListenerPriority; +import github.scarsz.discordsrv.api.Subscribe; +import github.scarsz.discordsrv.api.events.DiscordGuildMessageReceivedEvent; +import github.scarsz.discordsrv.dependencies.jda.api.entities.Message; +import github.scarsz.discordsrv.dependencies.jda.api.entities.User; +import java.util.Optional; +import me.oskar3123.staffchat.spigot.Main; +import org.bukkit.Bukkit; +import org.bukkit.configuration.Configuration; + +public class DiscordSrvListener { + + private final Main plugin; + private final DiscordSRV discordSrv; + + public DiscordSrvListener(Main plugin) { + this.plugin = plugin; + this.discordSrv = DiscordSRV.getPlugin(); + } + + @Subscribe(priority = ListenerPriority.MONITOR) + public void onDiscordGuildMessageReceivedEvent(DiscordGuildMessageReceivedEvent event) { + Configuration config = plugin.getConfig(); + if (!isDiscordSrvEnabled(config)) { + return; + } + String channel = config.getString("discordsrv.channel", "staffchat"); + Optional.ofNullable(discordSrv.getDestinationGameChannelNameForTextChannel(event.getChannel())) + .filter(gameChannel -> gameChannel.equals(channel)) + .ifPresent( + gameChannel -> { + String name = + Optional.ofNullable(event.getAuthor()).map(User::getName).orElse("Discord User"); + String message = + Optional.ofNullable(event.getMessage()) + .map(Message::getContentDisplay) + .orElse(""); + Bukkit.getScheduler() + .runTask( + plugin, + () -> + plugin.staffChatHandler.sendStaffChatMessage( + plugin + .getConfig() + .getString("discordsrv.discord-to-minecraft-format", ""), + name, + message)); + }); + } + + private boolean isDiscordSrvEnabled(Configuration config) { + return config.getBoolean("discordsrv.enable", false); + } +} diff --git a/src/main/java/me/oskar3123/staffchat/spigot/listener/StaffChatPml.java b/src/main/java/me/oskar3123/staffchat/spigot/listener/StaffChatPml.java new file mode 100644 index 0000000..a22b5c3 --- /dev/null +++ b/src/main/java/me/oskar3123/staffchat/spigot/listener/StaffChatPml.java @@ -0,0 +1,21 @@ +package me.oskar3123.staffchat.spigot.listener; + +import me.oskar3123.staffchat.spigot.handler.StaffChatHandler; +import org.bukkit.entity.Player; +import org.bukkit.plugin.messaging.PluginMessageListener; +import org.jetbrains.annotations.NotNull; + +public class StaffChatPml implements PluginMessageListener { + + private final StaffChatHandler staffChatHandler; + + public StaffChatPml(StaffChatHandler staffChatHandler) { + this.staffChatHandler = staffChatHandler; + } + + @Override + public void onPluginMessageReceived( + @NotNull String channel, @NotNull Player player, byte[] message) { + staffChatHandler.onPluginMessageReceived(channel, message); + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index c08d403..98f7b19 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -14,4 +14,5 @@ messages: discordsrv: enable: false channel: 'staffchat' - format: '{NAME} » {MESSAGE}' + minecraft-to-discord-format: '{NAME} » {MESSAGE}' + discord-to-minecraft-format: '&b(Discord) {NAME}: {MESSAGE}'