From 0a4cdd01ce51afe20cf0e9f2a00014805ae80ea5 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 8 Feb 2020 01:44:19 +0100 Subject: [PATCH 01/12] New approach for chat processing Created different providers for regex, range and string matching Handling one match at a time per provider TODO: Formatters should be executed one by one in declaration order Add enitre message by default Loop until all of the providers are finished Ignore any areas returned by the providers #71 --- .../components/formatter/ChatProcessing.java | 6 +- .../formatter/formatting/ChatFormatUtils.java | 31 ++++++ .../formatter/formatting/ChatFormatter.java | 104 ++++-------------- .../formatter/formatting/FormatSettings.java | 18 +++ .../formatting/FormattedSection.java | 25 +---- .../formatter/formatting/MatchProvider.java | 11 ++ .../formatting/RangeMatchProvider.java | 39 +++++++ .../formatting/RegexMatchProvider.java | 44 ++++++++ .../formatting/StringMatchProvider.java | 42 +++++++ 9 files changed, 214 insertions(+), 106 deletions(-) create mode 100644 src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatUtils.java create mode 100644 src/main/java/buttondevteam/chat/components/formatter/formatting/FormatSettings.java create mode 100644 src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProvider.java create mode 100644 src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java create mode 100644 src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java create mode 100644 src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java diff --git a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java index f83933d..e099775 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java +++ b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java @@ -49,7 +49,6 @@ public class ChatProcessing { private static final Pattern CONSOLE_PING_PATTERN = Pattern.compile("(?i)" + Pattern.quote("@console")); private static final Pattern HASHTAG_PATTERN = Pattern.compile("#(\\w+)"); private static final Pattern URL_PATTERN = Pattern.compile("(http[\\w:/?=$\\-_.+!*'(),&]+(?:#[\\w]+)?)"); - public static final Pattern ENTIRE_MESSAGE_PATTERN = Pattern.compile(".+"); private static final Pattern UNDERLINED_PATTERN = Pattern.compile("__"); private static final Pattern ITALIC_PATTERN = Pattern.compile("\\*"); private static final Pattern ITALIC_PATTERN_2 = Pattern.compile("_"); @@ -64,7 +63,10 @@ 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("escape", ESCAPE_PATTERN).build(); + /** + * A special range formatter that removes the effect of the next formatter + */ + public static final ChatFormatter ESCAPE_FORMATTER = ChatFormatter.builder("escape", ESCAPE_PATTERN).type(ChatFormatter.Type.Range).build(); private static ArrayList commonFormatters = Lists.newArrayList( ChatFormatter.builder("bold", BOLD_PATTERN).bold(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range) diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatUtils.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatUtils.java new file mode 100644 index 0000000..00f6018 --- /dev/null +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatUtils.java @@ -0,0 +1,31 @@ +package buttondevteam.chat.components.formatter.formatting; + +import buttondevteam.chat.commands.ucmds.admin.DebugCommand; + +import java.util.ArrayList; +import java.util.Arrays; + +public final class ChatFormatUtils { + private ChatFormatUtils() {} + + static void sendMessageWithPointer(String str, int... pointer) { + DebugCommand.SendDebugMessage(str); + StringBuilder sb = new StringBuilder(str.length()); + Arrays.sort(pointer); + for (int i = 0; i < pointer.length; i++) { + for (int j = 0; j < pointer[i] - (i > 0 ? pointer[i - 1] + 1 : 0); j++) + sb.append(' '); + if (pointer[i] == (i > 0 ? pointer[i - 1] : -1)) + continue; + sb.append('^'); + } + DebugCommand.SendDebugMessage(sb.toString()); + } + + /** + * Check if the given start and end position is inside any of the ranges + */ + static boolean isInRange(int start, int end, ArrayList ranges) { + return ranges.stream().anyMatch(range -> range[1] >= start && range[0] <= end - 1); + } +} 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 14294f3..b9f6e4a 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java @@ -5,14 +5,12 @@ 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; import lombok.Data; import lombok.val; import java.util.*; import java.util.function.Predicate; -import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -28,16 +26,6 @@ import java.util.stream.Collectors; @Builder public final class ChatFormatter { Pattern regex; - boolean italic; - boolean bold; - boolean underlined; - boolean strikethrough; - boolean obfuscated; - Color color; - TriFunc onmatch; - String openlink; - @Builder.Default - Priority priority = Priority.Normal; @Builder.Default short removeCharCount = 0; @Builder.Default @@ -64,18 +52,6 @@ public final class ChatFormatter { return config.getData(name + ".enabled", true); } - 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 - } - @FunctionalInterface public interface TriFunc { R apply(T1 x1, T2 x2, T3 x3); @@ -101,8 +77,8 @@ public final class ChatFormatter { */ val remchars = new ArrayList(); - header("Range section conversion"); - sections = convertRangeSections(str, sections, remchars); + header("Range section creation"); + sections = createRangeSections(str, sections, formatters, remchars); header("Adding remove chars (RC)"); // Important to add after the range section conversion addRemChars(sections, remchars, str); @@ -117,28 +93,6 @@ public final class ChatFormatter { 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 void newCombine(String str, ArrayList sections, ArrayList remchars) { @@ -154,7 +108,7 @@ public final class ChatFormatter { } } - private static ArrayList convertRangeSections(String str, ArrayList sections, ArrayList remchars) { + private static ArrayList createRangeSections(String str, List formatters, ArrayList remchars) { ArrayList combined = new ArrayList<>(); Map nextSection = new HashMap<>(); boolean escaped = false; @@ -172,7 +126,7 @@ public final class ChatFormatter { combined.add(section); // The above will delete the \ DebugCommand.SendDebugMessage("Added section: " + section); } - sendMessageWithPointer(str, section.Start, section.End); + ChatFormatUtils.sendMessageWithPointer(str, section.Start, section.End); continue; } if (!escaped) { @@ -183,17 +137,17 @@ public final class ChatFormatter { */ if (takenByBigGuy || formatter.removeCharCount < takenEnd - takenStart) { DebugCommand.SendDebugMessage("Lose: " + section); - sendMessageWithPointer(str, section.Start, section.End); + ChatFormatUtils.sendMessageWithPointer(str, section.Start, section.End); DebugCommand.SendDebugMessage("And win: " + takenFormatter); continue; // The current section loses } nextSection.remove(takenFormatter); // The current section wins DebugCommand.SendDebugMessage("Win: " + section); - sendMessageWithPointer(str, section.Start, section.End); + ChatFormatUtils.sendMessageWithPointer(str, section.Start, section.End); DebugCommand.SendDebugMessage("And lose: " + takenFormatter); } boolean hasFormatter = nextSection.containsKey(formatter); - if (!hasFormatter) { + /*if (!hasFormatter) { val ff = formatter; val cfo = nextSection.keySet().stream().filter(f -> f.removeCharCount > ff.removeCharCount).findAny(); if (cfo.isPresent()) { @@ -205,7 +159,7 @@ public final class ChatFormatter { continue; //Not the formatter we're looking for - TODO: It doesn't fix the problem of italics at the end } } - } + }*/ takenStart = section.Start; takenEnd = section.Start + formatter.removeCharCount; takenFormatter = formatter; @@ -218,19 +172,19 @@ public final class ChatFormatter { combined.add(s); takenByBigGuy = true; DebugCommand.SendDebugMessage("Finished section: " + s); - sendMessageWithPointer(str, s.Start, s.End); + ChatFormatUtils.sendMessageWithPointer(str, s.Start, s.End); } else { DebugCommand.SendDebugMessage("Adding next section: " + section); - sendMessageWithPointer(str, section.Start, section.End); + ChatFormatUtils.sendMessageWithPointer(str, section.Start, section.End); nextSection.put(formatter, section); takenByBigGuy = false; } DebugCommand .SendDebugMessage("New area taken: (" + takenStart + "-" + takenEnd + ") " + takenFormatter); - sendMessageWithPointer(str, takenStart, takenEnd); + ChatFormatUtils.sendMessageWithPointer(str, takenStart, takenEnd); } else { DebugCommand.SendDebugMessage("Skipping section: " + section); // This will keep the text (character) - sendMessageWithPointer(str, section.Start, section.End); + ChatFormatUtils.sendMessageWithPointer(str, section.Start, section.End); escaped = false; // Reset escaping if applied, like if we're at the '*' in '\*' } } @@ -250,7 +204,7 @@ public final class ChatFormatter { .forEach(remchars::add); DebugCommand.SendDebugMessage("Added remchars:"); DebugCommand.SendDebugMessage(remchars.stream().map(Arrays::toString).collect(Collectors.joining("; "))); - sendMessageWithPointer(str, + ChatFormatUtils.sendMessageWithPointer(str, remchars.stream().flatMapToInt(Arrays::stream).toArray()); } @@ -271,15 +225,15 @@ public final class ChatFormatter { lastSection = lastSect; } DebugCommand.SendDebugMessage("Combining sections " + firstSection); - sendMessageWithPointer(str, firstSection.Start, firstSection.End); + ChatFormatUtils.sendMessageWithPointer(str, firstSection.Start, firstSection.End); DebugCommand.SendDebugMessage(" and " + lastSection); - sendMessageWithPointer(str, lastSection.Start, lastSection.End); + ChatFormatUtils.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); firstSection.type = lastSection.type; DebugCommand.SendDebugMessage("To section " + firstSection); - sendMessageWithPointer(str, firstSection.Start, firstSection.End); + ChatFormatUtils.sendMessageWithPointer(str, firstSection.Start, firstSection.End); sections.remove(i); i = 0; sortSections(sections); @@ -305,7 +259,7 @@ public final class ChatFormatter { Predicate removeIfNeeded = s -> { if (s.Start < 0 || s.End < 0 || s.Start > s.End) { DebugCommand.SendDebugMessage(" Removed: " + s); - sendMessageWithPointer(str, s.Start, s.End); + ChatFormatUtils.sendMessageWithPointer(str, s.Start, s.End); sections.remove(s); return true; } @@ -315,15 +269,15 @@ public final class ChatFormatter { DebugCommand.SendDebugMessage("To sections"); if (!removeIfNeeded.test(firstSection)) { DebugCommand.SendDebugMessage(" 1:" + firstSection + ""); - sendMessageWithPointer(str, firstSection.Start, firstSection.End); + ChatFormatUtils.sendMessageWithPointer(str, firstSection.Start, firstSection.End); } if (!removeIfNeeded.test(section)) { DebugCommand.SendDebugMessage(" 2:" + section + ""); - sendMessageWithPointer(str, section.Start, section.End); + ChatFormatUtils.sendMessageWithPointer(str, section.Start, section.End); } if (!removeIfNeeded.test(lastSection)) { DebugCommand.SendDebugMessage(" 3:" + lastSection); - sendMessageWithPointer(str, lastSection.Start, lastSection.End); + ChatFormatUtils.sendMessageWithPointer(str, lastSection.Start, lastSection.End); } i = 0; } @@ -332,7 +286,7 @@ public final class ChatFormatter { for (int j = i - 1; j <= i + 1; j++) { if (j < sections.size() && sections.get(j).End < sections.get(j).Start) { DebugCommand.SendDebugMessage("Removing section: " + sections.get(j)); - sendMessageWithPointer(str, sections.get(j).Start, sections.get(j).End); + ChatFormatUtils.sendMessageWithPointer(str, sections.get(j).Start, sections.get(j).End); sections.remove(j); j--; i = 0; @@ -349,7 +303,7 @@ public final class ChatFormatter { String originaltext; int start = section.Start, end = section.End; DebugCommand.SendDebugMessage("Start: " + start + " - End: " + end); - sendMessageWithPointer(str, start, end); + ChatFormatUtils.sendMessageWithPointer(str, start, end); /*DebugCommand.SendDebugMessage("RCS: "+remchars.stream().filter(rc -> rc[0] <= start && start <= rc[1]).count()); DebugCommand.SendDebugMessage("RCE: "+remchars.stream().filter(rc -> rc[0] <= end && end <= rc[1]).count()); DebugCommand.SendDebugMessage("RCI: "+remchars.stream().filter(rc -> start < rc[0] || rc[1] < end).count());*/ @@ -432,20 +386,6 @@ public final class ChatFormatter { : Integer.compare(s1.Start, s2.Start)); } - private static void sendMessageWithPointer(String str, int... pointer) { - DebugCommand.SendDebugMessage(str); - StringBuilder sb = new StringBuilder(str.length()); - Arrays.sort(pointer); - for (int i = 0; i < pointer.length; i++) { - for (int j = 0; j < pointer[i] - (i > 0 ? pointer[i - 1] + 1 : 0); j++) - sb.append(' '); - if (pointer[i] == (i > 0 ? pointer[i - 1] : -1)) - continue; - sb.append('^'); - } - DebugCommand.SendDebugMessage(sb.toString()); - } - private static void header(String message) { DebugCommand.SendDebugMessage("\n--------\n" + message + "\n--------\n"); } diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/FormatSettings.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormatSettings.java new file mode 100644 index 0000000..39dce46 --- /dev/null +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormatSettings.java @@ -0,0 +1,18 @@ +package buttondevteam.chat.components.formatter.formatting; + +import buttondevteam.lib.chat.Color; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class FormatSettings { + boolean italic; + boolean bold; + boolean underlined; + boolean strikethrough; + boolean obfuscated; + Color color; + ChatFormatter.TriFunc onmatch; + String openlink; +} diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java index c609e58..0345479 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java @@ -1,36 +1,17 @@ package buttondevteam.chat.components.formatter.formatting; import java.util.ArrayList; -import java.util.Collection; public class FormattedSection { public int Start; public int End; - public ArrayList Formatters = new ArrayList(); + public FormatSettings Settings; public ArrayList Matches = new ArrayList(); - public ChatFormatter.Type type; - FormattedSection(ChatFormatter formatter, int start, int end, ArrayList matches, ChatFormatter.Type type) { + FormattedSection(FormatSettings settings, int start, int end, ArrayList matches) { Start = start; End = end; - Formatters.add(formatter); + Settings = settings; Matches.addAll(matches); - this.type = type; - } - - FormattedSection(Collection formatters, int start, int end, ArrayList matches, - ChatFormatter.Type type) { - Start = start; - End = end; - Formatters.addAll(formatters); - Matches.addAll(matches); - this.type = type; - } - - @Override - public String toString() { - return "Section(" + Start + ", " + End + ", formatters: " + - Formatters.toString() + ", matches: " + Matches.toString() + ", " + - type + ")"; } } \ No newline at end of file diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProvider.java new file mode 100644 index 0000000..db6a388 --- /dev/null +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProvider.java @@ -0,0 +1,11 @@ +package buttondevteam.chat.components.formatter.formatting; + +import javax.annotation.Nullable; +import java.util.ArrayList; + +public interface MatchProvider { + @Nullable + FormattedSection getNextSection(String message, ArrayList ignoredAreas, ArrayList removedCharacters); + + boolean isFinished(); +} diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java new file mode 100644 index 0000000..eefe32b --- /dev/null +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java @@ -0,0 +1,39 @@ +package buttondevteam.chat.components.formatter.formatting; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.ArrayList; + +@RequiredArgsConstructor +public class RangeMatchProvider implements MatchProvider { + private final String pattern; + private final FormatSettings settings; + @Getter + private boolean finished; + private int nextIndex = 0; + private FormattedSection startedSection; + + @SuppressWarnings("DuplicatedCode") + @Override + public FormattedSection getNextSection(String message, ArrayList ignoredAreas, ArrayList removedCharacters) { + int i, len; + do { + i = message.indexOf(pattern, nextIndex); + len = pattern.length(); + nextIndex = i + len; //Set for the next loop if it's escaped or for the next method call + } while (i > 0 && message.charAt(i - 1) == '\\'); + if (i == -1) { + finished = true; //Won't find any more - unfinished sections will be garbage collected + return null; + } + removedCharacters.add(new int[]{i, i + len - 1}); + if (startedSection == null) { + startedSection = new FormattedSection(settings, i, i + len - 1, new ArrayList<>(0)); + return null; + } else { + startedSection.End = i + len - 1; + return startedSection; + } + } +} diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java new file mode 100644 index 0000000..af2fc72 --- /dev/null +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java @@ -0,0 +1,44 @@ +package buttondevteam.chat.components.formatter.formatting; + +import buttondevteam.chat.commands.ucmds.admin.DebugCommand; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@RequiredArgsConstructor +public class RegexMatchProvider implements MatchProvider { + private final Pattern pattern; + private final FormatSettings settings; + private Matcher matcher; + @Getter + private boolean finished; + + @Nullable + @Override + public FormattedSection getNextSection(String message, ArrayList ignoredAreas, ArrayList removedCharacters) { + if (matcher == null) + matcher = pattern.matcher(message); + if (!matcher.find()) { + finished = true; + return null; + } + int start = matcher.start(), end = matcher.end() - 1; + DebugCommand.SendDebugMessage("Found regex match from " + start + " to " + end); + DebugCommand.SendDebugMessage("With settings: " + settings); + ChatFormatUtils.sendMessageWithPointer(message, start, end); + if (ChatFormatUtils.isInRange(start, end, ignoredAreas)) { + DebugCommand.SendDebugMessage("Formatter is in ignored area, skipping"); + return null; //Not setting finished to true, so it will go to the next match + } + 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)); + return new FormattedSection(settings, matcher.start(), matcher.end() - 1, groups); + } +} diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java new file mode 100644 index 0000000..bcab617 --- /dev/null +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java @@ -0,0 +1,42 @@ +package buttondevteam.chat.components.formatter.formatting; + +import lombok.Getter; + +import javax.annotation.Nullable; +import java.util.ArrayList; + +public class StringMatchProvider implements MatchProvider { + private final String[] strings; + private final FormatSettings settings; + @Getter + private boolean finished; + private int nextIndex = 0; + + /** + * Matches the given strings in the order given + * + * @param settings The format settings + * @param strings The strings to match in the correct order + */ + public StringMatchProvider(FormatSettings settings, String... strings) { + this.settings = settings; + this.strings = strings; + } + + @Nullable + @Override + public FormattedSection getNextSection(String message, ArrayList ignoredAreas, ArrayList removedCharacters) { + int i = -1, len = 0; + for (String string : strings) { + i = message.indexOf(string, nextIndex); + len = string.length(); + if (i != -1) break; + } + if (i == -1) { + finished = true; //Won't find any more + return null; + } + nextIndex = i + len; + return new FormattedSection(settings, i, i + len - 1, new ArrayList<>(0)); + } +} -- 2.30.2 From 1dc801575adea6b6ecd28e9118db5b47f9ef9d70 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 10 Feb 2020 13:46:39 +0100 Subject: [PATCH 02/12] GH Releases, formatter work, removed old code TBMCPlugins/ChromaCore#76 --- .idea/ButtonChat.iml | 2 +- .travis.yml | 15 +- .../formatter/formatting/ChatFormatter.java | 225 +++--------------- .../formatter/formatting/FormatSettings.java | 15 +- .../formatting/FormattedSection.java | 5 +- .../formatter/formatting/MatchProvider.java | 2 + .../formatting/MatchProviderBase.java | 26 ++ .../formatting/RangeMatchProvider.java | 23 +- .../formatting/RegexMatchProvider.java | 13 +- .../formatting/StringMatchProvider.java | 15 +- 10 files changed, 122 insertions(+), 219 deletions(-) create mode 100644 src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProviderBase.java diff --git a/.idea/ButtonChat.iml b/.idea/ButtonChat.iml index c640e48..215cb7a 100644 --- a/.idea/ButtonChat.iml +++ b/.idea/ButtonChat.iml @@ -19,7 +19,7 @@ - + diff --git a/.travis.yml b/.travis.yml index 1d962ae..f241e78 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,15 +13,10 @@ jdk: sudo: true dist: trusty # Needed for Java 8, although we might not need Java 8 deploy: - # deploy develop to the staging environment - - provider: script - script: chmod +x deploy.sh && sh deploy.sh staging + - provider: releases + api_key: + secure: "F5YiEuD6LyRENUDMCslcSl0O0dg4IDk+nNeb4X2VLYlmb8dW9beMuIgjH8efTMeaQ3D/ntIkN0Dtf2GKvpOduhwkSbAgw4WM028X60SY9f2hmpEO3LmM4T1tKoDlI1T3BmhYP4KeTKBYn+etV1mSPbT07vUybCm/vGzvr96yMZGNFEoKsWLaEu7dZfBFULj4tXOwrLh/KO6BsdAHvZcGKWNVupPq3YoUVT0dpGcUudf5cpn+aaqMwyd709zgMbyCuqf+c5Udps43q4EKvr9z7TWxFUkGTPVVAcUVygJsi2ytuyA8TLMPq/KhYe9htnkNUnizbqv/j49xww0gVaD7OJXENJ4hAUTV4sdn1DXG45JXW+dir3V7YzbRYn3M+eCuKB2O77SXRZBkxcGtTMtCmghP9/tcRAQlXDXnxu7oAnlUVp17g/+aFApvlzZEZVx2N+fkyEe7JrUFlRCixtHyrmTLWhyV0Px9p0FHJpvSSCL0S0UKVAT/sNHYHhD5gouK7owEomEbG58XCsRDH6Et7RuDksB98ekK8brZp6S7dNIS2CVuVx1vIkXC8PzUGcpJQoztvEYUE20Axahh5s8AkE9n/O9jzs9ajcfYaHhWzYeUZzHdHllOYF9l6VoCUitTk4Sl8eJifSq3GzI+T6wGMBepZHLpe230MvBIrqGZ+Vg=" + file: 'Chroma-Core/target/Chroma-Core.jar' on: - branch: dev - skip_cleanup: true - # deploy master to production - - provider: script - script: chmod +x deploy.sh && sh deploy.sh production - on: - branch: master + tags: true skip_cleanup: true 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 b9f6e4a..104cb23 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java @@ -1,8 +1,6 @@ package buttondevteam.chat.components.formatter.formatting; 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 lombok.Builder; @@ -11,7 +9,6 @@ import lombok.val; import java.util.*; import java.util.function.Predicate; -import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -21,35 +18,10 @@ import java.util.stream.Collectors; * * @author NorbiPeti */ -@SuppressWarnings("UnusedAssignment") @Data @Builder public final class ChatFormatter { - Pattern regex; - @Builder.Default - short removeCharCount = 0; - @Builder.Default - Type type = Type.Normal; - String hoverText; - String name; - - @Override - public String toString() { - return "ChatFormatter{" + - "name='" + 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); + private ChatFormatter() { } @FunctionalInterface @@ -57,7 +29,7 @@ public final class ChatFormatter { R apply(T1 x1, T2 x2, T3 x3); } - public static void Combine(List formatters, String str, TellrawPart tp, IHaveConfig config) { + public static void Combine(List formatters, String str, TellrawPart tp, IHaveConfig config) { /* * This method assumes that there is always a global formatter */ @@ -66,22 +38,14 @@ public final class ChatFormatter { 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)"); - createSections(formatters, str, sections, false); - sortSections(sections); - + var excluded = new ArrayList(); /* * 0: Start - 1: End index */ val remchars = new ArrayList(); - header("Range section creation"); - sections = createRangeSections(str, sections, formatters, remchars); - - header("Adding remove chars (RC)"); // Important to add after the range section conversion - addRemChars(sections, remchars, str); + createSections(formatters, str, sections, excluded, remchars); + sortSections(sections); header("Section combining"); combineSections(str, sections); @@ -91,123 +55,16 @@ public final class ChatFormatter { header("ChatFormatter.Combine done"); } - private static void createSections(List formatters, String str, ArrayList sections, - boolean excluders) { - } - - private static void newCombine(String str, ArrayList sections, ArrayList remchars) { - var stack = new Stack(); - for (int i = 0; i < str.length(); i++) { - for (Iterator iterator = sections.iterator(); iterator.hasNext(); ) { - FormattedSection section = iterator.next(); - if (section.Start <= i) { - stack.push(section); - iterator.remove(); - } - } + private static void createSections(List formatters, String str, ArrayList sections, + ArrayList excludedAreas, ArrayList removedCharacters) { + sections.add(new FormattedSection(FormatSettings.builder().color(Color.White).build(), 0, str.length() - 1, Collections.emptyList())); + for (var formatter : formatters) { + var sect = formatter.getNextSection(str, excludedAreas, removedCharacters); + if (sect != null) + sections.add(sect); } } - private static ArrayList createRangeSections(String str, List formatters, ArrayList remchars) { - ArrayList combined = new ArrayList<>(); - Map nextSection = new HashMap<>(); - boolean escaped = false; - int takenStart = -1, takenEnd = -1; - ChatFormatter takenFormatter = null; - boolean takenByBigGuy = false; //Can't win against him (finished sections take precedence) - for (final FormattedSection section : sections) { - // Set ending to -1 until closed with another 1 long "section" - only do this if IsRange is true - 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 - 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); - } - ChatFormatUtils.sendMessageWithPointer(str, section.Start, section.End); - continue; - } - if (!escaped) { - ChatFormatter formatter = section.Formatters.get(0); - 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) { - */ - if (takenByBigGuy || formatter.removeCharCount < takenEnd - takenStart) { - DebugCommand.SendDebugMessage("Lose: " + section); - ChatFormatUtils.sendMessageWithPointer(str, section.Start, section.End); - DebugCommand.SendDebugMessage("And win: " + takenFormatter); - continue; // The current section loses - } - nextSection.remove(takenFormatter); // The current section wins - DebugCommand.SendDebugMessage("Win: " + section); - ChatFormatUtils.sendMessageWithPointer(str, section.Start, section.End); - DebugCommand.SendDebugMessage("And lose: " + takenFormatter); - } - boolean hasFormatter = nextSection.containsKey(formatter); - /*if (!hasFormatter) { - val ff = formatter; - val cfo = nextSection.keySet().stream().filter(f -> f.removeCharCount > ff.removeCharCount).findAny(); - if (cfo.isPresent()) { - //formatter = cfo.get(); - val s = nextSection.get(cfo.get()); - int takenS = section.Start, takenE = section.Start + formatter.removeCharCount; - if (s.Start == takenS || (s.Start > takenS && s.Start < takenE)) { //Peek() - hasFormatter = true; - continue; //Not the formatter we're looking for - TODO: It doesn't fix the problem of italics at the end - } - } - }*/ - takenStart = section.Start; - takenEnd = section.Start + formatter.removeCharCount; - takenFormatter = formatter; - if (hasFormatter) { - FormattedSection s = nextSection.remove(formatter); - //HACK? If we can find another section that removes more characters, finish that instead - // section: the ending marker section - s: the to-be full section - s.End = takenEnd - 1; //Take the remCharCount into account as well - // s.IsRange = false; // IsRange means it's a 1 long section indicating a start or an end - combined.add(s); - takenByBigGuy = true; - DebugCommand.SendDebugMessage("Finished section: " + s); - ChatFormatUtils.sendMessageWithPointer(str, s.Start, s.End); - } else { - DebugCommand.SendDebugMessage("Adding next section: " + section); - ChatFormatUtils.sendMessageWithPointer(str, section.Start, section.End); - nextSection.put(formatter, section); - takenByBigGuy = false; - } - DebugCommand - .SendDebugMessage("New area taken: (" + takenStart + "-" + takenEnd + ") " + takenFormatter); - ChatFormatUtils.sendMessageWithPointer(str, takenStart, takenEnd); - } else { - DebugCommand.SendDebugMessage("Skipping section: " + section); // This will keep the text (character) - ChatFormatUtils.sendMessageWithPointer(str, section.Start, section.End); - escaped = false; // Reset escaping if applied, like if we're at the '*' in '\*' - } - } - //Do not finish unfinished sections, ignore them - sections = combined; - return sections; - } - - private static void addRemChars(ArrayList sections, ArrayList remchars, String str) { - 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(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(remchars::add); - DebugCommand.SendDebugMessage("Added remchars:"); - DebugCommand.SendDebugMessage(remchars.stream().map(Arrays::toString).collect(Collectors.joining("; "))); - ChatFormatUtils.sendMessageWithPointer(str, - remchars.stream().flatMapToInt(Arrays::stream).toArray()); - } - private static void combineSections(String str, ArrayList sections) { for (int i = 1; i < sections.size(); i++) { DebugCommand.SendDebugMessage("i: " + i); @@ -229,9 +86,8 @@ public final class ChatFormatter { DebugCommand.SendDebugMessage(" and " + lastSection); ChatFormatUtils.sendMessageWithPointer(str, lastSection.Start, lastSection.End); if (firstSection.Start == lastSection.Start && firstSection.End == lastSection.End) { - firstSection.Formatters.addAll(lastSection.Formatters); + firstSection.Settings.copyFrom(lastSection.Settings); firstSection.Matches.addAll(lastSection.Matches); - firstSection.type = lastSection.type; DebugCommand.SendDebugMessage("To section " + firstSection); ChatFormatUtils.sendMessageWithPointer(str, firstSection.Start, firstSection.End); sections.remove(i); @@ -242,14 +98,13 @@ public final class ChatFormatter { 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); + FormattedSection section = new FormattedSection(firstSection.Settings, lastSection.Start, origend, + firstSection.Matches); + section.Settings.copyFrom(lastSection.Settings); section.Matches.addAll(lastSection.Matches); // TODO: Clean sections.add(i, section); // Use the properties of the first section not the second one - lastSection.Formatters.clear(); - lastSection.Formatters.addAll(firstSection.Formatters); + lastSection.Settings = firstSection.Settings; lastSection.Matches.clear(); lastSection.Matches.addAll(firstSection.Matches); @@ -331,29 +186,28 @@ public final class ChatFormatter { } 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 + //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) - originaltext = formatter.onmatch.apply(originaltext, formatter, section); - if (formatter.color != null) - newtp.setColor(formatter.color); - if (formatter.bold) - newtp.setBold(true); - if (formatter.italic) - newtp.setItalic(true); - if (formatter.underlined) - newtp.setUnderlined(true); - if (formatter.strikethrough) - newtp.setStrikethrough(true); - if (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)); - } + var settings = section.Settings; + DebugCommand.SendDebugMessage("Applying settings: " + settings); + if (settings.onmatch != null) + originaltext = settings.onmatch.apply(originaltext, settings, section); + if (settings.color != null) + newtp.setColor(settings.color); + if (settings.bold) + newtp.setBold(true); + if (settings.italic) + newtp.setItalic(true); + if (settings.underlined) + newtp.setUnderlined(true); + if (settings.strikethrough) + newtp.setStrikethrough(true); + if (settings.obfuscated) + newtp.setObfuscated(true); + if (settings.openlink != null) + openlink = settings.openlink; + if (settings.hoverText != null) + newtp.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, settings.hoverText)); if (lasttp != null && newtp.getColor() == lasttp.getColor() && newtp.isBold() == lasttp.isBold() && newtp.isItalic() == lasttp.isItalic() @@ -381,8 +235,7 @@ public final class ChatFormatter { 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(s1.End, s2.End) + ? s1.End == s2.End ? 0 : Integer.compare(s1.End, s2.End) //TODO: Test : Integer.compare(s1.Start, s2.Start)); } diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/FormatSettings.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormatSettings.java index 39dce46..12d1ee9 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/FormatSettings.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormatSettings.java @@ -13,6 +13,19 @@ public class FormatSettings { boolean strikethrough; boolean obfuscated; Color color; - ChatFormatter.TriFunc onmatch; + ChatFormatter.TriFunc onmatch; String openlink; + String hoverText; + + public void copyFrom(FormatSettings settings) { + try { + for (var field : FormatSettings.class.getDeclaredFields()) + if (field.getType() == boolean.class && field.getBoolean(settings)) + field.setBoolean(this, true); //Set to true if either of them are true + else if (field.get(this) == null) + field.set(this, field.get(settings)); + } catch (Exception e) { + e.printStackTrace(); + } + } } diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java index 0345479..324c8e1 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java @@ -1,14 +1,15 @@ package buttondevteam.chat.components.formatter.formatting; import java.util.ArrayList; +import java.util.List; public class FormattedSection { public int Start; public int End; public FormatSettings Settings; - public ArrayList Matches = new ArrayList(); + public List Matches = new ArrayList(); - FormattedSection(FormatSettings settings, int start, int end, ArrayList matches) { + FormattedSection(FormatSettings settings, int start, int end, List matches) { Start = start; End = end; Settings = settings; diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProvider.java index db6a388..f232dd8 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProvider.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProvider.java @@ -8,4 +8,6 @@ public interface MatchProvider { FormattedSection getNextSection(String message, ArrayList ignoredAreas, ArrayList removedCharacters); boolean isFinished(); + + String getName(); } diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProviderBase.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProviderBase.java new file mode 100644 index 0000000..ccefcb5 --- /dev/null +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProviderBase.java @@ -0,0 +1,26 @@ +package buttondevteam.chat.components.formatter.formatting; + +import buttondevteam.lib.architecture.ConfigData; +import buttondevteam.lib.architecture.IHaveConfig; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import javax.annotation.Nullable; +import java.util.ArrayList; + +@RequiredArgsConstructor +public abstract class MatchProviderBase implements MatchProvider { + @Getter + protected boolean finished; + @Getter + private final String name; + + @Nullable + @Override + public abstract FormattedSection getNextSection(String message, ArrayList ignoredAreas, ArrayList removedCharacters); + + ConfigData enabled(IHaveConfig config) { + return config.getData(name + ".enabled", true); + } + +} diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java index eefe32b..909f7c3 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java @@ -1,19 +1,22 @@ package buttondevteam.chat.components.formatter.formatting; -import lombok.Getter; -import lombok.RequiredArgsConstructor; +import buttondevteam.chat.commands.ucmds.admin.DebugCommand; import java.util.ArrayList; +import java.util.Collections; -@RequiredArgsConstructor -public class RangeMatchProvider implements MatchProvider { +public class RangeMatchProvider extends MatchProviderBase { private final String pattern; private final FormatSettings settings; - @Getter - private boolean finished; private int nextIndex = 0; private FormattedSection startedSection; + public RangeMatchProvider(String name, String pattern, FormatSettings settings) { + super(name); + this.pattern = pattern; + this.settings = settings; + } + @SuppressWarnings("DuplicatedCode") @Override public FormattedSection getNextSection(String message, ArrayList ignoredAreas, ArrayList removedCharacters) { @@ -29,9 +32,15 @@ public class RangeMatchProvider implements MatchProvider { } removedCharacters.add(new int[]{i, i + len - 1}); if (startedSection == null) { - startedSection = new FormattedSection(settings, i, i + len - 1, new ArrayList<>(0)); + DebugCommand.SendDebugMessage("Started range match from " + i + " to " + (i + len - 1)); + DebugCommand.SendDebugMessage("With settings: " + settings); + ChatFormatUtils.sendMessageWithPointer(message, i, i + len - 1); + startedSection = new FormattedSection(settings, i, i + len - 1, Collections.emptyList()); return null; } else { + DebugCommand.SendDebugMessage("Finished range match from " + i + " to " + (i + len - 1)); + DebugCommand.SendDebugMessage("With settings: " + settings); + ChatFormatUtils.sendMessageWithPointer(message, i, i + len - 1); startedSection.End = i + len - 1; return startedSection; } diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java index af2fc72..213592f 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java @@ -1,21 +1,22 @@ package buttondevteam.chat.components.formatter.formatting; import buttondevteam.chat.commands.ucmds.admin.DebugCommand; -import lombok.Getter; -import lombok.RequiredArgsConstructor; import javax.annotation.Nullable; import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; -@RequiredArgsConstructor -public class RegexMatchProvider implements MatchProvider { +public class RegexMatchProvider extends MatchProviderBase { private final Pattern pattern; private final FormatSettings settings; private Matcher matcher; - @Getter - private boolean finished; + + public RegexMatchProvider(String name, Pattern pattern, FormatSettings settings) { + super(name); + this.pattern = pattern; + this.settings = settings; + } @Nullable @Override diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java index bcab617..dc197de 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java @@ -1,15 +1,14 @@ package buttondevteam.chat.components.formatter.formatting; -import lombok.Getter; +import buttondevteam.chat.commands.ucmds.admin.DebugCommand; import javax.annotation.Nullable; import java.util.ArrayList; +import java.util.Collections; -public class StringMatchProvider implements MatchProvider { +public class StringMatchProvider extends MatchProviderBase { private final String[] strings; private final FormatSettings settings; - @Getter - private boolean finished; private int nextIndex = 0; /** @@ -18,7 +17,8 @@ public class StringMatchProvider implements MatchProvider { * @param settings The format settings * @param strings The strings to match in the correct order */ - public StringMatchProvider(FormatSettings settings, String... strings) { + public StringMatchProvider(String name, FormatSettings settings, String... strings) { + super(name); this.settings = settings; this.strings = strings; } @@ -37,6 +37,9 @@ public class StringMatchProvider implements MatchProvider { return null; } nextIndex = i + len; - return new FormattedSection(settings, i, i + len - 1, new ArrayList<>(0)); + DebugCommand.SendDebugMessage("Found string match from " + i + " to " + (i + len - 1)); + DebugCommand.SendDebugMessage("With settings: " + settings); + ChatFormatUtils.sendMessageWithPointer(message, i, i + len - 1); + return new FormattedSection(settings, i, i + len - 1, Collections.emptyList()); } } -- 2.30.2 From 30ee99d49515627f28aa5c3aa2d396219e389dd0 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Wed, 12 Feb 2020 12:45:42 +0100 Subject: [PATCH 03/12] Converted formatters to match providers --- .idea/ButtonChat.iml | 38 ++++++ .../components/formatter/ChatProcessing.java | 119 +++++++----------- .../formatter/formatting/ChatFormatter.java | 10 +- 3 files changed, 89 insertions(+), 78 deletions(-) diff --git a/.idea/ButtonChat.iml b/.idea/ButtonChat.iml index 215cb7a..aa60b82 100644 --- a/.idea/ButtonChat.iml +++ b/.idea/ButtonChat.iml @@ -50,5 +50,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java index e099775..6587cc2 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java +++ b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java @@ -6,10 +6,7 @@ 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.formatter.formatting.*; import buttondevteam.chat.components.fun.FunComponent; import buttondevteam.chat.components.towny.TownyComponent; import buttondevteam.chat.listener.PlayerListener; @@ -63,55 +60,48 @@ public class ChatProcessing { private static final Pattern WORD_PATTERN = Pattern.compile("\\S+"); private static boolean pingedconsole = false; - /** - * A special range formatter that removes the effect of the next formatter - */ - public static final ChatFormatter ESCAPE_FORMATTER = ChatFormatter.builder("escape", ESCAPE_PATTERN).type(ChatFormatter.Type.Range).build(); - - private static ArrayList commonFormatters = Lists.newArrayList( - ChatFormatter.builder("bold", BOLD_PATTERN).bold(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range) - .priority(Priority.High).build(), - ChatFormatter.builder("italic", ITALIC_PATTERN).italic(true).removeCharCount((short) 1).type(ChatFormatter.Type.Range).build(), - ChatFormatter.builder("italic2", ITALIC_PATTERN_2).italic(true).removeCharCount((short) 1).type(ChatFormatter.Type.Range).build(), - ChatFormatter.builder("underlined", UNDERLINED_PATTERN).underlined(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range) - .build(), - ChatFormatter.builder("strikethrough", STRIKETHROUGH_PATTERN).strikethrough(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range) - .build(), - ChatFormatter.builder("spoiler", SPOILER_PATTERN).obfuscated(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range) + private static ArrayList commonFormatters = Lists.newArrayList( + new RangeMatchProvider("bold", "**", FormatSettings.builder().bold(true).build()), + new RangeMatchProvider("italic", "*", FormatSettings.builder().italic(true).build()), + new RangeMatchProvider("italic2", "_", FormatSettings.builder().italic(true).build()), + new RangeMatchProvider("underlined", "__", FormatSettings.builder().underlined(true).build()), + new RangeMatchProvider("strikethrough", "~~", FormatSettings.builder().strikethrough(true).build()), + new RangeMatchProvider("spoiler", "||", FormatSettings.builder().obfuscated(true) .onmatch((match, cf, fs) -> { cf.setHoverText(match); return match; - }).build(), - 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 - } - return match; - }).priority(Priority.High).build(), + }).build()), + new StringMatchProvider("nullMention", FormatSettings.builder().color(Color.DarkRed).build(), "null"), // Properly added a bug as a feature + new StringMatchProvider("consolePing", FormatSettings.builder().color(Color.Aqua) + .onmatch((match, builder, section) -> { + if (!pingedconsole) { + System.out.print("\007"); + pingedconsole = true; // Will set it to false in ProcessChat + } + return match; + }).build(), "@console"), - ChatFormatter.builder("hashtag", HASHTAG_PATTERN).color(Color.Blue).openlink("https://twitter.com/hashtag/$1") - .priority(Priority.High).build(), - 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("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("url", URL_PATTERN).underlined(true).openlink("$1").type(ChatFormatter.Type.Excluder).build(), - ChatFormatter.builder("someone", SOMEONE_PATTERN).color(Color.Aqua).onmatch((match, builder, section) -> { - if (Bukkit.getOnlinePlayers().size() == 0) return match; - var players = ImmutableList.copyOf(Bukkit.getOnlinePlayers()); - var playerC = new Random().nextInt(players.size()); - var player = players.get(playerC); - playPingSound(player, ComponentManager.getIfEnabled(FormatterComponent.class)); - return "@someone (" + player.getDisplayName() + "§r)"; - }).build()); + new RegexMatchProvider("hashtag", HASHTAG_PATTERN, FormatSettings.builder().color(Color.Blue).openlink("https://twitter.com/hashtag/$1").build()), + new StringMatchProvider("cyan", FormatSettings.builder().color(Color.Aqua).build(), "cyan"), // #55 + new RangeMatchProvider("code", "`", FormatSettings.builder().color(Color.DarkGray).build()), + new RegexMatchProvider("maskedLink", MASKED_LINK_PATTERN, FormatSettings.builder().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; + }).build()), + new RegexMatchProvider("url", URL_PATTERN, FormatSettings.builder().underlined(true).openlink("$1").build()), + new StringMatchProvider("someone", FormatSettings.builder().color(Color.Aqua) + .onmatch((match, builder, section) -> { + if (Bukkit.getOnlinePlayers().size() == 0) return match; + var players = ImmutableList.copyOf(Bukkit.getOnlinePlayers()); + var playerC = new Random().nextInt(players.size()); + var player = players.get(playerC); + playPingSound(player, ComponentManager.getIfEnabled(FormatterComponent.class)); + return "@someone (" + player.getDisplayName() + "§r)"; + }).build())); private static Gson gson = new GsonBuilder() .registerTypeHierarchyAdapter(TellrawSerializableEnum.class, new TellrawSerializer.TwEnum()) .registerTypeHierarchyAdapter(Collection.class, new TellrawSerializer.TwCollection()) @@ -157,7 +147,7 @@ public class ChatProcessing { colormode = Color.Green; // If greentext, ignore channel or player colors - ArrayList formatters; + ArrayList formatters; if (component.allowFormatting().get()) { formatters = addFormatters(colormode, e::shouldSendTo, component); if (colormode == channel.Color().get() && mp != null && mp.RainbowPresserColorMode) { // Only overwrite channel color @@ -165,8 +155,7 @@ public class ChatProcessing { } pingedconsole = false; // Will set it to true onmatch (static constructor) } else - formatters = Lists.newArrayList(ChatFormatter.builder("entireMessage", ENTIRE_MESSAGE_PATTERN) - .color(Color.White).priority(Priority.Low).build()); //This formatter is necessary + formatters = Lists.newArrayList(); TellrawPart json = createTellraw(sender, message, player, mp, e.getUser(), channelidentifier, e.getOrigin()); long combinetime = System.nanoTime(); @@ -266,31 +255,19 @@ public class ChatProcessing { + "]"; } - static ArrayList addFormatters(Color colormode, Predicate canSee, @Nullable FormatterComponent component) { + static ArrayList addFormatters(Color colormode, Predicate canSee, @Nullable FormatterComponent component) { @SuppressWarnings("unchecked") - ArrayList formatters = (ArrayList) commonFormatters.clone(); - - formatters.add( - ChatFormatter.builder("entireMessage", ENTIRE_MESSAGE_PATTERN).color(colormode).priority(Priority.Low).build()); + ArrayList formatters = (ArrayList) commonFormatters.clone(); boolean nottest; //Not assigning a default value, so that it can only be used in the if if ((nottest = Bukkit.getOnlinePlayers().size() > 0) || Bukkit.getVersion().equals("test")) { - StringBuilder namesb = new StringBuilder("(?i)("); - boolean addNameFormatter = false; //Needed because some names may be filtered out if they can't see the channel + String[] names; if (nottest) - for (Player p : Bukkit.getOnlinePlayers()) { - if (canSee.test(p)) { - namesb.append(p.getName()).append("|"); - addNameFormatter = true; - } - } + names = Bukkit.getOnlinePlayers().stream().filter(canSee).map(CommandSender::getName).toArray(String[]::new); else { - for (String testPlayer : testPlayers) - namesb.append(testPlayer).append("|"); - addNameFormatter = true; + names = new String[testPlayers.length]; + System.arraycopy(testPlayers, 0, names, 0, testPlayers.length); } - namesb.deleteCharAt(namesb.length() - 1); - namesb.append(")"); StringBuilder nicksb = new StringBuilder("(?i)("); boolean addNickFormatter = false; for (Player p : Bukkit.getOnlinePlayers()) { @@ -311,7 +288,7 @@ public class ChatProcessing { System.out.println(message); }; - if (addNameFormatter) + if (names.length > 0) formatters.add(ChatFormatter.builder("name", Pattern.compile(namesb.toString())).color(Color.Aqua) .onmatch((match, builder, section) -> { Player p = Bukkit.getPlayer(match); 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 104cb23..ffffd68 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java @@ -3,8 +3,6 @@ package buttondevteam.chat.components.formatter.formatting; import buttondevteam.chat.commands.ucmds.admin.DebugCommand; import buttondevteam.lib.architecture.IHaveConfig; import buttondevteam.lib.chat.Color; -import lombok.Builder; -import lombok.Data; import lombok.val; import java.util.*; @@ -17,9 +15,7 @@ import java.util.stream.Collectors; * again. * * @author NorbiPeti - */ -@Data -@Builder + */ //TODO: Update doc public final class ChatFormatter { private ChatFormatter() { } @@ -31,7 +27,7 @@ public final class ChatFormatter { public static void Combine(List formatters, String str, TellrawPart tp, IHaveConfig config) { /* - * This method assumes that there is always a global formatter + * A global formatter is no longer needed */ header("ChatFormatter.Combine begin"); ArrayList sections = new ArrayList<>(); @@ -57,7 +53,7 @@ public final class ChatFormatter { private static void createSections(List formatters, String str, ArrayList sections, ArrayList excludedAreas, ArrayList removedCharacters) { - sections.add(new FormattedSection(FormatSettings.builder().color(Color.White).build(), 0, str.length() - 1, Collections.emptyList())); + sections.add(new FormattedSection(FormatSettings.builder().color(Color.White).build(), 0, str.length() - 1, Collections.emptyList())); //Add entire message for (var formatter : formatters) { var sect = formatter.getNextSection(str, excludedAreas, removedCharacters); if (sect != null) -- 2.30.2 From 0dbfaa65a5f1621c4095b4b1ffb558880d73d07f Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Wed, 12 Feb 2020 19:16:05 +0100 Subject: [PATCH 04/12] Fix remaining compiler errors The italics test works so far --- .idea/ButtonChat.iml | 38 ++++++++++++++ .../components/formatter/ChatProcessing.java | 49 +++++-------------- .../formatter/formatting/ChatFormatter.java | 22 ++++++--- .../formatting/FormattedSection.java | 3 ++ .../formatting/MatchProviderBase.java | 3 ++ .../formatting/RangeMatchProvider.java | 3 ++ .../formatting/RegexMatchProvider.java | 3 ++ .../formatting/StringMatchProvider.java | 3 ++ .../components/formatter/ChatFormatIT.java | 8 ++- 9 files changed, 83 insertions(+), 49 deletions(-) diff --git a/.idea/ButtonChat.iml b/.idea/ButtonChat.iml index aa60b82..a340893 100644 --- a/.idea/ButtonChat.iml +++ b/.idea/ButtonChat.iml @@ -88,5 +88,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java index 6587cc2..d6b955e 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java +++ b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java @@ -16,7 +16,6 @@ import buttondevteam.lib.TBMCChatEvent; import buttondevteam.lib.TBMCChatEventBase; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.chat.Color; -import buttondevteam.lib.chat.Priority; import buttondevteam.lib.chat.TellrawSerializableEnum; import buttondevteam.lib.player.ChromaGamerBase; import buttondevteam.lib.player.TBMCPlayer; @@ -40,21 +39,9 @@ import java.util.function.Predicate; import java.util.regex.Pattern; public class ChatProcessing { - private static final Pattern NULL_MENTION_PATTERN = Pattern.compile("null"); - private static final Pattern CYAN_PATTERN = Pattern.compile("cyan"); - private static final Pattern ESCAPE_PATTERN = Pattern.compile("\\\\"); - private static final Pattern CONSOLE_PING_PATTERN = Pattern.compile("(?i)" + Pattern.quote("@console")); private static final Pattern HASHTAG_PATTERN = Pattern.compile("#(\\w+)"); private static final Pattern URL_PATTERN = Pattern.compile("(http[\\w:/?=$\\-_.+!*'(),&]+(?:#[\\w]+)?)"); - private static final Pattern UNDERLINED_PATTERN = Pattern.compile("__"); - private static final Pattern ITALIC_PATTERN = Pattern.compile("\\*"); - private static final Pattern ITALIC_PATTERN_2 = Pattern.compile("_"); - private static final Pattern BOLD_PATTERN = Pattern.compile("\\*\\*"); - private static final Pattern CODE_PATTERN = Pattern.compile("`"); private static final Pattern MASKED_LINK_PATTERN = Pattern.compile("\\[([^\\[\\]]+)]\\(([^()]+)\\)"); - private static final Pattern SOMEONE_PATTERN = Pattern.compile("@someone"); - private static final Pattern STRIKETHROUGH_PATTERN = Pattern.compile("~~"); - private static final Pattern SPOILER_PATTERN = Pattern.compile("\\|\\|"); private static final Color[] RainbowPresserColors = new Color[]{Color.Red, Color.Gold, Color.Yellow, Color.Green, Color.Blue, Color.DarkPurple}; private static final Pattern WORD_PATTERN = Pattern.compile("\\S+"); @@ -149,7 +136,7 @@ public class ChatProcessing { ArrayList formatters; if (component.allowFormatting().get()) { - formatters = addFormatters(colormode, e::shouldSendTo, component); + formatters = addFormatters(e::shouldSendTo, component); if (colormode == channel.Color().get() && mp != null && mp.RainbowPresserColorMode) { // Only overwrite channel color createRPC(colormode, formatters); } @@ -159,7 +146,7 @@ public class ChatProcessing { TellrawPart json = createTellraw(sender, message, player, mp, e.getUser(), channelidentifier, e.getOrigin()); long combinetime = System.nanoTime(); - ChatFormatter.Combine(formatters, message, json, component.getConfig()); + ChatFormatter.Combine(formatters, message, json, component.getConfig(), FormatSettings.builder().color(colormode).build()); combinetime = System.nanoTime() - combinetime; String jsonstr = toJson(json); if (jsonstr.length() >= 32767) { @@ -204,12 +191,12 @@ public class ChatProcessing { return false; } - static void createRPC(Color colormode, ArrayList formatters) { + static void createRPC(Color colormode, ArrayList formatters) { final AtomicInteger rpc = new AtomicInteger(0); - formatters.add(ChatFormatter.builder("rpc", WORD_PATTERN).color(colormode).onmatch((match, cf, s) -> { + formatters.add(new RegexMatchProvider("rpc", WORD_PATTERN, FormatSettings.builder().color(colormode).onmatch((match, cf, s) -> { cf.setColor(RainbowPresserColors[rpc.getAndUpdate(i -> ++i < RainbowPresserColors.length ? i : 0)]); return match; - }).build()); + }).build())); } public static String toJson(TellrawPart json) { @@ -255,7 +242,7 @@ public class ChatProcessing { + "]"; } - static ArrayList addFormatters(Color colormode, Predicate canSee, @Nullable FormatterComponent component) { + static ArrayList addFormatters(Predicate canSee, @Nullable FormatterComponent component) { @SuppressWarnings("unchecked") ArrayList formatters = (ArrayList) commonFormatters.clone(); @@ -268,18 +255,8 @@ public class ChatProcessing { names = new String[testPlayers.length]; System.arraycopy(testPlayers, 0, names, 0, testPlayers.length); } - 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("|"); - addNickFormatter = true; - } - } - nicksb.deleteCharAt(nicksb.length() - 1); - nicksb.append(")"); + String[] nicknames = Bukkit.getOnlinePlayers().stream().filter(canSee).map(Player::getUniqueId).map(PlayerListener.nicknames.inverse()::get) + .filter(Objects::nonNull).toArray(String[]::new); Consumer error = message -> { if (PluginMain.Instance != null) @@ -289,7 +266,7 @@ public class ChatProcessing { }; if (names.length > 0) - formatters.add(ChatFormatter.builder("name", Pattern.compile(namesb.toString())).color(Color.Aqua) + formatters.add(new StringMatchProvider("name", FormatSettings.builder().color(Color.Aqua) .onmatch((match, builder, section) -> { Player p = Bukkit.getPlayer(match); Optional pn = nottest ? Optional.empty() @@ -304,10 +281,10 @@ public class ChatProcessing { } String color = String.format("§%x", (mpp.GetFlairColor() == 0x00 ? 0xb : mpp.GetFlairColor())); return color + (nottest ? p.getName() : pn.get()) + "§r"; //Fix name casing, except when testing - }).priority(Priority.High).type(ChatFormatter.Type.Excluder).build()); + }).build(), names)); - if (addNickFormatter) - formatters.add(ChatFormatter.builder("nickname", Pattern.compile(nicksb.toString())).color(Color.Aqua) + if (nicknames.length > 0) + formatters.add(new StringMatchProvider("nickname", FormatSettings.builder().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())); @@ -322,7 +299,7 @@ public class ChatProcessing { error.accept("Player nicknamed " + match.toLowerCase() + " not found in nickname map but was reported as online."); return "§c" + match + "§r"; - }).priority(Priority.High).type(ChatFormatter.Type.Excluder).build()); + }).build(), nicknames)); } return formatters; } 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 ffffd68..e3d8cbd 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java @@ -25,7 +25,7 @@ public final class ChatFormatter { R apply(T1 x1, T2 x2, T3 x3); } - public static void Combine(List formatters, String str, TellrawPart tp, IHaveConfig config) { + public static void Combine(List formatters, String str, TellrawPart tp, IHaveConfig config, FormatSettings defaults) { /* * A global formatter is no longer needed */ @@ -40,7 +40,7 @@ public final class ChatFormatter { */ val remchars = new ArrayList(); - createSections(formatters, str, sections, excluded, remchars); + createSections(formatters, str, sections, excluded, remchars, defaults); sortSections(sections); header("Section combining"); @@ -52,12 +52,18 @@ public final class ChatFormatter { } private static void createSections(List formatters, String str, ArrayList sections, - ArrayList excludedAreas, ArrayList removedCharacters) { - sections.add(new FormattedSection(FormatSettings.builder().color(Color.White).build(), 0, str.length() - 1, Collections.emptyList())); //Add entire message - for (var formatter : formatters) { - var sect = formatter.getNextSection(str, excludedAreas, removedCharacters); - if (sect != null) - sections.add(sect); + ArrayList excludedAreas, ArrayList removedCharacters, FormatSettings defaults) { + sections.add(new FormattedSection(defaults, 0, str.length() - 1, Collections.emptyList())); //Add entire message + while (formatters.size() > 0) { + for (var iterator = formatters.iterator(); iterator.hasNext(); ) { + MatchProviderBase formatter = iterator.next(); + DebugCommand.SendDebugMessage("Checking provider: " + formatter); + var sect = formatter.getNextSection(str, excludedAreas, removedCharacters); + if (sect != null) + sections.add(sect); + if (formatter.isFinished()) + iterator.remove(); + } } } diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java index 324c8e1..f6bab89 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java @@ -1,8 +1,11 @@ package buttondevteam.chat.components.formatter.formatting; +import lombok.ToString; + import java.util.ArrayList; import java.util.List; +@ToString public class FormattedSection { public int Start; public int End; diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProviderBase.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProviderBase.java index ccefcb5..548a007 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProviderBase.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProviderBase.java @@ -19,6 +19,9 @@ public abstract class MatchProviderBase implements MatchProvider { @Override public abstract FormattedSection getNextSection(String message, ArrayList ignoredAreas, ArrayList removedCharacters); + @Override + public abstract String toString(); + ConfigData enabled(IHaveConfig config) { return config.getData(name + ".enabled", true); } diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java index 909f7c3..c28e9d1 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java @@ -1,12 +1,15 @@ package buttondevteam.chat.components.formatter.formatting; import buttondevteam.chat.commands.ucmds.admin.DebugCommand; +import lombok.ToString; import java.util.ArrayList; import java.util.Collections; +@ToString public class RangeMatchProvider extends MatchProviderBase { private final String pattern; + @ToString.Exclude private final FormatSettings settings; private int nextIndex = 0; private FormattedSection startedSection; diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java index 213592f..477c616 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java @@ -1,14 +1,17 @@ package buttondevteam.chat.components.formatter.formatting; import buttondevteam.chat.commands.ucmds.admin.DebugCommand; +import lombok.ToString; import javax.annotation.Nullable; import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; +@ToString public class RegexMatchProvider extends MatchProviderBase { private final Pattern pattern; + @ToString.Exclude private final FormatSettings settings; private Matcher matcher; diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java index dc197de..beabce1 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java @@ -1,13 +1,16 @@ package buttondevteam.chat.components.formatter.formatting; import buttondevteam.chat.commands.ucmds.admin.DebugCommand; +import lombok.ToString; import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Collections; +@ToString public class StringMatchProvider extends MatchProviderBase { private final String[] strings; + @ToString.Exclude private final FormatSettings settings; private int nextIndex = 0; diff --git a/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java b/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java index 8b39810..a119584 100644 --- a/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java +++ b/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java @@ -5,11 +5,9 @@ import buttondevteam.chat.ObjectTestRunner; import buttondevteam.chat.ObjectTestRunner.Objects; import buttondevteam.chat.PluginMain; import buttondevteam.chat.commands.ucmds.admin.DebugCommand; -import buttondevteam.chat.components.formatter.formatting.ChatFormatter; -import buttondevteam.chat.components.formatter.formatting.TellrawEvent; +import buttondevteam.chat.components.formatter.formatting.*; 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; @@ -109,12 +107,12 @@ public class ChatFormatIT { @Test public void testMessage() { - ArrayList cfs = ChatProcessing.addFormatters(Color.White, p -> true, null); + ArrayList cfs = ChatProcessing.addFormatters(p -> true, null); final String chid = ChatProcessing.getChannelID(Channel.GlobalChat, ChatUtils.MCORIGIN); if (rainbowMode) ChatProcessing.createRPC(Color.White, cfs); final TellrawPart tp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatUtils.MCORIGIN); - ChatFormatter.Combine(cfs, message, tp, null); + ChatFormatter.Combine(cfs, message, tp, null, FormatSettings.builder().color(Color.White).build()); System.out.println("Testing: " + message); // System.out.println(ChatProcessing.toJson(tp)); final TellrawPart expectedtp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatUtils.MCORIGIN); -- 2.30.2 From 4d0c7c170e2b7f48e5981f7a2fb38cdebf1ee480 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Thu, 13 Feb 2020 00:24:31 +0100 Subject: [PATCH 05/12] Fix many issues with the chat processing #71 --- .../components/formatter/ChatProcessing.java | 24 +++++++------- .../formatter/formatting/ChatFormatUtils.java | 6 +++- .../formatter/formatting/ChatFormatter.java | 30 +++++++++++------ .../formatter/formatting/FormatSettings.java | 12 ++++--- .../formatting/FormattedSection.java | 3 +- .../formatter/formatting/MatchProvider.java | 5 +++ .../formatting/MatchProviderBase.java | 7 ++++ .../formatting/RangeMatchProvider.java | 32 +++++++++++++------ .../formatting/RegexMatchProvider.java | 8 ++++- .../formatting/StringMatchProvider.java | 21 +++++++++++- 10 files changed, 109 insertions(+), 39 deletions(-) diff --git a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java index d6b955e..fc94817 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java +++ b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java @@ -50,26 +50,26 @@ public class ChatProcessing { private static ArrayList commonFormatters = Lists.newArrayList( new RangeMatchProvider("bold", "**", FormatSettings.builder().bold(true).build()), new RangeMatchProvider("italic", "*", FormatSettings.builder().italic(true).build()), - new RangeMatchProvider("italic2", "_", FormatSettings.builder().italic(true).build()), new RangeMatchProvider("underlined", "__", FormatSettings.builder().underlined(true).build()), + new RangeMatchProvider("italic2", "_", FormatSettings.builder().italic(true).build()), new RangeMatchProvider("strikethrough", "~~", FormatSettings.builder().strikethrough(true).build()), new RangeMatchProvider("spoiler", "||", FormatSettings.builder().obfuscated(true) .onmatch((match, cf, fs) -> { cf.setHoverText(match); return match; }).build()), - new StringMatchProvider("nullMention", FormatSettings.builder().color(Color.DarkRed).build(), "null"), // Properly added a bug as a feature + new StringMatchProvider("nullMention", FormatSettings.builder().color(Color.DarkRed).build(), true, "null"), // Properly added a bug as a feature new StringMatchProvider("consolePing", FormatSettings.builder().color(Color.Aqua) .onmatch((match, builder, section) -> { if (!pingedconsole) { System.out.print("\007"); pingedconsole = true; // Will set it to false in ProcessChat } - return match; - }).build(), "@console"), + return "@console"; + }).build(), true, "@console"), new RegexMatchProvider("hashtag", HASHTAG_PATTERN, FormatSettings.builder().color(Color.Blue).openlink("https://twitter.com/hashtag/$1").build()), - new StringMatchProvider("cyan", FormatSettings.builder().color(Color.Aqua).build(), "cyan"), // #55 + new StringMatchProvider("cyan", FormatSettings.builder().color(Color.Aqua).build(), true, "cyan"), // #55 new RangeMatchProvider("code", "`", FormatSettings.builder().color(Color.DarkGray).build()), new RegexMatchProvider("maskedLink", MASKED_LINK_PATTERN, FormatSettings.builder().underlined(true) .onmatch((match, builder, section) -> { @@ -88,7 +88,7 @@ public class ChatProcessing { var player = players.get(playerC); playPingSound(player, ComponentManager.getIfEnabled(FormatterComponent.class)); return "@someone (" + player.getDisplayName() + "§r)"; - }).build())); + }).build(), true, "@someone")); private static Gson gson = new GsonBuilder() .registerTypeHierarchyAdapter(TellrawSerializableEnum.class, new TellrawSerializer.TwEnum()) .registerTypeHierarchyAdapter(Collection.class, new TellrawSerializer.TwCollection()) @@ -265,8 +265,8 @@ public class ChatProcessing { System.out.println(message); }; - if (names.length > 0) - formatters.add(new StringMatchProvider("name", FormatSettings.builder().color(Color.Aqua) + if (names.length > 0) //Add as first so it handles special characters (_) - TODO: But after URLs + formatters.add(0, new StringMatchProvider("name", FormatSettings.builder().color(Color.Aqua) .onmatch((match, builder, section) -> { Player p = Bukkit.getPlayer(match); Optional pn = nottest ? Optional.empty() @@ -281,10 +281,10 @@ public class ChatProcessing { } String color = String.format("§%x", (mpp.GetFlairColor() == 0x00 ? 0xb : mpp.GetFlairColor())); return color + (nottest ? p.getName() : pn.get()) + "§r"; //Fix name casing, except when testing - }).build(), names)); + }).build(), true, names)); - if (nicknames.length > 0) - formatters.add(new StringMatchProvider("nickname", FormatSettings.builder().color(Color.Aqua) + if (nicknames.length > 0) //Add as first so it handles special characters + formatters.add(0, new StringMatchProvider("nickname", FormatSettings.builder().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())); @@ -299,7 +299,7 @@ public class ChatProcessing { error.accept("Player nicknamed " + match.toLowerCase() + " not found in nickname map but was reported as online."); return "§c" + match + "§r"; - }).build(), nicknames)); + }).build(), true, nicknames)); } return formatters; } diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatUtils.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatUtils.java index 00f6018..20d2083 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatUtils.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatUtils.java @@ -4,6 +4,7 @@ import buttondevteam.chat.commands.ucmds.admin.DebugCommand; import java.util.ArrayList; import java.util.Arrays; +import java.util.stream.Collectors; public final class ChatFormatUtils { private ChatFormatUtils() {} @@ -26,6 +27,9 @@ public final class ChatFormatUtils { * Check if the given start and end position is inside any of the ranges */ static boolean isInRange(int start, int end, ArrayList ranges) { - return ranges.stream().anyMatch(range -> range[1] >= start && range[0] <= end - 1); + System.out.println("Ranges: " + ranges.stream().map(x -> x[0] + "-" + x[1]).collect(Collectors.joining(", "))); + System.out.println("In range: " + start + " " + end + ": " + + ranges.stream().filter(range -> range[1] >= start && range[0] <= end).map(x -> x[0] + "-" + x[1]).findAny().orElse("none")); + return ranges.stream().anyMatch(range -> range[1] >= start && range[0] <= end); } } 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 e3d8cbd..87e3b3a 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java @@ -10,7 +10,7 @@ import java.util.function.Predicate; import java.util.stream.Collectors; /** - * 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 + * A {@link ChatFormatter} shows what formatting to use based on regular expressions. {@link ChatFormatter#Combine(List, String, TellrawPart, IHaveConfig, FormatSettings)}} 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. * @@ -40,6 +40,8 @@ public final class ChatFormatter { */ val remchars = new ArrayList(); + escapeThings(str, excluded, remchars); + createSections(formatters, str, sections, excluded, remchars, defaults); sortSections(sections); @@ -51,18 +53,32 @@ public final class ChatFormatter { header("ChatFormatter.Combine done"); } + private static void escapeThings(String str, ArrayList ignoredAreas, ArrayList remchars) { + boolean escaped = false; + for (int i = 0; i < str.length(); i++) { + if (str.charAt(i) == '\\') { + remchars.add(new int[]{i, i}); + ignoredAreas.add(new int[]{i + 1, i + 1}); + i++; //Ignore a potential second slash + } + } + } + private static void createSections(List formatters, String str, ArrayList sections, - ArrayList excludedAreas, ArrayList removedCharacters, FormatSettings defaults) { + ArrayList excludedAreas, ArrayList removedCharacters, FormatSettings defaults) { sections.add(new FormattedSection(defaults, 0, str.length() - 1, Collections.emptyList())); //Add entire message + formatters.forEach(MatchProviderBase::reset); //Reset state information, as we aren't doing deep cloning while (formatters.size() > 0) { for (var iterator = formatters.iterator(); iterator.hasNext(); ) { MatchProviderBase formatter = iterator.next(); DebugCommand.SendDebugMessage("Checking provider: " + formatter); var sect = formatter.getNextSection(str, excludedAreas, removedCharacters); - if (sect != null) + if (sect != null) //Not excluding the area here because the range matcher shouldn't take it all sections.add(sect); - if (formatter.isFinished()) + if (formatter.isFinished()) { + DebugCommand.SendDebugMessage("Provider finished"); iterator.remove(); + } } } } @@ -103,12 +119,8 @@ public final class ChatFormatter { FormattedSection section = new FormattedSection(firstSection.Settings, lastSection.Start, origend, firstSection.Matches); section.Settings.copyFrom(lastSection.Settings); - section.Matches.addAll(lastSection.Matches); // TODO: Clean + section.Matches.addAll(lastSection.Matches); sections.add(i, section); - // Use the properties of the first section not the second one - lastSection.Settings = firstSection.Settings; - lastSection.Matches.clear(); - lastSection.Matches.addAll(firstSection.Matches); lastSection.Start = origend + 1; lastSection.End = origend2; diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/FormatSettings.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormatSettings.java index 12d1ee9..f4fe9c7 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/FormatSettings.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormatSettings.java @@ -19,11 +19,15 @@ public class FormatSettings { public void copyFrom(FormatSettings settings) { try { - for (var field : FormatSettings.class.getDeclaredFields()) - if (field.getType() == boolean.class && field.getBoolean(settings)) - field.setBoolean(this, true); //Set to true if either of them are true - else if (field.get(this) == null) + for (var field : FormatSettings.class.getDeclaredFields()) { + if (field.getType() == boolean.class) { + if (field.getBoolean(settings)) + field.setBoolean(this, true); //Set to true if either of them are true + } else if (field.get(settings) != null) { + //System.out.println("Setting " + field.getType() + " " + field.getName() + " from " + field.get(this) + " to " + field.get(settings)); field.set(this, field.get(settings)); + } + } } catch (Exception e) { e.printStackTrace(); } diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java index f6bab89..f1b0de1 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java @@ -15,7 +15,8 @@ public class FormattedSection { FormattedSection(FormatSettings settings, int start, int end, List matches) { Start = start; End = end; - Settings = settings; + Settings = FormatSettings.builder().build(); + Settings.copyFrom(settings); Matches.addAll(matches); } } \ No newline at end of file diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProvider.java index f232dd8..13dafca 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProvider.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProvider.java @@ -10,4 +10,9 @@ public interface MatchProvider { boolean isFinished(); String getName(); + + @Override + String toString(); + + void reset(); } diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProviderBase.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProviderBase.java index 548a007..8bfa824 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProviderBase.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProviderBase.java @@ -22,6 +22,13 @@ public abstract class MatchProviderBase implements MatchProvider { @Override public abstract String toString(); + protected abstract void resetSubclass(); + + public void reset() { + finished = false; + resetSubclass(); + } + ConfigData enabled(IHaveConfig config) { return config.getData(name + ".enabled", true); } diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java index c28e9d1..4df0b22 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java @@ -24,16 +24,18 @@ public class RangeMatchProvider extends MatchProviderBase { @Override public FormattedSection getNextSection(String message, ArrayList ignoredAreas, ArrayList removedCharacters) { int i, len; - do { - i = message.indexOf(pattern, nextIndex); - len = pattern.length(); - nextIndex = i + len; //Set for the next loop if it's escaped or for the next method call - } while (i > 0 && message.charAt(i - 1) == '\\'); + i = message.indexOf(pattern, nextIndex); + len = pattern.length(); + nextIndex = i + len; //Set for the next method call if (i == -1) { finished = true; //Won't find any more - unfinished sections will be garbage collected return null; } - removedCharacters.add(new int[]{i, i + len - 1}); + if (ChatFormatUtils.isInRange(i, i + len - 1, ignoredAreas)) { + DebugCommand.SendDebugMessage("Range start is in ignored area, skipping"); + return null; //Not setting finished to true, so it will go to the next match + } + ignoredAreas.add(new int[]{i, i + len - 1}); if (startedSection == null) { DebugCommand.SendDebugMessage("Started range match from " + i + " to " + (i + len - 1)); DebugCommand.SendDebugMessage("With settings: " + settings); @@ -41,11 +43,21 @@ public class RangeMatchProvider extends MatchProviderBase { startedSection = new FormattedSection(settings, i, i + len - 1, Collections.emptyList()); return null; } else { - DebugCommand.SendDebugMessage("Finished range match from " + i + " to " + (i + len - 1)); + var section = startedSection; + DebugCommand.SendDebugMessage("Finished range match from " + section.Start + " to " + (i + len - 1)); DebugCommand.SendDebugMessage("With settings: " + settings); - ChatFormatUtils.sendMessageWithPointer(message, i, i + len - 1); - startedSection.End = i + len - 1; - return startedSection; + ChatFormatUtils.sendMessageWithPointer(message, section.Start, i + len - 1); + section.End = i + len - 1; + removedCharacters.add(new int[]{section.Start, section.Start + len - 1}); + removedCharacters.add(new int[]{i, i + len - 1}); + startedSection = null; //Reset so next find creates a new one + return section; } } + + @Override + public void resetSubclass() { + nextIndex = 0; + startedSection = null; + } } diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java index 477c616..bbd4b84 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java @@ -35,7 +35,7 @@ public class RegexMatchProvider extends MatchProviderBase { DebugCommand.SendDebugMessage("With settings: " + settings); ChatFormatUtils.sendMessageWithPointer(message, start, end); if (ChatFormatUtils.isInRange(start, end, ignoredAreas)) { - DebugCommand.SendDebugMessage("Formatter is in ignored area, skipping"); + DebugCommand.SendDebugMessage("Match is in ignored area, skipping"); return null; //Not setting finished to true, so it will go to the next match } ArrayList groups = new ArrayList<>(); @@ -43,6 +43,12 @@ public class RegexMatchProvider extends MatchProviderBase { groups.add(matcher.group(i + 1)); if (groups.size() > 0) DebugCommand.SendDebugMessage("First group: " + groups.get(0)); + ignoredAreas.add(new int[]{start, end}); return new FormattedSection(settings, matcher.start(), matcher.end() - 1, groups); } + + @Override + public void resetSubclass() { + matcher = null; + } } diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java index beabce1..9ed3d8d 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java @@ -13,6 +13,7 @@ public class StringMatchProvider extends MatchProviderBase { @ToString.Exclude private final FormatSettings settings; private int nextIndex = 0; + private boolean ignoreCase; /** * Matches the given strings in the order given @@ -20,15 +21,23 @@ public class StringMatchProvider extends MatchProviderBase { * @param settings The format settings * @param strings The strings to match in the correct order */ - public StringMatchProvider(String name, FormatSettings settings, String... strings) { + public StringMatchProvider(String name, FormatSettings settings, boolean ignoreCase, String... strings) { super(name); this.settings = settings; this.strings = strings; + this.ignoreCase = ignoreCase; + if (ignoreCase) { + for (int i = 0; i < strings.length; i++) { + strings[i] = strings[i].toLowerCase(); + } + } } @Nullable @Override public FormattedSection getNextSection(String message, ArrayList ignoredAreas, ArrayList removedCharacters) { + if (ignoreCase) + message = message.toLowerCase(); int i = -1, len = 0; for (String string : strings) { i = message.indexOf(string, nextIndex); @@ -40,9 +49,19 @@ public class StringMatchProvider extends MatchProviderBase { return null; } nextIndex = i + len; + if (ChatFormatUtils.isInRange(i, i + len - 1, ignoredAreas)) { + DebugCommand.SendDebugMessage("String is in ignored area, skipping"); + return null; //Not setting finished to true, so it will go to the next match + } DebugCommand.SendDebugMessage("Found string match from " + i + " to " + (i + len - 1)); DebugCommand.SendDebugMessage("With settings: " + settings); ChatFormatUtils.sendMessageWithPointer(message, i, i + len - 1); + ignoredAreas.add(new int[]{i, i + len - 1}); return new FormattedSection(settings, i, i + len - 1, Collections.emptyList()); } + + @Override + public void resetSubclass() { + nextIndex = 0; + } } -- 2.30.2 From 4952923f9b53ce63c3b0e5dbcff7afbcf4d65fd0 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Thu, 13 Feb 2020 17:20:17 +0100 Subject: [PATCH 06/12] Fix all remaining issues with the chat processing Checking regex formatters first, then string, then range Fix section combining 24/24 #71 --- .../components/formatter/ChatProcessing.java | 2 +- .../formatter/formatting/ChatFormatter.java | 29 +++++++++++++------ .../formatting/MatchProviderBase.java | 4 ++- .../formatting/RangeMatchProvider.java | 1 - .../formatting/RegexMatchProvider.java | 1 - .../formatting/StringMatchProvider.java | 1 - .../components/formatter/ChatFormatIT.java | 2 +- 7 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java index fc94817..e4b26b3 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java +++ b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java @@ -68,7 +68,6 @@ public class ChatProcessing { return "@console"; }).build(), true, "@console"), - new RegexMatchProvider("hashtag", HASHTAG_PATTERN, FormatSettings.builder().color(Color.Blue).openlink("https://twitter.com/hashtag/$1").build()), new StringMatchProvider("cyan", FormatSettings.builder().color(Color.Aqua).build(), true, "cyan"), // #55 new RangeMatchProvider("code", "`", FormatSettings.builder().color(Color.DarkGray).build()), new RegexMatchProvider("maskedLink", MASKED_LINK_PATTERN, FormatSettings.builder().underlined(true) @@ -80,6 +79,7 @@ public class ChatProcessing { return text; }).build()), new RegexMatchProvider("url", URL_PATTERN, FormatSettings.builder().underlined(true).openlink("$1").build()), + new RegexMatchProvider("hashtag", HASHTAG_PATTERN, FormatSettings.builder().color(Color.Blue).openlink("https://twitter.com/hashtag/$1").build()), new StringMatchProvider("someone", FormatSettings.builder().color(Color.Aqua) .onmatch((match, builder, section) -> { if (Bukkit.getOnlinePlayers().size() == 0) return match; 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 87e3b3a..1b6db79 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java @@ -42,7 +42,13 @@ public final class ChatFormatter { escapeThings(str, excluded, remchars); - createSections(formatters, str, sections, excluded, remchars, defaults); + sections.add(new FormattedSection(defaults, 0, str.length() - 1, Collections.emptyList())); //Add entire message + var providers = formatters.stream().filter(mp -> mp instanceof RegexMatchProvider).collect(Collectors.toList()); + createSections(providers, str, sections, excluded, remchars, defaults); + providers = formatters.stream().filter(mp -> mp instanceof StringMatchProvider).collect(Collectors.toList()); + createSections(providers, str, sections, excluded, remchars, defaults); + providers = formatters.stream().filter(mp -> mp instanceof RangeMatchProvider).collect(Collectors.toList()); + createSections(providers, str, sections, excluded, remchars, defaults); sortSections(sections); header("Section combining"); @@ -66,7 +72,6 @@ public final class ChatFormatter { private static void createSections(List formatters, String str, ArrayList sections, ArrayList excludedAreas, ArrayList removedCharacters, FormatSettings defaults) { - sections.add(new FormattedSection(defaults, 0, str.length() - 1, Collections.emptyList())); //Add entire message formatters.forEach(MatchProviderBase::reset); //Reset state information, as we aren't doing deep cloning while (formatters.size() > 0) { for (var iterator = formatters.iterator(); iterator.hasNext(); ) { @@ -91,7 +96,8 @@ public final class ChatFormatter { { FormattedSection firstSect = sections.get(i - 1); FormattedSection lastSect = sections.get(i); - if (firstSect.Start > lastSect.Start) { //The first can't start later + if (firstSect.Start > lastSect.Start //The first can't start later + || (firstSect.Start == lastSect.Start && firstSect.End < lastSect.End)) { var section = firstSect; firstSect = lastSect; lastSect = section; @@ -112,18 +118,23 @@ public final class ChatFormatter { i = 0; sortSections(sections); continue; - } else if (firstSection.End > lastSection.Start && firstSection.Start < lastSection.End) { - int origend2 = firstSection.End; + } else if (firstSection.End >= lastSection.Start && firstSection.Start <= lastSection.End) { + int firstSectEnd = firstSection.End; firstSection.End = lastSection.Start - 1; - int origend = lastSection.End; - FormattedSection section = new FormattedSection(firstSection.Settings, lastSection.Start, origend, + int lastSectEnd = lastSection.End; + FormattedSection section = new FormattedSection(firstSection.Settings, lastSection.Start, lastSectEnd, firstSection.Matches); section.Settings.copyFrom(lastSection.Settings); section.Matches.addAll(lastSection.Matches); sections.add(i, section); - lastSection.Start = origend + 1; - lastSection.End = origend2; + if (firstSectEnd > lastSection.End) { //Copy first section info to last as the lastSection initially cuts the firstSection in half + lastSection.Settings = FormatSettings.builder().build(); + lastSection.Settings.copyFrom(firstSection.Settings); + } + + lastSection.Start = lastSectEnd + 1; + lastSection.End = firstSectEnd; Predicate removeIfNeeded = s -> { if (s.Start < 0 || s.End < 0 || s.Start > s.End) { diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProviderBase.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProviderBase.java index 8bfa824..fd25901 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProviderBase.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProviderBase.java @@ -20,7 +20,9 @@ public abstract class MatchProviderBase implements MatchProvider { public abstract FormattedSection getNextSection(String message, ArrayList ignoredAreas, ArrayList removedCharacters); @Override - public abstract String toString(); + public String toString() { + return name; + } protected abstract void resetSubclass(); diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java index 4df0b22..ec94e83 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java @@ -6,7 +6,6 @@ import lombok.ToString; import java.util.ArrayList; import java.util.Collections; -@ToString public class RangeMatchProvider extends MatchProviderBase { private final String pattern; @ToString.Exclude diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java index bbd4b84..c64ddc9 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java @@ -8,7 +8,6 @@ import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; -@ToString public class RegexMatchProvider extends MatchProviderBase { private final Pattern pattern; @ToString.Exclude diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java index 9ed3d8d..a9a1184 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java @@ -7,7 +7,6 @@ import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Collections; -@ToString public class StringMatchProvider extends MatchProviderBase { private final String[] strings; @ToString.Exclude diff --git a/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java b/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java index a119584..d54aa5a 100644 --- a/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java +++ b/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java @@ -62,7 +62,7 @@ public class ChatFormatIT { list.add(new ChatFormatIT(sender, "*https://norbipeti.github.io/ heh*", new TellrawPart("https://norbipeti.github.io/").setItalic(true).setUnderlined(true) .setHoverEvent(TellrawEvent.create(HoverAction.SHOW_TEXT, new TellrawPart("Click to open").setColor(Color.Blue))) - .setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://norbipeti.github.io/")), new TellrawPart(" heh").setItalic(true))); + .setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://norbipeti.github.io/")).setColor(Color.White), new TellrawPart(" heh").setItalic(true).setColor(Color.White))); list.add(new ChatFormatIT(sender, "*test _test_ test*", new TellrawPart("test test test").setItalic(true).setColor(Color.White))); list.add(new ChatFormatIT(sender, "*test __test__ test*", new TellrawPart("test ").setItalic(true).setColor(Color.White), new TellrawPart("test").setItalic(true).setUnderlined(true).setColor(Color.White), new TellrawPart(" test").setItalic(true).setColor(Color.White))); -- 2.30.2 From f19aa412054e6bf19cb1f5a1ceb419796be5eba3 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 15 Feb 2020 00:23:04 +0100 Subject: [PATCH 07/12] Configure CI build for GitHub Packages Also fixed a couple issues based on an analysis Removed debug souts --- .gitignore | 445 +++++++++--------- .idea/ButtonChat.iml | 130 ----- .travis.yml | 1 + Mvn.txt | 1 - ci/settings.xml | 36 ++ deploy.sh | 10 - .../chatonly/ChatOnlyComponent.java | 3 +- .../components/flair/SetFlairCommand.java | 2 +- .../formatter/formatting/ChatFormatUtils.java | 4 - .../formatting/FormattedSection.java | 2 +- .../formatting/RangeMatchProvider.java | 1 - .../formatter/formatting/TellrawEvent.java | 2 +- .../formatting/TellrawSerializer.java | 1 + .../towncolors/TownColorCommand.java | 14 - src/main/resources/plugin.yml | 2 +- .../buttondevteam/chat/ObjectTestRunner.java | 24 +- .../components/formatter/ChatFormatIT.java | 2 +- 17 files changed, 276 insertions(+), 404 deletions(-) delete mode 100644 .idea/ButtonChat.iml delete mode 100644 Mvn.txt create mode 100644 ci/settings.xml delete mode 100644 deploy.sh diff --git a/.gitignore b/.gitignore index 456756d..a84274b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,224 +1,221 @@ -################# -## Eclipse -################# - -*.pydevproject -.metadata/ -bin/ -tmp/ -*.tmp -*.bak -*.swp -*~.nib -local.properties -.classpath -.settings/ -.loadpath -target/ -.project - -# External tool builders -.externalToolBuilders/ - -# Locally stored "Eclipse launch configurations" -*.launch - -# CDT-specific -.cproject - -# PDT-specific -.buildpath - - -################# -## Visual Studio -################# - -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. - -# User-specific files -*.suo -*.user -*.sln.docstates - -# Build results - -[Dd]ebug/ -[Rr]elease/ -x64/ -build/ -[Bb]in/ -[Oo]bj/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -*_i.c -*_p.c -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.log -*.scc - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opensdf -*.sdf -*.cachefile - -# Visual Studio profiler -*.psess -*.vsp -*.vspx - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# NCrunch -*.ncrunch* -.*crunch*.local.xml - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.Publish.xml -*.pubxml -*.publishproj - -# NuGet Packages Directory -## TO!DO: If you have NuGet Package Restore enabled, uncomment the next line -#packages/ - -# Windows Azure Build Output -csx -*.build.csdef - -# Windows Store app package directory -AppPackages/ - -# Others -sql/ -*.Cache -ClientBin/ -[Ss]tyle[Cc]op.* -~$* -*~ -*.dbmdl -*.[Pp]ublish.xml -*.pfx -*.publishsettings - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file to a newer -# Visual Studio version. Backup files are not needed, because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm - -# SQL Server files -App_Data/*.mdf -App_Data/*.ldf - -############# -## Windows detritus -############# - -# Windows image file caches -Thumbs.db -ehthumbs.db - -# Folder config file -Desktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Mac crap -.DS_Store - - -############# -## Python -############# - -*.py[cod] - -# Packages -*.egg -*.egg-info -dist/ -build/ -eggs/ -parts/ -var/ -sdist/ -develop-eggs/ -.installed.cfg - -# Installer logs -pip-log.txt - -# Unit test / coverage reports -.coverage -.tox - -#Translations -*.mo - -#Mr Developer -.mr.developer.cfg -.metadata/* -TheButtonAutoFlair/out/artifacts/Autoflair/Autoflair.jar -#*.iml -*.name -.idea/compiler.xml -*.xml -/.apt_generated/ +################# +## Eclipse +################# + +*.pydevproject +.metadata/ +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath +target/ +.project + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + + +################# +## Visual Studio +################# + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results + +[Dd]ebug/ +[Rr]elease/ +x64/ +build/ +[Bb]in/ +[Oo]bj/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml +*.pubxml +*.publishproj + +# NuGet Packages Directory +## TO!DO: If you have NuGet Package Restore enabled, uncomment the next line +#packages/ + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +App_Data/*.mdf +App_Data/*.ldf + +############# +## Windows detritus +############# + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Mac crap +.DS_Store + + +############# +## Python +############# + +*.py[cod] + +# Packages +*.egg +*.egg-info +dist/ +eggs/ +parts/ +var/ +sdist/ +develop-eggs/ +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg +.metadata/* +TheButtonAutoFlair/out/artifacts/Autoflair/Autoflair.jar +*.iml +*.name +.idea/compiler.xml +*.xml +/.apt_generated/ diff --git a/.idea/ButtonChat.iml b/.idea/ButtonChat.iml deleted file mode 100644 index a340893..0000000 --- a/.idea/ButtonChat.iml +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index f241e78..a3dfe4a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ before_install: | # Wget BuildTools and run if cached folder not found # grep so that download counts don't appear in log files java -jar BuildTools.jar --rev 1.12.2 | grep -vE "[^/ ]*/[^/ ]*\s*KB\s*$" | grep -v "^\s*$" fi + cp ci/settings.xml $HOME/.m2/ language: java jdk: - oraclejdk8 diff --git a/Mvn.txt b/Mvn.txt deleted file mode 100644 index 8e9f41f..0000000 --- a/Mvn.txt +++ /dev/null @@ -1 +0,0 @@ -apache-maven-3.2.5/bin/mvn install:install-file -Dfile=Towny.jar -DgroupId=com.palmergames -DartifactId=Towny -Dversion=0.90.0.0 -Dpackaging=jar diff --git a/ci/settings.xml b/ci/settings.xml new file mode 100644 index 0000000..a0cab53 --- /dev/null +++ b/ci/settings.xml @@ -0,0 +1,36 @@ + + + + github + + + + + github + + + + github + GitHub Towny Apache Maven Packages + https://maven.pkg.github.com/TownyAdvanced/Towny + + + + + + + + github + NorbiPeti + ${env.GHTOKEN} + + + diff --git a/deploy.sh b/deploy.sh deleted file mode 100644 index 82c8e92..0000000 --- a/deploy.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -FILENAME=$(find target/ -maxdepth 1 ! -name '*original*' -name '*.jar') -echo Found file: $FILENAME - -if [ $1 = 'production' ]; then -echo Production mode -echo $UPLOAD_KEY > upload_key -chmod 400 upload_key -yes | scp -B -i upload_key -o StrictHostKeyChecking=no $FILENAME travis@server.figytuna.com:/minecraft/main/TBMC/pluginupdates -fi diff --git a/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java b/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java index 2aca8df..f67c888 100644 --- a/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java +++ b/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java @@ -1,6 +1,7 @@ package buttondevteam.chat.components.chatonly; import buttondevteam.chat.ChatPlayer; +import buttondevteam.chat.PluginMain; import buttondevteam.chat.components.formatter.formatting.TellrawEvent; import buttondevteam.chat.components.formatter.formatting.TellrawPart; import buttondevteam.core.ComponentManager; @@ -20,7 +21,7 @@ import org.bukkit.event.player.PlayerTeleportEvent; * Allows players to enter chat-only mode which puts them into spectator mode and disallows everything besides chatting. */ @ComponentMetadata(enabledByDefault = false) -public class ChatOnlyComponent extends Component implements Listener { +public class ChatOnlyComponent extends Component implements Listener { @Override protected void enable() { registerListener(this); diff --git a/src/main/java/buttondevteam/chat/components/flair/SetFlairCommand.java b/src/main/java/buttondevteam/chat/components/flair/SetFlairCommand.java index 36d9275..575d57f 100644 --- a/src/main/java/buttondevteam/chat/components/flair/SetFlairCommand.java +++ b/src/main/java/buttondevteam/chat/components/flair/SetFlairCommand.java @@ -23,7 +23,7 @@ public class SetFlairCommand extends AdminCommandBase { sender.sendMessage("§cPlayer not found.&r"); return true; } - short ft = 0x00; + short ft; if (flairtime.equalsIgnoreCase("non-presser")) ft = ChatPlayer.FlairTimeNonPresser; else if (flairtime.equalsIgnoreCase("cant-press")) diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatUtils.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatUtils.java index 20d2083..e9f41d2 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatUtils.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatUtils.java @@ -4,7 +4,6 @@ import buttondevteam.chat.commands.ucmds.admin.DebugCommand; import java.util.ArrayList; import java.util.Arrays; -import java.util.stream.Collectors; public final class ChatFormatUtils { private ChatFormatUtils() {} @@ -27,9 +26,6 @@ public final class ChatFormatUtils { * Check if the given start and end position is inside any of the ranges */ static boolean isInRange(int start, int end, ArrayList ranges) { - System.out.println("Ranges: " + ranges.stream().map(x -> x[0] + "-" + x[1]).collect(Collectors.joining(", "))); - System.out.println("In range: " + start + " " + end + ": " + - ranges.stream().filter(range -> range[1] >= start && range[0] <= end).map(x -> x[0] + "-" + x[1]).findAny().orElse("none")); return ranges.stream().anyMatch(range -> range[1] >= start && range[0] <= end); } } diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java index f1b0de1..eab4575 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java @@ -10,7 +10,7 @@ public class FormattedSection { public int Start; public int End; public FormatSettings Settings; - public List Matches = new ArrayList(); + public List Matches = new ArrayList<>(); FormattedSection(FormatSettings settings, int start, int end, List matches) { Start = start; diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java index ec94e83..aa872cb 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java @@ -19,7 +19,6 @@ public class RangeMatchProvider extends MatchProviderBase { this.settings = settings; } - @SuppressWarnings("DuplicatedCode") @Override public FormattedSection getNextSection(String message, ArrayList ignoredAreas, ArrayList removedCharacters) { int i, len; diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawEvent.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawEvent.java index 4c532e5..53fe988 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawEvent.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawEvent.java @@ -71,6 +71,6 @@ public final class TellrawEvent implements Serial } } - public static interface Action extends TellrawSerializableEnum { + public interface Action extends TellrawSerializableEnum { } } diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawSerializer.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawSerializer.java index b1a36fd..4f9c450 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawSerializer.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawSerializer.java @@ -48,6 +48,7 @@ public abstract class TellrawSerializer { throw new UnsupportedOperationException(); } + @SuppressWarnings("ConstantConditions") @Override public void write(JsonWriter writer, Boolean val) throws IOException { if (val) diff --git a/src/main/java/buttondevteam/chat/components/towncolors/TownColorCommand.java b/src/main/java/buttondevteam/chat/components/towncolors/TownColorCommand.java index 0bfdcd6..8dd911c 100644 --- a/src/main/java/buttondevteam/chat/components/towncolors/TownColorCommand.java +++ b/src/main/java/buttondevteam/chat/components/towncolors/TownColorCommand.java @@ -12,8 +12,6 @@ import lombok.RequiredArgsConstructor; import lombok.val; import org.bukkit.entity.Player; -import java.lang.reflect.Method; - @CommandClass(helpText = { "Town Color", // "This command allows setting a color for a town.", // @@ -23,18 +21,6 @@ import java.lang.reflect.Method; @RequiredArgsConstructor public class TownColorCommand extends UCommandBase { private final TownColorComponent component; - @Override - public String[] getHelpText(Method method, Command2.Subcommand ann) { - StringBuilder cns = new StringBuilder(" "); - for (int i = 2; i <= component.colorCount().get(); i++) - cns.append(" [colorname").append(i).append("]"); - return new String[] { // - "§6---- Town Color ----", // - "This command allows setting color(s) for a town.", // - "The town will be shown with this color on Dynmap and all players in the town will appear in chat with these colors.", // - "The colors will split the name evenly.", // - }; - } @Command2.Subcommand public boolean def(Player player, String... colornames) { diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 20f270a..5eefc33 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Chroma-Chat main: buttondevteam.chat.PluginMain -version: 4.0 +version: '4.0' commands: u: description: Auto-flair system. Accept or ignore flair. diff --git a/src/test/java/buttondevteam/chat/ObjectTestRunner.java b/src/test/java/buttondevteam/chat/ObjectTestRunner.java index 25785ee..1b5a034 100644 --- a/src/test/java/buttondevteam/chat/ObjectTestRunner.java +++ b/src/test/java/buttondevteam/chat/ObjectTestRunner.java @@ -1,15 +1,5 @@ package buttondevteam.chat; -import java.lang.annotation.Annotation; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - import org.junit.runner.Runner; import org.junit.runner.notification.RunNotifier; import org.junit.runners.BlockJUnit4ClassRunner; @@ -20,6 +10,12 @@ import org.junit.runners.model.InitializationError; import org.junit.runners.model.Statement; import org.junit.runners.model.TestClass; +import java.lang.annotation.*; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + /** * Based on {@link Parameterized} * @@ -32,10 +28,10 @@ public class ObjectTestRunner extends Suite { */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) - public static @interface Objects { + public @interface Objects { } - private class TestClassRunnerForObjects extends BlockJUnit4ClassRunner { + private static class TestClassRunnerForObjects extends BlockJUnit4ClassRunner { private List objectList; private int fParameterSetNumber; @@ -77,13 +73,13 @@ public class ObjectTestRunner extends Suite { } } - private final ArrayList runners = new ArrayList(); + private final ArrayList runners = new ArrayList<>(); /** * Only called reflectively. Do not use programmatically. */ public ObjectTestRunner(Class klass) throws Throwable { - super(klass, Collections.emptyList()); + super(klass, Collections.emptyList()); List objectsList = getObjectsList(getTestClass()); for (int i = 0; i < objectsList.size(); i++) runners.add(new TestClassRunnerForObjects(getTestClass().getJavaClass(), objectsList, i)); diff --git a/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java b/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java index d54aa5a..7d2d250 100644 --- a/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java +++ b/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java @@ -30,7 +30,7 @@ public class ChatFormatIT { DebugCommand.DebugMode = true; PluginMain.permission = Mockito.mock(Permission.class); - List list = new ArrayList(); + List list = new ArrayList<>(); list.add(new ChatFormatIT(sender, "*test*", new TellrawPart("test").setItalic(true).setColor(Color.White))); list.add(new ChatFormatIT(sender, "**test**", new TellrawPart("test").setBold(true).setColor(Color.White))); -- 2.30.2 From 6af2ad79a7c9bfe61a3805786635d10f80560953 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sun, 16 Feb 2020 20:28:19 +0100 Subject: [PATCH 08/12] Remove old loading code, use inherited registerCommand() --- .../java/buttondevteam/chat/PluginMain.java | 14 +++++----- .../towncolors/TownColorComponent.java | 27 ------------------- 2 files changed, 7 insertions(+), 34 deletions(-) diff --git a/src/main/java/buttondevteam/chat/PluginMain.java b/src/main/java/buttondevteam/chat/PluginMain.java index 6e0f929..acfd694 100644 --- a/src/main/java/buttondevteam/chat/PluginMain.java +++ b/src/main/java/buttondevteam/chat/PluginMain.java @@ -69,13 +69,13 @@ public class PluginMain extends ButtonPlugin { // Translated to Java: 2015.07.15 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()); - getCommand2MC().registerCommand(new InfoCommand()); - getCommand2MC().registerCommand(new MWikiCommand()); - getCommand2MC().registerCommand(new ReloadCommand()); - getCommand2MC().registerCommand(new SnapCommand()); + registerCommand(new DebugCommand()); + registerCommand(new HelpCommand()); + registerCommand(new HistoryCommand()); + registerCommand(new InfoCommand()); + registerCommand(new MWikiCommand()); + registerCommand(new ReloadCommand()); + registerCommand(new SnapCommand()); } public static Essentials essentials = null; diff --git a/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java b/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java index d6d0886..7c50ebd 100644 --- a/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java +++ b/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java @@ -19,14 +19,12 @@ import lombok.val; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.plugin.Plugin; import org.dynmap.towny.DTBridge; -import java.io.File; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.BiFunction; @@ -81,14 +79,10 @@ public class TownColorComponent extends Component implements Listene var cs = getConfig().getConfig().getConfigurationSection("towncolors"); if (cs != null) loadTC.accept(cs); - else - load_old(loadTC, null); //Load old data if (usenc) { var ncs = getConfig().getConfig().getConfigurationSection("nationcolors"); if (ncs != null) loadNC.accept(ncs); - else - load_old(null, loadNC); //Why not choose by making different args null } TownColors.keySet().removeIf(t -> !TownyComponent.TU.getTownsMap().containsKey(t)); // Removes town colors for deleted/renamed towns @@ -227,25 +221,4 @@ public class TownColorComponent extends Component implements Listene public void onPlayerJoin(TBMCPlayerJoinEvent event) { updatePlayerColors(event.getPlayer(), event.GetPlayer().asPluginPlayer(ChatPlayer.class)); } - - private static void load_old(Consumer loadTC, - Consumer loadNC) { - PluginMain.Instance.getLogger().info("Loading files..."); - try { - File file = new File("TBMC/chatsettings.yml"); - if (file.exists()) { - YamlConfiguration yc = new YamlConfiguration(); - yc.load(file); - ConfigurationSection cs; - if (loadTC != null && (cs = yc.getConfigurationSection("towncolors")) != null) - loadTC.accept(cs); - if (loadNC != null && (cs = yc.getConfigurationSection("nationcolors")) != null) - loadNC.accept(cs); - PluginMain.Instance.getLogger().info("Loaded files!"); - } else - PluginMain.Instance.getLogger().info("No files to load, first run probably."); - } catch (Exception e) { - TBMCCoreAPI.SendException("Error while loading chat files!", e); - } - } } -- 2.30.2 From 661534b92d74c08af0bdaa311e94ba589afde985 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 2 Mar 2020 12:40:16 +0100 Subject: [PATCH 09/12] Update README.md --- .idea/ButtonChat.iml | 2 +- README.md | 143 +++--------------- .../chatonly/ChatOnlyComponent.java | 2 +- 3 files changed, 21 insertions(+), 126 deletions(-) diff --git a/.idea/ButtonChat.iml b/.idea/ButtonChat.iml index c640e48..dec5138 100644 --- a/.idea/ButtonChat.iml +++ b/.idea/ButtonChat.iml @@ -19,7 +19,7 @@ - + diff --git a/README.md b/README.md index 32b9c62..b00ded7 100644 --- a/README.md +++ b/README.md @@ -1,133 +1,28 @@ -# The Button Minecraft server chat plugin +# Chroma-Chat plugin +A plugin that provides markdown formatting, name mentioning and other chat features. -## How to use -### Players -#### Obtaining the flair (/u accept) -At first, you need to connect your Reddit account with your Minecraft account. This is done by writing your Minecraft name to [this thread](https://www.reddit.com/r/Chromagamers/comments/51ys94/flair_thread_for_the_mc_server/), following the instructions in the post. +## Components -When you're done, connect to the server, if you aren't already on. You should see a message after a while (max. 10 seconds) asking if you're the correct Reddit user. Type /u accept to confirm it and accept your flair. +### Announcer +This component simply sends messages globally based on a configurable list in a given interval. -__Note__: You can comment your ingame name from multiple Reddit accounts. In this case, you'll need to specify the exact username you want to pair with your Minecraft account. For example: +### Append text +This component allows the players to put tableflips and other texts after their messages using /tableflip and other commands. - /u accept NorbiPeti +### Chat-only +This component lets a player become invincible at the cost of not being able to move. It was made for chat clients. -#### Hiding the message (/u ignore) -You can use this command to hide the notice showing up after you log in if you don't have a flair accepted. +### Flair +This component downloads /r/TheButton flairs from Reddit for users who comment in a specific thread. This was the original function of the plugin. -#### Flair not showing up -Please note that in some cases your flair cannot be obtained (specifically, if it's not stored by karmadecay.com, in which case possibly Karmancer can't show it as well). In this case, there are two possibilities. +### Formatter +This component provides the Markdown and other formatting and name mentioning. -If you're a non-presser or a can't press and only your time is recorded, it will automatically decide based on your account creation date. +### Fun +This component has some random things I added for fun, including "Press F to pay respects" and rainbow chat. -If nothing is known about your flair, you need to ask an admin to set the flair for you. Please prepare a link to a comment you made on /r/thebutton, if possible. +### Town colors +This component allows mayors and kings to set a color for their town/nation, which sets each resident's name colors and also shows on Dynmap. -#### Getting someone's Reddit username (/u name) -You can see a player's username if they have a flair shown. - -#### Name mentioning -If you simply say any online player's full playername or nickname, it'll highlight it and play a sound for the target player. - -If you say a nickname, it'll show it's original colors, if you say a username, then it will choose based on flair color if known, otherwise it'll use the aqua color. - -You can also use @console to ping the console. If someone is there, they'll receive an audible bell signal. - -#### RP/OOC mode (/nrp or /ooc) -You can use /ooc to say something Out-of-Character. Otherwise everything you speak should be treated as said in RP, except when it is obvious it's not in RP (like talking about the server). - -#### Greentext support (>message) -Start your message with '>' to make it green. - -#### Hashtags (#hashtag) -If you say a hashtag in global chat, it'll highlight it and makes it clickable, linking to the hashtag page on Twitter. - -#### Paying respects (F) -If a player dies, sometimes the plugin will tell everyone "Press F to pay respects.". After a few seconds, a message will tell everyone how many people paid their respects. - -If you hover over a player's name in chat, you can see how much respect they gained this way, divided by the number of eligible deaths. - -#### Copy messages -To copy a message from chat, click the channel identifier (for example: [g] or [TC]) at the beginning of the message. - -#### Tableflipping (/tableflip and /unflip) and shrug (/shrug) -The idea of this command came from Discord. - -Examples: - - /tableflip - (╯°□°)╯︵ ┻━┻ - /tableflip test - test(╯°□°)╯︵ ┻━┻ - /unflip - ┬─┬ ノ( ゜-゜ノ) - /unflip test - test┬─┬ ノ( ゜-゜ノ) - -#### Chat only (/chatonly) -You can use this mode to protect yourself if you connect from a chat-only client. This will make you invincible, but unable to move, teleport or interact with the world in any way. - -#### Rainbow chat (/u c) -Chat in rainbow/Presser colors. - -### Admins -Type /u admin for a list of the commands. -#### Seeing player information (/u admin playerinfo) -You can check someone's flair status and other infos in case something goes wrong. - -It outputs the player name (useful if something goes *really* wrong), the player's current ingame flair, the Reddit username, and their flair status: - -* Accepted: The user has a flair shown after their name. -* Ignored: The user chose to hide their flair, but they have one. -* Recognised: The user has recognised flair(s) but haven't accepted any. -* Commented: The user commented, but their flair isn't known. -* NoComment: The user haven't commented in the thread. - -#### Reloading the plugin (/u admin reload) -This is useful if you want to change a file related to the plugin. - -Be careful and make sure you do /u admin save before you reload the plugin. You need to confirm your action (/u admin confirm) to make sure no setting is lost. - -If you want to edit a file, you need to do /u admin save, then edit the file you want, then do /u admin reload. - -#### Setting the flair by hand (/u admin setflair) -This allows you to set any flair you want to any player. This will override the automatic flairs, though it's not recommended to do so. However, the player can reset the automatic flair at any time (see /u accept). - -* To remove a user's flair: - - /u admin setflair none false - -* To set a non-presser or can't press flair: - - /u admin setflair non-presser/cant-press false - -* To set a cheater flair: - - /u admin setflair