diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..4b9e6ec --- /dev/null +++ b/.editorconfig @@ -0,0 +1,19 @@ +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = false +indent_style = space +indent_size = 4 + +[*.json] +indent_style = space +indent_size = 2 + +[*.java] +indent_style = tab +tab_width = 4 + +[{*.yml, *.yaml}] +indent_style = space +indent_size = 2 + diff --git a/Notes.txt b/Notes.txt deleted file mode 100644 index 78af086..0000000 --- a/Notes.txt +++ /dev/null @@ -1,36 +0,0 @@ -Expected: - -***test*** -||- ||- - -||: bold --: italic - - -Actual: - -***test*** -||- ||- --|| -|| - - - - -nextSection: -*: italic(0) -**: -Either italic(0), bold(0) - Delete italic - bold(0), italic(1) - Delete italic - bold(0) -Or bold(0), italic(0) - Delete italic? - italic, italic - 0-length section as result, delete? - -takenStart, takenEnd -because it's ordered, the indexes will be either the same or ascending - - -^^ Implemented - -**test** -^ ^ <-- ! -start end -RemChar: 2 -tes* diff --git a/lombok.config b/lombok.config new file mode 100644 index 0000000..d959b09 --- /dev/null +++ b/lombok.config @@ -0,0 +1 @@ +lombok.var.flagUsage = ALLOW diff --git a/pom.xml b/pom.xml index f9ca404..67ca3b2 100644 --- a/pom.xml +++ b/pom.xml @@ -96,6 +96,46 @@ + @@ -143,7 +183,7 @@ com.github.TBMCPlugins.ButtonCore ButtonCore - master-SNAPSHOT + ${env.TRAVIS_BRANCH}-SNAPSHOT diff --git a/src/main/java/buttondevteam/chat/AnnouncerThread.java b/src/main/java/buttondevteam/chat/AnnouncerThread.java index b1b11da..60d40e7 100644 --- a/src/main/java/buttondevteam/chat/AnnouncerThread.java +++ b/src/main/java/buttondevteam/chat/AnnouncerThread.java @@ -13,6 +13,7 @@ public class AnnouncerThread implements Runnable { } catch (InterruptedException ex) { Thread.currentThread().interrupt(); } + if (Bukkit.getOnlinePlayers().size() == 0) continue; //Don't post to Discord if nobody is on if (PluginMain.AnnounceMessages.size() > AnnounceMessageIndex) { Bukkit.broadcastMessage(PluginMain.AnnounceMessages.get(AnnounceMessageIndex)); AnnounceMessageIndex++; diff --git a/src/main/java/buttondevteam/chat/ChatProcessing.java b/src/main/java/buttondevteam/chat/ChatProcessing.java index 6591cd6..77d1f03 100644 --- a/src/main/java/buttondevteam/chat/ChatProcessing.java +++ b/src/main/java/buttondevteam/chat/ChatProcessing.java @@ -1,343 +1,345 @@ -package buttondevteam.chat; - -import buttondevteam.chat.commands.UnlolCommand; -import buttondevteam.chat.commands.ucmds.admin.DebugCommand; -import buttondevteam.chat.formatting.ChatFormatter; -import buttondevteam.chat.formatting.TellrawEvent; -import buttondevteam.chat.formatting.TellrawPart; -import buttondevteam.chat.formatting.TellrawSerializer; -import buttondevteam.chat.listener.PlayerListener; -import buttondevteam.lib.TBMCChatEvent; -import buttondevteam.lib.TBMCChatEventBase; -import buttondevteam.lib.TBMCCoreAPI; -import buttondevteam.lib.chat.*; -import buttondevteam.lib.player.ChromaGamerBase; -import buttondevteam.lib.player.TBMCPlayer; -import buttondevteam.lib.player.TBMCPlayerBase; -import com.earth2me.essentials.User; -import com.google.common.collect.Lists; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import lombok.val; -import org.bukkit.Bukkit; -import org.bukkit.Sound; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.scoreboard.Objective; - -import javax.annotation.Nullable; -import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; -import java.util.regex.Pattern; - -public class ChatProcessing { - private static final Pattern NULL_MENTION_PATTERN = Pattern.compile("null"); - private static final Pattern CYAN_PATTERN = Pattern.compile("cyan"); - private static final Pattern ESCAPE_PATTERN = Pattern.compile("\\\\"); - private static final Pattern CONSOLE_PING_PATTERN = Pattern.compile("(?i)" + Pattern.quote("@console")); - private static final Pattern HASHTAG_PATTERN = Pattern.compile("#(\\w+)"); - private static final Pattern URL_PATTERN = Pattern.compile("(http[\\w:/?=$\\-_.+!*'(),]+)"); - public static final Pattern ENTIRE_MESSAGE_PATTERN = Pattern.compile(".+"); - private static final Pattern UNDERLINED_PATTERN = Pattern.compile("_"); - private static final Pattern ITALIC_PATTERN = Pattern.compile("\\*"); - private static final Pattern BOLD_PATTERN = Pattern.compile("\\*\\*"); - private static final Pattern CODE_PATTERN = Pattern.compile("`"); - private static final Pattern MASKED_LINK_PATTERN = Pattern.compile("\\[([^\\[\\]])\\]\\(([^()])\\)"); - private static final Pattern SOMEONE_PATTERN = Pattern.compile("@someone"); //TODO - private static final Pattern STRIKETHROUGH_PATTERN = Pattern.compile("~~"); - private static final Color[] RainbowPresserColors = new Color[]{Color.Red, Color.Gold, Color.Yellow, Color.Green, - Color.Blue, Color.DarkPurple}; - private static boolean pingedconsole = false; - - public static final ChatFormatter ESCAPE_FORMATTER = ChatFormatter.builder().regex(ESCAPE_PATTERN).build(); - - private static ArrayList commonFormatters = Lists.newArrayList( - ChatFormatter.builder().regex(BOLD_PATTERN).bold(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range) - .priority(Priority.High).build(), - ChatFormatter.builder().regex(ITALIC_PATTERN).italic(true).removeCharCount((short) 1).type(ChatFormatter.Type.Range).build(), - ChatFormatter.builder().regex(UNDERLINED_PATTERN).underlined(true).removeCharCount((short) 1).type(ChatFormatter.Type.Range) - .build(), - ChatFormatter.builder().regex(STRIKETHROUGH_PATTERN).strikethrough(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range) - .build(), - ESCAPE_FORMATTER, ChatFormatter.builder().regex(URL_PATTERN).underlined(true).openlink("$1").type(ChatFormatter.Type.Excluder).build(), - ChatFormatter.builder().regex(NULL_MENTION_PATTERN).color(Color.DarkRed).build(), // Properly added a bug as a feature - ChatFormatter.builder().regex(CONSOLE_PING_PATTERN).color(Color.Aqua).onmatch((match, builder) -> { - if (!pingedconsole) { - System.out.print("\007"); - pingedconsole = true; // Will set it to false in ProcessChat - } - return match; - }).priority(Priority.High).build(), - - ChatFormatter.builder().regex(HASHTAG_PATTERN).color(Color.Blue).openlink("https://twitter.com/hashtag/$1") - .priority(Priority.High).build(), - ChatFormatter.builder().regex(CYAN_PATTERN).color(Color.Aqua).build(), // #55 - ChatFormatter.builder().regex(CODE_PATTERN).color(Color.DarkGray).removeCharCount((short) 1).type(ChatFormatter.Type.Range) - .build(), - ChatFormatter.builder().regex(MASKED_LINK_PATTERN).underlined(true).onmatch((match, builder) -> { - return match; // TODO! - }).build()); - private static Gson gson = new GsonBuilder() - .registerTypeHierarchyAdapter(TellrawSerializableEnum.class, new TellrawSerializer.TwEnum()) - .registerTypeHierarchyAdapter(Collection.class, new TellrawSerializer.TwCollection()) - .registerTypeAdapter(Boolean.class, new TellrawSerializer.TwBool()) - .registerTypeAdapter(boolean.class, new TellrawSerializer.TwBool()).disableHtmlEscaping().create(); - private static final String[] testPlayers = {"Koiiev", "iie", "Alisolarflare", "NorbiPeti", "Arsen_Derby_FTW", "carrot_lynx"}; - - private ChatProcessing() { - } - - public static boolean ProcessChat(TBMCChatEvent e) { - Channel channel = e.getChannel(); - CommandSender sender = e.getSender(); - String message = e.getMessage(); - long processstart = System.nanoTime(); - Player player = (sender instanceof Player ? (Player) sender : null); - User user = PluginMain.essentials.getUser(player); - - if (player != null) { - user.updateActivity(true); //Could talk in a private channel, so broadcast - if (user.isMuted()) - return true; - } - - doFunStuff(sender, e, message); - - ChatPlayer mp; - if (player != null) - mp = TBMCPlayerBase.getPlayer(player.getUniqueId(), ChatPlayer.class); - else //Due to the online player map, getPlayer() can be more efficient than getAs() - mp = e.getUser().getAs(ChatPlayer.class); //May be null - - Color colormode = channel.color; - if (mp != null && mp.OtherColorMode != null) - colormode = mp.OtherColorMode; - if (message.startsWith(">")) - colormode = Color.Green; - // If greentext, ignore channel or player colors - - ArrayList formatters = addFormatters(colormode); - if (colormode == channel.color && mp != null && mp.RainbowPresserColorMode) { // Only overwrite channel color - final AtomicInteger rpc = new AtomicInteger(0); - formatters.add(ChatFormatter.builder().color(colormode).onmatch((match, cf) -> { - cf.setColor(RainbowPresserColors[rpc.getAndUpdate(i -> ++i < RainbowPresserColors.length ? i : 0)]); - return match; - }).build()); - } - pingedconsole = false; // Will set it to true onmatch (static constructor) - final String channelidentifier = getChannelID(channel, sender); - - TellrawPart json = createTellraw(sender, message, player, mp, e.getUser(), channelidentifier); - long combinetime = System.nanoTime(); - ChatFormatter.Combine(formatters, message, json); - combinetime = System.nanoTime() - combinetime; - String jsonstr = toJson(json); - if (jsonstr.length() >= 32767) { - sender.sendMessage( - "§cError: Message too long. Try shortening it, or remove hashtags and other formatting."); - return true; - } - DebugCommand.SendDebugMessage(jsonstr); - - try { - if (channel.filteranderrormsg != null) { - Objective obj = PluginMain.SB.getObjective(channel.ID); - int score = -1; - for (Player p : Bukkit.getOnlinePlayers()) { - final int mcScore; - if (player != null - && PluginMain.essentials.getUser(p).isIgnoredPlayer(PluginMain.essentials.getUser(player))) - mcScore = -1; // Don't send the message to them - else - mcScore = VanillaUtils.getMCScoreIfChatOn(p, e); - obj.getScore(p.getName()) - .setScore(p.getUniqueId().equals(player == null ? null : player.getUniqueId()) // p.UniqueID==player?.UniqueID - ? score = mcScore : mcScore); - } - if (score == -1) // Even if the player object isn't null, it may not be in OnlinePlayers - score = e.getMCScore(sender); - if (score < 0) // Never send messages to score below 0 - sender.sendMessage("§cYou don't have permission to send this message or something went wrong"); - else { - PluginMain.Instance.getServer().dispatchCommand(PluginMain.Console, - String.format("tellraw @a[score_%s=%d,score_%s_min=%d] %s", channel.ID, score, channel.ID, - score, jsonstr)); - if (e.getChannel().ID.equals(PluginMain.TownChat.ID) - || e.getChannel().ID.equals(PluginMain.NationChat.ID)) { - ((List) json.getExtra()).add(0, new TellrawPart("[SPY]")); - jsonstr = toJson(json); - Bukkit.getServer().dispatchCommand(PluginMain.Console, String.format( - "tellraw @a[score_%s=1000,score_%s_min=1000] %s", channel.ID, channel.ID, jsonstr)); - } - } - } else - PluginMain.Instance.getServer().dispatchCommand(PluginMain.Console, - String.format("tellraw @a %s", jsonstr)); - } catch (Exception ex) { - TBMCCoreAPI.SendException("An error occured while sending a chat message!", ex); - sender.sendMessage("§cAn error occured while sending the message."); - return true; - } - PluginMain.Instance.getServer().getConsoleSender() - .sendMessage(String.format("%s <%s§r> %s", channelidentifier, getSenderName(sender, player), message)); - DebugCommand.SendDebugMessage( - "-- Full ChatProcessing time: " + (System.nanoTime() - processstart) / 1000000f + " ms"); - DebugCommand.SendDebugMessage("-- ChatFormatter.Combine time: " + combinetime / 1000000f + " ms"); - return false; - } - - static String toJson(TellrawPart json) { - return gson.toJson(json); - } - - static TellrawPart createTellraw(CommandSender sender, String message, @Nullable Player player, - @Nullable ChatPlayer mp, @Nullable ChromaGamerBase cg, final String channelidentifier) { - TellrawPart json = new TellrawPart(""); - if (mp != null && mp.ChatOnly) { - json.addExtra(new TellrawPart("[C]") - .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Chat only"))); - } - json.addExtra( - new TellrawPart(channelidentifier) - .setHoverEvent( - TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, - new TellrawPart((sender instanceof IDiscordSender ? "From Discord\n" : "") - + "Copy message").setColor(Color.Blue))) - .setClickEvent(TellrawEvent.create(TellrawEvent.ClickAction.SUGGEST_COMMAND, message))); - if (PluginMain.permission.has(sender, "tbmc.badge.diamond")) - json.addExtra(new TellrawPart("[P]").setColor(Color.Aqua).setBold(true) - .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Diamond Patreon supporter"))); - else if (PluginMain.permission.has(sender, "tbmc.badge.gold")) - json.addExtra(new TellrawPart("[P]").setColor(Color.Gold).setBold(true) - .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Gold Patreon supporter"))); - json.addExtra(new TellrawPart(" <")); - TellrawPart hovertp = new TellrawPart(""); - if (cg != null) - hovertp.addExtra(new TellrawPart(cg.getInfo(ChromaGamerBase.InfoTarget.MCHover))); - json.addExtra(new TellrawPart(getSenderName(sender, player)) - .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, hovertp))); - json.addExtra(new TellrawPart("> ")); - return json; - } - - private static String getSenderName(CommandSender sender, Player player) { - if (player == null) - return sender.getName(); - return player.getDisplayName(); - } - - static String getChannelID(Channel channel, CommandSender sender) { - return ("[" + (sender instanceof IDiscordSender ? "§8D§r|" : "") + channel.DisplayName) - + "]"; - } - - static ArrayList addFormatters(Color colormode) { - @SuppressWarnings("unchecked") - ArrayList formatters = (ArrayList) commonFormatters.clone(); - - formatters.add( - ChatFormatter.builder().regex(ENTIRE_MESSAGE_PATTERN).color(colormode).priority(Priority.Low).build()); - - boolean nottest; //Not assigning a default value, so that it can only be used in the if - if ((nottest = Bukkit.getOnlinePlayers().size() > 0) || Bukkit.getVersion().equals("test")) { - StringBuilder namesb = new StringBuilder("(?i)("); - if (nottest) - for (Player p : Bukkit.getOnlinePlayers()) - namesb.append(p.getName()).append("|"); - else - for (String testPlayer : testPlayers) - namesb.append(testPlayer).append("|"); - namesb.deleteCharAt(namesb.length() - 1); - namesb.append(")"); - StringBuilder nicksb = new StringBuilder("(?i)("); - boolean addNickFormatter = false; - final int size = Bukkit.getOnlinePlayers().size(); - int index = 0; - for (Player p : Bukkit.getOnlinePlayers()) { - final String nick = PlayerListener.nicknames.inverse().get(p.getUniqueId()); - if (nick != null) { - nicksb.append(nick); - if (index < size - 1) { - nicksb.append("|"); - addNickFormatter = true; - } - } - index++; - } - nicksb.append(")"); - - Consumer error = message -> { - if (PluginMain.Instance != null) - PluginMain.Instance.getLogger().warning(message); - else - System.out.println(message); - }; - - formatters.add(ChatFormatter.builder().regex(Pattern.compile(namesb.toString())).color(Color.Aqua) - .onmatch((match, builder) -> { - Player p = Bukkit.getPlayer(match); - Optional pn = nottest ? Optional.empty() - : Arrays.stream(testPlayers).filter(tp -> tp.equalsIgnoreCase(match)).findAny(); - if (nottest ? p == null : !pn.isPresent()) { - error.accept("Error: Can't find player " + match + " but was reported as online."); - return "§c" + match + "§r"; - } - ChatPlayer mpp = TBMCPlayer.getPlayer(nottest ? p.getUniqueId() : new UUID(0, 0), ChatPlayer.class); - if (nottest) { - if (PlayerListener.NotificationSound == null) - p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1.0f, 0.5f); // TODO: Airhorn - else - p.playSound(p.getLocation(), PlayerListener.NotificationSound, 1.0f, - (float) PlayerListener.NotificationPitch); - } - String color = String.format("§%x", (mpp.GetFlairColor() == 0x00 ? 0xb : mpp.GetFlairColor())); - return color + (nottest ? p.getName() : pn.get()) + "§r"; //Fix name casing, except when testing - }).priority(Priority.High).type(ChatFormatter.Type.Excluder).build()); - - if (addNickFormatter) - formatters.add(ChatFormatter.builder().regex((Pattern.compile(nicksb.toString()))).color(Color.Aqua) - .onmatch((match, builder) -> { - if (PlayerListener.nicknames.containsKey(match.toLowerCase())) { //Made a stream and all that but I can actually store it lowercased - Player p = Bukkit.getPlayer(PlayerListener.nicknames.get(match.toLowerCase())); - if (p == null) { - error.accept("Error: Can't find player nicknamed " - + match.toLowerCase() + " but was reported as online."); - return "§c" + match + "§r"; - } - if (PlayerListener.NotificationSound == null) - p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1.0f, 0.5f); - else - p.playSound(p.getLocation(), PlayerListener.NotificationSound, 1.0f, - (float) PlayerListener.NotificationPitch); - return PluginMain.essentials.getUser(p).getNickname(); - } - error.accept("Player nicknamed " + match.toLowerCase() - + " not found in nickname map but was reported as online."); - return "§c" + match + "§r"; - }).priority(Priority.High).type(ChatFormatter.Type.Excluder).build()); - } - return formatters; - } - - static void doFunStuff(CommandSender sender, TBMCChatEventBase event, String message) { - if (PlayerListener.ActiveF && !PlayerListener.Fs.contains(sender) && message.equalsIgnoreCase("F")) - PlayerListener.Fs.add(sender); - - String msg = message.toLowerCase(); - val lld = new UnlolCommand.LastlolData(sender, event, System.nanoTime()); - boolean add; - if (add = msg.contains("lol")) - lld.setLolornot(true); - else { - for (int i = 0; i < PlayerListener.LaughStrings.length; i++) { - if (add = msg.contains(PlayerListener.LaughStrings[i])) { - lld.setLolornot(false); - break; - } - } - } - if (add) - UnlolCommand.Lastlol.put(event.getChannel(), lld); - } -} +package buttondevteam.chat; + +import buttondevteam.chat.commands.UnlolCommand; +import buttondevteam.chat.commands.ucmds.admin.DebugCommand; +import buttondevteam.chat.formatting.ChatFormatter; +import buttondevteam.chat.formatting.TellrawEvent; +import buttondevteam.chat.formatting.TellrawPart; +import buttondevteam.chat.formatting.TellrawSerializer; +import buttondevteam.chat.listener.PlayerListener; +import buttondevteam.lib.TBMCChatEvent; +import buttondevteam.lib.TBMCChatEventBase; +import buttondevteam.lib.TBMCCoreAPI; +import buttondevteam.lib.chat.Channel; +import buttondevteam.lib.chat.Color; +import buttondevteam.lib.chat.Priority; +import buttondevteam.lib.chat.TellrawSerializableEnum; +import buttondevteam.lib.player.ChromaGamerBase; +import buttondevteam.lib.player.TBMCPlayer; +import buttondevteam.lib.player.TBMCPlayerBase; +import com.earth2me.essentials.User; +import com.google.common.collect.Lists; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import lombok.val; +import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.Objective; + +import javax.annotation.Nullable; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; +import java.util.regex.Pattern; + +public class ChatProcessing { + private static final Pattern NULL_MENTION_PATTERN = Pattern.compile("null"); + private static final Pattern CYAN_PATTERN = Pattern.compile("cyan"); + private static final Pattern ESCAPE_PATTERN = Pattern.compile("\\\\"); + private static final Pattern CONSOLE_PING_PATTERN = Pattern.compile("(?i)" + Pattern.quote("@console")); + private static final Pattern HASHTAG_PATTERN = Pattern.compile("#(\\w+)"); + private static final Pattern URL_PATTERN = Pattern.compile("(http[\\w:/?=$\\-_.+!*'(),&]+(?:#[\\w]+)?)"); + public static final Pattern ENTIRE_MESSAGE_PATTERN = Pattern.compile(".+"); + private static final Pattern UNDERLINED_PATTERN = Pattern.compile("_"); + private static final Pattern ITALIC_PATTERN = Pattern.compile("\\*"); + private static final Pattern BOLD_PATTERN = Pattern.compile("\\*\\*"); + private static final Pattern CODE_PATTERN = Pattern.compile("`"); + private static final Pattern MASKED_LINK_PATTERN = Pattern.compile("\\[([^\\[\\]])\\]\\(([^()])\\)"); + private static final Pattern SOMEONE_PATTERN = Pattern.compile("@someone"); //TODO + private static final Pattern STRIKETHROUGH_PATTERN = Pattern.compile("~~"); + private static final Color[] RainbowPresserColors = new Color[]{Color.Red, Color.Gold, Color.Yellow, Color.Green, + Color.Blue, Color.DarkPurple}; + private static boolean pingedconsole = false; + + public static final ChatFormatter ESCAPE_FORMATTER = ChatFormatter.builder().regex(ESCAPE_PATTERN).build(); + + private static ArrayList commonFormatters = Lists.newArrayList( + ChatFormatter.builder().regex(BOLD_PATTERN).bold(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range) + .priority(Priority.High).build(), + ChatFormatter.builder().regex(ITALIC_PATTERN).italic(true).removeCharCount((short) 1).type(ChatFormatter.Type.Range).build(), + ChatFormatter.builder().regex(UNDERLINED_PATTERN).underlined(true).removeCharCount((short) 1).type(ChatFormatter.Type.Range) + .build(), + ChatFormatter.builder().regex(STRIKETHROUGH_PATTERN).strikethrough(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range) + .build(), + ESCAPE_FORMATTER, ChatFormatter.builder().regex(URL_PATTERN).underlined(true).openlink("$1").type(ChatFormatter.Type.Excluder).build(), + ChatFormatter.builder().regex(NULL_MENTION_PATTERN).color(Color.DarkRed).build(), // Properly added a bug as a feature + ChatFormatter.builder().regex(CONSOLE_PING_PATTERN).color(Color.Aqua).onmatch((match, builder) -> { + if (!pingedconsole) { + System.out.print("\007"); + pingedconsole = true; // Will set it to false in ProcessChat + } + return match; + }).priority(Priority.High).build(), + + ChatFormatter.builder().regex(HASHTAG_PATTERN).color(Color.Blue).openlink("https://twitter.com/hashtag/$1") + .priority(Priority.High).build(), + ChatFormatter.builder().regex(CYAN_PATTERN).color(Color.Aqua).build(), // #55 + ChatFormatter.builder().regex(CODE_PATTERN).color(Color.DarkGray).removeCharCount((short) 1).type(ChatFormatter.Type.Range) + .build(), + ChatFormatter.builder().regex(MASKED_LINK_PATTERN).underlined(true).onmatch((match, builder) -> { + return match; // TODO! + }).build()); + private static Gson gson = new GsonBuilder() + .registerTypeHierarchyAdapter(TellrawSerializableEnum.class, new TellrawSerializer.TwEnum()) + .registerTypeHierarchyAdapter(Collection.class, new TellrawSerializer.TwCollection()) + .registerTypeAdapter(Boolean.class, new TellrawSerializer.TwBool()) + .registerTypeAdapter(boolean.class, new TellrawSerializer.TwBool()).disableHtmlEscaping().create(); + private static final String[] testPlayers = {"Koiiev", "iie", "Alisolarflare", "NorbiPeti", "Arsen_Derby_FTW", "carrot_lynx"}; + static final String MCORIGIN = "Minecraft"; //Shouldn't change, like ever - TBMCPlayer.getFolderForType(TBMCPlayer.class) capitalized + + private ChatProcessing() { + } + + public static boolean ProcessChat(TBMCChatEvent e) { + Channel channel = e.getChannel(); + CommandSender sender = e.getSender(); + String message = e.getMessage(); + long processstart = System.nanoTime(); + Player player = (sender instanceof Player ? (Player) sender : null); + User user = PluginMain.essentials.getUser(player); + + if (player != null) { + user.updateActivity(true); //Could talk in a private channel, so broadcast + if (user.isMuted()) + return true; + } + + doFunStuff(sender, e, message); + + ChatPlayer mp; + if (player != null) + mp = TBMCPlayerBase.getPlayer(player.getUniqueId(), ChatPlayer.class); + else //Due to the online player map, getPlayer() can be more efficient than getAs() + mp = e.getUser().getAs(ChatPlayer.class); //May be null + + Color colormode = channel.color; + if (mp != null && mp.OtherColorMode != null) + colormode = mp.OtherColorMode; + if (message.startsWith(">")) + colormode = Color.Green; + // If greentext, ignore channel or player colors + + ArrayList formatters = addFormatters(colormode); + if (colormode == channel.color && mp != null && mp.RainbowPresserColorMode) { // Only overwrite channel color + final AtomicInteger rpc = new AtomicInteger(0); + formatters.add(ChatFormatter.builder().color(colormode).onmatch((match, cf) -> { + cf.setColor(RainbowPresserColors[rpc.getAndUpdate(i -> ++i < RainbowPresserColors.length ? i : 0)]); + return match; + }).build()); + } + pingedconsole = false; // Will set it to true onmatch (static constructor) + final String channelidentifier = getChannelID(channel, sender, e.getOrigin()); + + TellrawPart json = createTellraw(sender, message, player, mp, e.getUser(), channelidentifier, e.getOrigin()); + long combinetime = System.nanoTime(); + ChatFormatter.Combine(formatters, message, json); + combinetime = System.nanoTime() - combinetime; + String jsonstr = toJson(json); + if (jsonstr.length() >= 32767) { + sender.sendMessage( + "§cError: Message too long. Try shortening it, or remove hashtags and other formatting."); + return true; + } + DebugCommand.SendDebugMessage(jsonstr); + + try { + if (!channel.isGlobal()) { + Objective obj = PluginMain.SB.getObjective(channel.ID); + int score = -1; + for (Player p : Bukkit.getOnlinePlayers()) { + final int mcScore; + if (player != null + && PluginMain.essentials.getUser(p).isIgnoredPlayer(PluginMain.essentials.getUser(player))) + mcScore = -1; // Don't send the message to them + else + mcScore = VanillaUtils.getMCScoreIfChatOn(p, e); + obj.getScore(p.getName()) + .setScore(p.getUniqueId().equals(player == null ? null : player.getUniqueId()) // p.UniqueID==player?.UniqueID + ? score = mcScore : mcScore); + } + if (score == -1) // Even if the player object isn't null, it may not be in OnlinePlayers + score = e.getMCScore(sender); + if (score < 0) // Never send messages to score below 0 + sender.sendMessage("§cYou don't have permission to send this message or something went wrong"); + else { + PluginMain.Instance.getServer().dispatchCommand(PluginMain.Console, + String.format("tellraw @a[score_%s=%d,score_%s_min=%d] %s", channel.ID, score, channel.ID, + score, jsonstr)); + if (e.getChannel().ID.equals(PluginMain.TownChat.ID) + || e.getChannel().ID.equals(PluginMain.NationChat.ID)) { + ((List) json.getExtra()).add(0, new TellrawPart("[SPY]")); + jsonstr = toJson(json); + Bukkit.getServer().dispatchCommand(PluginMain.Console, String.format( + "tellraw @a[score_%s=1000,score_%s_min=1000] %s", channel.ID, channel.ID, jsonstr)); + } + } + } else + PluginMain.Instance.getServer().dispatchCommand(PluginMain.Console, + String.format("tellraw @a %s", jsonstr)); + } catch (Exception ex) { + TBMCCoreAPI.SendException("An error occured while sending a chat message!", ex); + sender.sendMessage("§cAn error occured while sending the message."); + return true; + } + PluginMain.Instance.getServer().getConsoleSender() + .sendMessage(String.format("%s <%s§r> %s", channelidentifier, getSenderName(sender, player), message)); + DebugCommand.SendDebugMessage( + "-- Full ChatProcessing time: " + (System.nanoTime() - processstart) / 1000000f + " ms"); + DebugCommand.SendDebugMessage("-- ChatFormatter.Combine time: " + combinetime / 1000000f + " ms"); + return false; + } + + static String toJson(TellrawPart json) { + return gson.toJson(json); + } + + static TellrawPart createTellraw(CommandSender sender, String message, @Nullable Player player, + @Nullable ChatPlayer mp, @Nullable ChromaGamerBase cg, final String channelidentifier, + String origin) { + TellrawPart json = new TellrawPart(""); + if (mp != null && mp.ChatOnly) { + json.addExtra(new TellrawPart("[C]") + .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Chat only"))); + } + json.addExtra( + new TellrawPart(channelidentifier) + .setHoverEvent( + TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, + new TellrawPart((MCORIGIN.equals(origin) ? "" : "From " + origin + "n") + + "Copy message").setColor(Color.Blue))) + .setClickEvent(TellrawEvent.create(TellrawEvent.ClickAction.SUGGEST_COMMAND, message))); + if (PluginMain.permission.has(sender, "tbmc.badge.diamond")) + json.addExtra(new TellrawPart("[P]").setColor(Color.Aqua).setBold(true) + .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Diamond Patreon supporter"))); + else if (PluginMain.permission.has(sender, "tbmc.badge.gold")) + json.addExtra(new TellrawPart("[P]").setColor(Color.Gold).setBold(true) + .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Gold Patreon supporter"))); + json.addExtra(new TellrawPart(" <")); + TellrawPart hovertp = new TellrawPart(""); + if (cg != null) + hovertp.addExtra(new TellrawPart(cg.getInfo(ChromaGamerBase.InfoTarget.MCHover))); + json.addExtra(new TellrawPart(getSenderName(sender, player)) + .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, hovertp))); + json.addExtra(new TellrawPart("> ")); + return json; + } + + private static String getSenderName(CommandSender sender, Player player) { + if (player == null) + return sender.getName(); + return player.getDisplayName(); + } + + static String getChannelID(Channel channel, CommandSender sender, String origin) { + return ("[" + (MCORIGIN.equals(origin) ? "" : "§8" + origin.substring(0, 1) + "§r|") + channel.DisplayName) + + "]"; + } + + static ArrayList addFormatters(Color colormode) { + @SuppressWarnings("unchecked") + ArrayList formatters = (ArrayList) commonFormatters.clone(); + + formatters.add( + ChatFormatter.builder().regex(ENTIRE_MESSAGE_PATTERN).color(colormode).priority(Priority.Low).build()); + + boolean nottest; //Not assigning a default value, so that it can only be used in the if + if ((nottest = Bukkit.getOnlinePlayers().size() > 0) || Bukkit.getVersion().equals("test")) { + StringBuilder namesb = new StringBuilder("(?i)("); + if (nottest) + for (Player p : Bukkit.getOnlinePlayers()) + namesb.append(p.getName()).append("|"); + else + for (String testPlayer : testPlayers) + namesb.append(testPlayer).append("|"); + namesb.deleteCharAt(namesb.length() - 1); + namesb.append(")"); + StringBuilder nicksb = new StringBuilder("(?i)("); + boolean addNickFormatter = false; + int index = 0; + for (Player p : Bukkit.getOnlinePlayers()) { + final String nick = PlayerListener.nicknames.inverse().get(p.getUniqueId()); + if (nick != null) { + nicksb.append(nick).append("|"); + addNickFormatter = true; //Add it even if there's only 1 player online (it was in the if) + } + index++; + } + nicksb.deleteCharAt(nicksb.length() - 1); + nicksb.append(")"); + + Consumer error = message -> { + if (PluginMain.Instance != null) + PluginMain.Instance.getLogger().warning(message); + else + System.out.println(message); + }; + + formatters.add(ChatFormatter.builder().regex(Pattern.compile(namesb.toString())).color(Color.Aqua) + .onmatch((match, builder) -> { + Player p = Bukkit.getPlayer(match); + Optional pn = nottest ? Optional.empty() + : Arrays.stream(testPlayers).filter(tp -> tp.equalsIgnoreCase(match)).findAny(); + if (nottest ? p == null : !pn.isPresent()) { + error.accept("Error: Can't find player " + match + " but was reported as online."); + return "§c" + match + "§r"; + } + ChatPlayer mpp = TBMCPlayer.getPlayer(nottest ? p.getUniqueId() : new UUID(0, 0), ChatPlayer.class); + if (nottest) { + if (PlayerListener.NotificationSound == null) + p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1.0f, 0.5f); // TODO: Airhorn + else + p.playSound(p.getLocation(), PlayerListener.NotificationSound, 1.0f, + (float) PlayerListener.NotificationPitch); + } + String color = String.format("§%x", (mpp.GetFlairColor() == 0x00 ? 0xb : mpp.GetFlairColor())); + return color + (nottest ? p.getName() : pn.get()) + "§r"; //Fix name casing, except when testing + }).priority(Priority.High).type(ChatFormatter.Type.Excluder).build()); + + if (addNickFormatter) + formatters.add(ChatFormatter.builder().regex((Pattern.compile(nicksb.toString()))).color(Color.Aqua) + .onmatch((match, builder) -> { + if (PlayerListener.nicknames.containsKey(match.toLowerCase())) { //Made a stream and all that but I can actually store it lowercased + Player p = Bukkit.getPlayer(PlayerListener.nicknames.get(match.toLowerCase())); + if (p == null) { + error.accept("Error: Can't find player nicknamed " + + match.toLowerCase() + " but was reported as online."); + return "§c" + match + "§r"; + } + if (PlayerListener.NotificationSound == null) + p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1.0f, 0.5f); + else + p.playSound(p.getLocation(), PlayerListener.NotificationSound, 1.0f, + (float) PlayerListener.NotificationPitch); + return PluginMain.essentials.getUser(p).getNickname(); + } + error.accept("Player nicknamed " + match.toLowerCase() + + " not found in nickname map but was reported as online."); + return "§c" + match + "§r"; + }).priority(Priority.High).type(ChatFormatter.Type.Excluder).build()); + } + return formatters; + } + + static void doFunStuff(CommandSender sender, TBMCChatEventBase event, String message) { + if (PlayerListener.ActiveF && !PlayerListener.Fs.contains(sender) && message.equalsIgnoreCase("F")) + PlayerListener.Fs.add(sender); + + String msg = message.toLowerCase(); + val lld = new UnlolCommand.LastlolData(sender, event, System.nanoTime()); + boolean add; + if (add = msg.contains("lol")) + lld.setLolornot(true); + else { + for (int i = 0; i < PlayerListener.LaughStrings.length; i++) { + if (add = msg.contains(PlayerListener.LaughStrings[i])) { + lld.setLolornot(false); + break; + } + } + } + if (add) + UnlolCommand.Lastlol.put(event.getChannel(), lld); + } +} diff --git a/src/main/java/buttondevteam/chat/PluginMain.java b/src/main/java/buttondevteam/chat/PluginMain.java index 7ad1825..b02f678 100644 --- a/src/main/java/buttondevteam/chat/PluginMain.java +++ b/src/main/java/buttondevteam/chat/PluginMain.java @@ -2,6 +2,7 @@ package buttondevteam.chat; import buttondevteam.chat.commands.YeehawCommand; import buttondevteam.chat.commands.ucmds.TownColorCommand; +import buttondevteam.chat.listener.PlayerJoinLeaveListener; import buttondevteam.chat.listener.PlayerListener; import buttondevteam.chat.listener.TownyListener; import buttondevteam.lib.TBMCCoreAPI; @@ -81,6 +82,7 @@ public class PluginMain extends JavaPlugin { // Translated to Java: 2015.07.15. PluginMain.essentials = (Essentials) (Bukkit.getPluginManager().getPlugin("Essentials")); TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this); + TBMCCoreAPI.RegisterEventsForExceptions(new PlayerJoinLeaveListener(), this); TBMCCoreAPI.RegisterEventsForExceptions(new TownyListener(), this); TBMCChatAPI.AddCommands(this, YeehawCommand.class); Console = this.getServer().getConsoleSender(); diff --git a/src/main/java/buttondevteam/chat/commands/ucmds/HistoryCommand.java b/src/main/java/buttondevteam/chat/commands/ucmds/HistoryCommand.java new file mode 100644 index 0000000..e39600a --- /dev/null +++ b/src/main/java/buttondevteam/chat/commands/ucmds/HistoryCommand.java @@ -0,0 +1,83 @@ +package buttondevteam.chat.commands.ucmds; + +import buttondevteam.lib.chat.Channel; +import buttondevteam.lib.chat.ChatMessage; +import buttondevteam.lib.chat.CommandClass; +import lombok.RequiredArgsConstructor; +import lombok.experimental.var; +import lombok.val; +import org.bukkit.command.CommandSender; + +import javax.annotation.Nullable; +import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Function; +import java.util.stream.Stream; + +@CommandClass +public class HistoryCommand extends UCommandBase { + /** + * Key: ChannelID_groupID + */ + private static HashMap> messages = new HashMap<>(); + + @Override + public String[] GetHelpText(String alias) { + return new String[]{ // + "§6--- Chat History ----", // + "Returns the last 10 messages the player can see." // + }; + } + + @Override + public boolean OnCommand(CommandSender sender, String alias, String[] args) { + return showHistory(sender, alias, args, this); + } + + public static boolean showHistory(CommandSender sender, String alias, String[] args, @Nullable HistoryCommand hc) { + Function> getThem = ch -> messages.get(ch.ID + "_" + ch.getGroupID(sender)); //If can't see, groupID is null, and that shouldn't be in the map + sender.sendMessage("§6---- Chat History ----"); + Stream stream; + if (args.length == 0) { + stream = Channel.getChannels().stream(); + } else { + Optional och = Channel.getChannels().stream().filter(chan -> chan.ID.equalsIgnoreCase(args[0])).findAny(); + if (!och.isPresent()) { + sender.sendMessage("§cChannel not found. Use the ID, for example: /" + (hc == null ? "u history" : hc.GetCommandPath()) + " ooc"); + return true; + } + stream = Stream.of(och.get()); + } + AtomicBoolean sent = new AtomicBoolean(); + val arr = stream.map(getThem).filter(Objects::nonNull).flatMap(Collection::stream) + .sorted(Comparator.comparingLong(he -> he.timestamp)).toArray(HistoryEntry[]::new); + for (int i = Math.max(0, arr.length - 10); i < arr.length; i++) { + HistoryEntry e = arr[i]; + val cm = e.chatMessage; + sender.sendMessage("[" + e.channel.DisplayName + "] " + cm.getSender().getName() + ": " + cm.getMessage()); + sent.set(true); + } + if (!sent.get()) + sender.sendMessage("No messages can be found."); + return true; + } + + @RequiredArgsConstructor + private static class HistoryEntry { + /** + * System.nanoTime() + */ + private final long timestamp; + private final ChatMessage chatMessage; + private final Channel channel; + } + + public static void addChatMessage(ChatMessage chatMessage, Channel channel) { + val groupID = channel.getGroupID(chatMessage.getPermCheck()); + if (groupID == null) return; //Just to be sure + var ll = messages.computeIfAbsent(channel.ID + "_" + groupID, k -> new LinkedList<>()); //<-- TIL + ll.add(new HistoryEntry(System.nanoTime(), chatMessage, channel)); //Adds as last element + while (ll.size() > 10) + ll.remove(); //Removes the first element + } +} diff --git a/src/main/java/buttondevteam/chat/commands/ucmds/NColorCommand.java b/src/main/java/buttondevteam/chat/commands/ucmds/NColorCommand.java index 9ac3cff..88403b1 100644 --- a/src/main/java/buttondevteam/chat/commands/ucmds/NColorCommand.java +++ b/src/main/java/buttondevteam/chat/commands/ucmds/NColorCommand.java @@ -58,16 +58,16 @@ public class NColorCommand extends UCommandBase { player.sendMessage("§cYour town doesn't have a color set. The town mayor can set it using /u towncolor."); return true; } - if (nameparts.length < towncolors.length) { - player.sendMessage("§cYou need more vertical lines (|) or colons (:) in your name. (Should have " + (towncolors.length - 1) + ")"); + if (nameparts.length < towncolors.length + 1) { //+1: Nation color + player.sendMessage("§cYou need more vertical lines (|) or colons (:) in your name. (Should have " + (towncolors.length - 1 + 1) + ")"); //Nation color return true; } - if (nameparts.length > towncolors.length * 2) { - player.sendMessage("§cYou have waay too many vertical lines (|) or colons (:) in your name. (Should have " + (towncolors.length - 1) + ")"); + if (nameparts.length > (towncolors.length + 1) * 2) { + player.sendMessage("§cYou have waay too many vertical lines (|) or colons (:) in your name. (Should have " + (towncolors.length - 1 + 1) + ")"); return true; } - if (nameparts.length > towncolors.length) { - player.sendMessage("§cYou have too many vertical lines (|) or colons (:) in your name. (Should have " + (towncolors.length - 1) + ")"); + if (nameparts.length > towncolors.length + 1) { + player.sendMessage("§cYou have too many vertical lines (|) or colons (:) in your name. (Should have " + (towncolors.length - 1 + 1) + ")"); return true; } ChatPlayer.getPlayer(player.getUniqueId(), ChatPlayer.class).NameColorLocations() diff --git a/src/main/java/buttondevteam/chat/commands/ucmds/admin/NationColorCommand.java b/src/main/java/buttondevteam/chat/commands/ucmds/admin/NationColorCommand.java index 60564c5..ddc8e5b 100644 --- a/src/main/java/buttondevteam/chat/commands/ucmds/admin/NationColorCommand.java +++ b/src/main/java/buttondevteam/chat/commands/ucmds/admin/NationColorCommand.java @@ -2,6 +2,7 @@ package buttondevteam.chat.commands.ucmds.admin; import buttondevteam.chat.PluginMain; import buttondevteam.chat.listener.TownyListener; +import buttondevteam.lib.chat.Color; import com.palmergames.bukkit.towny.object.Nation; import com.palmergames.bukkit.towny.object.Town; import lombok.val; @@ -37,6 +38,14 @@ public class NationColorCommand extends AdminCommandBase { } val c = TownColorCommand.getColorOrSendError(args[1], sender); if (!c.isPresent()) return true; + if (!c.get().getName().equals(Color.White.getName())) { //Default nation color + for (val nc : PluginMain.NationColor.values()) { + if (nc.getName().equals(c.get().getName())) { + sender.sendMessage("§cAnother nation already uses this color!"); + return true; + } + } + } PluginMain.NationColor.put(args[0].toLowerCase(), c.get()); Bukkit.getScheduler().runTaskAsynchronously(PluginMain.Instance, () -> { for (Town t : nation.getTowns()) diff --git a/src/main/java/buttondevteam/chat/commands/ucmds/admin/TownColorCommand.java b/src/main/java/buttondevteam/chat/commands/ucmds/admin/TownColorCommand.java index e1cd357..97224ad 100644 --- a/src/main/java/buttondevteam/chat/commands/ucmds/admin/TownColorCommand.java +++ b/src/main/java/buttondevteam/chat/commands/ucmds/admin/TownColorCommand.java @@ -10,6 +10,7 @@ import org.bukkit.command.CommandSender; import org.dynmap.towny.DynmapTownyPlugin; import java.util.Arrays; +import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; @@ -46,6 +47,33 @@ public class TownColorCommand extends AdminCommandBase { return true; clrs[i - 1] = c.get(); } + for (Map.Entry other : PluginMain.TownColors.entrySet()) { + Color nc, tnc; + try { + nc = PluginMain.NationColor.get(PluginMain.TU.getTownsMap().get(other.getKey()).getNation().getName().toLowerCase()); + } catch (Exception e) { //Too lazy for lots of null-checks and it may throw exceptions anyways + nc = null; + } + if (nc == null) nc = Color.White; //Default nation color + try { + tnc = PluginMain.NationColor.get(targetTown.getNation().getName().toLowerCase()); + } catch (Exception e) { + tnc = null; + } + if (tnc == null) tnc = Color.White; //Default nation color - TODO: Make configurable + if (nc.getName().equals(tnc.getName())) { + int C = 0; + if (clrs.length == other.getValue().length) + for (int i = 0; i < clrs.length; i++) + if (clrs[i].getName().equals(other.getValue()[i].getName())) + C++; + else break; + if (C == clrs.length) { + sender.sendMessage("§cThis town color combination is already used!"); + return true; + } + } + } PluginMain.TownColors.put(args[0].toLowerCase(), clrs); TownyListener.updateTownMembers(targetTown); diff --git a/src/main/java/buttondevteam/chat/commands/ucmds/admin/UpdatePlugin.java b/src/main/java/buttondevteam/chat/commands/ucmds/admin/UpdatePlugin.java index b60690e..be6f274 100644 --- a/src/main/java/buttondevteam/chat/commands/ucmds/admin/UpdatePlugin.java +++ b/src/main/java/buttondevteam/chat/commands/ucmds/admin/UpdatePlugin.java @@ -1,12 +1,11 @@ package buttondevteam.chat.commands.ucmds.admin; +import buttondevteam.chat.PluginMain; +import buttondevteam.component.updater.PluginUpdater; +import buttondevteam.lib.TBMCCoreAPI; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; -import buttondevteam.chat.PluginMain; -import buttondevteam.lib.PluginUpdater; -import buttondevteam.lib.TBMCCoreAPI; - public class UpdatePlugin extends AdminCommandBase { @Override diff --git a/src/main/java/buttondevteam/chat/components/TownColorComponent.java b/src/main/java/buttondevteam/chat/components/TownColorComponent.java new file mode 100644 index 0000000..b731ea7 --- /dev/null +++ b/src/main/java/buttondevteam/chat/components/TownColorComponent.java @@ -0,0 +1,24 @@ +package buttondevteam.chat.components; + +import buttondevteam.lib.architecture.Component; +import buttondevteam.lib.architecture.ConfigData; + +public class TownColorComponent extends Component { + public ConfigData colorCount() { //TODO + return getData("colorCount", (byte) 1, cc -> (byte) cc, cc -> (int) cc); + } + + public ConfigData useNationColors() { //TODO + return getData("useNationColors", true); + } + + @Override + protected void enable() { + //TODO: Don't register all commands automatically (welp) + } + + @Override + protected void disable() { + + } +} diff --git a/src/main/java/buttondevteam/chat/listener/PlayerJoinLeaveListener.java b/src/main/java/buttondevteam/chat/listener/PlayerJoinLeaveListener.java index 0c57e7c..3a49a4a 100644 --- a/src/main/java/buttondevteam/chat/listener/PlayerJoinLeaveListener.java +++ b/src/main/java/buttondevteam/chat/listener/PlayerJoinLeaveListener.java @@ -5,6 +5,7 @@ import buttondevteam.chat.FlairStates; import buttondevteam.chat.PlayerJoinTimerTask; import buttondevteam.chat.PluginMain; import buttondevteam.chat.commands.UnlolCommand; +import buttondevteam.chat.commands.ucmds.HistoryCommand; import buttondevteam.lib.chat.Color; import buttondevteam.lib.player.TBMCPlayerJoinEvent; import buttondevteam.lib.player.TBMCPlayerLoadEvent; @@ -64,14 +65,14 @@ public class PlayerJoinLeaveListener implements Listener { nwithoutformatting = p.getName(); PlayerListener.nicknames.forcePut(nwithoutformatting.toLowerCase(), p.getUniqueId()); - Bukkit.getScheduler().runTaskLater(PluginMain.Instance, () -> { - updatePlayerColors(p, cp); //TODO: Doesn't have effect - }, 5); + updatePlayerColors(p, cp); //TO!DO: Doesn't have effect - It can help to register the listener if (cp.ChatOnly || p.getGameMode().equals(GameMode.SPECTATOR)) { cp.ChatOnly = false; p.setGameMode(GameMode.SURVIVAL); } + + HistoryCommand.showHistory(e.getPlayer(), "u history", new String[0], null); } @EventHandler diff --git a/src/main/java/buttondevteam/chat/listener/PlayerListener.java b/src/main/java/buttondevteam/chat/listener/PlayerListener.java index 4997347..fd8dfb5 100644 --- a/src/main/java/buttondevteam/chat/listener/PlayerListener.java +++ b/src/main/java/buttondevteam/chat/listener/PlayerListener.java @@ -3,6 +3,7 @@ package buttondevteam.chat.listener; import buttondevteam.chat.ChatPlayer; import buttondevteam.chat.ChatProcessing; import buttondevteam.chat.PluginMain; +import buttondevteam.chat.commands.ucmds.HistoryCommand; import buttondevteam.lib.TBMCChatEvent; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.chat.*; @@ -258,6 +259,7 @@ public class PlayerListener implements Listener { try { if (e.isCancelled()) return; + HistoryCommand.addChatMessage(e.getCm(), e.getChannel()); e.setCancelled(ChatProcessing.ProcessChat(e)); } catch (NoClassDefFoundError | Exception ex) { // Weird things can happen for (Player p : Bukkit.getOnlinePlayers()) @@ -272,7 +274,7 @@ public class PlayerListener implements Listener { @EventHandler public void onChannelRegistered(ChatChannelRegisterEvent e) { - if (e.getChannel().filteranderrormsg != null && PluginMain.SB.getObjective(e.getChannel().ID) == null) // Not global chat and doesn't exist yet + if (!e.getChannel().isGlobal() && PluginMain.SB.getObjective(e.getChannel().ID) == null) // Not global chat and doesn't exist yet PluginMain.SB.registerNewObjective(e.getChannel().ID, "dummy"); } diff --git a/src/test/java/buttondevteam/chat/ChatFormatIT.java b/src/test/java/buttondevteam/chat/ChatFormatIT.java index a1831cd..bb508cc 100644 --- a/src/test/java/buttondevteam/chat/ChatFormatIT.java +++ b/src/test/java/buttondevteam/chat/ChatFormatIT.java @@ -65,6 +65,11 @@ public class ChatFormatIT { .setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://norbipeti.github.io/")), new TellrawPart(" heh").setItalic(true))); list.add(new ChatFormatIT(sender, "*test _test_ test*", new TellrawPart("test ").setItalic(true).setColor(Color.White), new TellrawPart("test").setItalic(true).setUnderlined(true).setColor(Color.White), new TellrawPart(" test").setItalic(true).setColor(Color.White))); + list.add(new ChatFormatIT(sender, "https://norbipeti.github.io/test?test&test#test", new TellrawPart("https://norbipeti.github.io/test?test&test#test") + .setColor(Color.White).setUnderlined(true) + .setHoverEvent(TellrawEvent.create(HoverAction.SHOW_TEXT, + new TellrawPart("Click to open").setColor(Color.Blue))) + .setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://norbipeti.github.io/test?test&test#test")))); return list; } @@ -82,12 +87,12 @@ public class ChatFormatIT { @Test public void testMessage() { ArrayList cfs = ChatProcessing.addFormatters(Color.White); - final String chid = ChatProcessing.getChannelID(Channel.GlobalChat, sender); - final TellrawPart tp = ChatProcessing.createTellraw(sender, message, null, null, null, chid); + final String chid = ChatProcessing.getChannelID(Channel.GlobalChat, sender, ChatProcessing.MCORIGIN); + final TellrawPart tp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatProcessing.MCORIGIN); ChatFormatter.Combine(cfs, message, tp); System.out.println("Testing: " + message); // System.out.println(ChatProcessing.toJson(tp)); - final TellrawPart expectedtp = ChatProcessing.createTellraw(sender, message, null, null, null, chid); + final TellrawPart expectedtp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatProcessing.MCORIGIN); // System.out.println("Raw: " + ChatProcessing.toJson(expectedtp)); for (TellrawPart extra : extras) expectedtp.addExtra(extra);