package me.totalfreedom.totalfreedommod; import com.google.common.base.Strings; import io.papermc.paper.event.player.AsyncChatEvent; import me.totalfreedom.totalfreedommod.admin.Admin; import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.player.FPlayer; import me.totalfreedom.totalfreedommod.player.PlayerData; import me.totalfreedom.totalfreedommod.rank.Displayable; import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FUtil; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.bukkit.Sound; import org.bukkit.SoundCategory; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import java.util.Arrays; public class ChatManager extends FreedomService { @Override public void onStart() { } @Override public void onStop() { } @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onPlayerChat(AsyncChatEvent event) { // Important information for later down the line String steamrolled = FUtil.steamroll(event.originalMessage()); Player player = event.getPlayer(); FPlayer fPlayer = plugin.pl.getPlayer(player); PlayerData playerData = plugin.pl.getData(player); // Chat is disabled if (!ConfigEntry.TOGGLE_CHAT.getBoolean() && !plugin.al.isAdmin(player)) { event.getPlayer().sendMessage(FUtil.miniMessage("The chat is currently disabled.")); event.setCancelled(true); return; } // Locked up else if (fPlayer.isLockedUp()) { event.getPlayer().sendMessage(FUtil.miniMessage("You are locked up and thus can't talk.")); event.setCancelled(true); return; } // Admin chat is enabled else if (fPlayer.inAdminChat()) { adminChat(player, steamrolled); event.setCancelled(true); return; } // The event was already cancelled elsewhere or the player was muted else if (event.isCancelled() || fPlayer.isMuted()) { return; } // Tag Component tag = fPlayer.getTag().append(Component.space()); // Nickname Component nickname = player.displayName(); // Splitter Component splitter = Component.text("ยป", NamedTextColor.DARK_GRAY); // Message TextComponent.Builder message = Component.text(); // Truncate the message if it's too long if (steamrolled.length() > 256) { steamrolled = steamrolled.substring(0, 256); } // Pinging Arrays.stream(steamrolled.split(" ")).filter(string -> string.startsWith("@")).forEach(possiblePlayer -> { Player potential = server.getPlayer(possiblePlayer.replace("@", "")); // Ping only that particular player if (potential != null) { ping(player); } // Ping everyone (if the person pinging is an admin) else if (possiblePlayer.equalsIgnoreCase("@everyone") && plugin.al.isAdmin(player)) { server.getOnlinePlayers().forEach(this::ping); } }); // Did this because sonarlint was complaining about doing the unboxing in the if statement. // Something about returning null because it was boxed... I'm not sure. boolean unboxed = ConfigEntry.FOURCHAN_ENABLED.getBoolean(); // Chat colorization // -- 4chan mode -- if (steamrolled.startsWith("> ") && unboxed) { message.append(Component.text(steamrolled, NamedTextColor.GREEN)); } // -- Legacy chat colors -- else if (FUtil.containsChatColor(steamrolled)) { message.append(FUtil.colorizeAsComponent(steamrolled.replace("&k", ""))); } // -- MiniMessage -- else { message.append(FUtil.miniMessage(steamrolled)); } // This simply filters out shit like &k in a simple but stupid way. Component filtered = FUtil.miniMessage(FUtil.miniMessage(message.build())); event.setCancelled(true); server.broadcast(FUtil.miniMessage(" ", Placeholder.component("tag", tag), Placeholder.component("nickname", nickname), Placeholder.component("splitter", splitter), Placeholder.component("message", filtered))); } public TextColor getColor(Displayable display) { return display.getColor(); } public Component getColoredTag(Displayable display) { return display.getColoredTag(); } public void adminChat(CommandSender sender, String message) { Displayable display = plugin.rm.getDisplay(sender); FLog.info("[ADMIN] " + sender.getName() + " " + display.getTag() + ": " + message, true); if (plugin.dc != null) { plugin.dc.messageAdminChatChannel(sender.getName() + " \u00BB " + message); } server.getOnlinePlayers().stream().filter(player -> plugin.al.isAdmin(player)).forEach(player -> { Admin admin = plugin.al.getAdmin(player); if (!Strings.isNullOrEmpty(admin.getAcFormat())) { String format = admin.getAcFormat(); String flatAbv = FUtil.miniMessage(display.getAbbr()); player.sendMessage(FUtil.miniMessage(format, Placeholder.unparsed("name", sender.getName()), Placeholder.unparsed("rank", flatAbv), TagResolver.resolver("rankcolor", Tag.styling(getColor(display))), Placeholder.unparsed("message", message))); } else { Component defaultFormat = FUtil.miniMessage("[ADMIN] ]: ", Placeholder.unparsed("", sender.getName()), Placeholder.component("", getColoredTag(display)), Placeholder.unparsed("", message)); player.sendMessage(defaultFormat); } }); } public void reportAction(Player reporter, String reportedName, String report) { messageAllAdmins("[REPORTS] has reported for .", Placeholder.unparsed("reporter", reporter.getName()), Placeholder.unparsed("reported", reportedName), Placeholder.unparsed("reason", report)); } public void messageAllAdmins(String message, TagResolver... placeholders) { Component parsed = FUtil.miniMessage(message, placeholders); plugin.getComponentLogger().info(parsed); server.getOnlinePlayers().stream().filter(player -> plugin.al.isAdmin(player)).forEach(player -> player.sendMessage(parsed)); } public void broadcastSplit(String forAdmins, String forOperators, TagResolver... placeholders) { messageAllAdmins(forAdmins, placeholders); server.getOnlinePlayers().stream().filter(player -> !plugin.al.isAdmin(player)).forEach(player -> player.sendMessage(FUtil.miniMessage(forOperators, placeholders))); } public void ping(Player player) { player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, SoundCategory.MASTER, 1337F, 0.9F); } }