From 049ad551689ac56e19be3713c95d60dfe659b3a9 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 16 Mar 2019 14:33:03 +0100 Subject: [PATCH 01/20] Town/nation color fixes, reload command --- .../java/buttondevteam/chat/PluginMain.java | 2 ++ .../chat/commands/ucmds/ReloadCommand.java | 20 +++++++++++++++++++ .../towncolors/TownColorComponent.java | 1 + .../towncolors/admin/NationColorCommand.java | 2 +- .../towncolors/admin/TownColorCommand.java | 2 +- 5 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 src/main/java/buttondevteam/chat/commands/ucmds/ReloadCommand.java diff --git a/src/main/java/buttondevteam/chat/PluginMain.java b/src/main/java/buttondevteam/chat/PluginMain.java index ad7efb5..f35261b 100644 --- a/src/main/java/buttondevteam/chat/PluginMain.java +++ b/src/main/java/buttondevteam/chat/PluginMain.java @@ -4,6 +4,7 @@ import buttondevteam.chat.commands.MWikiCommand; import buttondevteam.chat.commands.ucmds.HelpCommand; import buttondevteam.chat.commands.ucmds.HistoryCommand; import buttondevteam.chat.commands.ucmds.InfoCommand; +import buttondevteam.chat.commands.ucmds.ReloadCommand; import buttondevteam.chat.commands.ucmds.admin.DebugCommand; import buttondevteam.chat.components.announce.AnnouncerComponent; import buttondevteam.chat.components.appendext.AppendTextComponent; @@ -77,6 +78,7 @@ public class PluginMain extends ButtonPlugin { // Translated to Java: 2015.07.15 getCommand2MC().registerCommand(new HistoryCommand()); getCommand2MC().registerCommand(new InfoCommand()); getCommand2MC().registerCommand(new MWikiCommand()); + getCommand2MC().registerCommand(new ReloadCommand()); } public static Essentials essentials = null; diff --git a/src/main/java/buttondevteam/chat/commands/ucmds/ReloadCommand.java b/src/main/java/buttondevteam/chat/commands/ucmds/ReloadCommand.java new file mode 100644 index 0000000..e5b5ef4 --- /dev/null +++ b/src/main/java/buttondevteam/chat/commands/ucmds/ReloadCommand.java @@ -0,0 +1,20 @@ +package buttondevteam.chat.commands.ucmds; + +import buttondevteam.chat.PluginMain; +import buttondevteam.lib.chat.Command2; +import buttondevteam.lib.chat.CommandClass; +import org.bukkit.command.CommandSender; + +@CommandClass(helpText = { + "Reload", + "Reloads Thorpe-Chat" +}, modOnly = true) +public class ReloadCommand extends UCommandBase { + @Command2.Subcommand + public void def(CommandSender sender) { + if (PluginMain.Instance.tryReloadConfig()) + sender.sendMessage("§bReloaded config"); + else + sender.sendMessage("§cFailed to reload config."); + } +} diff --git a/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java b/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java index ab41374..00c92ac 100644 --- a/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java +++ b/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java @@ -113,6 +113,7 @@ public class TownColorComponent extends Component implements Listene if (useNationColors().get()) registerCommand(new buttondevteam.chat.components.towncolors.admin.NationColorCommand()); registerCommand(new TCCount()); + registerCommand(new NColorCommand()); registerListener(new TownyListener()); registerListener(this); } diff --git a/src/main/java/buttondevteam/chat/components/towncolors/admin/NationColorCommand.java b/src/main/java/buttondevteam/chat/components/towncolors/admin/NationColorCommand.java index 963cb05..77bba40 100644 --- a/src/main/java/buttondevteam/chat/components/towncolors/admin/NationColorCommand.java +++ b/src/main/java/buttondevteam/chat/components/towncolors/admin/NationColorCommand.java @@ -35,7 +35,7 @@ public class NationColorCommand extends AdminCommandBase { if (!c.get().getName().equals(Color.White.getName())) { //Default nation color for (val e : TownColorComponent.NationColor.entrySet()) { if (e.getValue().getName().equals(c.get().getName())) { - sender.sendMessage("§The nation " + e.getKey() + " already uses this color!"); + sender.sendMessage("§cThe nation " + e.getKey() + " already uses this color!"); return true; } } diff --git a/src/main/java/buttondevteam/chat/components/towncolors/admin/TownColorCommand.java b/src/main/java/buttondevteam/chat/components/towncolors/admin/TownColorCommand.java index 618ef06..288447e 100644 --- a/src/main/java/buttondevteam/chat/components/towncolors/admin/TownColorCommand.java +++ b/src/main/java/buttondevteam/chat/components/towncolors/admin/TownColorCommand.java @@ -41,7 +41,7 @@ public class TownColorCommand extends AdminCommandBase { //TODO: Command path al val c = getColorOrSendError(colors[i], sender); if (!c.isPresent()) return true; - clrs[i - 1] = c.get(); + clrs[i] = c.get(); } Color tnc; boolean usenc = TownColorComponent.getComponent().useNationColors().get(); From 8907d5308f808a5af7fcf70950addcef125c1d9d Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sun, 30 Jun 2019 22:04:33 +0200 Subject: [PATCH 02/20] 1.14 prep & chat formatter organizing (1.14 prep is older code) --- .../buttondevteam/chat/ChatProcessing.java | 7 +- .../java/buttondevteam/chat/ChatUtils.java | 20 ++ .../chat/formatting/ChatFormatter.java | 328 +++++++++--------- 3 files changed, 180 insertions(+), 175 deletions(-) create mode 100644 src/main/java/buttondevteam/chat/ChatUtils.java diff --git a/src/main/java/buttondevteam/chat/ChatProcessing.java b/src/main/java/buttondevteam/chat/ChatProcessing.java index 6028b8a..3b4c3de 100644 --- a/src/main/java/buttondevteam/chat/ChatProcessing.java +++ b/src/main/java/buttondevteam/chat/ChatProcessing.java @@ -178,15 +178,14 @@ public class ChatProcessing { 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, + ChatUtils.dispatchConsoleCommand( String.format("tellraw @a[score_%s=%d,score_%s_min=%d] %s", channel.ID, score, channel.ID, - score, jsonstr)); + score, jsonstr), true); val tc = ComponentManager.getIfEnabled(TownyComponent.class); if (tc != null) tc.handleSpies(channel, json, ChatProcessing::toJson); } } else - PluginMain.Instance.getServer().dispatchCommand(PluginMain.Console, - String.format("tellraw @a %s", jsonstr)); + ChatUtils.dispatchConsoleCommand(String.format("tellraw @a %s", jsonstr), true); } catch (Exception ex) { TBMCCoreAPI.SendException("An error occured while sending a chat message!", ex); sender.sendMessage("§cAn error occured while sending the message."); diff --git a/src/main/java/buttondevteam/chat/ChatUtils.java b/src/main/java/buttondevteam/chat/ChatUtils.java new file mode 100644 index 0000000..247c2e2 --- /dev/null +++ b/src/main/java/buttondevteam/chat/ChatUtils.java @@ -0,0 +1,20 @@ +package buttondevteam.chat; + +import org.bukkit.Bukkit; + +public final class ChatUtils { + private ChatUtils() {} + + /** + * Dispatch a console command. + * + * @param command The command + * @param async Whether the caller is async + */ + public static void dispatchConsoleCommand(String command, boolean async) { + if (async) + Bukkit.getScheduler().runTask(PluginMain.Instance, () -> Bukkit.dispatchCommand(PluginMain.Console, command)); + else + Bukkit.dispatchCommand(PluginMain.Console, command); + } +} diff --git a/src/main/java/buttondevteam/chat/formatting/ChatFormatter.java b/src/main/java/buttondevteam/chat/formatting/ChatFormatter.java index aa7eb96..8c2d03e 100644 --- a/src/main/java/buttondevteam/chat/formatting/ChatFormatter.java +++ b/src/main/java/buttondevteam/chat/formatting/ChatFormatter.java @@ -18,9 +18,8 @@ import java.util.stream.Collectors; * A {@link ChatFormatter} shows what formatting to use based on regular expressions. {@link ChatFormatter#Combine(List, String, TellrawPart)} is used to turn it into a {@link TellrawPart}, combining * intersecting parts found, for example when {@code _abc*def*ghi_} is said in chat, it'll turn it into an underlined part, then an underlined and italics part, finally an underlined part * again. - * - * @author NorbiPeti * + * @author NorbiPeti */ @Data @Builder @@ -39,20 +38,20 @@ public final class ChatFormatter { @Builder.Default short removeCharCount = 0; @Builder.Default - Type type = Type.Normal; + Type type = Type.Normal; String hoverText; public enum Type { - Normal, - /** - * Matches a start and an end section which gets converted to one section (for example see italics) - */ - Range, - /** - * Exclude matching area from further processing (besides this formatter) - */ - Excluder - } + Normal, + /** + * Matches a start and an end section which gets converted to one section (for example see italics) + */ + Range, + /** + * Exclude matching area from further processing (besides this formatter) + */ + Excluder + } @FunctionalInterface public interface TriFunc { @@ -62,95 +61,82 @@ public final class ChatFormatter { public static void Combine(List formatters, String str, TellrawPart tp) { /* * This method assumes that there is always a global formatter - */ - header("ChatFormatter.Combine begin"); - ArrayList sections = new ArrayList(); + */ + header("ChatFormatter.Combine begin"); + ArrayList sections = new ArrayList<>(); - for (ChatFormatter formatter : formatters) { - if (formatter.type != Type.Excluder) - continue; - Matcher matcher = formatter.regex.matcher(str); - while (matcher.find()) { - DebugCommand.SendDebugMessage("Found match from " + matcher.start() + " to " + (matcher.end() - 1)); - DebugCommand.SendDebugMessage("With excluder formatter:" + formatter); - sendMessageWithPointer(str, matcher.start(), matcher.end() - 1); - if (formatter.regex != ChatProcessing.ENTIRE_MESSAGE_PATTERN && sections.stream().anyMatch(fs -> fs.type == Type.Excluder && (fs.End >= matcher.start() && fs.Start <= matcher.end() - 1))) { - DebugCommand.SendDebugMessage("Ignoring formatter because of an excluder"); - continue; //Exclude areas matched by excluders - Range sections are correctly handled afterwards - } - ArrayList groups = new ArrayList(); - for (int i = 0; i < matcher.groupCount(); i++) - groups.add(matcher.group(i + 1)); - if (groups.size() > 0) - DebugCommand.SendDebugMessage("First group: " + groups.get(0)); - FormattedSection section = new FormattedSection(formatter, matcher.start(), matcher.end() - 1, groups, - formatter.type); - sections.add(section); - } - } + createSections(formatters, str, sections, true); - header("Section creation (excluders done)"); - for (ChatFormatter formatter : formatters) { - if (formatter.type == Type.Excluder) - continue; - Matcher matcher = formatter.regex.matcher(str); - while (matcher.find()) { - DebugCommand.SendDebugMessage("Found match from " + matcher.start() + " to " + (matcher.end() - 1)); - DebugCommand.SendDebugMessage("With formatter:" + formatter); - sendMessageWithPointer(str, matcher.start(), matcher.end() - 1); - if (formatter.regex != ChatProcessing.ENTIRE_MESSAGE_PATTERN && sections.stream().anyMatch(fs -> fs.type == Type.Excluder && (fs.End >= matcher.start() && fs.Start <= matcher.end() - 1))) { - DebugCommand.SendDebugMessage("Ignoring formatter because of an excluder"); - continue; //Exclude areas matched by excluders - Range sections are correctly handled afterwards - } - ArrayList groups = new ArrayList(); - for (int i = 0; i < matcher.groupCount(); i++) - groups.add(matcher.group(i + 1)); - if (groups.size() > 0) - DebugCommand.SendDebugMessage("First group: " + groups.get(0)); - FormattedSection section = new FormattedSection(formatter, matcher.start(), matcher.end() - 1, groups, - formatter.type); - sections.add(section); - } - } - sections.sort( - (s1, s2) -> s1.Start == s2.Start - ? s1.End == s2.End ? Integer.compare(s2.Formatters.get(0).priority.GetValue(), - s1.Formatters.get(0).priority.GetValue()) : Integer.compare(s2.End, s1.End) - : Integer.compare(s1.Start, s2.Start)); + header("Section creation (excluders done)"); + createSections(formatters, str, sections, false); + sortSections(sections); - /** + /* * 0: Start - 1: End index */ val remchars = new ArrayList(); header("Range section conversion"); + sections = convertRangeSections(str, sections, remchars); + + header("Adding remove chars (RC)"); // Important to add after the range section conversion + addRemChars(sections, remchars); + + header("Section combining"); + combineSections(str, sections); + + header("Section applying"); + applySections(str, tp, sections, remchars); + header("ChatFormatter.Combine done"); + } + + private static void createSections(List formatters, String str, ArrayList sections, + boolean excluders) { + for (ChatFormatter formatter : formatters) { + if (excluders == (formatter.type != Type.Excluder)) + continue; //If we're looking at excluders and this isn't one, skip - or vica-versa + Matcher matcher = formatter.regex.matcher(str); + while (matcher.find()) { + DebugCommand.SendDebugMessage("Found match from " + matcher.start() + " to " + (matcher.end() - 1)); + DebugCommand.SendDebugMessage("With " + (excluders ? "excluder " : "") + "formatter: " + formatter); + sendMessageWithPointer(str, matcher.start(), matcher.end() - 1); + if (formatter.regex != ChatProcessing.ENTIRE_MESSAGE_PATTERN && sections.stream().anyMatch(fs -> fs.type == Type.Excluder && (fs.End >= matcher.start() && fs.Start <= matcher.end() - 1))) { + DebugCommand.SendDebugMessage("Ignoring formatter because of an excluder"); + continue; //Exclude areas matched by excluders - Range sections are correctly handled afterwards + } + ArrayList groups = new ArrayList<>(); + for (int i = 0; i < matcher.groupCount(); i++) + groups.add(matcher.group(i + 1)); + if (groups.size() > 0) + DebugCommand.SendDebugMessage("First group: " + groups.get(0)); + FormattedSection section = new FormattedSection(formatter, matcher.start(), matcher.end() - 1, groups, + formatter.type); + sections.add(section); + } + } + } + + private static ArrayList convertRangeSections(String str, ArrayList sections, ArrayList remchars) { ArrayList combined = new ArrayList<>(); Map nextSection = new HashMap<>(); boolean escaped = false; int takenStart = -1, takenEnd = -1; ChatFormatter takenFormatter = null; - for (int i = 0; i < sections.size(); i++) { + for (final FormattedSection section : sections) { // Set ending to -1 until closed with another 1 long "section" - only do this if IsRange is true - final FormattedSection section = sections.get(i); - if (section.type!=Type.Range) { + if (section.type != Type.Range) { escaped = section.Formatters.contains(ChatProcessing.ESCAPE_FORMATTER) && !escaped; // Enable escaping on first \, disable on second - if (escaped) {// Don't add the escape character + if (escaped) {// Don't add the escape character remchars.add(new int[]{section.Start, section.Start}); - DebugCommand.SendDebugMessage("Found escaper section: " + section); - } else { - combined.add(section); // The above will delete the \ - DebugCommand.SendDebugMessage("Added section: " + section); - } + DebugCommand.SendDebugMessage("Found escaper section: " + section); + } else { + combined.add(section); // The above will delete the \ + DebugCommand.SendDebugMessage("Added section: " + section); + } sendMessageWithPointer(str, section.Start, section.End); continue; - } - if (!escaped) { - if (combined.stream().anyMatch(s -> section.type != Type.Range && (s.Start == section.Start - || (s.Start < section.Start ? s.End >= section.Start : s.Start <= section.End)))) { - DebugCommand.SendDebugMessage("Range " + section + " overlaps with a combined section, ignoring."); - sendMessageWithPointer(str, section.Start, section.End); - continue; - } + } + if (!escaped) { if (section.Start == takenStart || (section.Start > takenStart && section.Start < takenEnd)) { /* * if (nextSection.containsKey(section.Formatters.get(0)) ? section.RemCharFromStart <= takenEnd - takenStart : section.RemCharFromStart > takenEnd - takenStart) { @@ -183,7 +169,7 @@ public final class ChatFormatter { nextSection.put(section.Formatters.get(0), section); } DebugCommand - .SendDebugMessage("New area taken: (" + takenStart + "-" + takenEnd + ") " + takenFormatter); + .SendDebugMessage("New area taken: (" + takenStart + "-" + takenEnd + ") " + takenFormatter); sendMessageWithPointer(str, takenStart, takenEnd); } else { DebugCommand.SendDebugMessage("Skipping section: " + section); // This will keep the text (character) @@ -193,24 +179,27 @@ public final class ChatFormatter { } //Do not finish unfinished sections, ignore them sections = combined; + return sections; + } - header("Adding remove chars (RC)"); // Important to add after the range section conversion + private static void addRemChars(ArrayList sections, ArrayList remchars) { sections.stream() - .flatMap(fs -> fs.Formatters.stream().filter(cf -> cf.removeCharCount > 0) - .mapToInt(cf -> cf.removeCharCount).mapToObj(rcc -> new int[]{fs.Start, fs.Start + rcc - 1})) - .forEach(rc -> remchars.add(rc)); + .flatMap(fs -> fs.Formatters.stream().filter(cf -> cf.removeCharCount > 0) + .mapToInt(cf -> cf.removeCharCount).mapToObj(rcc -> new int[]{fs.Start, fs.Start + rcc - 1})) + .forEach(remchars::add); sections.stream() - .flatMap(fs -> fs.Formatters.stream().filter(cf -> cf.removeCharCount > 0) - .mapToInt(cf -> cf.removeCharCount).mapToObj(rcc -> new int[]{fs.End - rcc + 1, fs.End})) - .forEach(rc -> remchars.add(rc)); + .flatMap(fs -> fs.Formatters.stream().filter(cf -> cf.removeCharCount > 0) + .mapToInt(cf -> cf.removeCharCount).mapToObj(rcc -> new int[]{fs.End - rcc + 1, fs.End})) + .forEach(remchars::add); DebugCommand.SendDebugMessage("Added remchars:"); DebugCommand - .SendDebugMessage(remchars.stream().map(rc -> Arrays.toString(rc)).collect(Collectors.joining("; "))); + .SendDebugMessage(remchars.stream().map(Arrays::toString).collect(Collectors.joining("; "))); + } - header("Section combining"); + private static void combineSections(String str, ArrayList sections) { boolean cont = true; boolean found = false; - for (int i = 1; cont;) { + for (int i = 1; cont; ) { int nextindex = i + 1; if (sections.size() < 2) break; @@ -218,47 +207,40 @@ public final class ChatFormatter { FormattedSection firstSection = sections.get(i - 1); DebugCommand.SendDebugMessage("Combining sections " + firstSection); sendMessageWithPointer(str, firstSection.Start, firstSection.End); - DebugCommand.SendDebugMessage(" and " + sections.get(i)); - sendMessageWithPointer(str, sections.get(i).Start, sections.get(i).End); - if (firstSection.Start == sections.get(i).Start && firstSection.End == sections.get(i).End) { - firstSection.Formatters.addAll(sections.get(i).Formatters); - firstSection.Matches.addAll(sections.get(i).Matches); + final FormattedSection lastSection = sections.get(i); + DebugCommand.SendDebugMessage(" and " + lastSection); + sendMessageWithPointer(str, lastSection.Start, lastSection.End); + if (firstSection.Start == lastSection.Start && firstSection.End == lastSection.End) { + firstSection.Formatters.addAll(lastSection.Formatters); + firstSection.Matches.addAll(lastSection.Matches); DebugCommand.SendDebugMessage("To section " + firstSection); sendMessageWithPointer(str, firstSection.Start, firstSection.End); sections.remove(i); found = true; - } else if (firstSection.End > sections.get(i).Start && firstSection.Start < sections.get(i).End) { - int origend = firstSection.End; - firstSection.End = sections.get(i).Start - 1; - int origend2 = sections.get(i).End; - boolean switchends; - if (switchends = origend2 < origend) { - int tmp = origend; - origend = origend2; - origend2 = tmp; - } - FormattedSection section = new FormattedSection(firstSection.Formatters, sections.get(i).Start, origend, - firstSection.Matches, Type.Normal); - section.Formatters.addAll(sections.get(i).Formatters); - section.Matches.addAll(sections.get(i).Matches); // TODO: Clean + } else if (firstSection.End > lastSection.Start && firstSection.Start < lastSection.End) { + int origend2 = firstSection.End; + firstSection.End = lastSection.Start - 1; + int origend = lastSection.End; + FormattedSection section = new FormattedSection(firstSection.Formatters, lastSection.Start, origend, + firstSection.Matches, Type.Normal); + section.Formatters.addAll(lastSection.Formatters); + section.Matches.addAll(lastSection.Matches); // TODO: Clean sections.add(i, section); nextindex++; - FormattedSection thirdFormattedSection = sections.get(i + 1); - if (switchends) { // Use the properties of the first section not the second one - thirdFormattedSection.Formatters.clear(); - thirdFormattedSection.Formatters.addAll(firstSection.Formatters); - thirdFormattedSection.Matches.clear(); - thirdFormattedSection.Matches.addAll(firstSection.Matches); - } - thirdFormattedSection.Start = origend + 1; - thirdFormattedSection.End = origend2; + // Use the properties of the first section not the second one + lastSection.Formatters.clear(); + lastSection.Formatters.addAll(firstSection.Formatters); + lastSection.Matches.clear(); + lastSection.Matches.addAll(firstSection.Matches); + + lastSection.Start = origend + 1; + lastSection.End = origend2; - ArrayList sts = sections; Predicate removeIfNeeded = s -> { if (s.Start < 0 || s.End < 0 || s.Start > s.End) { DebugCommand.SendDebugMessage("Removing section: " + s); sendMessageWithPointer(str, s.Start, s.End); - sts.remove(s); + sections.remove(s); return true; } return false; @@ -273,9 +255,9 @@ public final class ChatFormatter { DebugCommand.SendDebugMessage(" 2:" + section + ""); sendMessageWithPointer(str, section.Start, section.End); } - if (!removeIfNeeded.test(thirdFormattedSection)) { - DebugCommand.SendDebugMessage(" 3:" + thirdFormattedSection); - sendMessageWithPointer(str, thirdFormattedSection.Start, thirdFormattedSection.End); + if (!removeIfNeeded.test(lastSection)) { + DebugCommand.SendDebugMessage(" 3:" + lastSection); + sendMessageWithPointer(str, lastSection.Start, lastSection.End); } found = true; } @@ -294,48 +276,44 @@ public final class ChatFormatter { if (found) { i = 1; found = false; - sections.sort( - (s1, s2) -> s1.Start == s2.Start - ? s1.End == s2.End - ? Integer.compare(s2.Formatters.get(0).priority.GetValue(), - s1.Formatters.get(0).priority.GetValue()) - : Integer.compare(s2.End, s1.End) - : Integer.compare(s1.Start, s2.Start)); + sortSections(sections); } else cont = false; } } + } - header("Section applying"); - TellrawPart lasttp = null; String lastlink = null; - for (FormattedSection section : sections) { + private static void applySections(String str, TellrawPart tp, ArrayList sections, ArrayList remchars) { + TellrawPart lasttp = null; + String lastlink = null; + for (FormattedSection section : sections) { DebugCommand.SendDebugMessage("Applying section: " + section); String originaltext; int start = section.Start, end = section.End; DebugCommand.SendDebugMessage("Start: " + start + " - End: " + end); sendMessageWithPointer(str, start, end); - val rcs = remchars.stream().filter(rc -> rc[0] <= start && start <= rc[1]).findAny(); - val rce = remchars.stream().filter(rc -> rc[0] <= end && end <= rc[1]).findAny(); - val rci = remchars.stream().filter(rc -> start < rc[0] && rc[1] < end).toArray(int[][]::new); + val rcs = remchars.stream().filter(rc -> rc[0] <= start && start <= rc[1]).findAny(); + val rce = remchars.stream().filter(rc -> rc[0] <= end && end <= rc[1]).findAny(); + val rci = remchars.stream().filter(rc -> start < rc[0] && rc[1] < end).toArray(int[][]::new); int s = start, e = end; if (rcs.isPresent()) s = rcs.get()[1] + 1; if (rce.isPresent()) e = rce.get()[0] - 1; DebugCommand.SendDebugMessage("After RC - Start: " + s + " - End: " + e); - if (e - s < 0) { //e-s==0 means the end char is the same as start char, so one char message - DebugCommand.SendDebugMessage("Skipping section because of remchars (length would be " + (e - s + 1) + ")"); + if (e - s < 0) { //e-s==0 means the end char is the same as start char, so one char message + DebugCommand.SendDebugMessage("Skipping section because of remchars (length would be " + (e - s + 1) + ")"); continue; } originaltext = str.substring(s, e + 1); - val sb = new StringBuilder(originaltext); - for (int x = rci.length - 1; x >= 0; x--) - sb.delete(rci[x][0] - start - 1, rci[x][1] - start); //Delete going backwards - originaltext = sb.toString(); + val sb = new StringBuilder(originaltext); + for (int x = rci.length - 1; x >= 0; x--) + sb.delete(rci[x][0] - start - 1, rci[x][1] - start); //Delete going backwards + originaltext = sb.toString(); DebugCommand.SendDebugMessage("Section text: " + originaltext); - String openlink = null; - section.Formatters.sort(Comparator.comparing(cf2 -> cf2.priority.GetValue())); //Apply the highest last, to overwrite previous ones - TellrawPart newtp = new TellrawPart(""); + String openlink = null; + section.Formatters.sort(Comparator.comparing(cf2 -> cf2.priority.GetValue())); //Apply the highest last, to overwrite previous ones + TellrawPart newtp = new TellrawPart(""); for (ChatFormatter formatter : section.Formatters) { DebugCommand.SendDebugMessage("Applying formatter: " + formatter); if (formatter.onmatch != null) @@ -343,42 +321,50 @@ public final class ChatFormatter { if (formatter.color != null) newtp.setColor(formatter.color); if (formatter.bold) - newtp.setBold(formatter.bold); + newtp.setBold(true); if (formatter.italic) - newtp.setItalic(formatter.italic); + newtp.setItalic(true); if (formatter.underlined) - newtp.setUnderlined(formatter.underlined); + newtp.setUnderlined(true); if (formatter.strikethrough) - newtp.setStrikethrough(formatter.strikethrough); + newtp.setStrikethrough(true); if (formatter.obfuscated) - newtp.setObfuscated(formatter.obfuscated); + newtp.setObfuscated(true); if (formatter.openlink != null) openlink = formatter.openlink; if (formatter.hoverText != null) newtp.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, formatter.hoverText)); } - if (lasttp != null && newtp.getColor() == lasttp.getColor() - && newtp.isBold() == lasttp.isBold() - && newtp.isItalic() == lasttp.isItalic() - && newtp.isUnderlined() == lasttp.isUnderlined() - && newtp.isStrikethrough() == lasttp.isStrikethrough() - && newtp.isObfuscated() == lasttp.isObfuscated() - && Objects.equals(openlink, lastlink)) { - DebugCommand.SendDebugMessage("This part has the same properties as the previous one, combining."); - lasttp.setText(lasttp.getText() + originaltext); - continue; //Combine parts with the same properties - } + if (lasttp != null && newtp.getColor() == lasttp.getColor() + && newtp.isBold() == lasttp.isBold() + && newtp.isItalic() == lasttp.isItalic() + && newtp.isUnderlined() == lasttp.isUnderlined() + && newtp.isStrikethrough() == lasttp.isStrikethrough() + && newtp.isObfuscated() == lasttp.isObfuscated() + && Objects.equals(openlink, lastlink)) { + DebugCommand.SendDebugMessage("This part has the same properties as the previous one, combining."); + lasttp.setText(lasttp.getText() + originaltext); + continue; //Combine parts with the same properties + } + lastlink = openlink; newtp.setText(originaltext); if (openlink != null && openlink.length() > 0) { newtp.setClickEvent(TellrawEvent.create(TellrawEvent.ClickAction.OPEN_URL, - (section.Matches.size() > 0 ? openlink.replace("$1", section.Matches.get(0)) : openlink))) - .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, - new TellrawPart("Click to open").setColor(Color.Blue))); + (section.Matches.size() > 0 ? openlink.replace("$1", section.Matches.get(0)) : openlink))) + .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, + new TellrawPart("Click to open").setColor(Color.Blue))); } tp.addExtra(newtp); - lasttp = newtp; + lasttp = newtp; } - header("ChatFormatter.Combine done"); + } + + private static void sortSections(ArrayList sections) { + sections.sort( + (s1, s2) -> s1.Start == s2.Start + ? s1.End == s2.End ? Integer.compare(s2.Formatters.get(0).priority.GetValue(), + s1.Formatters.get(0).priority.GetValue()) : Integer.compare(s2.End, s1.End) + : Integer.compare(s1.Start, s2.Start)); } private static void sendMessageWithPointer(String str, int... pointer) { From 4956837e5d6cdc49de0c4897bf57bdfdf023e69e Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 22 Jul 2019 22:37:23 +0200 Subject: [PATCH 03/20] Not processing messages when nobody is online --- .../java/buttondevteam/chat/ChatProcessing.java | 9 ++++++--- src/main/java/buttondevteam/chat/ChatUtils.java | 16 ++++++++++++++++ .../java/buttondevteam/chat/VanillaUtils.java | 14 +++++++++++--- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/main/java/buttondevteam/chat/ChatProcessing.java b/src/main/java/buttondevteam/chat/ChatProcessing.java index 3b4c3de..be67739 100644 --- a/src/main/java/buttondevteam/chat/ChatProcessing.java +++ b/src/main/java/buttondevteam/chat/ChatProcessing.java @@ -122,6 +122,12 @@ public class ChatProcessing { doFunStuff(sender, e, message); + final String channelidentifier = getChannelID(channel, e.getOrigin()); + PluginMain.Instance.getServer().getConsoleSender() + .sendMessage(String.format("%s <%s§r> %s", channelidentifier, getSenderName(sender, player), message)); + + if (Bukkit.getOnlinePlayers().size() == 0) return false; //Don't try to send to nobody (errors on 1.14) + ChatPlayer mp; if (player != null) mp = TBMCPlayerBase.getPlayer(player.getUniqueId(), ChatPlayer.class); @@ -144,7 +150,6 @@ public class ChatProcessing { }).build()); } pingedconsole = false; // Will set it to true onmatch (static constructor) - final String channelidentifier = getChannelID(channel, e.getOrigin()); TellrawPart json = createTellraw(sender, message, player, mp, e.getUser(), channelidentifier, e.getOrigin()); long combinetime = System.nanoTime(); @@ -191,8 +196,6 @@ public class ChatProcessing { 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"); diff --git a/src/main/java/buttondevteam/chat/ChatUtils.java b/src/main/java/buttondevteam/chat/ChatUtils.java index 247c2e2..c090a35 100644 --- a/src/main/java/buttondevteam/chat/ChatUtils.java +++ b/src/main/java/buttondevteam/chat/ChatUtils.java @@ -2,6 +2,8 @@ package buttondevteam.chat; import org.bukkit.Bukkit; +import java.util.Optional; + public final class ChatUtils { private ChatUtils() {} @@ -17,4 +19,18 @@ public final class ChatUtils { else Bukkit.dispatchCommand(PluginMain.Console, command); } + + /** + * Returns the string between the start and end strings (exclusive). + * + * @param str The original string + * @param start The start string + * @param end The end string + * @return The result string + */ + public static Optional coolSubstring(String str, String start, String end) { + int a = str.indexOf(start) + start.length(); + int b = str.indexOf(end, a); + return a != -1 && b != -1 ? Optional.of(str.substring(a, b)) : Optional.empty(); + } } diff --git a/src/main/java/buttondevteam/chat/VanillaUtils.java b/src/main/java/buttondevteam/chat/VanillaUtils.java index 68f749b..5cbd16c 100644 --- a/src/main/java/buttondevteam/chat/VanillaUtils.java +++ b/src/main/java/buttondevteam/chat/VanillaUtils.java @@ -1,11 +1,10 @@ package buttondevteam.chat; -import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; -import org.bukkit.entity.Player; - import buttondevteam.lib.TBMCChatEvent; import lombok.experimental.UtilityClass; import net.minecraft.server.v1_12_R1.EntityHuman.EnumChatVisibility; +import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; +import org.bukkit.entity.Player; @UtilityClass public class VanillaUtils { @@ -15,4 +14,13 @@ public class VanillaUtils { else return -1; } + + /*private String version; + + public short getMCVersion() { + if (version != null) return version; + val v = ChatUtils.coolSubstring(Bukkit.getServer().getVersion().getClass().getPackage().getName(), + "org.bukkit.craftbukkit.v", "_R1").orElse("1_8").replace("_", ""); + return Short.parseShort(v); + }*/ } From 7b2ecdbf7b8b84fdf4950ad5ebe2397f041ebae1 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Wed, 7 Aug 2019 18:28:47 +0200 Subject: [PATCH 04/20] Renamed config methods to match the keys --- .idea/ButtonChat.iml | 2 +- .../components/announce/AnnounceCommand.java | 16 ++++++++-------- .../components/announce/AnnouncerComponent.java | 12 ++++++------ .../chat/components/flair/AcceptCommand.java | 2 +- .../chat/components/flair/FlairComponent.java | 4 ++-- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.idea/ButtonChat.iml b/.idea/ButtonChat.iml index 3d32cdf..9f0759b 100644 --- a/.idea/ButtonChat.iml +++ b/.idea/ButtonChat.iml @@ -26,7 +26,7 @@ - + diff --git a/src/main/java/buttondevteam/chat/components/announce/AnnounceCommand.java b/src/main/java/buttondevteam/chat/components/announce/AnnounceCommand.java index 050687d..d6864d1 100644 --- a/src/main/java/buttondevteam/chat/components/announce/AnnounceCommand.java +++ b/src/main/java/buttondevteam/chat/components/announce/AnnounceCommand.java @@ -20,7 +20,7 @@ public class AnnounceCommand extends UCommandBase { }) public boolean add(CommandSender sender, @Command2.TextArg String text) { String finalmessage = text.replace('&', '§'); - component.AnnounceMessages().get().add(finalmessage); + component.announceMessages().get().add(finalmessage); sender.sendMessage("§bAnnouncement added.§r"); return true; } @@ -34,9 +34,9 @@ public class AnnounceCommand extends UCommandBase { String finalmessage1 = text.replace('&', '§'); if (index > 100) return false; - while (component.AnnounceMessages().get().size() <= index) - component.AnnounceMessages().get().add(""); - component.AnnounceMessages().get().set(index, finalmessage1); + while (component.announceMessages().get().size() <= index) + component.announceMessages().get().add(""); + component.announceMessages().get().set(index, finalmessage1); sender.sendMessage("Announcement edited."); return true; } @@ -49,10 +49,10 @@ public class AnnounceCommand extends UCommandBase { sender.sendMessage("§bList of announce messages:§r"); sender.sendMessage("§bFormat: [index] message§r"); int i = 0; - for (String message : component.AnnounceMessages().get()) + for (String message : component.announceMessages().get()) sender.sendMessage("[" + i++ + "] " + message); sender.sendMessage("§bCurrent wait time between announcements: " - + component.AnnounceTime().get() / 60 / 1000 + " minute(s)§r"); + + component.announceTime().get() / 60 / 1000 + " minute(s)§r"); return true; } @@ -61,7 +61,7 @@ public class AnnounceCommand extends UCommandBase { "This command removes an announcement" }) public boolean remove(CommandSender sender, int index) { - val msgs = component.AnnounceMessages().get(); + val msgs = component.announceMessages().get(); if (index < 0 || index > msgs.size()) return false; msgs.remove(index); sender.sendMessage("Announcement removed."); @@ -73,7 +73,7 @@ public class AnnounceCommand extends UCommandBase { "This command sets the time between the announcements" }) public boolean settime(CommandSender sender, int minutes) { - component.AnnounceTime().set(minutes * 60 * 1000); + component.announceTime().set(minutes * 60 * 1000); sender.sendMessage("Time set between announce messages to " + minutes + " minutes"); return true; } diff --git a/src/main/java/buttondevteam/chat/components/announce/AnnouncerComponent.java b/src/main/java/buttondevteam/chat/components/announce/AnnouncerComponent.java index cecc285..1d41d62 100644 --- a/src/main/java/buttondevteam/chat/components/announce/AnnouncerComponent.java +++ b/src/main/java/buttondevteam/chat/components/announce/AnnouncerComponent.java @@ -11,11 +11,11 @@ import org.bukkit.Bukkit; import java.util.ArrayList; public class AnnouncerComponent extends Component implements Runnable { - public ConfigData> AnnounceMessages() { + public ConfigData> announceMessages() { return getConfig().getData("announceMessages", new ArrayList<>(0)); } - public ConfigData AnnounceTime() { + public ConfigData announceTime() { return getConfig().getData("announceTime", 15 * 60 * 1000); } @@ -27,15 +27,15 @@ public class AnnouncerComponent extends Component implements Runnabl public void run() { while (isEnabled()) { try { - Thread.sleep(AnnounceTime().get()); + Thread.sleep(announceTime().get()); } catch (InterruptedException ex) { Thread.currentThread().interrupt(); } if (Bukkit.getOnlinePlayers().size() == 0) continue; //Don't post to Discord if nobody is on - if (AnnounceMessages().get().size() > AnnounceMessageIndex) { - TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, AnnounceMessages().get().get(AnnounceMessageIndex), target); + if (announceMessages().get().size() > AnnounceMessageIndex) { + TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, announceMessages().get().get(AnnounceMessageIndex), target); AnnounceMessageIndex++; - if (AnnounceMessageIndex == AnnounceMessages().get().size()) + if (AnnounceMessageIndex == announceMessages().get().size()) AnnounceMessageIndex = 0; } } diff --git a/src/main/java/buttondevteam/chat/components/flair/AcceptCommand.java b/src/main/java/buttondevteam/chat/components/flair/AcceptCommand.java index 8ebd6ed..1c47167 100644 --- a/src/main/java/buttondevteam/chat/components/flair/AcceptCommand.java +++ b/src/main/java/buttondevteam/chat/components/flair/AcceptCommand.java @@ -39,7 +39,7 @@ public class AcceptCommand extends UCommandBase { } if (p.FlairState().get().equals(FlairStates.NoComment) || p.UserNames().size() == 0) { player.sendMessage("§cError: You need to write your username to the reddit thread§r"); - player.sendMessage(component.FlairThreadURL().get()); + player.sendMessage(component.flairThreadURL().get()); return true; } if (username != null && !p.UserNames().contains(username)) { diff --git a/src/main/java/buttondevteam/chat/components/flair/FlairComponent.java b/src/main/java/buttondevteam/chat/components/flair/FlairComponent.java index a5f4878..7c8440a 100644 --- a/src/main/java/buttondevteam/chat/components/flair/FlairComponent.java +++ b/src/main/java/buttondevteam/chat/components/flair/FlairComponent.java @@ -23,7 +23,7 @@ import java.text.SimpleDateFormat; import java.util.*; public class FlairComponent extends Component { - ConfigData FlairThreadURL() { + ConfigData flairThreadURL() { return getConfig().getData("flairThreadURL", "https://www.reddit.com/r/Chromagamers/comments/51ys94/flair_thread_for_the_mc_server/"); } @@ -54,7 +54,7 @@ public class FlairComponent extends Component { int errorcount = 0; while (isEnabled()) { try { - String body = TBMCCoreAPI.DownloadString(FlairThreadURL().get() + ".json?limit=1000"); + String body = TBMCCoreAPI.DownloadString(flairThreadURL().get() + ".json?limit=1000"); JsonArray json = new JsonParser().parse(body).getAsJsonArray().get(1).getAsJsonObject().get("data") .getAsJsonObject().get("children").getAsJsonArray(); for (Object obj : json) { From 415e61a40147a670ac9921d739304fc2d899266a Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 12 Aug 2019 02:50:18 +0200 Subject: [PATCH 05/20] isChatOn fix, tellRaw start --- pom.xml | 18 ++++-- .../java/buttondevteam/chat/VanillaUtils.java | 64 +++++++++++++++++-- .../chat/components/towny/TownyComponent.java | 5 +- 3 files changed, 75 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index 5626ea8..6bca684 100644 --- a/pom.xml +++ b/pom.xml @@ -217,12 +217,18 @@ 1.16.16 provided - - org.spigotmc - spigot - 1.12.2-R0.1-SNAPSHOT - provided - + + org.spigotmc + spigot + 1.12.2-R0.1-SNAPSHOT + provided + + com.github.webbukkit Dynmap-Towny diff --git a/src/main/java/buttondevteam/chat/VanillaUtils.java b/src/main/java/buttondevteam/chat/VanillaUtils.java index 5cbd16c..b1a3586 100644 --- a/src/main/java/buttondevteam/chat/VanillaUtils.java +++ b/src/main/java/buttondevteam/chat/VanillaUtils.java @@ -1,18 +1,65 @@ package buttondevteam.chat; +import buttondevteam.core.MainPlugin; import buttondevteam.lib.TBMCChatEvent; import lombok.experimental.UtilityClass; -import net.minecraft.server.v1_12_R1.EntityHuman.EnumChatVisibility; +import lombok.val; +import net.minecraft.server.v1_12_R1.ChatComponentUtils; +import net.minecraft.server.v1_12_R1.IChatBaseComponent; import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; import org.bukkit.entity.Player; +import java.util.function.Predicate; + @UtilityClass public class VanillaUtils { public int getMCScoreIfChatOn(Player p, TBMCChatEvent e) { - if (!(p instanceof CraftPlayer) || ((CraftPlayer) p).getHandle().getChatFlags() == EnumChatVisibility.FULL) // Only send if client allows chat + try { + if (isChatOn(p)) // Only send if client allows chat + return e.getMCScore(p); + else + return -1; + } catch (NoClassDefFoundError ex) { + MainPlugin.Instance.getLogger().warning("Compatibility error, can't check if the chat is hidden by the player."); return e.getMCScore(p); - else - return -1; + } + } + + private Predicate isChatOn; + + private boolean isChatOn(Player p) { + try { + if (isChatOn == null) { + val cl = p.getClass(); + if (!cl.getSimpleName().contains("CraftPlayer")) return true; // p instanceof CraftPlayer + val hm = cl.getMethod("getHandle"); + val handle = hm.invoke(p); //p.getHandle() + val vpcl = handle.getClass(); + val gcfm = vpcl.getMethod("getChatFlags"); + Class encl; + try { + encl = Class.forName(handle.getClass().getPackage().getName() + ".EnumChatVisibility"); + } catch (ClassNotFoundException e) { + encl = Class.forName(handle.getClass().getPackage().getName() + ".EntityHuman$EnumChatVisibility"); + } + val ff = encl.getField("FULL"); + val full = ff.get(null); // EnumChatVisibility.FULL + isChatOn = pl -> { + try { + val ph = hm.invoke(pl); //pl.getHandle() + val flags = gcfm.invoke(ph); //handle.getChatFlags() + return flags == full; //TODO: It's only checked if not global + } catch (Exception e) { + e.printStackTrace(); + return true; + } + }; + } + return isChatOn.test(p); + } catch (Exception e) { + e.printStackTrace(); + return true; + } } /*private String version; @@ -23,4 +70,13 @@ public class VanillaUtils { "org.bukkit.craftbukkit.v", "_R1").orElse("1_8").replace("_", ""); return Short.parseShort(v); }*/ + + public String tellRaw(Player p, String json) { + try { + ChatComponentUtils.filterForDisplay(((CraftPlayer) p).getHandle(), //TODO: Reflection + IChatBaseComponent.ChatSerializer.a(json), ((CraftPlayer) p).getHandle()); + } catch (Exception e) { + e.printStackTrace(); + } + } } diff --git a/src/main/java/buttondevteam/chat/components/towny/TownyComponent.java b/src/main/java/buttondevteam/chat/components/towny/TownyComponent.java index dbfe93c..dc4777b 100644 --- a/src/main/java/buttondevteam/chat/components/towny/TownyComponent.java +++ b/src/main/java/buttondevteam/chat/components/towny/TownyComponent.java @@ -1,5 +1,6 @@ package buttondevteam.chat.components.towny; +import buttondevteam.chat.ChatUtils; import buttondevteam.chat.PluginMain; import buttondevteam.chat.formatting.TellrawPart; import buttondevteam.core.component.channel.Channel; @@ -51,8 +52,8 @@ public class TownyComponent extends Component { if (channel.ID.equals(TownChat.ID) || channel.ID.equals(NationChat.ID)) { ((List) json.getExtra()).add(0, new TellrawPart("[SPY]")); String jsonstr = toJson.apply(json); - Bukkit.getServer().dispatchCommand(PluginMain.Console, String.format( - "tellraw @a[score_%s=1000,score_%s_min=1000] %s", channel.ID, channel.ID, jsonstr)); + ChatUtils.dispatchConsoleCommand(String.format( + "tellraw @a[score_%s=1000,score_%s_min=1000] %s", channel.ID, channel.ID, jsonstr), true); } } From f3904a84488a4ebe92235805db06df1b00ecc3e3 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Tue, 13 Aug 2019 01:19:55 +0200 Subject: [PATCH 06/20] tellRaw continue Didn't commit it earlier today, but I'm not gonna work on it now --- .../java/buttondevteam/chat/VanillaUtils.java | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/main/java/buttondevteam/chat/VanillaUtils.java b/src/main/java/buttondevteam/chat/VanillaUtils.java index b1a3586..157afbc 100644 --- a/src/main/java/buttondevteam/chat/VanillaUtils.java +++ b/src/main/java/buttondevteam/chat/VanillaUtils.java @@ -9,6 +9,7 @@ import net.minecraft.server.v1_12_R1.IChatBaseComponent; import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; import org.bukkit.entity.Player; +import java.util.function.BiConsumer; import java.util.function.Predicate; @UtilityClass @@ -31,7 +32,7 @@ public class VanillaUtils { try { if (isChatOn == null) { val cl = p.getClass(); - if (!cl.getSimpleName().contains("CraftPlayer")) return true; // p instanceof CraftPlayer + if (notCraftPlayer(cl)) return true; // p instanceof CraftPlayer val hm = cl.getMethod("getHandle"); val handle = hm.invoke(p); //p.getHandle() val vpcl = handle.getClass(); @@ -71,12 +72,38 @@ public class VanillaUtils { return Short.parseShort(v); }*/ - public String tellRaw(Player p, String json) { + private BiConsumer tellRaw; + + public boolean tellRaw(Player p, String json) { try { - ChatComponentUtils.filterForDisplay(((CraftPlayer) p).getHandle(), //TODO: Reflection - IChatBaseComponent.ChatSerializer.a(json), ((CraftPlayer) p).getHandle()); + val pcl = p.getClass(); + if (notCraftPlayer(pcl)) return false; + val hm = pcl.getMethod("getHandle"); + val handle = hm.invoke(p); ; + val nms = handle.getClass().getPackage().getName(); + val chatcompcl = Class.forName(nms + ".IChatBaseComponent"); + val sendmsg = handle.getClass().getMethod("sendMessage", chatcompcl); + + val ccucl = Class.forName(nms + ".ChatComponentUtils"); + val iclcl = Class.forName(nms + ".ICommandListener"); + val encl = Class.forName(nms + ".Entity"); + val ffdm = ccucl.getMethod("filterForDisplay", iclcl, chatcompcl, encl); + + val cscl = Class.forName(chatcompcl.getName() + "$ChatSerializer"); + val am = cscl.getMethod("a", String.class); + val deserialized = am.invoke(null, json); + val filtered = ffdm.invoke(null, handle, deserialized, handle); //TODO: Use BiConsumer + sendmsg.invoke(handle, filtered); + + ((CraftPlayer) p).getHandle().sendMessage(ChatComponentUtils + .filterForDisplay(((CraftPlayer) p).getHandle(), + IChatBaseComponent.ChatSerializer.a(json), ((CraftPlayer) p).getHandle())); } catch (Exception e) { e.printStackTrace(); } } + + private boolean notCraftPlayer(Class cl) { + return !cl.getSimpleName().contains("CraftPlayer"); + } } From 1275cdafd0c94906384ad8c4b5053ff0ee17084f Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Tue, 13 Aug 2019 15:02:34 +0200 Subject: [PATCH 07/20] Removed scoreboard that has been there for a long time PluginMain.java:40 Also made the channel scores unnecessary As well as the recently introduced dispatchConsoleCommand method Also probably fixed Towny spy (#100) --- pom.xml | 8 +- .../buttondevteam/chat/ChatProcessing.java | 497 +++++++++--------- .../java/buttondevteam/chat/PluginMain.java | 5 - .../java/buttondevteam/chat/VanillaUtils.java | 69 ++- .../chat/components/towny/TownyComponent.java | 19 +- .../chat/listener/PlayerListener.java | 7 - 6 files changed, 305 insertions(+), 300 deletions(-) diff --git a/pom.xml b/pom.xml index 6bca684..b06f542 100644 --- a/pom.xml +++ b/pom.xml @@ -155,10 +155,10 @@ Essentials http://repo.ess3.net/content/repositories/essrel/ - - Minigames - http://maven.addstar.com.au/artifactory/release - + From fa375c49125605d8da2c17a41adac3120b433946 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 16 Sep 2019 15:35:28 +0200 Subject: [PATCH 12/20] Updated code relying on Towny & updated Lombok version Towny now uses log4j Newer Lombok supports Java 11 --- .idea/ButtonChat.iml | 3 +- pom.xml | 23 +++++++++----- .../chat/components/towny/TownyAnnouncer.java | 30 ++++++++++--------- .../chat/components/towny/TownyComponent.java | 6 ++-- 4 files changed, 36 insertions(+), 26 deletions(-) diff --git a/.idea/ButtonChat.iml b/.idea/ButtonChat.iml index 19d6c49..8f59b6f 100644 --- a/.idea/ButtonChat.iml +++ b/.idea/ButtonChat.iml @@ -39,7 +39,7 @@ - + @@ -50,5 +50,6 @@ + \ No newline at end of file diff --git a/pom.xml b/pom.xml index ac73cc8..21eb434 100644 --- a/pom.xml +++ b/pom.xml @@ -212,12 +212,14 @@ master-SNAPSHOT provided - - org.projectlombok - lombok - 1.16.16 - provided - + + + org.projectlombok + lombok + 1.18.10 + provided + + org.spigotmc spigot @@ -247,7 +249,14 @@ 4.12 test - + + + log4j + log4j + 1.2.17 + + + ButtonChat TBMCPlugins diff --git a/src/main/java/buttondevteam/chat/components/towny/TownyAnnouncer.java b/src/main/java/buttondevteam/chat/components/towny/TownyAnnouncer.java index 55702c7..020993b 100644 --- a/src/main/java/buttondevteam/chat/components/towny/TownyAnnouncer.java +++ b/src/main/java/buttondevteam/chat/components/towny/TownyAnnouncer.java @@ -4,20 +4,22 @@ import buttondevteam.chat.ChatProcessing; import buttondevteam.core.component.channel.Channel; import buttondevteam.lib.TBMCSystemChatEvent; import buttondevteam.lib.chat.TBMCChatAPI; -import com.palmergames.bukkit.towny.TownyLogger; import lombok.val; +import org.apache.log4j.Appender; +import org.apache.log4j.AppenderSkeleton; +import org.apache.log4j.LogManager; +import org.apache.log4j.spi.LoggingEvent; -import java.util.logging.Handler; -import java.util.logging.LogRecord; import java.util.regex.Pattern; public class TownyAnnouncer { private static final Pattern LOG_TYPE_PATTERN = Pattern.compile("\\[(\\w+) (?:Msg|Message)](?: (\\w+):)?"); - private static final Handler HANDLER = new Handler() { + private static final Appender HANDLER = new AppenderSkeleton() { @Override - public void publish(LogRecord logRecord) { + public void append(LoggingEvent logRecord) { if (logRecord.getMessage() == null) return; - val m = LOG_TYPE_PATTERN.matcher(logRecord.getMessage()); + String message = logRecord.getMessage().toString(); + val m = LOG_TYPE_PATTERN.matcher(message); if (!m.find()) return; String groupID = m.group(2); //The group ID is correctly cased switch (String.valueOf(m.group(1))) { //valueOf: Handles null @@ -25,30 +27,30 @@ public class TownyAnnouncer { if (townChannel == null) return; TBMCChatAPI.SendSystemMessage(townChannel, new Channel.RecipientTestResult(TownyComponent.getTownNationIndex(groupID, false), groupID), - logRecord.getMessage(), target, ChatProcessing.MCORIGIN); + message, target, ChatProcessing.MCORIGIN); break; case "Nation": if (nationChannel == null) return; TBMCChatAPI.SendSystemMessage(nationChannel, new Channel.RecipientTestResult(TownyComponent.getTownNationIndex(groupID, true), groupID), - logRecord.getMessage(), target, ChatProcessing.MCORIGIN); + message, target, ChatProcessing.MCORIGIN); break; case "Global": TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, - logRecord.getMessage(), target, ChatProcessing.MCORIGIN); + message, target, ChatProcessing.MCORIGIN); break; } } @Override - public void flush() { + public void close() throws SecurityException { } @Override - public void close() throws SecurityException { - + public boolean requiresLayout() { + return false; } }; @@ -60,7 +62,7 @@ public class TownyAnnouncer { target = TBMCSystemChatEvent.BroadcastTarget.add("towny"); TownyAnnouncer.townChannel = townChannel; TownyAnnouncer.nationChannel = nationChannel; - TownyLogger.log.addHandler(HANDLER); + LogManager.getLogger("com.palmergames.bukkit.towny").addAppender(HANDLER); } public static void setdown() { @@ -68,6 +70,6 @@ public class TownyAnnouncer { target = null; TownyAnnouncer.townChannel = null; TownyAnnouncer.nationChannel = null; - TownyLogger.log.removeHandler(HANDLER); + LogManager.getLogger("com.palmergames.bukkit.towny").removeAppender(HANDLER); } } diff --git a/src/main/java/buttondevteam/chat/components/towny/TownyComponent.java b/src/main/java/buttondevteam/chat/components/towny/TownyComponent.java index 0ddd52c..dfdec58 100644 --- a/src/main/java/buttondevteam/chat/components/towny/TownyComponent.java +++ b/src/main/java/buttondevteam/chat/components/towny/TownyComponent.java @@ -7,14 +7,12 @@ import buttondevteam.core.component.channel.Channel; import buttondevteam.lib.architecture.Component; import buttondevteam.lib.chat.Color; import buttondevteam.lib.chat.TBMCChatAPI; -import com.palmergames.bukkit.towny.Towny; +import com.palmergames.bukkit.towny.TownyUniverse; import com.palmergames.bukkit.towny.exceptions.NotRegisteredException; import com.palmergames.bukkit.towny.object.Nation; import com.palmergames.bukkit.towny.object.Resident; import com.palmergames.bukkit.towny.object.Town; -import com.palmergames.bukkit.towny.object.TownyUniverse; import lombok.val; -import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -34,7 +32,7 @@ public class TownyComponent extends Component { @Override protected void enable() { - TU = ((Towny) Bukkit.getPluginManager().getPlugin("Towny")).getTownyUniverse(); + TU = TownyUniverse.getInstance(); Towns = TU.getTownsMap().values().stream().map(Town::getName).collect(Collectors.toCollection(ArrayList::new)); // Creates a snapshot of towns, new towns will be added when needed Nations = TU.getNationsMap().values().stream().map(Nation::getName).collect(Collectors.toCollection(ArrayList::new)); // Same here but with nations TBMCChatAPI.RegisterChatChannel( From bd656015bfa24a562eca23c60b05c5901a565a02 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 21 Sep 2019 02:21:53 +0200 Subject: [PATCH 13/20] Fixes, improved color mode command Renaming Fixed TownyAnnouncer once again - but it still doesn't work Improved color mode (separated "unknown color" and "reset") Fixed ping sound hiding for nicknames (#90) --- .idea/ButtonChat.iml | 6 ++-- pom.xml | 10 +++--- .../buttondevteam/chat/ChatProcessing.java | 1 + .../chat/commands/ucmds/HelpCommand.java | 2 +- .../chat/commands/ucmds/ReloadCommand.java | 2 +- .../chat/components/fun/CCommand.java | 28 +++++++++------- .../chat/components/fun/FunComponent.java | 2 +- .../chat/components/towny/TownyAnnouncer.java | 33 +++++++++---------- 8 files changed, 42 insertions(+), 42 deletions(-) diff --git a/.idea/ButtonChat.iml b/.idea/ButtonChat.iml index 8f59b6f..966c902 100644 --- a/.idea/ButtonChat.iml +++ b/.idea/ButtonChat.iml @@ -11,9 +11,6 @@ - - - @@ -50,6 +47,7 @@ - + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 21eb434..9fca21e 100644 --- a/pom.xml +++ b/pom.xml @@ -249,13 +249,13 @@ 4.12 test - + - log4j - log4j - 1.2.17 + org.apache.logging.log4j + log4j-core + 2.8.1 + provided - ButtonChat diff --git a/src/main/java/buttondevteam/chat/ChatProcessing.java b/src/main/java/buttondevteam/chat/ChatProcessing.java index dc02c3a..e472147 100644 --- a/src/main/java/buttondevteam/chat/ChatProcessing.java +++ b/src/main/java/buttondevteam/chat/ChatProcessing.java @@ -269,6 +269,7 @@ public class ChatProcessing { StringBuilder nicksb = new StringBuilder("(?i)("); boolean addNickFormatter = false; for (Player p : Bukkit.getOnlinePlayers()) { + if (!canSee.test(p)) continue; final String nick = PlayerListener.nicknames.inverse().get(p.getUniqueId()); if (nick != null) { nicksb.append(nick).append("|"); diff --git a/src/main/java/buttondevteam/chat/commands/ucmds/HelpCommand.java b/src/main/java/buttondevteam/chat/commands/ucmds/HelpCommand.java index 67d88c5..b7c10fa 100644 --- a/src/main/java/buttondevteam/chat/commands/ucmds/HelpCommand.java +++ b/src/main/java/buttondevteam/chat/commands/ucmds/HelpCommand.java @@ -19,7 +19,7 @@ public final class HelpCommand extends UCommandBase { public boolean def(CommandSender sender, @Command2.TextArg @Command2.OptionalArg String topicOrCommand) { if (topicOrCommand == null) { sender.sendMessage(new String[]{ - "§6---- Thorpe Help ----", + "§6---- Chroma Help ----", "Do /u help for more info", "Do /u help [subcommands] for more info about a command", "Topics:", diff --git a/src/main/java/buttondevteam/chat/commands/ucmds/ReloadCommand.java b/src/main/java/buttondevteam/chat/commands/ucmds/ReloadCommand.java index e5b5ef4..2a49259 100644 --- a/src/main/java/buttondevteam/chat/commands/ucmds/ReloadCommand.java +++ b/src/main/java/buttondevteam/chat/commands/ucmds/ReloadCommand.java @@ -7,7 +7,7 @@ import org.bukkit.command.CommandSender; @CommandClass(helpText = { "Reload", - "Reloads Thorpe-Chat" + "Reloads the config" }, modOnly = true) public class ReloadCommand extends UCommandBase { @Command2.Subcommand diff --git a/src/main/java/buttondevteam/chat/components/fun/CCommand.java b/src/main/java/buttondevteam/chat/components/fun/CCommand.java index 252f028..42acb07 100644 --- a/src/main/java/buttondevteam/chat/components/fun/CCommand.java +++ b/src/main/java/buttondevteam/chat/components/fun/CCommand.java @@ -7,6 +7,7 @@ import buttondevteam.lib.player.TBMCPlayer; import org.bukkit.entity.Player; import java.util.Arrays; +import java.util.Optional; @CommandClass(path = "u c", helpText = { "Rainbow mode", @@ -18,7 +19,7 @@ public class CCommand extends ICommand2MC { public boolean def(Player player, @Command2.OptionalArg String color) { ChatPlayer p = TBMCPlayer.getPlayer(player.getUniqueId(), ChatPlayer.class); if (color == null) { - if (PluginMain.permission.has(player, "thorpe.color.rainbow")) { + if (PluginMain.permission.has(player, "chroma.color.rainbow")) { p.RainbowPresserColorMode = !p.RainbowPresserColorMode; p.OtherColorMode = null; if (p.RainbowPresserColorMode) @@ -30,20 +31,23 @@ public class CCommand extends ICommand2MC { return true; } } else { - if (PluginMain.permission.has(player, "thorpe.color.custom")) { - p.RainbowPresserColorMode = false; - p.OtherColorMode = null; - try { - String x = color.toLowerCase(); - p.OtherColorMode = Arrays.stream(Color.values()).filter(c -> c.getName().equals(x)).findAny().orElse(null); - } catch (Exception e) { + if (PluginMain.permission.has(player, "chroma.color.custom")) { + String x = color.toLowerCase(); + if ("off".equals(x)) { + p.OtherColorMode = null; + player.sendMessage("§eMessage color reset."); + return true; + } + Optional oc = Arrays.stream(Color.values()).filter(c -> c.getName().equals(x)).findAny(); + if (!oc.isPresent()) { player.sendMessage("§cUnknown message color: " + color); player.sendMessage("§cUse color names, like blue, or dark_aqua"); + player.sendMessage("§cOr use 'off' to disable"); + return true; } - if (p.OtherColorMode != null) - player.sendMessage(String.format("§eMessage color set to %s", p.OtherColorMode)); - else - player.sendMessage("§eMessage color reset."); + p.RainbowPresserColorMode = false; + p.OtherColorMode = oc.get(); + player.sendMessage(String.format("§eMessage color set to %s", p.OtherColorMode)); } else { player.sendMessage("§cYou don't have permission for this command."); return true; diff --git a/src/main/java/buttondevteam/chat/components/fun/FunComponent.java b/src/main/java/buttondevteam/chat/components/fun/FunComponent.java index 3f47ea8..6acf3e5 100644 --- a/src/main/java/buttondevteam/chat/components/fun/FunComponent.java +++ b/src/main/java/buttondevteam/chat/components/fun/FunComponent.java @@ -139,7 +139,7 @@ public class FunComponent extends Component implements Listener { if (ht.getName().equalsIgnoreCase(cmd)) return; } - if (PluginMain.permission.has(event.getSender(), "thorpe.unanything")) { + if (PluginMain.permission.has(event.getSender(), "chroma.unanything")) { event.setCancelled(true); int index = cmd.lastIndexOf(' '); if (index == -1) { diff --git a/src/main/java/buttondevteam/chat/components/towny/TownyAnnouncer.java b/src/main/java/buttondevteam/chat/components/towny/TownyAnnouncer.java index 020993b..e8cf4d6 100644 --- a/src/main/java/buttondevteam/chat/components/towny/TownyAnnouncer.java +++ b/src/main/java/buttondevteam/chat/components/towny/TownyAnnouncer.java @@ -5,18 +5,25 @@ import buttondevteam.core.component.channel.Channel; import buttondevteam.lib.TBMCSystemChatEvent; import buttondevteam.lib.chat.TBMCChatAPI; import lombok.val; -import org.apache.log4j.Appender; -import org.apache.log4j.AppenderSkeleton; -import org.apache.log4j.LogManager; -import org.apache.log4j.spi.LoggingEvent; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.Appender; +import org.apache.logging.log4j.core.Filter; +import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.Logger; +import org.apache.logging.log4j.core.appender.AbstractAppender; +import org.apache.logging.log4j.core.filter.LevelRangeFilter; +import org.apache.logging.log4j.core.layout.PatternLayout; import java.util.regex.Pattern; public class TownyAnnouncer { private static final Pattern LOG_TYPE_PATTERN = Pattern.compile("\\[(\\w+) (?:Msg|Message)](?: (\\w+):)?"); - private static final Appender HANDLER = new AppenderSkeleton() { + private static final Appender HANDLER = new AbstractAppender(TownyAnnouncer.class.getSimpleName(), + LevelRangeFilter.createFilter(Level.INFO, Level.INFO, Filter.Result.ACCEPT, Filter.Result.DENY), + PatternLayout.createDefaultLayout()) { @Override - public void append(LoggingEvent logRecord) { + public void append(LogEvent logRecord) { if (logRecord.getMessage() == null) return; String message = logRecord.getMessage().toString(); val m = LOG_TYPE_PATTERN.matcher(message); @@ -42,16 +49,6 @@ public class TownyAnnouncer { break; } } - - @Override - public void close() throws SecurityException { - - } - - @Override - public boolean requiresLayout() { - return false; - } }; private static TBMCSystemChatEvent.BroadcastTarget target; @@ -62,7 +59,7 @@ public class TownyAnnouncer { target = TBMCSystemChatEvent.BroadcastTarget.add("towny"); TownyAnnouncer.townChannel = townChannel; TownyAnnouncer.nationChannel = nationChannel; - LogManager.getLogger("com.palmergames.bukkit.towny").addAppender(HANDLER); + ((Logger) LogManager.getLogger("com.palmergames.bukkit.towny")).getContext().getConfiguration().addAppender(HANDLER); } public static void setdown() { @@ -70,6 +67,6 @@ public class TownyAnnouncer { target = null; TownyAnnouncer.townChannel = null; TownyAnnouncer.nationChannel = null; - LogManager.getLogger("com.palmergames.bukkit.towny").removeAppender(HANDLER); + ((Logger) LogManager.getLogger("com.palmergames.bukkit.towny")).getContext().getConfiguration().getAppenders().remove(TownyAnnouncer.class.getSimpleName()); } } From 750b71de65e6e53a527aab94976d40b8c97f08a1 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 23 Sep 2019 13:21:42 +0200 Subject: [PATCH 14/20] Created FormatterComponent & formatters can be disabled It allows disabling chat processing as a whole or formatting Formatters can be disabled one by one #85 --- .../java/buttondevteam/chat/ChatUtils.java | 26 +- .../chatonly/ChatOnlyComponent.java | 4 +- .../formatter}/ChatProcessing.java | 50 ++-- .../formatter/FormatterComponent.java | 39 +++ .../formatter}/formatting/ChatFormatter.java | 15 +- .../formatting/FormattedSection.java | 2 +- .../formatter}/formatting/TellrawEvent.java | 152 ++++++------ .../formatter}/formatting/TellrawPart.java | 230 +++++++++--------- .../formatting/TellrawSerializer.java | 118 ++++----- .../chat/components/towny/TownyAnnouncer.java | 8 +- .../chat/components/towny/TownyComponent.java | 2 +- .../chat/listener/PlayerListener.java | 31 ++- .../formatter}/ChatFormatIT.java | 28 ++- 13 files changed, 392 insertions(+), 313 deletions(-) rename src/main/java/buttondevteam/chat/{ => components/formatter}/ChatProcessing.java (88%) create mode 100644 src/main/java/buttondevteam/chat/components/formatter/FormatterComponent.java rename src/main/java/buttondevteam/chat/{ => components/formatter}/formatting/ChatFormatter.java (96%) rename src/main/java/buttondevteam/chat/{ => components/formatter}/formatting/FormattedSection.java (94%) rename src/main/java/buttondevteam/chat/{ => components/formatter}/formatting/TellrawEvent.java (93%) rename src/main/java/buttondevteam/chat/{ => components/formatter}/formatting/TellrawPart.java (92%) rename src/main/java/buttondevteam/chat/{ => components/formatter}/formatting/TellrawSerializer.java (90%) rename src/test/java/buttondevteam/chat/{ => components/formatter}/ChatFormatIT.java (86%) diff --git a/src/main/java/buttondevteam/chat/ChatUtils.java b/src/main/java/buttondevteam/chat/ChatUtils.java index c090a35..d716acc 100644 --- a/src/main/java/buttondevteam/chat/ChatUtils.java +++ b/src/main/java/buttondevteam/chat/ChatUtils.java @@ -1,11 +1,19 @@ package buttondevteam.chat; +import buttondevteam.lib.TBMCChatEvent; +import buttondevteam.lib.ThorpeUtils; +import lombok.var; import org.bukkit.Bukkit; +import org.bukkit.entity.Player; import java.util.Optional; +import java.util.function.Function; public final class ChatUtils { - private ChatUtils() {} + public static final String MCORIGIN = "Minecraft"; //Shouldn't change, like ever - TBMCPlayer.getFolderForType(TBMCPlayer.class) capitalized + + private ChatUtils() { + } /** * Dispatch a console command. @@ -33,4 +41,20 @@ public final class ChatUtils { int b = str.indexOf(end, a); return a != -1 && b != -1 ? Optional.of(str.substring(a, b)) : Optional.empty(); } + + /** + * Sends a regular (non-Markdown) chat message. Used as a fallback if the chat processing fails. + * + * @param e The chat event + * @param modifier A function that alters the message to be displayed to the player + */ + public static void sendChatMessage(TBMCChatEvent e, Function modifier) { + var str = "[" + e.getChannel().DisplayName().get() + "] <" + + ThorpeUtils.getDisplayName(e.getSender()) + "> " + e.getMessage(); + str = modifier.apply(str); + for (Player p : Bukkit.getOnlinePlayers()) + if (e.shouldSendTo(p)) + p.sendMessage(str); + Bukkit.getConsoleSender().sendMessage(str); + } } diff --git a/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java b/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java index 7f17848..5f012dd 100644 --- a/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java +++ b/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java @@ -1,8 +1,8 @@ package buttondevteam.chat.components.chatonly; import buttondevteam.chat.ChatPlayer; -import buttondevteam.chat.formatting.TellrawEvent; -import buttondevteam.chat.formatting.TellrawPart; +import buttondevteam.chat.components.formatter.formatting.TellrawEvent; +import buttondevteam.chat.components.formatter.formatting.TellrawPart; import buttondevteam.core.ComponentManager; import buttondevteam.lib.architecture.Component; import buttondevteam.lib.player.TBMCPlayer; diff --git a/src/main/java/buttondevteam/chat/ChatProcessing.java b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java similarity index 88% rename from src/main/java/buttondevteam/chat/ChatProcessing.java rename to src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java index e472147..8b7ae65 100644 --- a/src/main/java/buttondevteam/chat/ChatProcessing.java +++ b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java @@ -1,13 +1,17 @@ -package buttondevteam.chat; +package buttondevteam.chat.components.formatter; +import buttondevteam.chat.ChatPlayer; +import buttondevteam.chat.ChatUtils; +import buttondevteam.chat.PluginMain; +import buttondevteam.chat.VanillaUtils; import buttondevteam.chat.commands.ucmds.admin.DebugCommand; import buttondevteam.chat.components.chatonly.ChatOnlyComponent; +import buttondevteam.chat.components.formatter.formatting.ChatFormatter; +import buttondevteam.chat.components.formatter.formatting.TellrawEvent; +import buttondevteam.chat.components.formatter.formatting.TellrawPart; +import buttondevteam.chat.components.formatter.formatting.TellrawSerializer; import buttondevteam.chat.components.fun.FunComponent; import buttondevteam.chat.components.towny.TownyComponent; -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.core.ComponentManager; import buttondevteam.core.component.channel.Channel; @@ -101,12 +105,11 @@ public class ChatProcessing { .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"}; - public static final String MCORIGIN = "Minecraft"; //Shouldn't change, like ever - TBMCPlayer.getFolderForType(TBMCPlayer.class) capitalized private ChatProcessing() { } - public static boolean ProcessChat(TBMCChatEvent e) { + public static boolean ProcessChat(TBMCChatEvent e, FormatterComponent component) { Channel channel = e.getChannel(); CommandSender sender = e.getSender(); String message = e.getMessage(); @@ -141,19 +144,24 @@ public class ChatProcessing { colormode = Color.Green; // If greentext, ignore channel or player colors - ArrayList formatters = addFormatters(colormode, e::shouldSendTo); - if (colormode == channel.Color().get() && mp != null && mp.RainbowPresserColorMode) { // Only overwrite channel color - final AtomicInteger rpc = new AtomicInteger(0); - formatters.add(ChatFormatter.builder().regex(WORD_PATTERN).color(colormode).onmatch((match, cf, s) -> { - cf.setColor(RainbowPresserColors[rpc.getAndUpdate(i -> ++i < RainbowPresserColors.length ? i : 0)]); - return match; - }).build()); - } - pingedconsole = false; // Will set it to true onmatch (static constructor) + ArrayList formatters; + if (component.allowFormatting().get()) { + formatters = addFormatters(colormode, e::shouldSendTo); + if (colormode == channel.Color().get() && mp != null && mp.RainbowPresserColorMode) { // Only overwrite channel color + final AtomicInteger rpc = new AtomicInteger(0); + formatters.add(ChatFormatter.builder().regex(WORD_PATTERN).color(colormode).onmatch((match, cf, s) -> { + cf.setColor(RainbowPresserColors[rpc.getAndUpdate(i -> ++i < RainbowPresserColors.length ? i : 0)]); + return match; + }).build()); + } + pingedconsole = false; // Will set it to true onmatch (static constructor) + } else + formatters = Lists.newArrayList(ChatFormatter.builder().regex(ENTIRE_MESSAGE_PATTERN) + .color(Color.White).priority(Priority.Low).build()); //This formatter is necessary TellrawPart json = createTellraw(sender, message, player, mp, e.getUser(), channelidentifier, e.getOrigin()); long combinetime = System.nanoTime(); - ChatFormatter.Combine(formatters, message, json); + ChatFormatter.Combine(formatters, message, json, component.getConfig()); combinetime = System.nanoTime() - combinetime; String jsonstr = toJson(json); if (jsonstr.length() >= 32767) { @@ -203,15 +211,15 @@ public class ChatProcessing { } static TellrawPart createTellraw(CommandSender sender, String message, @Nullable Player player, - @Nullable ChatPlayer mp, @Nullable ChromaGamerBase cg, final String channelidentifier, - String origin) { + @Nullable ChatPlayer mp, @Nullable ChromaGamerBase cg, final String channelidentifier, + String origin) { TellrawPart json = new TellrawPart(""); ChatOnlyComponent.tellrawCreate(mp, json); //TODO: Make nice API json.addExtra( new TellrawPart(channelidentifier) .setHoverEvent( TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, - new TellrawPart((MCORIGIN.equals(origin) ? "" : "From " + origin + "n") + new TellrawPart((ChatUtils.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")) @@ -237,7 +245,7 @@ public class ChatProcessing { } static String getChannelID(Channel channel, String origin) { - return ("[" + (MCORIGIN.equals(origin) ? "" : "§8" + origin.substring(0, 1) + "§r|") + channel.DisplayName().get()) + return ("[" + (ChatUtils.MCORIGIN.equals(origin) ? "" : "§8" + origin.substring(0, 1) + "§r|") + channel.DisplayName().get()) + "]"; } diff --git a/src/main/java/buttondevteam/chat/components/formatter/FormatterComponent.java b/src/main/java/buttondevteam/chat/components/formatter/FormatterComponent.java new file mode 100644 index 0000000..fadc86c --- /dev/null +++ b/src/main/java/buttondevteam/chat/components/formatter/FormatterComponent.java @@ -0,0 +1,39 @@ +package buttondevteam.chat.components.formatter; + +import buttondevteam.chat.PluginMain; +import buttondevteam.core.ComponentManager; +import buttondevteam.lib.TBMCChatEvent; +import buttondevteam.lib.architecture.Component; +import buttondevteam.lib.architecture.ConfigData; + +/** + * This component handles the custom processing of chat messages. If this component is disabled channels won't be supported either in Minecraft. + * If you only want to disable the formatting features, set allowFormatting to false. + */ +public class FormatterComponent extends Component { + ConfigData allowFormatting() { + return getConfig().getData("allowFormatting", true); + } + + @Override + protected void enable() { + + } + + @Override + protected void disable() { + + } + + /** + * Handles the chat if the component is enabled. + * + * @param event The chat event + * @return Whether the chat message shouldn't be sent for some reason + */ + public static boolean handleChat(TBMCChatEvent event) { + FormatterComponent component = ComponentManager.getIfEnabled(FormatterComponent.class); + if (component == null) return false; + return ChatProcessing.ProcessChat(event, component); + } +} diff --git a/src/main/java/buttondevteam/chat/formatting/ChatFormatter.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java similarity index 96% rename from src/main/java/buttondevteam/chat/formatting/ChatFormatter.java rename to src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java index 8c2d03e..dbd65ea 100644 --- a/src/main/java/buttondevteam/chat/formatting/ChatFormatter.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java @@ -1,7 +1,9 @@ -package buttondevteam.chat.formatting; +package buttondevteam.chat.components.formatter.formatting; -import buttondevteam.chat.ChatProcessing; import buttondevteam.chat.commands.ucmds.admin.DebugCommand; +import buttondevteam.chat.components.formatter.ChatProcessing; +import buttondevteam.lib.architecture.ConfigData; +import buttondevteam.lib.architecture.IHaveConfig; import buttondevteam.lib.chat.Color; import buttondevteam.lib.chat.Priority; import lombok.Builder; @@ -40,6 +42,11 @@ public final class ChatFormatter { @Builder.Default Type type = Type.Normal; String hoverText; + String name; + + private ConfigData enabled(IHaveConfig config) { + return config.getData(name + ".enabled", true); + } public enum Type { Normal, @@ -58,13 +65,15 @@ public final class ChatFormatter { R apply(T1 x1, T2 x2, T3 x3); } - public static void Combine(List formatters, String str, TellrawPart tp) { + public static void Combine(List formatters, String str, TellrawPart tp, IHaveConfig config) { /* * This method assumes that there is always a global formatter */ header("ChatFormatter.Combine begin"); ArrayList sections = new ArrayList<>(); + if (config != null) //null if testing + formatters.removeIf(cf -> !cf.enabled(config).get()); //Remove disabled formatters createSections(formatters, str, sections, true); header("Section creation (excluders done)"); diff --git a/src/main/java/buttondevteam/chat/formatting/FormattedSection.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java similarity index 94% rename from src/main/java/buttondevteam/chat/formatting/FormattedSection.java rename to src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java index 15101c4..c609e58 100644 --- a/src/main/java/buttondevteam/chat/formatting/FormattedSection.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java @@ -1,4 +1,4 @@ -package buttondevteam.chat.formatting; +package buttondevteam.chat.components.formatter.formatting; import java.util.ArrayList; import java.util.Collection; diff --git a/src/main/java/buttondevteam/chat/formatting/TellrawEvent.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawEvent.java similarity index 93% rename from src/main/java/buttondevteam/chat/formatting/TellrawEvent.java rename to src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawEvent.java index 8f43d63..4c532e5 100644 --- a/src/main/java/buttondevteam/chat/formatting/TellrawEvent.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawEvent.java @@ -1,76 +1,76 @@ -package buttondevteam.chat.formatting; - -import java.io.Serializable; - -import buttondevteam.lib.chat.TellrawSerializableEnum; - -public final class TellrawEvent implements Serializable { - private static final long serialVersionUID = -1681364161210561505L; - private transient boolean hoverEvent; - private T action; - private Object value; - - private TellrawEvent(T action, String value) { - this.hoverEvent = action instanceof HoverAction; - this.action = action; - this.value = value; - } - - private TellrawEvent(T action, TellrawPart value) { - this.hoverEvent = action instanceof HoverAction; - this.action = action; - this.value = value; - } - - public static TellrawEvent create(V action, String value) { - return new TellrawEvent<>(action, value); - } - - public static TellrawEvent create(V action, TellrawPart value) { - return new TellrawEvent<>(action, value); - } - - public boolean isHoverEvent() { - return hoverEvent; - } - - public T getAction() { - return action; - } - - public Object getValue() { - return value; - } - - public enum ClickAction implements Action { - OPEN_URL("open_url"), RUN_COMMAND("run_command"), SUGGEST_COMMAND("suggest_command"); - private String action; - - ClickAction(String action) { - this.action = action; - } - - @Override - public String getName() { - return action; - } - } - - public enum HoverAction implements Action { - SHOW_TEXT("show_text"), SHOW_ITEM("show_item"), SHOW_ACHIEVEMENT("show_achievement"), SHOW_ENTITY( - "show_entity"); - private String action; - - HoverAction(String action) { - this.action = action; - } - - @Override - public String getName() { - return action; - } - } - - public static interface Action extends TellrawSerializableEnum { - } -} +package buttondevteam.chat.components.formatter.formatting; + +import buttondevteam.lib.chat.TellrawSerializableEnum; + +import java.io.Serializable; + +public final class TellrawEvent implements Serializable { + private static final long serialVersionUID = -1681364161210561505L; + private transient boolean hoverEvent; + private T action; + private Object value; + + private TellrawEvent(T action, String value) { + this.hoverEvent = action instanceof HoverAction; + this.action = action; + this.value = value; + } + + private TellrawEvent(T action, TellrawPart value) { + this.hoverEvent = action instanceof HoverAction; + this.action = action; + this.value = value; + } + + public static TellrawEvent create(V action, String value) { + return new TellrawEvent<>(action, value); + } + + public static TellrawEvent create(V action, TellrawPart value) { + return new TellrawEvent<>(action, value); + } + + public boolean isHoverEvent() { + return hoverEvent; + } + + public T getAction() { + return action; + } + + public Object getValue() { + return value; + } + + public enum ClickAction implements Action { + OPEN_URL("open_url"), RUN_COMMAND("run_command"), SUGGEST_COMMAND("suggest_command"); + private String action; + + ClickAction(String action) { + this.action = action; + } + + @Override + public String getName() { + return action; + } + } + + public enum HoverAction implements Action { + SHOW_TEXT("show_text"), SHOW_ITEM("show_item"), SHOW_ACHIEVEMENT("show_achievement"), SHOW_ENTITY( + "show_entity"); + private String action; + + HoverAction(String action) { + this.action = action; + } + + @Override + public String getName() { + return action; + } + } + + public static interface Action extends TellrawSerializableEnum { + } +} diff --git a/src/main/java/buttondevteam/chat/formatting/TellrawPart.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawPart.java similarity index 92% rename from src/main/java/buttondevteam/chat/formatting/TellrawPart.java rename to src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawPart.java index 0e7dc72..2425574 100644 --- a/src/main/java/buttondevteam/chat/formatting/TellrawPart.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawPart.java @@ -1,115 +1,115 @@ -package buttondevteam.chat.formatting; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import buttondevteam.lib.chat.*; - -public final class TellrawPart implements Serializable { - private static final long serialVersionUID = 4125357644462144024L; - private Color color; - private boolean italic; - private boolean bold; - private boolean underlined; - private boolean strikethrough; - private boolean obfuscated; - private List extra = new ArrayList<>(); - private String text; - private TellrawEvent hoverEvent; - private TellrawEvent clickEvent; - - public TellrawPart(String text) { - this.text = text; - } - - public Color getColor() { - return color; - } - - public TellrawPart setColor(Color color) { - this.color = color; - return this; - } - - public boolean isItalic() { - return italic; - } - - public TellrawPart setItalic(boolean italic) { - this.italic = italic; - return this; - } - - public boolean isBold() { - return bold; - } - - public TellrawPart setBold(boolean bold) { - this.bold = bold; - return this; - } - - public boolean isUnderlined() { - return underlined; - } - - public TellrawPart setUnderlined(boolean underlined) { - this.underlined = underlined; - return this; - } - - public boolean isStrikethrough() { - return strikethrough; - } - - public TellrawPart setStrikethrough(boolean strikethrough) { - this.strikethrough = strikethrough; - return this; - } - - public boolean isObfuscated() { - return obfuscated; - } - - public TellrawPart setObfuscated(boolean obfuscated) { - this.obfuscated = obfuscated; - return this; - } - - public Iterable getExtra() { - return extra; - } - - public TellrawPart addExtra(TellrawPart extra) { - this.extra.add(extra); - return this; - } - - public String getText() { - return text; - } - - public TellrawPart setText(String text) { - this.text = text; - return this; - } - - public TellrawEvent getHoverEvent() { - return hoverEvent; - } - - public TellrawPart setHoverEvent(TellrawEvent hoverEvent) { - this.hoverEvent = hoverEvent; - return this; - } - - public TellrawEvent getClickEvent() { - return clickEvent; - } - - public TellrawPart setClickEvent(TellrawEvent clickEvent) { - this.clickEvent = clickEvent; - return this; - } -} +package buttondevteam.chat.components.formatter.formatting; + +import buttondevteam.lib.chat.Color; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public final class TellrawPart implements Serializable { + private static final long serialVersionUID = 4125357644462144024L; + private Color color; + private boolean italic; + private boolean bold; + private boolean underlined; + private boolean strikethrough; + private boolean obfuscated; + private List extra = new ArrayList<>(); + private String text; + private TellrawEvent hoverEvent; + private TellrawEvent clickEvent; + + public TellrawPart(String text) { + this.text = text; + } + + public Color getColor() { + return color; + } + + public TellrawPart setColor(Color color) { + this.color = color; + return this; + } + + public boolean isItalic() { + return italic; + } + + public TellrawPart setItalic(boolean italic) { + this.italic = italic; + return this; + } + + public boolean isBold() { + return bold; + } + + public TellrawPart setBold(boolean bold) { + this.bold = bold; + return this; + } + + public boolean isUnderlined() { + return underlined; + } + + public TellrawPart setUnderlined(boolean underlined) { + this.underlined = underlined; + return this; + } + + public boolean isStrikethrough() { + return strikethrough; + } + + public TellrawPart setStrikethrough(boolean strikethrough) { + this.strikethrough = strikethrough; + return this; + } + + public boolean isObfuscated() { + return obfuscated; + } + + public TellrawPart setObfuscated(boolean obfuscated) { + this.obfuscated = obfuscated; + return this; + } + + public Iterable getExtra() { + return extra; + } + + public TellrawPart addExtra(TellrawPart extra) { + this.extra.add(extra); + return this; + } + + public String getText() { + return text; + } + + public TellrawPart setText(String text) { + this.text = text; + return this; + } + + public TellrawEvent getHoverEvent() { + return hoverEvent; + } + + public TellrawPart setHoverEvent(TellrawEvent hoverEvent) { + this.hoverEvent = hoverEvent; + return this; + } + + public TellrawEvent getClickEvent() { + return clickEvent; + } + + public TellrawPart setClickEvent(TellrawEvent clickEvent) { + this.clickEvent = clickEvent; + return this; + } +} diff --git a/src/main/java/buttondevteam/chat/formatting/TellrawSerializer.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawSerializer.java similarity index 90% rename from src/main/java/buttondevteam/chat/formatting/TellrawSerializer.java rename to src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawSerializer.java index f8b591e..b1a36fd 100644 --- a/src/main/java/buttondevteam/chat/formatting/TellrawSerializer.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawSerializer.java @@ -1,59 +1,59 @@ -package buttondevteam.chat.formatting; - -import java.io.IOException; -import java.lang.reflect.Type; -import java.util.Collection; - -import com.google.gson.*; -import com.google.gson.stream.*; - -import buttondevteam.lib.chat.TellrawSerializableEnum; - -public abstract class TellrawSerializer { - public static class TwEnum extends TypeAdapter { - @Override - public TellrawSerializableEnum read(JsonReader reader) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public void write(JsonWriter writer, TellrawSerializableEnum enumval) throws IOException { - if (enumval == null) - writer.nullValue(); - else - writer.value(enumval.getName()); - } - } - - public static class TwCollection implements JsonSerializer> { - @Override - public JsonElement serialize(Collection src, Type typeOfSrc, JsonSerializationContext context) { - if (src == null || src.isEmpty()) - return null; - - JsonArray array = new JsonArray(); - - for (Object child : src) { - JsonElement element = context.serialize(child); - array.add(element); - } - - return array; - } - } - - public static class TwBool extends TypeAdapter { - @Override - public Boolean read(JsonReader reader) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public void write(JsonWriter writer, Boolean val) throws IOException { - if (val) - writer.value(val); - else - writer.nullValue(); - } - } -} +package buttondevteam.chat.components.formatter.formatting; + +import buttondevteam.lib.chat.TellrawSerializableEnum; +import com.google.gson.*; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.Collection; + +public abstract class TellrawSerializer { + public static class TwEnum extends TypeAdapter { + @Override + public TellrawSerializableEnum read(JsonReader reader) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void write(JsonWriter writer, TellrawSerializableEnum enumval) throws IOException { + if (enumval == null) + writer.nullValue(); + else + writer.value(enumval.getName()); + } + } + + public static class TwCollection implements JsonSerializer> { + @Override + public JsonElement serialize(Collection src, Type typeOfSrc, JsonSerializationContext context) { + if (src == null || src.isEmpty()) + return null; + + JsonArray array = new JsonArray(); + + for (Object child : src) { + JsonElement element = context.serialize(child); + array.add(element); + } + + return array; + } + } + + public static class TwBool extends TypeAdapter { + @Override + public Boolean read(JsonReader reader) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void write(JsonWriter writer, Boolean val) throws IOException { + if (val) + writer.value(val); + else + writer.nullValue(); + } + } +} diff --git a/src/main/java/buttondevteam/chat/components/towny/TownyAnnouncer.java b/src/main/java/buttondevteam/chat/components/towny/TownyAnnouncer.java index e8cf4d6..ccfd298 100644 --- a/src/main/java/buttondevteam/chat/components/towny/TownyAnnouncer.java +++ b/src/main/java/buttondevteam/chat/components/towny/TownyAnnouncer.java @@ -1,6 +1,6 @@ package buttondevteam.chat.components.towny; -import buttondevteam.chat.ChatProcessing; +import buttondevteam.chat.ChatUtils; import buttondevteam.core.component.channel.Channel; import buttondevteam.lib.TBMCSystemChatEvent; import buttondevteam.lib.chat.TBMCChatAPI; @@ -34,18 +34,18 @@ public class TownyAnnouncer { if (townChannel == null) return; TBMCChatAPI.SendSystemMessage(townChannel, new Channel.RecipientTestResult(TownyComponent.getTownNationIndex(groupID, false), groupID), - message, target, ChatProcessing.MCORIGIN); + message, target, ChatUtils.MCORIGIN); break; case "Nation": if (nationChannel == null) return; TBMCChatAPI.SendSystemMessage(nationChannel, new Channel.RecipientTestResult(TownyComponent.getTownNationIndex(groupID, true), groupID), - message, target, ChatProcessing.MCORIGIN); + message, target, ChatUtils.MCORIGIN); break; case "Global": TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, - message, target, ChatProcessing.MCORIGIN); + message, target, ChatUtils.MCORIGIN); break; } } diff --git a/src/main/java/buttondevteam/chat/components/towny/TownyComponent.java b/src/main/java/buttondevteam/chat/components/towny/TownyComponent.java index dfdec58..a77bc83 100644 --- a/src/main/java/buttondevteam/chat/components/towny/TownyComponent.java +++ b/src/main/java/buttondevteam/chat/components/towny/TownyComponent.java @@ -2,7 +2,7 @@ package buttondevteam.chat.components.towny; import buttondevteam.chat.PluginMain; import buttondevteam.chat.VanillaUtils; -import buttondevteam.chat.formatting.TellrawPart; +import buttondevteam.chat.components.formatter.formatting.TellrawPart; import buttondevteam.core.component.channel.Channel; import buttondevteam.lib.architecture.Component; import buttondevteam.lib.chat.Color; diff --git a/src/main/java/buttondevteam/chat/listener/PlayerListener.java b/src/main/java/buttondevteam/chat/listener/PlayerListener.java index 54f7b4d..7fa3048 100644 --- a/src/main/java/buttondevteam/chat/listener/PlayerListener.java +++ b/src/main/java/buttondevteam/chat/listener/PlayerListener.java @@ -1,10 +1,11 @@ package buttondevteam.chat.listener; import buttondevteam.chat.ChatPlayer; -import buttondevteam.chat.ChatProcessing; +import buttondevteam.chat.ChatUtils; import buttondevteam.chat.PluginMain; import buttondevteam.chat.commands.ucmds.HistoryCommand; import buttondevteam.chat.components.flair.FlairComponent; +import buttondevteam.chat.components.formatter.FormatterComponent; import buttondevteam.chat.components.towncolors.TownColorComponent; import buttondevteam.core.ComponentManager; import buttondevteam.core.component.channel.Channel; @@ -51,7 +52,8 @@ public class PlayerListener implements Listener { if (event.isCancelled()) return; //The custom event is called in the core, but doesn't cancel the MC event - event.setCancelled(true); // The custom event should only be cancelled when muted or similar + if (ComponentManager.isEnabled(FormatterComponent.class)) //If not enabled, then let the other plugins deal with the message + event.setCancelled(true); // The custom event should only be cancelled when muted or similar } @EventHandler(priority = EventPriority.HIGHEST) @@ -94,7 +96,7 @@ public class PlayerListener implements Listener { Player player = Bukkit.getPlayer(message.substring(index + 1)); if (player != null && sender instanceof Player) player.sendMessage("§b" + ((Player) sender).getDisplayName() + " §bis in this world: " //TODO: Move to the Core - + ((Player) sender).getWorld().getName()); + + ((Player) sender).getWorld().getName()); } else if (cmd.equalsIgnoreCase("minecraft:me")) { if (!(sender instanceof Player) || !PluginMain.essentials.getUser((Player) sender).isMuted()) { String msg = message.substring(index + 1); @@ -130,7 +132,7 @@ public class PlayerListener implements Listener { String name = e.getLastToken(); for (Entry nicknamekv : nicknames.entrySet()) { if (nicknamekv.getKey().startsWith(name.toLowerCase())) - e.getTabCompletions().add(PluginMain.essentials.getUser(Bukkit.getPlayer(nicknamekv.getValue())).getNick(true)); //Tabcomplete with the correct case + e.getTabCompletions().add(PluginMain.essentials.getUser(Bukkit.getPlayer(nicknamekv.getValue())).getNick(true)); //Tabcomplete with the correct case } } @@ -153,7 +155,7 @@ public class PlayerListener implements Listener { if (flair.length() > 0) e.addInfo("/r/TheButton flair: " + flair); } - e.addInfo(String.format("Respect: %.2f", cp.getF())); + e.addInfo(String.format("Respect: %.2f", cp.getF())); } catch (Exception ex) { TBMCCoreAPI.SendException("Error while providing chat info for player " + e.getPlayer().getFileName(), ex); } @@ -165,25 +167,20 @@ public class PlayerListener implements Listener { if (e.isCancelled()) return; HistoryCommand.addChatMessage(e.getCm(), e.getChannel()); - e.setCancelled(ChatProcessing.ProcessChat(e)); + e.setCancelled(FormatterComponent.handleChat(e)); } catch (NoClassDefFoundError | Exception ex) { // Weird things can happen - val str = "§c!§r[" + e.getChannel().DisplayName().get() + "] <" - + ThorpeUtils.getDisplayName(e.getSender()) + "> " + e.getMessage(); - for (Player p : Bukkit.getOnlinePlayers()) - if (e.shouldSendTo(p)) - p.sendMessage(str); - Bukkit.getConsoleSender().sendMessage(str); + ChatUtils.sendChatMessage(e, s -> "§c!§r" + s); TBMCCoreAPI.SendException("An error occured while processing a chat message!", ex); } } @EventHandler public void onNickChange(NickChangeEvent e) { - String nick = e.getValue(); - if (nick == null) - nicknames.inverse().remove(e.getAffected().getBase().getUniqueId()); - else - nicknames.inverse().forcePut(e.getAffected().getBase().getUniqueId(), ChatColor.stripColor(nick).toLowerCase()); + String nick = e.getValue(); + if (nick == null) + nicknames.inverse().remove(e.getAffected().getBase().getUniqueId()); + else + nicknames.inverse().forcePut(e.getAffected().getBase().getUniqueId(), ChatColor.stripColor(nick).toLowerCase()); Bukkit.getScheduler().runTaskLater(PluginMain.Instance, () -> { TownColorComponent.updatePlayerColors(e.getAffected().getBase()); //Won't fire this event again diff --git a/src/test/java/buttondevteam/chat/ChatFormatIT.java b/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java similarity index 86% rename from src/test/java/buttondevteam/chat/ChatFormatIT.java rename to src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java index d1ea14f..438155d 100644 --- a/src/test/java/buttondevteam/chat/ChatFormatIT.java +++ b/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java @@ -1,17 +1,21 @@ -package buttondevteam.chat; +package buttondevteam.chat.components.formatter; +import buttondevteam.chat.ChatUtils; +import buttondevteam.chat.ObjectTestRunner; import buttondevteam.chat.ObjectTestRunner.Objects; +import buttondevteam.chat.PluginMain; import buttondevteam.chat.commands.ucmds.admin.DebugCommand; -import buttondevteam.chat.formatting.ChatFormatter; -import buttondevteam.chat.formatting.TellrawEvent; -import buttondevteam.chat.formatting.TellrawEvent.ClickAction; -import buttondevteam.chat.formatting.TellrawEvent.HoverAction; -import buttondevteam.chat.formatting.TellrawPart; +import buttondevteam.chat.components.formatter.formatting.ChatFormatter; +import buttondevteam.chat.components.formatter.formatting.TellrawEvent; +import buttondevteam.chat.components.formatter.formatting.TellrawEvent.ClickAction; +import buttondevteam.chat.components.formatter.formatting.TellrawEvent.HoverAction; +import buttondevteam.chat.components.formatter.formatting.TellrawPart; import buttondevteam.core.TestPrepare; import buttondevteam.core.component.channel.Channel; import buttondevteam.lib.chat.Color; import net.milkbowl.vault.permission.Permission; import org.bukkit.command.CommandSender; +import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; @@ -19,8 +23,6 @@ import org.mockito.Mockito; import java.util.ArrayList; import java.util.List; -import static org.junit.Assert.assertEquals; - @RunWith(ObjectTestRunner.class) public class ChatFormatIT { @Objects @@ -92,15 +94,15 @@ public class ChatFormatIT { @Test public void testMessage() { ArrayList cfs = ChatProcessing.addFormatters(Color.White, p -> true); - final String chid = ChatProcessing.getChannelID(Channel.GlobalChat, ChatProcessing.MCORIGIN); - final TellrawPart tp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatProcessing.MCORIGIN); - ChatFormatter.Combine(cfs, message, tp); + final String chid = ChatProcessing.getChannelID(Channel.GlobalChat, ChatUtils.MCORIGIN); + final TellrawPart tp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatUtils.MCORIGIN); + ChatFormatter.Combine(cfs, message, tp, null); System.out.println("Testing: " + message); // System.out.println(ChatProcessing.toJson(tp)); - final TellrawPart expectedtp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatProcessing.MCORIGIN); + final TellrawPart expectedtp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatUtils.MCORIGIN); // System.out.println("Raw: " + ChatProcessing.toJson(expectedtp)); for (TellrawPart extra : extras) expectedtp.addExtra(extra); - assertEquals(ChatProcessing.toJson(expectedtp), ChatProcessing.toJson(tp)); + Assert.assertEquals(ChatProcessing.toJson(expectedtp), ChatProcessing.toJson(tp)); } } From 6a16a3a1d53f48d84573b14c41c352f65f5efc92 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 23 Sep 2019 13:41:24 +0200 Subject: [PATCH 15/20] Actually setting names for the formatters Also made the name and the pattern mandatory #85 --- .../components/formatter/ChatProcessing.java | 36 +++++++++---------- .../formatter/formatting/ChatFormatter.java | 11 +++++- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java index 8b7ae65..333048c 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java +++ b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java @@ -62,23 +62,23 @@ public class ChatProcessing { private static final Pattern WORD_PATTERN = Pattern.compile("\\S+"); private static boolean pingedconsole = false; - public static final ChatFormatter ESCAPE_FORMATTER = ChatFormatter.builder().regex(ESCAPE_PATTERN).build(); + public static final ChatFormatter ESCAPE_FORMATTER = ChatFormatter.builder("escape", ESCAPE_PATTERN).build(); private static ArrayList commonFormatters = Lists.newArrayList( - ChatFormatter.builder().regex(BOLD_PATTERN).bold(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range) + ChatFormatter.builder("bold", 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) + ChatFormatter.builder("italic", ITALIC_PATTERN).italic(true).removeCharCount((short) 1).type(ChatFormatter.Type.Range).build(), + ChatFormatter.builder("underlined", 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) + ChatFormatter.builder("strikethrough", STRIKETHROUGH_PATTERN).strikethrough(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range) .build(), - ChatFormatter.builder().regex(SPOILER_PATTERN).obfuscated(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range) + ChatFormatter.builder("spoiler", SPOILER_PATTERN).obfuscated(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range) .onmatch((match, cf, fs) -> { cf.setHoverText(match); return match; }).build(), - ESCAPE_FORMATTER, 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, section) -> { + ESCAPE_FORMATTER, ChatFormatter.builder("nullMention", NULL_MENTION_PATTERN).color(Color.DarkRed).build(), // Properly added a bug as a feature + ChatFormatter.builder("consolePing", CONSOLE_PING_PATTERN).color(Color.Aqua).onmatch((match, builder, section) -> { if (!pingedconsole) { System.out.print("\007"); pingedconsole = true; // Will set it to false in ProcessChat @@ -86,19 +86,19 @@ public class ChatProcessing { return match; }).priority(Priority.High).build(), - ChatFormatter.builder().regex(HASHTAG_PATTERN).color(Color.Blue).openlink("https://twitter.com/hashtag/$1") + ChatFormatter.builder("hashtag", 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) + ChatFormatter.builder("cyan", CYAN_PATTERN).color(Color.Aqua).build(), // #55 + ChatFormatter.builder("code", CODE_PATTERN).color(Color.DarkGray).removeCharCount((short) 1).type(ChatFormatter.Type.Range) .build(), - ChatFormatter.builder().regex(MASKED_LINK_PATTERN).underlined(true).onmatch((match, builder, section) -> { + ChatFormatter.builder("maskedLink", MASKED_LINK_PATTERN).underlined(true).onmatch((match, builder, section) -> { String text, link; if (section.Matches.size() < 2 || (text = section.Matches.get(0)).length() == 0 || (link = section.Matches.get(1)).length() == 0) return ""; builder.setOpenlink(link); return text; }).type(ChatFormatter.Type.Excluder).build(), - ChatFormatter.builder().regex(URL_PATTERN).underlined(true).openlink("$1").type(ChatFormatter.Type.Excluder).build()); + ChatFormatter.builder("url", URL_PATTERN).underlined(true).openlink("$1").type(ChatFormatter.Type.Excluder).build()); private static Gson gson = new GsonBuilder() .registerTypeHierarchyAdapter(TellrawSerializableEnum.class, new TellrawSerializer.TwEnum()) .registerTypeHierarchyAdapter(Collection.class, new TellrawSerializer.TwCollection()) @@ -149,14 +149,14 @@ public class ChatProcessing { formatters = addFormatters(colormode, e::shouldSendTo); if (colormode == channel.Color().get() && mp != null && mp.RainbowPresserColorMode) { // Only overwrite channel color final AtomicInteger rpc = new AtomicInteger(0); - formatters.add(ChatFormatter.builder().regex(WORD_PATTERN).color(colormode).onmatch((match, cf, s) -> { + formatters.add(ChatFormatter.builder("word", WORD_PATTERN).color(colormode).onmatch((match, cf, s) -> { cf.setColor(RainbowPresserColors[rpc.getAndUpdate(i -> ++i < RainbowPresserColors.length ? i : 0)]); return match; }).build()); } pingedconsole = false; // Will set it to true onmatch (static constructor) } else - formatters = Lists.newArrayList(ChatFormatter.builder().regex(ENTIRE_MESSAGE_PATTERN) + formatters = Lists.newArrayList(ChatFormatter.builder("entireMessage", ENTIRE_MESSAGE_PATTERN) .color(Color.White).priority(Priority.Low).build()); //This formatter is necessary TellrawPart json = createTellraw(sender, message, player, mp, e.getUser(), channelidentifier, e.getOrigin()); @@ -254,7 +254,7 @@ public class ChatProcessing { ArrayList formatters = (ArrayList) commonFormatters.clone(); formatters.add( - ChatFormatter.builder().regex(ENTIRE_MESSAGE_PATTERN).color(colormode).priority(Priority.Low).build()); + ChatFormatter.builder("entireMessage", 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")) { @@ -295,7 +295,7 @@ public class ChatProcessing { }; if (addNameFormatter) - formatters.add(ChatFormatter.builder().regex(Pattern.compile(namesb.toString())).color(Color.Aqua) + formatters.add(ChatFormatter.builder("name", Pattern.compile(namesb.toString())).color(Color.Aqua) .onmatch((match, builder, section) -> { Player p = Bukkit.getPlayer(match); Optional pn = nottest ? Optional.empty() @@ -313,7 +313,7 @@ public class ChatProcessing { }).priority(Priority.High).type(ChatFormatter.Type.Excluder).build()); if (addNickFormatter) - formatters.add(ChatFormatter.builder().regex((Pattern.compile(nicksb.toString()))).color(Color.Aqua) + formatters.add(ChatFormatter.builder("nickname", Pattern.compile(nicksb.toString())).color(Color.Aqua) .onmatch((match, builder, section) -> { 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())); diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java index dbd65ea..e39eef5 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java @@ -17,12 +17,13 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; /** - * A {@link ChatFormatter} shows what formatting to use based on regular expressions. {@link ChatFormatter#Combine(List, String, TellrawPart)} is used to turn it into a {@link TellrawPart}, combining + * A {@link ChatFormatter} shows what formatting to use based on regular expressions. {@link ChatFormatter#Combine(List, String, TellrawPart, IHaveConfig)} is used to turn it into a {@link TellrawPart}, combining * intersecting parts found, for example when {@code _abc*def*ghi_} is said in chat, it'll turn it into an underlined part, then an underlined and italics part, finally an underlined part * again. * * @author NorbiPeti */ +@SuppressWarnings("UnusedAssignment") @Data @Builder public final class ChatFormatter { @@ -44,6 +45,14 @@ public final class ChatFormatter { String hoverText; String name; + public static ChatFormatterBuilder builder(String name, Pattern regex) { + return builder().regex(regex).name(name); + } + + private static ChatFormatterBuilder builder() { + return new ChatFormatterBuilder(); + } + private ConfigData enabled(IHaveConfig config) { return config.getData(name + ".enabled", true); } From aa455e373df25daa5f296af80ec94e2b9bff01eb Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 30 Sep 2019 11:52:32 +0200 Subject: [PATCH 16/20] Only send the message to the same group #106 --- .../chat/components/formatter/ChatProcessing.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java index 333048c..e94372c 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java +++ b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java @@ -174,7 +174,7 @@ public class ChatProcessing { try { if (!channel.isGlobal()) { String senderGroup = e.getGroupID(sender); - if (senderGroup == null) { // Never send messages to score below 0 + if (senderGroup == null) { // Never send messages if the group is null sender.sendMessage("§cYou don't have permission to send this message or something went wrong"); return true; } @@ -187,7 +187,7 @@ public class ChatProcessing { group = null; // Don't send the message to them else group = VanillaUtils.getGroupIfChatOn(p, e); - if (group != null) + if (senderGroup.equals(group)) VanillaUtils.tellRaw(p, jsonstr); else if (tc != null) tc.handleSpies(channel, p); //Only sends if didn't send normally From a91ee1b8421ec11fde9bc7564805e5bc2ea4cd68 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 30 Sep 2019 15:55:25 +0200 Subject: [PATCH 17/20] Registering the formatter component Only disabling the chat handler if the component is enabled --- pom.xml | 2 +- src/main/java/buttondevteam/chat/PluginMain.java | 3 ++- .../chat/components/formatter/FormatterComponent.java | 5 +++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 9fca21e..7e928a4 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ maven-compiler-plugin - 3.3 + 3.8.1 1.8 1.8 diff --git a/src/main/java/buttondevteam/chat/PluginMain.java b/src/main/java/buttondevteam/chat/PluginMain.java index 89c4ed1..b6095a1 100644 --- a/src/main/java/buttondevteam/chat/PluginMain.java +++ b/src/main/java/buttondevteam/chat/PluginMain.java @@ -10,6 +10,7 @@ import buttondevteam.chat.commands.ucmds.admin.DebugCommand; import buttondevteam.chat.components.announce.AnnouncerComponent; import buttondevteam.chat.components.appendext.AppendTextComponent; import buttondevteam.chat.components.flair.FlairComponent; +import buttondevteam.chat.components.formatter.FormatterComponent; import buttondevteam.chat.components.fun.FunComponent; import buttondevteam.chat.components.towncolors.TownColorComponent; import buttondevteam.chat.components.towny.TownyComponent; @@ -52,7 +53,6 @@ public class PluginMain extends ButtonPlugin { // Translated to Java: 2015.07.15 TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this); TBMCCoreAPI.RegisterEventsForExceptions(new PlayerJoinLeaveListener(), this); - MainPlugin.Instance.setChatHandlerEnabled(false); //Disable Core chat handler Console = this.getServer().getConsoleSender(); if (Bukkit.getPluginManager().isPluginEnabled("Towny")) @@ -69,6 +69,7 @@ public class PluginMain extends ButtonPlugin { // Translated to Java: 2015.07.15 Component.registerComponent(this, new AnnouncerComponent()); Component.registerComponent(this, new FunComponent()); Component.registerComponent(this, new AppendTextComponent()); + Component.registerComponent(this, new FormatterComponent()); getCommand2MC().registerCommand(new DebugCommand()); getCommand2MC().registerCommand(new HelpCommand()); getCommand2MC().registerCommand(new HistoryCommand()); diff --git a/src/main/java/buttondevteam/chat/components/formatter/FormatterComponent.java b/src/main/java/buttondevteam/chat/components/formatter/FormatterComponent.java index fadc86c..6789b0d 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/FormatterComponent.java +++ b/src/main/java/buttondevteam/chat/components/formatter/FormatterComponent.java @@ -2,6 +2,7 @@ package buttondevteam.chat.components.formatter; import buttondevteam.chat.PluginMain; import buttondevteam.core.ComponentManager; +import buttondevteam.core.MainPlugin; import buttondevteam.lib.TBMCChatEvent; import buttondevteam.lib.architecture.Component; import buttondevteam.lib.architecture.ConfigData; @@ -17,12 +18,12 @@ public class FormatterComponent extends Component { @Override protected void enable() { - + MainPlugin.Instance.setChatHandlerEnabled(false); //Disable Core chat handler - if this component is disabled then let it do it's job } @Override protected void disable() { - + MainPlugin.Instance.setChatHandlerEnabled(true); } /** From cc6c477add9566d7060dd063317d7fe23d1f9336 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sun, 20 Oct 2019 02:29:54 +0200 Subject: [PATCH 18/20] Fixed TownyAnnouncer It took way too long to figure out how to add an appender that actually takes effect Also changed Towny dep, it'll likely break Travis builds --- .idea/ButtonChat.iml | 4 +-- pom.xml | 6 ++--- .../chat/components/towny/TownyAnnouncer.java | 27 +++++++++++++++---- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/.idea/ButtonChat.iml b/.idea/ButtonChat.iml index 966c902..f7d11c6 100644 --- a/.idea/ButtonChat.iml +++ b/.idea/ButtonChat.iml @@ -33,8 +33,8 @@ - - + + diff --git a/pom.xml b/pom.xml index 7e928a4..67c858b 100644 --- a/pom.xml +++ b/pom.xml @@ -168,7 +168,7 @@ projectlombok.org http://projectlombok.org/mavenrepo - + org.spigotmc @@ -199,9 +199,9 @@ provided - com.github.TownyAdvanced + com.palmergames.bukkit.towny Towny - 0.94.0.9 + 0.95.0.0 provided