From 0a4cdd01ce51afe20cf0e9f2a00014805ae80ea5 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 8 Feb 2020 01:44:19 +0100 Subject: [PATCH 01/10] 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)); + } +} From 1dc801575adea6b6ecd28e9118db5b47f9ef9d70 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 10 Feb 2020 13:46:39 +0100 Subject: [PATCH 02/10] 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()); } } From 30ee99d49515627f28aa5c3aa2d396219e389dd0 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Wed, 12 Feb 2020 12:45:42 +0100 Subject: [PATCH 03/10] 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) From 0dbfaa65a5f1621c4095b4b1ffb558880d73d07f Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Wed, 12 Feb 2020 19:16:05 +0100 Subject: [PATCH 04/10] 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); From 4d0c7c170e2b7f48e5981f7a2fb38cdebf1ee480 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Thu, 13 Feb 2020 00:24:31 +0100 Subject: [PATCH 05/10] 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; + } } From 4952923f9b53ce63c3b0e5dbcff7afbcf4d65fd0 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Thu, 13 Feb 2020 17:20:17 +0100 Subject: [PATCH 06/10] 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))); From f19aa412054e6bf19cb1f5a1ceb419796be5eba3 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 15 Feb 2020 00:23:04 +0100 Subject: [PATCH 07/10] 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))); From 6af2ad79a7c9bfe61a3805786635d10f80560953 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sun, 16 Feb 2020 20:28:19 +0100 Subject: [PATCH 08/10] 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); - } - } } From aad65e0222b687fc3417a7de85c15134159a524c Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Wed, 4 Mar 2020 10:45:26 +0100 Subject: [PATCH 09/10] Remove 2 TODOs --- .../buttondevteam/chat/components/formatter/ChatProcessing.java | 2 +- .../chat/components/formatter/formatting/ChatFormatter.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java index e4b26b3..7c5148b 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java +++ b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java @@ -265,7 +265,7 @@ public class ChatProcessing { System.out.println(message); }; - if (names.length > 0) //Add as first so it handles special characters (_) - TODO: But after URLs + if (names.length > 0) //Add as first so it handles special characters (_) - though the order of the different types are defined formatters.add(0, new StringMatchProvider("name", FormatSettings.builder().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 1b6db79..4606097 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java @@ -260,7 +260,7 @@ public final class ChatFormatter { private static void sortSections(ArrayList sections) { sections.sort( (s1, s2) -> s1.Start == s2.Start - ? s1.End == s2.End ? 0 : Integer.compare(s1.End, s2.End) //TODO: Test + ? s1.End == s2.End ? 0 : Integer.compare(s1.End, s2.End) : Integer.compare(s1.Start, s2.Start)); } From 0421cc6d16317a15e221299510a41313b5ee2b5a Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Wed, 4 Mar 2020 23:07:56 +0100 Subject: [PATCH 10/10] Small formatter fixes, docs --- .../formatter/formatting/ChatFormatter.java | 15 ++++++++------- .../formatter/formatting/FormatSettings.java | 3 +++ .../formatter/formatting/MatchProvider.java | 3 +++ 3 files changed, 14 insertions(+), 7 deletions(-) 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 4606097..bee0798 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java @@ -10,12 +10,12 @@ 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, FormatSettings)}} is used to turn it into a {@link TellrawPart}, combining + * A {@link MatchProvider} finds where the given {@link FormatSettings} need to be applied. {@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. * * @author NorbiPeti - */ //TODO: Update doc + */ public final class ChatFormatter { private ChatFormatter() { } @@ -25,7 +25,8 @@ public final class ChatFormatter { R apply(T1 x1, T2 x2, T3 x3); } - public static void Combine(List formatters, String str, TellrawPart tp, IHaveConfig config, FormatSettings defaults) { + //synchronized: Some of the formatters are reused, see createSections(...) + public static synchronized void Combine(List formatters, String str, TellrawPart tp, IHaveConfig config, FormatSettings defaults) { /* * A global formatter is no longer needed */ @@ -44,11 +45,11 @@ public final class ChatFormatter { 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); + createSections(providers, str, sections, excluded, remchars); providers = formatters.stream().filter(mp -> mp instanceof StringMatchProvider).collect(Collectors.toList()); - createSections(providers, str, sections, excluded, remchars, defaults); + createSections(providers, str, sections, excluded, remchars); providers = formatters.stream().filter(mp -> mp instanceof RangeMatchProvider).collect(Collectors.toList()); - createSections(providers, str, sections, excluded, remchars, defaults); + createSections(providers, str, sections, excluded, remchars); sortSections(sections); header("Section combining"); @@ -71,7 +72,7 @@ public final class ChatFormatter { } private static void createSections(List formatters, String str, ArrayList sections, - ArrayList excludedAreas, ArrayList removedCharacters, FormatSettings defaults) { + ArrayList excludedAreas, ArrayList removedCharacters) { 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(); ) { 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 f4fe9c7..e0bfa4c 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/FormatSettings.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormatSettings.java @@ -4,6 +4,9 @@ import buttondevteam.lib.chat.Color; import lombok.Builder; import lombok.Data; +/** + * Describes how a matched section of the message should look. May be combined with other format settings. + */ @Data @Builder public class FormatSettings { 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 13dafca..c1d2d46 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProvider.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProvider.java @@ -3,6 +3,9 @@ package buttondevteam.chat.components.formatter.formatting; import javax.annotation.Nullable; import java.util.ArrayList; +/** + * Attempts to find a match for the provided message, returning null if none was found. + */ public interface MatchProvider { @Nullable FormattedSection getNextSection(String message, ArrayList ignoredAreas, ArrayList removedCharacters);