Added RPC support & fixed channels in MC!

Probably
Also did some security-kind of fixing and some refactoring
This commit is contained in:
Norbi Peti 2017-07-19 21:25:53 +02:00
parent 55053d635e
commit 2aa0443286
4 changed files with 118 additions and 126 deletions

View file

@ -2,6 +2,7 @@ package buttondevteam.chat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -11,6 +12,7 @@ import org.bukkit.entity.Player;
import org.bukkit.scoreboard.Objective; import org.bukkit.scoreboard.Objective;
import com.earth2me.essentials.Essentials; import com.earth2me.essentials.Essentials;
import com.google.common.collect.Lists;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import buttondevteam.chat.commands.UnlolCommand; import buttondevteam.chat.commands.UnlolCommand;
@ -36,48 +38,47 @@ public class ChatProcessing {
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("\\*\\*");
private static final String[] RainbowPresserColors = new String[] { "red", "gold", "yellow", "green", "blue", private static final Color[] RainbowPresserColors = new Color[] { Color.Red, Color.Gold, Color.Yellow, Color.Green,
"dark_purple" }; // TODO Color.Blue, Color.DarkPurple };
private static boolean pingedconsole = false; private static boolean pingedconsole = false;
private static ArrayList<ChatFormatter> commonFormatters = new ArrayList<>();
private static Gson gson;
public static final ChatFormatter ESCAPE_FORMATTER = new ChatFormatterBuilder().setRegex(ESCAPE_PATTERN).build(); public static final ChatFormatter ESCAPE_FORMATTER = new ChatFormatterBuilder().setRegex(ESCAPE_PATTERN).build();
private static ArrayList<ChatFormatter> commonFormatters = Lists.newArrayList(
new ChatFormatterBuilder().setRegex(BOLD_PATTERN).setBold(true).setRemoveCharCount((short) 2).setRange(true)
.setPriority(Priority.High).build(),
new ChatFormatterBuilder().setRegex(ITALIC_PATTERN).setItalic(true).setRemoveCharCount((short) 1)
.setRange(true).build(),
new ChatFormatterBuilder().setRegex(UNDERLINED_PATTERN).setUnderlined(true).setRemoveCharCount((short) 1)
.setRange(true).build(),
ESCAPE_FORMATTER,
new ChatFormatterBuilder().setRegex(URL_PATTERN).setUnderlined(true).setOpenlink("$1").setRange(true)
.build(),
new ChatFormatterBuilder().setRegex(NULL_MENTION_PATTERN).setColor(Color.DarkRed).build(), // Properly added a bug as a feature
new ChatFormatterBuilder().setRegex(CONSOLE_PING_PATTERN).setColor(Color.Aqua)
.setOnmatch((match, builder) ->
{
if (!pingedconsole) {
System.out.print("\007");
pingedconsole = true; // Will set it to false in ProcessChat
}
return match;
}).setPriority(Priority.High).build(),
new ChatFormatterBuilder().setRegex(HASHTAG_PATTERN).setColor(Color.Blue)
.setOpenlink("https://twitter.com/hashtag/$1").setPriority(Priority.High).build(),
new ChatFormatterBuilder().setRegex(CYAN_PATTERN).setColor(Color.Aqua).build() // #55
);
private static Gson gson = new GsonBuilder()
.registerTypeHierarchyAdapter(TellrawSerializableEnum.class, new TellrawSerializer.TwEnum())
.registerTypeHierarchyAdapter(Collection.class, new TellrawSerializer.TwCollection())
.registerTypeAdapter(Boolean.class, new TellrawSerializer.TwBool())
.registerTypeAdapter(boolean.class, new TellrawSerializer.TwBool()).disableHtmlEscaping().create();
private ChatProcessing() { private ChatProcessing() {
} }
static {
commonFormatters.add(new ChatFormatterBuilder().setRegex(BOLD_PATTERN).setBold(true)
.setRemoveCharCount((short) 2).setRange(true).setPriority(Priority.High).build());
commonFormatters.add(new ChatFormatterBuilder().setRegex(ITALIC_PATTERN).setItalic(true)
.setRemoveCharCount((short) 1).setRange(true).build());
commonFormatters.add(new ChatFormatterBuilder().setRegex(UNDERLINED_PATTERN).setUnderlined(true)
.setRemoveCharCount((short) 1).setRange(true).build());
commonFormatters.add(ESCAPE_FORMATTER);
commonFormatters.add(new ChatFormatterBuilder().setRegex(URL_PATTERN).setUnderlined(true).setOpenlink("$1")
.setRange(true).build());
commonFormatters.add(new ChatFormatterBuilder().setRegex(NULL_MENTION_PATTERN).setColor(Color.DarkRed).build()); // Properly added a bug as a feature
commonFormatters.add(new ChatFormatterBuilder().setRegex(CONSOLE_PING_PATTERN).setColor(Color.Aqua)
.setOnmatch((String match) -> {
if (!pingedconsole) {
System.out.print("\007");
pingedconsole = true; // Will set it to false in ProcessChat
}
return match;
}).setPriority(Priority.High).build());
commonFormatters.add(new ChatFormatterBuilder().setRegex(HASHTAG_PATTERN).setColor(Color.Blue)
.setOpenlink("https://twitter.com/hashtag/$1").setPriority(Priority.High).build());
commonFormatters.add(new ChatFormatterBuilder().setRegex(CYAN_PATTERN).setColor(Color.Aqua).build()); // #55
gson = new GsonBuilder()
.registerTypeHierarchyAdapter(TellrawSerializableEnum.class, new TellrawSerializer.TwEnum())
.registerTypeHierarchyAdapter(Collection.class, new TellrawSerializer.TwCollection())
.registerTypeAdapter(Boolean.class, new TellrawSerializer.TwBool())
.registerTypeAdapter(boolean.class, new TellrawSerializer.TwBool()).disableHtmlEscaping().create();
}
public static boolean ProcessChat(TBMCChatEvent e) { public static boolean ProcessChat(TBMCChatEvent e) {
Channel channel = e.getChannel(); Channel channel = e.getChannel();
CommandSender sender = e.getSender(); CommandSender sender = e.getSender();
@ -99,13 +100,19 @@ public class ChatProcessing {
Color colormode = channel.color; Color colormode = channel.color;
if (mp != null && mp.OtherColorMode != null) if (mp != null && mp.OtherColorMode != null)
colormode = mp.OtherColorMode; colormode = mp.OtherColorMode;
if (mp != null && mp.RainbowPresserColorMode)
colormode = Color.RPC;
if (message.startsWith(">")) if (message.startsWith(">"))
colormode = Color.Green; colormode = Color.Green;
// If greentext, ignore channel or player colors // If greentext, ignore channel or player colors
ArrayList<ChatFormatter> formatters = addFormatters(colormode); ArrayList<ChatFormatter> formatters = addFormatters(colormode);
if (colormode == channel.color && mp != null && mp.RainbowPresserColorMode) { // Only overwrite channel color
final AtomicInteger rpc = new AtomicInteger(0);
formatters.add(new ChatFormatterBuilder().setColor(colormode).setOnmatch((match, builder) -> {
builder.setColor(
RainbowPresserColors[rpc.getAndUpdate(i -> ++i < RainbowPresserColors.length ? i : 0)]);
return match;
}).build());
}
pingedconsole = false; // Will set it to true onmatch (static constructor) pingedconsole = false; // Will set it to true onmatch (static constructor)
final String channelidentifier = getChannelID(channel, sender, mp); final String channelidentifier = getChannelID(channel, sender, mp);
@ -125,9 +132,8 @@ public class ChatProcessing {
if (channel.filteranderrormsg != null) { if (channel.filteranderrormsg != null) {
Objective obj = PluginMain.SB.getObjective(channel.ID); Objective obj = PluginMain.SB.getObjective(channel.ID);
int score = -1; int score = -1;
for (Player p : Bukkit.getOnlinePlayers()) { for (Player p : Bukkit.getOnlinePlayers())
obj.getScore(p.getUniqueId().toString()).setScore(score = e.getMCScore(p)); obj.getScore(p.getName()).setScore(score = e.getMCScore(p));
}
PluginMain.Instance.getServer().dispatchCommand(PluginMain.Console, String.format( PluginMain.Instance.getServer().dispatchCommand(PluginMain.Console, String.format(
"tellraw @a[score_%s=%d,score_%s_min=%d] %s", channel.ID, score, channel.ID, score, jsonstr)); "tellraw @a[score_%s=%d,score_%s_min=%d] %s", channel.ID, score, channel.ID, score, jsonstr));
} else } else
@ -243,7 +249,7 @@ public class ChatProcessing {
nicksb.append(")"); nicksb.append(")");
formatters.add(new ChatFormatterBuilder().setRegex(Pattern.compile(namesb.toString())).setColor(Color.Aqua) formatters.add(new ChatFormatterBuilder().setRegex(Pattern.compile(namesb.toString())).setColor(Color.Aqua)
.setOnmatch((String match) -> { .setOnmatch((match, builder) -> {
Player p = Bukkit.getPlayer(match); Player p = Bukkit.getPlayer(match);
if (p == null) { if (p == null) {
PluginMain.Instance.getLogger() PluginMain.Instance.getLogger()
@ -262,7 +268,7 @@ public class ChatProcessing {
if (addNickFormatter) if (addNickFormatter)
formatters.add(new ChatFormatterBuilder().setRegex(Pattern.compile(nicksb.toString())) formatters.add(new ChatFormatterBuilder().setRegex(Pattern.compile(nicksb.toString()))
.setColor(Color.Aqua).setOnmatch((String match) -> { .setColor(Color.Aqua).setOnmatch((match, builder) -> {
if (PlayerListener.nicknames.containsKey(match)) { if (PlayerListener.nicknames.containsKey(match)) {
Player p = Bukkit.getPlayer(PlayerListener.nicknames.get(match)); Player p = Bukkit.getPlayer(PlayerListener.nicknames.get(match));
if (p == null) { if (p == null) {

View file

@ -7,45 +7,23 @@ import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern;
import buttondevteam.chat.ChatProcessing; import buttondevteam.chat.ChatProcessing;
import buttondevteam.chat.commands.ucmds.admin.DebugCommand; import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
import buttondevteam.lib.chat.*; import buttondevteam.lib.chat.*;
/**
* A {@link ChatFormatter} shows what formatting to use based on regular expressions. {@link ChatFormatter#Combine(List, String, TellrawPart)} is used to turn it into a {@link TellrawPart}, combining
* intersecting parts found, for example when {@code _abc*def*ghi_} is said in chat, it'll turn it into an underlined part, then an underlined <i>and italics</i> part, finally an underlined part
* again.
*
* @author NorbiPeti
*
*/
public final class ChatFormatter { public final class ChatFormatter {
private Pattern regex; private ChatFormatterBuilder builder;
private boolean italic;
private boolean bold;
private boolean underlined;
private boolean strikethrough;
private boolean obfuscated;
private Color color;
private Function<String, String> onmatch;
private String openlink;
private Priority priority;
private short removecharcount = 0;
private boolean isrange;
public ChatFormatter(Pattern regex, boolean italic, boolean bold, boolean underlined, boolean strikethrough, public ChatFormatter(ChatFormatterBuilder builder) {
boolean obfuscated, Color color, Function<String, String> onmatch, String openlink, Priority priority, this.builder = builder;
short removecharcount, boolean isrange) {
super();
this.regex = regex;
this.italic = italic;
this.bold = bold;
this.underlined = underlined;
this.strikethrough = strikethrough;
this.obfuscated = obfuscated;
this.color = color;
this.onmatch = onmatch;
this.openlink = openlink;
if (priority == null)
this.priority = Priority.Normal;
else
this.priority = priority;
this.removecharcount = removecharcount;
this.isrange = isrange;
} }
public static void Combine(List<ChatFormatter> formatters, String str, TellrawPart tp) { public static void Combine(List<ChatFormatter> formatters, String str, TellrawPart tp) {
@ -55,7 +33,7 @@ public final class ChatFormatter {
header("ChatFormatter.Combine begin"); header("ChatFormatter.Combine begin");
ArrayList<FormattedSection> sections = new ArrayList<FormattedSection>(); ArrayList<FormattedSection> sections = new ArrayList<FormattedSection>();
for (ChatFormatter formatter : formatters) { for (ChatFormatter formatter : formatters) {
Matcher matcher = formatter.regex.matcher(str); Matcher matcher = formatter.builder.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);
@ -66,13 +44,13 @@ public final class ChatFormatter {
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.removecharcount, formatter.removecharcount, formatter.isrange); formatter.builder.removecharcount, formatter.builder.removecharcount, formatter.builder.range);
sections.add(section); sections.add(section);
} }
} }
sections.sort((s1, s2) -> s1.Start == s2.Start sections.sort((s1, s2) -> s1.Start == s2.Start
? s1.End == s2.End ? Integer.compare(s2.Formatters.get(0).priority.GetValue(), ? s1.End == s2.End ? Integer.compare(s2.Formatters.get(0).builder.priority.GetValue(),
s1.Formatters.get(0).priority.GetValue()) : Integer.compare(s2.End, s1.End) s1.Formatters.get(0).builder.priority.GetValue()) : Integer.compare(s2.End, s1.End)
: Integer.compare(s1.Start, s2.Start)); : Integer.compare(s1.Start, s2.Start));
header("Range section conversion"); header("Range section conversion");
@ -265,10 +243,11 @@ public final class ChatFormatter {
if (found) { if (found) {
i = 1; i = 1;
found = false; found = false;
sections.sort((s1, s2) -> s1.Start == s2.Start sections.sort((s1,
? s1.End == s2.End ? Integer.compare(s2.Formatters.get(0).priority.GetValue(), s2) -> s1.Start == s2.Start ? s1.End == s2.End
s1.Formatters.get(0).priority.GetValue()) : Integer.compare(s2.End, s1.End) ? Integer.compare(s2.Formatters.get(0).builder.priority.GetValue(),
: Integer.compare(s1.Start, s2.Start)); s1.Formatters.get(0).builder.priority.GetValue())
: Integer.compare(s2.End, s1.End) : Integer.compare(s1.Start, s2.Start));
} else } else
cont = false; cont = false;
} }
@ -279,34 +258,33 @@ public final class ChatFormatter {
FormattedSection section = sections.get(i); FormattedSection section = sections.get(i);
DebugCommand.SendDebugMessage("Applying section: " + section); DebugCommand.SendDebugMessage("Applying section: " + section);
String originaltext; String originaltext;
int start = section.Start + section.RemCharFromStart, end = section.End + 1 - section.RemCharFromEnd; // TODO: RemCharPos int start = section.Start + section.RemCharFromStart, end = section.End + 1 - section.RemCharFromEnd;
DebugCommand.SendDebugMessage("Start: " + start + " - End: " + end); DebugCommand.SendDebugMessage("Start: " + start + " - End: " + end);
sendMessageWithPointer(str, start, end); sendMessageWithPointer(str, start, end);
StringBuilder textsb = new StringBuilder(str.substring(start, end)); originaltext = str.substring(start, end);
originaltext = textsb.toString();
DebugCommand.SendDebugMessage("Section text: " + originaltext); DebugCommand.SendDebugMessage("Section text: " + originaltext);
Color color = null; Color color = null;
boolean bold = false, italic = false, underlined = false, strikethrough = false, obfuscated = false; boolean bold = false, italic = false, underlined = false, strikethrough = false, obfuscated = false;
String openlink = null; String openlink = null;
section.Formatters.sort((cf2, cf1) -> cf1.priority.compareTo(cf2.priority)); section.Formatters.sort((cf2, cf1) -> cf1.builder.priority.compareTo(cf2.builder.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.builder.onmatch != null)
originaltext = formatter.onmatch.apply(originaltext); originaltext = formatter.builder.onmatch.apply(originaltext, formatter.builder);
if (formatter.color != null) if (formatter.builder.color != null)
color = formatter.color; color = formatter.builder.color;
if (formatter.bold) if (formatter.builder.bold)
bold = true; bold = true;
if (formatter.italic) if (formatter.builder.italic)
italic = true; italic = true;
if (formatter.underlined) if (formatter.builder.underlined)
underlined = true; underlined = true;
if (formatter.strikethrough) if (formatter.builder.strikethrough)
strikethrough = true; strikethrough = true;
if (formatter.obfuscated) if (formatter.builder.obfuscated)
obfuscated = true; obfuscated = true;
if (formatter.openlink != null) if (formatter.builder.openlink != null)
openlink = formatter.openlink; openlink = formatter.builder.openlink;
} }
TellrawPart newtp = new TellrawPart(""); TellrawPart newtp = new TellrawPart("");
newtp.setText(originaltext); newtp.setText(originaltext);
@ -330,11 +308,12 @@ public final class ChatFormatter {
@Override @Override
public String toString() { public String toString() {
return new StringBuilder("F(").append(color).append(", ") return new StringBuilder("F(").append(builder.color).append(", ")
.append((bold ? "bold" : "") + (italic ? "italic" : "") + (underlined ? "underlined" : "") .append((builder.bold ? "bold" : "") + (builder.italic ? "italic" : "")
+ (strikethrough ? "strikethrough" : "") + (obfuscated ? "obfuscated" : "")) + (builder.underlined ? "underlined" : "") + (builder.strikethrough ? "strikethrough" : "")
.append(", ").append(openlink).append(", ").append(priority).append(", ").append(regex).append(")") + (builder.obfuscated ? "obfuscated" : ""))
.toString(); .append(", ").append(builder.openlink).append(", ").append(builder.priority).append(", ")
.append(builder.regex).append(")").toString(); // TODO: Lombok
} }
/** /**

View file

@ -1,27 +1,30 @@
package buttondevteam.chat.formatting; package buttondevteam.chat.formatting;
import java.util.function.Function; import java.io.Serializable;
import java.util.function.BiFunction;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.commons.lang.SerializationUtils;
import buttondevteam.lib.chat.*; import buttondevteam.lib.chat.*;
public class ChatFormatterBuilder { public class ChatFormatterBuilder implements Serializable {
private Pattern regex; private static final long serialVersionUID = -6115913400749778686L;
private boolean italic; Pattern regex;
private boolean bold; boolean italic;
private boolean underlined; boolean bold;
private boolean strikethrough; boolean underlined;
private boolean obfuscated; boolean strikethrough;
private Color color; boolean obfuscated;
private Function<String, String> onmatch; Color color;
private String openlink; BiFunction<String, ChatFormatterBuilder, String> onmatch;
private Priority priority; String openlink;
private short removecharcount = 0; Priority priority = Priority.Normal;
private boolean range = false; short removecharcount = 0;
boolean range = false;
public ChatFormatter build() { public ChatFormatter build() {
return new ChatFormatter(regex, italic, bold, underlined, strikethrough, obfuscated, color, onmatch, openlink, return new ChatFormatter((ChatFormatterBuilder) SerializationUtils.clone(this));
priority, removecharcount, range);
} }
public Pattern getRegex() { public Pattern getRegex() {
@ -87,11 +90,14 @@ public class ChatFormatterBuilder {
return this; return this;
} }
public Function<String, String> getOnmatch() { public BiFunction<String, ChatFormatterBuilder, String> getOnmatch() {
return onmatch; return onmatch;
} }
public ChatFormatterBuilder setOnmatch(Function<String, String> onmatch) { /**
* Making any changes here using the builder will not affect the previous matches with the current design
*/
public ChatFormatterBuilder setOnmatch(BiFunction<String, ChatFormatterBuilder, String> onmatch) {
this.onmatch = onmatch; this.onmatch = onmatch;
return this; return this;
} }
@ -110,7 +116,7 @@ public class ChatFormatterBuilder {
} }
public ChatFormatterBuilder setPriority(Priority priority) { public ChatFormatterBuilder setPriority(Priority priority) {
this.priority = priority; this.priority = priority == null ? Priority.Normal : priority;
return this; return this;
} }

View file

@ -277,10 +277,11 @@ public class PlayerListener implements Listener {
e.setCancelled(ChatProcessing.ProcessChat(e)); e.setCancelled(ChatProcessing.ProcessChat(e));
} catch (Exception ex) { } catch (Exception ex) {
for (Player p : Bukkit.getOnlinePlayers()) for (Player p : Bukkit.getOnlinePlayers())
p.sendMessage("§c!§r[" if (e.shouldSendTo(p))
+ e.getChannel().DisplayName + "] <" + (e.getSender() instanceof Player p.sendMessage("§c!§r["
? ((Player) e.getSender()).getDisplayName() : e.getSender().getName()) + e.getChannel().DisplayName + "] <" + (e.getSender() instanceof Player
+ "> " + e.getMessage()); ? ((Player) e.getSender()).getDisplayName() : e.getSender().getName())
+ "> " + e.getMessage());
TBMCCoreAPI.SendException("An error occured while processing a chat message!", ex); TBMCCoreAPI.SendException("An error occured while processing a chat message!", ex);
} }
} }