Fixed /shrug, name mentioning and other formatting issues #87
4 changed files with 160 additions and 81 deletions
|
@ -27,10 +27,9 @@ import org.bukkit.entity.Player;
|
||||||
import org.bukkit.scoreboard.Objective;
|
import org.bukkit.scoreboard.Objective;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class ChatProcessing {
|
public class ChatProcessing {
|
||||||
|
@ -40,7 +39,7 @@ public class ChatProcessing {
|
||||||
private static final Pattern CONSOLE_PING_PATTERN = Pattern.compile("(?i)" + Pattern.quote("@console"));
|
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 HASHTAG_PATTERN = Pattern.compile("#(\\w+)");
|
||||||
private static final Pattern URL_PATTERN = Pattern.compile("(http[\\w:/?=$\\-_.+!*'(),]+)");
|
private static final Pattern URL_PATTERN = Pattern.compile("(http[\\w:/?=$\\-_.+!*'(),]+)");
|
||||||
private static final Pattern ENTIRE_MESSAGE_PATTERN = Pattern.compile(".+");
|
public static final Pattern ENTIRE_MESSAGE_PATTERN = Pattern.compile(".+");
|
||||||
private static final Pattern UNDERLINED_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 = Pattern.compile("\\*");
|
||||||
private static final Pattern BOLD_PATTERN = Pattern.compile("\\*\\*");
|
private static final Pattern BOLD_PATTERN = Pattern.compile("\\*\\*");
|
||||||
|
@ -55,14 +54,14 @@ public class ChatProcessing {
|
||||||
public static final ChatFormatter ESCAPE_FORMATTER = ChatFormatter.builder().regex(ESCAPE_PATTERN).build();
|
public static final ChatFormatter ESCAPE_FORMATTER = ChatFormatter.builder().regex(ESCAPE_PATTERN).build();
|
||||||
|
|
||||||
private static ArrayList<ChatFormatter> commonFormatters = Lists.newArrayList(
|
private static ArrayList<ChatFormatter> commonFormatters = Lists.newArrayList(
|
||||||
ChatFormatter.builder().regex(BOLD_PATTERN).bold(true).removeCharCount((short) 2).range(true)
|
ChatFormatter.builder().regex(BOLD_PATTERN).bold(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range)
|
||||||
.priority(Priority.High).build(),
|
.priority(Priority.High).build(),
|
||||||
ChatFormatter.builder().regex(ITALIC_PATTERN).italic(true).removeCharCount((short) 1).range(true).build(),
|
ChatFormatter.builder().regex(ITALIC_PATTERN).italic(true).removeCharCount((short) 1).type(ChatFormatter.Type.Range).build(),
|
||||||
ChatFormatter.builder().regex(UNDERLINED_PATTERN).underlined(true).removeCharCount((short) 1).range(true)
|
ChatFormatter.builder().regex(UNDERLINED_PATTERN).underlined(true).removeCharCount((short) 1).type(ChatFormatter.Type.Range)
|
||||||
.build(),
|
.build(),
|
||||||
ChatFormatter.builder().regex(STRIKETHROUGH_PATTERN).strikethrough(true).removeCharCount((short) 2).range(true)
|
ChatFormatter.builder().regex(STRIKETHROUGH_PATTERN).strikethrough(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range)
|
||||||
.build(),
|
.build(),
|
||||||
ESCAPE_FORMATTER, ChatFormatter.builder().regex(URL_PATTERN).underlined(true).openlink("$1").build(),
|
ESCAPE_FORMATTER, ChatFormatter.builder().regex(URL_PATTERN).underlined(true).openlink("$1").type(ChatFormatter.Type.Excluder).build(),
|
||||||
ChatFormatter.builder().regex(NULL_MENTION_PATTERN).color(Color.DarkRed).build(), // Properly added a bug as a feature
|
ChatFormatter.builder().regex(NULL_MENTION_PATTERN).color(Color.DarkRed).build(), // Properly added a bug as a feature
|
||||||
ChatFormatter.builder().regex(CONSOLE_PING_PATTERN).color(Color.Aqua).onmatch((match, builder) -> {
|
ChatFormatter.builder().regex(CONSOLE_PING_PATTERN).color(Color.Aqua).onmatch((match, builder) -> {
|
||||||
if (!pingedconsole) {
|
if (!pingedconsole) {
|
||||||
|
@ -75,7 +74,7 @@ public class ChatProcessing {
|
||||||
ChatFormatter.builder().regex(HASHTAG_PATTERN).color(Color.Blue).openlink("https://twitter.com/hashtag/$1")
|
ChatFormatter.builder().regex(HASHTAG_PATTERN).color(Color.Blue).openlink("https://twitter.com/hashtag/$1")
|
||||||
.priority(Priority.High).build(),
|
.priority(Priority.High).build(),
|
||||||
ChatFormatter.builder().regex(CYAN_PATTERN).color(Color.Aqua).build(), // #55
|
ChatFormatter.builder().regex(CYAN_PATTERN).color(Color.Aqua).build(), // #55
|
||||||
ChatFormatter.builder().regex(CODE_PATTERN).color(Color.DarkGray).removeCharCount((short) 1).range(true)
|
ChatFormatter.builder().regex(CODE_PATTERN).color(Color.DarkGray).removeCharCount((short) 1).type(ChatFormatter.Type.Range)
|
||||||
.build(),
|
.build(),
|
||||||
ChatFormatter.builder().regex(MASKED_LINK_PATTERN).underlined(true).onmatch((match, builder) -> {
|
ChatFormatter.builder().regex(MASKED_LINK_PATTERN).underlined(true).onmatch((match, builder) -> {
|
||||||
return match; // TODO!
|
return match; // TODO!
|
||||||
|
@ -85,6 +84,7 @@ public class ChatProcessing {
|
||||||
.registerTypeHierarchyAdapter(Collection.class, new TellrawSerializer.TwCollection())
|
.registerTypeHierarchyAdapter(Collection.class, new TellrawSerializer.TwCollection())
|
||||||
.registerTypeAdapter(Boolean.class, new TellrawSerializer.TwBool())
|
.registerTypeAdapter(Boolean.class, new TellrawSerializer.TwBool())
|
||||||
.registerTypeAdapter(boolean.class, new TellrawSerializer.TwBool()).disableHtmlEscaping().create();
|
.registerTypeAdapter(boolean.class, new TellrawSerializer.TwBool()).disableHtmlEscaping().create();
|
||||||
|
private static final String[] testPlayers = {"Koiiev", "iie", "Alisolarflare", "NorbiPeti", "Arsen_Derby_FTW", "carrot_lynx"};
|
||||||
|
|
||||||
private ChatProcessing() {
|
private ChatProcessing() {
|
||||||
}
|
}
|
||||||
|
@ -242,10 +242,15 @@ public class ChatProcessing {
|
||||||
formatters.add(
|
formatters.add(
|
||||||
ChatFormatter.builder().regex(ENTIRE_MESSAGE_PATTERN).color(colormode).priority(Priority.Low).build());
|
ChatFormatter.builder().regex(ENTIRE_MESSAGE_PATTERN).color(colormode).priority(Priority.Low).build());
|
||||||
|
|
||||||
if (Bukkit.getOnlinePlayers().size() > 0) {
|
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)(");
|
StringBuilder namesb = new StringBuilder("(?i)(");
|
||||||
for (Player p : Bukkit.getOnlinePlayers())
|
if (nottest)
|
||||||
namesb.append(p.getName()).append("|");
|
for (Player p : Bukkit.getOnlinePlayers())
|
||||||
|
namesb.append(p.getName()).append("|");
|
||||||
|
else
|
||||||
|
for (String testPlayer : testPlayers)
|
||||||
|
namesb.append(testPlayer).append("|");
|
||||||
namesb.deleteCharAt(namesb.length() - 1);
|
namesb.deleteCharAt(namesb.length() - 1);
|
||||||
namesb.append(")");
|
namesb.append(")");
|
||||||
StringBuilder nicksb = new StringBuilder("(?i)(");
|
StringBuilder nicksb = new StringBuilder("(?i)(");
|
||||||
|
@ -265,23 +270,33 @@ public class ChatProcessing {
|
||||||
}
|
}
|
||||||
nicksb.append(")");
|
nicksb.append(")");
|
||||||
|
|
||||||
|
Consumer<String> error = message -> {
|
||||||
|
if (PluginMain.Instance != null)
|
||||||
|
PluginMain.Instance.getLogger().warning(message);
|
||||||
|
else
|
||||||
|
System.out.println(message);
|
||||||
|
};
|
||||||
|
|
||||||
formatters.add(ChatFormatter.builder().regex(Pattern.compile(namesb.toString())).color(Color.Aqua)
|
formatters.add(ChatFormatter.builder().regex(Pattern.compile(namesb.toString())).color(Color.Aqua)
|
||||||
.onmatch((match, builder) -> {
|
.onmatch((match, builder) -> {
|
||||||
Player p = Bukkit.getPlayer(match);
|
Player p = Bukkit.getPlayer(match);
|
||||||
if (p == null) {
|
Optional<String> pn = nottest ? Optional.empty()
|
||||||
PluginMain.Instance.getLogger()
|
: Arrays.stream(testPlayers).filter(tp -> tp.equalsIgnoreCase(match)).findAny();
|
||||||
.warning("Error: Can't find player " + match + " but was reported as online.");
|
if (nottest ? p == null : !pn.isPresent()) {
|
||||||
|
error.accept("Error: Can't find player " + match + " but was reported as online.");
|
||||||
return "§c" + match + "§r";
|
return "§c" + match + "§r";
|
||||||
}
|
}
|
||||||
ChatPlayer mpp = TBMCPlayer.getPlayer(p.getUniqueId(), ChatPlayer.class);
|
ChatPlayer mpp = TBMCPlayer.getPlayer(nottest ? p.getUniqueId() : new UUID(0, 0), ChatPlayer.class);
|
||||||
if (PlayerListener.NotificationSound == null)
|
if (nottest) {
|
||||||
p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1.0f, 0.5f); // TODO: Airhorn
|
if (PlayerListener.NotificationSound == null)
|
||||||
else
|
p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1.0f, 0.5f); // TODO: Airhorn
|
||||||
p.playSound(p.getLocation(), PlayerListener.NotificationSound, 1.0f,
|
else
|
||||||
(float) PlayerListener.NotificationPitch);
|
p.playSound(p.getLocation(), PlayerListener.NotificationSound, 1.0f,
|
||||||
|
(float) PlayerListener.NotificationPitch);
|
||||||
|
}
|
||||||
String color = String.format("§%x", (mpp.GetFlairColor() == 0x00 ? 0xb : mpp.GetFlairColor()));
|
String color = String.format("§%x", (mpp.GetFlairColor() == 0x00 ? 0xb : mpp.GetFlairColor()));
|
||||||
return color + p.getName() + "§r";
|
return color + (nottest ? p.getName() : pn.get()) + "§r"; //Fix name casing, except when testing
|
||||||
}).priority(Priority.High).build());
|
}).priority(Priority.High).type(ChatFormatter.Type.Excluder).build());
|
||||||
|
|
||||||
if (addNickFormatter)
|
if (addNickFormatter)
|
||||||
formatters.add(ChatFormatter.builder().regex((Pattern.compile(nicksb.toString()))).color(Color.Aqua)
|
formatters.add(ChatFormatter.builder().regex((Pattern.compile(nicksb.toString()))).color(Color.Aqua)
|
||||||
|
@ -289,7 +304,7 @@ public class ChatProcessing {
|
||||||
if (PlayerListener.nicknames.containsKey(match.toLowerCase())) { //Made a stream and all that but I can actually store it lowercased
|
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()));
|
Player p = Bukkit.getPlayer(PlayerListener.nicknames.get(match.toLowerCase()));
|
||||||
if (p == null) {
|
if (p == null) {
|
||||||
PluginMain.Instance.getLogger().warning("Error: Can't find player nicknamed "
|
error.accept("Error: Can't find player nicknamed "
|
||||||
+ match.toLowerCase() + " but was reported as online.");
|
+ match.toLowerCase() + " but was reported as online.");
|
||||||
return "§c" + match + "§r";
|
return "§c" + match + "§r";
|
||||||
}
|
}
|
||||||
|
@ -300,10 +315,10 @@ public class ChatProcessing {
|
||||||
(float) PlayerListener.NotificationPitch);
|
(float) PlayerListener.NotificationPitch);
|
||||||
return PluginMain.essentials.getUser(p).getNickname();
|
return PluginMain.essentials.getUser(p).getNickname();
|
||||||
}
|
}
|
||||||
Bukkit.getServer().getLogger().warning("Player nicknamed " + match.toLowerCase()
|
error.accept("Player nicknamed " + match.toLowerCase()
|
||||||
+ " not found in nickname map but was reported as online.");
|
+ " not found in nickname map but was reported as online.");
|
||||||
return "§c" + match + "§r";
|
return "§c" + match + "§r";
|
||||||
}).priority(Priority.High).build());
|
}).priority(Priority.High).type(ChatFormatter.Type.Excluder).build());
|
||||||
}
|
}
|
||||||
return formatters;
|
return formatters;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,27 +40,70 @@ public final class ChatFormatter {
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
short removeCharCount = 0;
|
short removeCharCount = 0;
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
boolean range = false;
|
Type type = Type.Normal;
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
public static void Combine(List<ChatFormatter> formatters, String str, TellrawPart tp) {
|
public static void Combine(List<ChatFormatter> formatters, String str, TellrawPart tp) {
|
||||||
/*
|
/*
|
||||||
* This method assumes that there is always a global formatter
|
* This method assumes that there is always a global formatter
|
||||||
*/
|
*/
|
||||||
header("ChatFormatter.Combine begin");
|
header("ChatFormatter.Combine begin");
|
||||||
ArrayList<FormattedSection> sections = new ArrayList<FormattedSection>();
|
ArrayList<FormattedSection> sections = new ArrayList<FormattedSection>();
|
||||||
|
|
||||||
|
for (ChatFormatter formatter : formatters) {
|
||||||
|
if (formatter.type != Type.Excluder)
|
||||||
|
continue;
|
||||||
|
Matcher matcher = formatter.regex.matcher(str);
|
||||||
|
while (matcher.find()) {
|
||||||
|
DebugCommand.SendDebugMessage("Found match from " + matcher.start() + " to " + (matcher.end() - 1));
|
||||||
|
DebugCommand.SendDebugMessage("With excluder formatter:" + formatter);
|
||||||
|
sendMessageWithPointer(str, matcher.start(), matcher.end() - 1);
|
||||||
|
if (formatter.regex != ChatProcessing.ENTIRE_MESSAGE_PATTERN && sections.stream().anyMatch(fs -> fs.type == Type.Excluder && (fs.End >= matcher.start() && fs.Start <= matcher.end() - 1))) {
|
||||||
|
DebugCommand.SendDebugMessage("Ignoring formatter because of an excluder");
|
||||||
|
continue; //Exclude areas matched by excluders - Range sections are correctly handled afterwards
|
||||||
|
}
|
||||||
|
ArrayList<String> groups = new ArrayList<String>();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
header("Section creation (excluders done)");
|
||||||
for (ChatFormatter formatter : formatters) {
|
for (ChatFormatter formatter : formatters) {
|
||||||
|
if (formatter.type == Type.Excluder)
|
||||||
|
continue;
|
||||||
Matcher matcher = formatter.regex.matcher(str);
|
Matcher matcher = formatter.regex.matcher(str);
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
DebugCommand.SendDebugMessage("Found match from " + matcher.start() + " to " + (matcher.end() - 1));
|
DebugCommand.SendDebugMessage("Found match from " + matcher.start() + " to " + (matcher.end() - 1));
|
||||||
DebugCommand.SendDebugMessage("With formatter:" + formatter);
|
DebugCommand.SendDebugMessage("With formatter:" + formatter);
|
||||||
sendMessageWithPointer(str, matcher.start(), matcher.end() - 1);
|
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<String> groups = new ArrayList<String>();
|
ArrayList<String> groups = new ArrayList<String>();
|
||||||
for (int i = 0; i < matcher.groupCount(); i++)
|
for (int i = 0; i < matcher.groupCount(); i++)
|
||||||
groups.add(matcher.group(i + 1));
|
groups.add(matcher.group(i + 1));
|
||||||
if (groups.size() > 0)
|
if (groups.size() > 0)
|
||||||
DebugCommand.SendDebugMessage("First group: " + groups.get(0));
|
DebugCommand.SendDebugMessage("First group: " + groups.get(0));
|
||||||
FormattedSection section = new FormattedSection(formatter, matcher.start(), matcher.end() - 1, groups,
|
FormattedSection section = new FormattedSection(formatter, matcher.start(), matcher.end() - 1, groups,
|
||||||
formatter.range);
|
formatter.type);
|
||||||
sections.add(section);
|
sections.add(section);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,17 +127,20 @@ public final class ChatFormatter {
|
||||||
for (int i = 0; i < sections.size(); i++) {
|
for (int i = 0; i < sections.size(); i++) {
|
||||||
// Set ending to -1 until closed with another 1 long "section" - only do this if IsRange is true
|
// Set ending to -1 until closed with another 1 long "section" - only do this if IsRange is true
|
||||||
final FormattedSection section = sections.get(i);
|
final FormattedSection section = sections.get(i);
|
||||||
if (!section.IsRange) {
|
if (section.type!=Type.Range) {
|
||||||
escaped = section.Formatters.contains(ChatProcessing.ESCAPE_FORMATTER) && !escaped; // Enable escaping on first \, disable on second
|
escaped = section.Formatters.contains(ChatProcessing.ESCAPE_FORMATTER) && !escaped; // Enable escaping on first \, disable on second
|
||||||
if (escaped) // Don't add the escape character
|
if (escaped) {// Don't add the escape character
|
||||||
remchars.add(new int[]{section.Start, section.Start});
|
remchars.add(new int[]{section.Start, section.Start});
|
||||||
combined.add(section); // This will delete the \
|
DebugCommand.SendDebugMessage("Found escaper section: " + section);
|
||||||
DebugCommand.SendDebugMessage("Added " + (!escaped ? "not " : "") + "escaper section: " + section);
|
} else {
|
||||||
|
combined.add(section); // The above will delete the \
|
||||||
|
DebugCommand.SendDebugMessage("Added section: " + section);
|
||||||
|
}
|
||||||
sendMessageWithPointer(str, section.Start, section.End);
|
sendMessageWithPointer(str, section.Start, section.End);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!escaped) {
|
if (!escaped) {
|
||||||
if (combined.stream().anyMatch(s -> s.IsRange && (s.Start == section.Start
|
if (combined.stream().anyMatch(s -> section.type != Type.Range && (s.Start == section.Start
|
||||||
|| (s.Start < section.Start ? s.End >= section.Start : s.Start <= section.End)))) {
|
|| (s.Start < section.Start ? s.End >= section.Start : s.Start <= section.End)))) {
|
||||||
DebugCommand.SendDebugMessage("Range " + section + " overlaps with a combined section, ignoring.");
|
DebugCommand.SendDebugMessage("Range " + section + " overlaps with a combined section, ignoring.");
|
||||||
sendMessageWithPointer(str, section.Start, section.End);
|
sendMessageWithPointer(str, section.Start, section.End);
|
||||||
|
@ -140,12 +186,7 @@ public final class ChatFormatter {
|
||||||
escaped = false; // Reset escaping if applied, like if we're at the '*' in '\*'
|
escaped = false; // Reset escaping if applied, like if we're at the '*' in '\*'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (val sec : nextSection.values()) {
|
//Do not finish unfinished sections, ignore them
|
||||||
sec.End = str.length() - 1;
|
|
||||||
combined.add(sec);
|
|
||||||
DebugCommand.SendDebugMessage("Finished unfinished section: " + sec);
|
|
||||||
sendMessageWithPointer(str, sec.Start, sec.End);
|
|
||||||
}
|
|
||||||
sections = combined;
|
sections = combined;
|
||||||
|
|
||||||
header("Adding remove chars (RC)"); // Important to add after the range section conversion
|
header("Adding remove chars (RC)"); // Important to add after the range section conversion
|
||||||
|
@ -192,7 +233,7 @@ public final class ChatFormatter {
|
||||||
origend2 = tmp;
|
origend2 = tmp;
|
||||||
}
|
}
|
||||||
FormattedSection section = new FormattedSection(firstSection.Formatters, sections.get(i).Start, origend,
|
FormattedSection section = new FormattedSection(firstSection.Formatters, sections.get(i).Start, origend,
|
||||||
firstSection.Matches, false);
|
firstSection.Matches, Type.Normal);
|
||||||
section.Formatters.addAll(sections.get(i).Formatters);
|
section.Formatters.addAll(sections.get(i).Formatters);
|
||||||
section.Matches.addAll(sections.get(i).Matches); // TODO: Clean
|
section.Matches.addAll(sections.get(i).Matches); // TODO: Clean
|
||||||
sections.add(i, section);
|
sections.add(i, section);
|
||||||
|
@ -238,6 +279,7 @@ public final class ChatFormatter {
|
||||||
DebugCommand.SendDebugMessage("Removing section: " + sections.get(j));
|
DebugCommand.SendDebugMessage("Removing section: " + sections.get(j));
|
||||||
sendMessageWithPointer(str, sections.get(j).Start, sections.get(j).End);
|
sendMessageWithPointer(str, sections.get(j).Start, sections.get(j).End);
|
||||||
sections.remove(j);
|
sections.remove(j);
|
||||||
|
j--;
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,15 +302,16 @@ public final class ChatFormatter {
|
||||||
}
|
}
|
||||||
|
|
||||||
header("Section applying");
|
header("Section applying");
|
||||||
for (int i = 0; i < sections.size(); i++) {
|
TellrawPart lasttp = null; String lastlink = null;
|
||||||
FormattedSection section = sections.get(i);
|
for (FormattedSection section : sections) {
|
||||||
DebugCommand.SendDebugMessage("Applying section: " + section);
|
DebugCommand.SendDebugMessage("Applying section: " + section);
|
||||||
String originaltext;
|
String originaltext;
|
||||||
int start = section.Start, end = section.End;
|
int start = section.Start, end = section.End;
|
||||||
DebugCommand.SendDebugMessage("Start: " + start + " - End: " + end);
|
DebugCommand.SendDebugMessage("Start: " + start + " - End: " + end);
|
||||||
sendMessageWithPointer(str, start, end);
|
sendMessageWithPointer(str, start, end);
|
||||||
val rcs = remchars.stream().filter(rc -> rc[0] <= start && start <= rc[1]).findAny();
|
val rcs = remchars.stream().filter(rc -> rc[0] <= start && start <= rc[1]).findAny();
|
||||||
val rce = remchars.stream().filter(rc -> rc[0] <= end && end <= rc[1]).findAny();
|
val rce = remchars.stream().filter(rc -> rc[0] <= end && end <= rc[1]).findAny();
|
||||||
|
val rci = remchars.stream().filter(rc -> start < rc[0] && rc[1] < end).toArray(int[][]::new);
|
||||||
int s = start, e = end;
|
int s = start, e = end;
|
||||||
if (rcs.isPresent())
|
if (rcs.isPresent())
|
||||||
s = rcs.get()[1] + 1;
|
s = rcs.get()[1] + 1;
|
||||||
|
@ -280,39 +323,45 @@ public final class ChatFormatter {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
originaltext = str.substring(s, e + 1);
|
originaltext = str.substring(s, e + 1);
|
||||||
|
val sb = new StringBuilder(originaltext);
|
||||||
|
for (int x = rci.length - 1; x >= 0; x--)
|
||||||
|
sb.delete(rci[x][0] - start - 1, rci[x][1] - start); //Delete going backwards
|
||||||
|
originaltext = sb.toString();
|
||||||
DebugCommand.SendDebugMessage("Section text: " + originaltext);
|
DebugCommand.SendDebugMessage("Section text: " + originaltext);
|
||||||
Color color = null;
|
String openlink = null;
|
||||||
boolean bold = false, italic = false, underlined = false, strikethrough = false, obfuscated = false;
|
section.Formatters.sort(Comparator.comparing(cf2 -> cf2.priority.GetValue())); //Apply the highest last, to overwrite previous ones
|
||||||
String openlink = null;
|
TellrawPart newtp = new TellrawPart("");
|
||||||
section.Formatters.sort((cf2, cf1) -> cf1.priority.compareTo(cf2.priority));
|
|
||||||
for (ChatFormatter formatter : section.Formatters) {
|
for (ChatFormatter formatter : section.Formatters) {
|
||||||
DebugCommand.SendDebugMessage("Applying formatter: " + formatter);
|
DebugCommand.SendDebugMessage("Applying formatter: " + formatter);
|
||||||
if (formatter.onmatch != null)
|
if (formatter.onmatch != null)
|
||||||
originaltext = formatter.onmatch.apply(originaltext, formatter);
|
originaltext = formatter.onmatch.apply(originaltext, formatter);
|
||||||
if (formatter.color != null)
|
if (formatter.color != null)
|
||||||
color = formatter.color;
|
newtp.setColor(formatter.color);
|
||||||
if (formatter.bold)
|
if (formatter.bold)
|
||||||
bold = true;
|
newtp.setBold(formatter.bold);
|
||||||
if (formatter.italic)
|
if (formatter.italic)
|
||||||
italic = true;
|
newtp.setItalic(formatter.italic);
|
||||||
if (formatter.underlined)
|
if (formatter.underlined)
|
||||||
underlined = true;
|
newtp.setUnderlined(formatter.underlined);
|
||||||
if (formatter.strikethrough)
|
if (formatter.strikethrough)
|
||||||
strikethrough = true;
|
newtp.setStrikethrough(formatter.strikethrough);
|
||||||
if (formatter.obfuscated)
|
if (formatter.obfuscated)
|
||||||
obfuscated = true;
|
newtp.setObfuscated(formatter.obfuscated);
|
||||||
if (formatter.openlink != null)
|
if (formatter.openlink != null)
|
||||||
openlink = formatter.openlink;
|
openlink = formatter.openlink;
|
||||||
}
|
}
|
||||||
TellrawPart newtp = new TellrawPart("");
|
if (lasttp != null && newtp.getColor() == lasttp.getColor()
|
||||||
|
&& newtp.isBold() == lasttp.isBold()
|
||||||
|
&& newtp.isItalic() == lasttp.isItalic()
|
||||||
|
&& newtp.isUnderlined() == lasttp.isUnderlined()
|
||||||
|
&& newtp.isStrikethrough() == lasttp.isStrikethrough()
|
||||||
|
&& newtp.isObfuscated() == lasttp.isObfuscated()
|
||||||
|
&& (openlink == null ? lastlink == null : openlink.equals(lastlink))) {
|
||||||
|
DebugCommand.SendDebugMessage("This part has the same properties as the previous one, combining.");
|
||||||
|
lasttp.setText(lasttp.getText() + originaltext);
|
||||||
|
continue; //Combine parts with the same properties
|
||||||
|
}
|
||||||
newtp.setText(originaltext);
|
newtp.setText(originaltext);
|
||||||
if (color != null)
|
|
||||||
newtp.setColor(color);
|
|
||||||
newtp.setBold(bold);
|
|
||||||
newtp.setItalic(italic);
|
|
||||||
newtp.setUnderlined(underlined);
|
|
||||||
newtp.setStrikethrough(strikethrough);
|
|
||||||
newtp.setObfuscated(obfuscated);
|
|
||||||
if (openlink != null && openlink.length() > 0) {
|
if (openlink != null && openlink.length() > 0) {
|
||||||
newtp.setClickEvent(TellrawEvent.create(TellrawEvent.ClickAction.OPEN_URL,
|
newtp.setClickEvent(TellrawEvent.create(TellrawEvent.ClickAction.OPEN_URL,
|
||||||
(section.Matches.size() > 0 ? openlink.replace("$1", section.Matches.get(0)) : openlink)))
|
(section.Matches.size() > 0 ? openlink.replace("$1", section.Matches.get(0)) : openlink)))
|
||||||
|
@ -320,6 +369,7 @@ public final class ChatFormatter {
|
||||||
new TellrawPart("Click to open").setColor(Color.Blue)));
|
new TellrawPart("Click to open").setColor(Color.Blue)));
|
||||||
}
|
}
|
||||||
tp.addExtra(newtp);
|
tp.addExtra(newtp);
|
||||||
|
lasttp = newtp;
|
||||||
}
|
}
|
||||||
header("ChatFormatter.Combine done");
|
header("ChatFormatter.Combine done");
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,32 +8,29 @@ class FormattedSection {
|
||||||
int End;
|
int End;
|
||||||
ArrayList<ChatFormatter> Formatters = new ArrayList<ChatFormatter>();
|
ArrayList<ChatFormatter> Formatters = new ArrayList<ChatFormatter>();
|
||||||
ArrayList<String> Matches = new ArrayList<String>();
|
ArrayList<String> Matches = new ArrayList<String>();
|
||||||
/**
|
ChatFormatter.Type type;
|
||||||
* Is it a 1-long section indicating a start or an end
|
|
||||||
*/
|
|
||||||
boolean IsRange;
|
|
||||||
|
|
||||||
FormattedSection(ChatFormatter formatter, int start, int end, ArrayList<String> matches, boolean isrange) {
|
FormattedSection(ChatFormatter formatter, int start, int end, ArrayList<String> matches, ChatFormatter.Type type) {
|
||||||
Start = start;
|
Start = start;
|
||||||
End = end;
|
End = end;
|
||||||
Formatters.add(formatter);
|
Formatters.add(formatter);
|
||||||
Matches.addAll(matches);
|
Matches.addAll(matches);
|
||||||
IsRange = isrange;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
FormattedSection(Collection<ChatFormatter> formatters, int start, int end, ArrayList<String> matches,
|
FormattedSection(Collection<ChatFormatter> formatters, int start, int end, ArrayList<String> matches,
|
||||||
boolean isrange) {
|
ChatFormatter.Type type) {
|
||||||
Start = start;
|
Start = start;
|
||||||
End = end;
|
End = end;
|
||||||
Formatters.addAll(formatters);
|
Formatters.addAll(formatters);
|
||||||
Matches.addAll(matches);
|
Matches.addAll(matches);
|
||||||
IsRange = isrange;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new StringBuilder("Section(").append(Start).append(", ").append(End).append(", formatters: ")
|
return "Section(" + Start + ", " + End + ", formatters: " +
|
||||||
.append(Formatters.toString()).append(", matches: ").append(Matches.toString()).append(", ")
|
Formatters.toString() + ", matches: " + Matches.toString() + ", " +
|
||||||
.append(IsRange).append(")").toString();
|
type + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -40,14 +40,31 @@ public class ChatFormatIT {
|
||||||
new TellrawPart("test").setBold(true).setItalic(true).setUnderlined(true).setColor(Color.White)));
|
new TellrawPart("test").setBold(true).setItalic(true).setUnderlined(true).setColor(Color.White)));
|
||||||
list.add(new ChatFormatIT(sender, "***_~~test~~_***", new TellrawPart("test").setBold(true).setItalic(true)
|
list.add(new ChatFormatIT(sender, "***_~~test~~_***", new TellrawPart("test").setBold(true).setItalic(true)
|
||||||
.setUnderlined(true).setStrikethrough(true).setColor(Color.White)));
|
.setUnderlined(true).setStrikethrough(true).setColor(Color.White)));
|
||||||
list.add(new ChatFormatIT(sender, "¯\\\\\\_(ツ)\\_/¯", new TellrawPart("¯").setColor(Color.White),
|
list.add(new ChatFormatIT(sender, "¯\\\\\\_(ツ)\\_/¯", new TellrawPart("¯\\_(ツ)_/¯").setColor(Color.White)));
|
||||||
new TellrawPart("\\").setColor(Color.White), new TellrawPart("_(ツ)").setColor(Color.White),
|
|
||||||
new TellrawPart("_/¯").setColor(Color.White)));
|
|
||||||
list.add(new ChatFormatIT(sender, "https://google.hu/",
|
list.add(new ChatFormatIT(sender, "https://google.hu/",
|
||||||
new TellrawPart("https://google.hu/").setColor(Color.White).setUnderlined(true)
|
new TellrawPart("https://google.hu/").setColor(Color.White).setUnderlined(true)
|
||||||
.setHoverEvent(TellrawEvent.create(HoverAction.SHOW_TEXT,
|
.setHoverEvent(TellrawEvent.create(HoverAction.SHOW_TEXT,
|
||||||
new TellrawPart("Click to open").setColor(Color.Blue)))
|
new TellrawPart("Click to open").setColor(Color.Blue)))
|
||||||
.setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://google.hu/"))));
|
.setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://google.hu/"))));
|
||||||
|
list.add(new ChatFormatIT(sender, "*test", new TellrawPart("*test").setColor(Color.White)));
|
||||||
|
list.add(new ChatFormatIT(sender, "**test*", new TellrawPart("**test*").setColor(Color.White)));
|
||||||
|
list.add(new ChatFormatIT(sender, "***test", new TellrawPart("***test").setColor(Color.White)));
|
||||||
|
list.add(new ChatFormatIT(sender, "Koiiev", new TellrawPart("§bKoiiev§r").setColor(Color.Aqua)));
|
||||||
|
list.add(new ChatFormatIT(sender, "norbipeti", new TellrawPart("§bNorbiPeti§r").setColor(Color.Aqua)));
|
||||||
|
list.add(new ChatFormatIT(sender, "Arsen_Derby_FTW", new TellrawPart("§bArsen_Derby_FTW§r").setColor(Color.Aqua)));
|
||||||
|
list.add(new ChatFormatIT(sender, "carrot_lynx", new TellrawPart("§bcarrot_lynx§r").setColor(Color.Aqua)));
|
||||||
|
list.add(new ChatFormatIT(sender, "*carrot_lynx*", new TellrawPart("§bcarrot_lynx§r").setItalic(true).setColor(Color.Aqua)));
|
||||||
|
list.add(new ChatFormatIT(sender, "https://norbipeti.github.io/", new TellrawPart("https://norbipeti.github.io/")
|
||||||
|
.setColor(Color.White).setUnderlined(true)
|
||||||
|
.setHoverEvent(TellrawEvent.create(HoverAction.SHOW_TEXT,
|
||||||
|
new TellrawPart("Click to open").setColor(Color.Blue)))
|
||||||
|
.setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://norbipeti.github.io/"))));
|
||||||
|
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)));
|
||||||
|
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)));
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue