diff --git a/.idea/ButtonChat.iml b/.idea/ButtonChat.iml
index 3d32cdf..28193ee 100644
--- a/.idea/ButtonChat.iml
+++ b/.idea/ButtonChat.iml
@@ -1,12 +1,13 @@
-
+
+
@@ -24,11 +25,19 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -39,5 +48,7 @@
+
+
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 808d9b0..1d962ae 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,6 +11,7 @@ language: java
jdk:
- oraclejdk8
sudo: true
+dist: trusty # Needed for Java 8, although we might not need Java 8
deploy:
# deploy develop to the staging environment
- provider: script
diff --git a/pom.xml b/pom.xml
index 5626ea8..987b17c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,6 +1,11 @@
4.0.0
+
+ com.github.TBMCPlugins.ButtonCore
+ CorePOM
+ master-SNAPSHOT
+
0.0.1-SNAPSHOT
The Button Minecraft Chat Plugin
The Button Minecraft Chat Plugin
@@ -26,18 +31,10 @@
ButtonChat
-
- maven-compiler-plugin
- 3.3
-
-
- 1.8
-
-
org.apache.maven.plugins
maven-shade-plugin
- 2.4.2
+ 3.2.1
package
@@ -48,7 +45,6 @@
net.sourceforge.htmlcleaner:htmlcleaner
- org.javassist:javassist
@@ -151,14 +147,14 @@
jitpack
https://jitpack.io/
-
- Essentials
- http://repo.ess3.net/content/repositories/essrel/
-
-
- Minigames
- http://maven.addstar.com.au/artifactory/release
-
+
+ ess-repo
+ https://ci.ender.zone/plugin/repository/everything/
+
+
@@ -211,18 +209,26 @@
master-SNAPSHOT
provided
-
- org.projectlombok
- lombok
- 1.16.16
- provided
-
-
- org.spigotmc
- spigot
- 1.12.2-R0.1-SNAPSHOT
- provided
-
+
+
+ org.projectlombok
+ lombok
+ 1.18.10
+ provided
+
+
+
+ org.spigotmc
+ spigot
+ 1.12.2-R0.1-SNAPSHOT
+ provided
+
+
com.github.webbukkit
Dynmap-Towny
@@ -240,7 +246,14 @@
4.12
test
-
+
+
+ org.apache.logging.log4j
+ log4j-core
+ 2.8.1
+ provided
+
+
ButtonChat
TBMCPlugins
diff --git a/src/main/java/buttondevteam/chat/ChatProcessing.java b/src/main/java/buttondevteam/chat/ChatProcessing.java
deleted file mode 100644
index 6028b8a..0000000
--- a/src/main/java/buttondevteam/chat/ChatProcessing.java
+++ /dev/null
@@ -1,333 +0,0 @@
-package buttondevteam.chat;
-
-import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
-import buttondevteam.chat.components.chatonly.ChatOnlyComponent;
-import buttondevteam.chat.components.fun.FunComponent;
-import buttondevteam.chat.components.towny.TownyComponent;
-import buttondevteam.chat.formatting.ChatFormatter;
-import buttondevteam.chat.formatting.TellrawEvent;
-import buttondevteam.chat.formatting.TellrawPart;
-import buttondevteam.chat.formatting.TellrawSerializer;
-import buttondevteam.chat.listener.PlayerListener;
-import buttondevteam.core.ComponentManager;
-import buttondevteam.core.component.channel.Channel;
-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;
-import buttondevteam.lib.player.TBMCPlayerBase;
-import com.earth2me.essentials.User;
-import com.google.common.collect.Lists;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import lombok.val;
-import org.bukkit.Bukkit;
-import org.bukkit.Sound;
-import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
-import org.bukkit.scoreboard.Objective;
-
-import javax.annotation.Nullable;
-import java.util.*;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Consumer;
-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]+)?)");
- 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 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"); //TODO
- 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+");
- private static boolean pingedconsole = false;
-
- public static final ChatFormatter ESCAPE_FORMATTER = ChatFormatter.builder().regex(ESCAPE_PATTERN).build();
-
- private static ArrayList commonFormatters = Lists.newArrayList(
- ChatFormatter.builder().regex(BOLD_PATTERN).bold(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range)
- .priority(Priority.High).build(),
- ChatFormatter.builder().regex(ITALIC_PATTERN).italic(true).removeCharCount((short) 1).type(ChatFormatter.Type.Range).build(),
- ChatFormatter.builder().regex(UNDERLINED_PATTERN).underlined(true).removeCharCount((short) 1).type(ChatFormatter.Type.Range)
- .build(),
- ChatFormatter.builder().regex(STRIKETHROUGH_PATTERN).strikethrough(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range)
- .build(),
- ChatFormatter.builder().regex(SPOILER_PATTERN).obfuscated(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range)
- .onmatch((match, cf, fs) -> {
- cf.setHoverText(match);
- return match;
- }).build(),
- ESCAPE_FORMATTER, ChatFormatter.builder().regex(NULL_MENTION_PATTERN).color(Color.DarkRed).build(), // Properly added a bug as a feature
- ChatFormatter.builder().regex(CONSOLE_PING_PATTERN).color(Color.Aqua).onmatch((match, builder, section) -> {
- if (!pingedconsole) {
- System.out.print("\007");
- pingedconsole = true; // Will set it to false in ProcessChat
- }
- return match;
- }).priority(Priority.High).build(),
-
- ChatFormatter.builder().regex(HASHTAG_PATTERN).color(Color.Blue).openlink("https://twitter.com/hashtag/$1")
- .priority(Priority.High).build(),
- ChatFormatter.builder().regex(CYAN_PATTERN).color(Color.Aqua).build(), // #55
- ChatFormatter.builder().regex(CODE_PATTERN).color(Color.DarkGray).removeCharCount((short) 1).type(ChatFormatter.Type.Range)
- .build(),
- ChatFormatter.builder().regex(MASKED_LINK_PATTERN).underlined(true).onmatch((match, builder, section) -> {
- String text, link;
- if (section.Matches.size() < 2 || (text = section.Matches.get(0)).length() == 0 || (link = section.Matches.get(1)).length() == 0)
- return "";
- builder.setOpenlink(link);
- return text;
- }).type(ChatFormatter.Type.Excluder).build(),
- ChatFormatter.builder().regex(URL_PATTERN).underlined(true).openlink("$1").type(ChatFormatter.Type.Excluder).build());
- 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 static final String[] testPlayers = {"Koiiev", "iie", "Alisolarflare", "NorbiPeti", "Arsen_Derby_FTW", "carrot_lynx"};
- public static final String MCORIGIN = "Minecraft"; //Shouldn't change, like ever - TBMCPlayer.getFolderForType(TBMCPlayer.class) capitalized
-
- private ChatProcessing() {
- }
-
- public static boolean ProcessChat(TBMCChatEvent e) {
- Channel channel = e.getChannel();
- CommandSender sender = e.getSender();
- String message = e.getMessage();
- long processstart = System.nanoTime();
- Player player = (sender instanceof Player ? (Player) sender : null);
- User user = PluginMain.essentials.getUser(player);
-
- if (player != null) {
- user.updateActivity(true); //Could talk in a private channel, so broadcast
- if (user.isMuted())
- return true;
- }
-
- doFunStuff(sender, e, message);
-
- ChatPlayer mp;
- if (player != null)
- mp = TBMCPlayerBase.getPlayer(player.getUniqueId(), ChatPlayer.class);
- else //Due to the online player map, getPlayer() can be more efficient than getAs()
- mp = e.getUser().getAs(ChatPlayer.class); //May be null
-
- Color colormode = channel.Color().get();
- if (mp != null && mp.OtherColorMode != null)
- colormode = mp.OtherColorMode;
- if (message.startsWith(">"))
- colormode = Color.Green;
- // If greentext, ignore channel or player colors
-
- ArrayList formatters = addFormatters(colormode);
- if (colormode == channel.Color().get() && mp != null && mp.RainbowPresserColorMode) { // Only overwrite channel color
- final AtomicInteger rpc = new AtomicInteger(0);
- formatters.add(ChatFormatter.builder().regex(WORD_PATTERN).color(colormode).onmatch((match, cf, s) -> {
- cf.setColor(RainbowPresserColors[rpc.getAndUpdate(i -> ++i < RainbowPresserColors.length ? i : 0)]);
- return match;
- }).build());
- }
- pingedconsole = false; // Will set it to true onmatch (static constructor)
- final String channelidentifier = getChannelID(channel, e.getOrigin());
-
- TellrawPart json = createTellraw(sender, message, player, mp, e.getUser(), channelidentifier, e.getOrigin());
- long combinetime = System.nanoTime();
- ChatFormatter.Combine(formatters, message, json);
- combinetime = System.nanoTime() - combinetime;
- String jsonstr = toJson(json);
- if (jsonstr.length() >= 32767) {
- sender.sendMessage(
- "§cError: Message too long. Try shortening it, or remove hashtags and other formatting.");
- return true;
- }
- DebugCommand.SendDebugMessage(jsonstr);
-
- try {
- if (!channel.isGlobal()) {
- Objective obj = PluginMain.SB.getObjective(channel.ID);
- int score = -1;
- for (Player p : Bukkit.getOnlinePlayers()) {
- final int mcScore;
- if (player != null
- && PluginMain.essentials.getUser(p).isIgnoredPlayer(PluginMain.essentials.getUser(player)))
- mcScore = -1; // Don't send the message to them
- else
- mcScore = VanillaUtils.getMCScoreIfChatOn(p, e);
- obj.getScore(p.getName())
- .setScore(p.getUniqueId().equals(player == null ? null : player.getUniqueId()) // p.UniqueID==player?.UniqueID
- ? score = mcScore : mcScore);
- }
- if (score == -1) // Even if the player object isn't null, it may not be in OnlinePlayers
- score = e.getMCScore(sender);
- if (score < 0) // Never send messages to score below 0
- sender.sendMessage("§cYou don't have permission to send this message or something went wrong");
- else {
- PluginMain.Instance.getServer().dispatchCommand(PluginMain.Console,
- String.format("tellraw @a[score_%s=%d,score_%s_min=%d] %s", channel.ID, score, channel.ID,
- score, jsonstr));
- val tc = ComponentManager.getIfEnabled(TownyComponent.class);
- if (tc != null) tc.handleSpies(channel, json, ChatProcessing::toJson);
- }
- } else
- PluginMain.Instance.getServer().dispatchCommand(PluginMain.Console,
- String.format("tellraw @a %s", jsonstr));
- } catch (Exception ex) {
- TBMCCoreAPI.SendException("An error occured while sending a chat message!", ex);
- sender.sendMessage("§cAn error occured while sending the message.");
- return true;
- }
- PluginMain.Instance.getServer().getConsoleSender()
- .sendMessage(String.format("%s <%s§r> %s", channelidentifier, getSenderName(sender, player), message));
- DebugCommand.SendDebugMessage(
- "-- Full ChatProcessing time: " + (System.nanoTime() - processstart) / 1000000f + " ms");
- DebugCommand.SendDebugMessage("-- ChatFormatter.Combine time: " + combinetime / 1000000f + " ms");
- return false;
- }
-
- static String toJson(TellrawPart json) {
- return gson.toJson(json);
- }
-
- static TellrawPart createTellraw(CommandSender sender, String message, @Nullable Player player,
- @Nullable ChatPlayer mp, @Nullable ChromaGamerBase cg, final String channelidentifier,
- String origin) {
- TellrawPart json = new TellrawPart("");
- ChatOnlyComponent.tellrawCreate(mp, json); //TODO: Make nice API
- json.addExtra(
- new TellrawPart(channelidentifier)
- .setHoverEvent(
- TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT,
- new TellrawPart((MCORIGIN.equals(origin) ? "" : "From " + origin + "n")
- + "Copy message").setColor(Color.Blue)))
- .setClickEvent(TellrawEvent.create(TellrawEvent.ClickAction.SUGGEST_COMMAND, message)));
- if (PluginMain.permission.has(sender, "tbmc.badge.diamond"))
- json.addExtra(new TellrawPart("[P]").setColor(Color.Aqua).setBold(true)
- .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Diamond Patreon supporter")));
- else if (PluginMain.permission.has(sender, "tbmc.badge.gold"))
- json.addExtra(new TellrawPart("[P]").setColor(Color.Gold).setBold(true)
- .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Gold Patreon supporter")));
- json.addExtra(new TellrawPart(" <"));
- TellrawPart hovertp = new TellrawPart("");
- if (cg != null)
- hovertp.addExtra(new TellrawPart(cg.getInfo(ChromaGamerBase.InfoTarget.MCHover)));
- json.addExtra(new TellrawPart(getSenderName(sender, player))
- .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, hovertp)));
- json.addExtra(new TellrawPart("> "));
- return json;
- }
-
- private static String getSenderName(CommandSender sender, Player player) {
- if (player == null)
- return sender.getName();
- return player.getDisplayName();
- }
-
- static String getChannelID(Channel channel, String origin) {
- return ("[" + (MCORIGIN.equals(origin) ? "" : "§8" + origin.substring(0, 1) + "§r|") + channel.DisplayName().get())
- + "]";
- }
-
- static ArrayList addFormatters(Color colormode) {
- @SuppressWarnings("unchecked")
- ArrayList formatters = (ArrayList) commonFormatters.clone();
-
- formatters.add(
- ChatFormatter.builder().regex(ENTIRE_MESSAGE_PATTERN).color(colormode).priority(Priority.Low).build());
-
- boolean nottest; //Not assigning a default value, so that it can only be used in the if
- if ((nottest = Bukkit.getOnlinePlayers().size() > 0) || Bukkit.getVersion().equals("test")) {
- StringBuilder namesb = new StringBuilder("(?i)(");
- if (nottest)
- 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.append(")");
- StringBuilder nicksb = new StringBuilder("(?i)(");
- boolean addNickFormatter = false;
- for (Player p : Bukkit.getOnlinePlayers()) {
- final String nick = PlayerListener.nicknames.inverse().get(p.getUniqueId());
- if (nick != null) {
- nicksb.append(nick).append("|");
- addNickFormatter = true; //Add it even if there's only 1 player online (it was in the if)
- }
- }
- nicksb.deleteCharAt(nicksb.length() - 1);
- nicksb.append(")");
-
- Consumer 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)
- .onmatch((match, builder, section) -> {
- Player p = Bukkit.getPlayer(match);
- Optional pn = nottest ? Optional.empty()
- : Arrays.stream(testPlayers).filter(tp -> tp.equalsIgnoreCase(match)).findAny();
- if (nottest ? p == null : !pn.isPresent()) {
- error.accept("Error: Can't find player " + match + " but was reported as online.");
- return "§c" + match + "§r";
- }
- ChatPlayer mpp = TBMCPlayer.getPlayer(nottest ? p.getUniqueId() : new UUID(0, 0), ChatPlayer.class);
- if (nottest) {
- playPingSound(p);
- }
- 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());
-
- if (addNickFormatter)
- formatters.add(ChatFormatter.builder().regex((Pattern.compile(nicksb.toString()))).color(Color.Aqua)
- .onmatch((match, builder, section) -> {
- if (PlayerListener.nicknames.containsKey(match.toLowerCase())) { //Made a stream and all that but I can actually store it lowercased
- Player p = Bukkit.getPlayer(PlayerListener.nicknames.get(match.toLowerCase()));
- if (p == null) {
- error.accept("Error: Can't find player nicknamed "
- + match.toLowerCase() + " but was reported as online.");
- return "§c" + match + "§r";
- }
- playPingSound(p);
- return PluginMain.essentials.getUser(p).getNickname();
- }
- 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());
- }
- return formatters;
- }
-
- private static void playPingSound(Player p) {
- if (PluginMain.Instance.notificationSound().get().length() == 0)
- p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1.0f, 0.5f); // TODO: Airhorn
- else
- p.playSound(p.getLocation(), PluginMain.Instance.notificationSound().get(), 1.0f,
- PluginMain.Instance.notificationPitch().get());
- }
-
- static void doFunStuff(CommandSender sender, TBMCChatEventBase event, String message) {
- val fc=ComponentManager.getIfEnabled(FunComponent.class);
- if(fc!=null) fc.onChat(sender, event, message);
- }
-}
diff --git a/src/main/java/buttondevteam/chat/ChatUtils.java b/src/main/java/buttondevteam/chat/ChatUtils.java
new file mode 100644
index 0000000..9a3b15e
--- /dev/null
+++ b/src/main/java/buttondevteam/chat/ChatUtils.java
@@ -0,0 +1,59 @@
+package buttondevteam.chat;
+
+import buttondevteam.lib.ChromaUtils;
+import buttondevteam.lib.TBMCChatEvent;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+
+import java.util.Optional;
+import java.util.function.Function;
+
+public final class ChatUtils {
+ public static final String MCORIGIN = "Minecraft"; //Shouldn't change, like ever - TBMCPlayer.getFolderForType(TBMCPlayer.class) capitalized
+
+ private ChatUtils() {
+ }
+
+ /**
+ * Dispatch a console command.
+ *
+ * @param command The command
+ * @param async Whether the caller is async
+ */
+ public static void dispatchConsoleCommand(String command, boolean async) {
+ if (async)
+ Bukkit.getScheduler().runTask(PluginMain.Instance, () -> Bukkit.dispatchCommand(PluginMain.Console, command));
+ else
+ Bukkit.dispatchCommand(PluginMain.Console, command);
+ }
+
+ /**
+ * Returns the string between the start and end strings (exclusive).
+ *
+ * @param str The original string
+ * @param start The start string
+ * @param end The end string
+ * @return The result string
+ */
+ public static Optional coolSubstring(String str, String start, String end) {
+ int a = str.indexOf(start) + start.length();
+ int b = str.indexOf(end, a);
+ return a != -1 && b != -1 ? Optional.of(str.substring(a, b)) : Optional.empty();
+ }
+
+ /**
+ * Sends a regular (non-Markdown) chat message. Used as a fallback if the chat processing fails.
+ *
+ * @param e The chat event
+ * @param modifier A function that alters the message to be displayed to the player
+ */
+ public static void sendChatMessage(TBMCChatEvent e, Function modifier) {
+ var str = "[" + e.getChannel().DisplayName().get() + "] <"
+ + ChromaUtils.getDisplayName(e.getSender()) + "> " + e.getMessage();
+ str = modifier.apply(str);
+ for (Player p : Bukkit.getOnlinePlayers())
+ if (e.shouldSendTo(p))
+ p.sendMessage(str);
+ Bukkit.getConsoleSender().sendMessage(str);
+ }
+}
diff --git a/src/main/java/buttondevteam/chat/PluginMain.java b/src/main/java/buttondevteam/chat/PluginMain.java
index ba05c44..b6095a1 100644
--- a/src/main/java/buttondevteam/chat/PluginMain.java
+++ b/src/main/java/buttondevteam/chat/PluginMain.java
@@ -5,10 +5,12 @@ import buttondevteam.chat.commands.SnapCommand;
import buttondevteam.chat.commands.ucmds.HelpCommand;
import buttondevteam.chat.commands.ucmds.HistoryCommand;
import buttondevteam.chat.commands.ucmds.InfoCommand;
+import buttondevteam.chat.commands.ucmds.ReloadCommand;
import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
import buttondevteam.chat.components.announce.AnnouncerComponent;
import buttondevteam.chat.components.appendext.AppendTextComponent;
import buttondevteam.chat.components.flair.FlairComponent;
+import buttondevteam.chat.components.formatter.FormatterComponent;
import buttondevteam.chat.components.fun.FunComponent;
import buttondevteam.chat.components.towncolors.TownColorComponent;
import buttondevteam.chat.components.towny.TownyComponent;
@@ -28,7 +30,6 @@ import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.plugin.RegisteredServiceProvider;
-import org.bukkit.scoreboard.Scoreboard;
public class PluginMain extends ButtonPlugin { // Translated to Java: 2015.07.15.
// A user, which flair isn't obtainable:
@@ -36,8 +37,6 @@ public class PluginMain extends ButtonPlugin { // Translated to Java: 2015.07.15
public static PluginMain Instance;
public static ConsoleCommandSender Console;
- public static Scoreboard SB;
-
public ConfigData notificationSound() {
return getIConfig().getData("notificationSound", "");
}
@@ -54,11 +53,8 @@ public class PluginMain extends ButtonPlugin { // Translated to Java: 2015.07.15
TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this);
TBMCCoreAPI.RegisterEventsForExceptions(new PlayerJoinLeaveListener(), this);
- MainPlugin.Instance.setChatHandlerEnabled(false); //Disable Core chat handler
Console = this.getServer().getConsoleSender();
- SB = getServer().getScoreboardManager().getMainScoreboard(); // Main can be detected with @a[score_...]
-
if (Bukkit.getPluginManager().isPluginEnabled("Towny"))
Component.registerComponent(this, new TownyComponent());
@@ -73,11 +69,13 @@ public class PluginMain extends ButtonPlugin { // Translated to Java: 2015.07.15
Component.registerComponent(this, new AnnouncerComponent());
Component.registerComponent(this, new FunComponent());
Component.registerComponent(this, new AppendTextComponent());
+ Component.registerComponent(this, new FormatterComponent());
getCommand2MC().registerCommand(new DebugCommand());
getCommand2MC().registerCommand(new HelpCommand());
getCommand2MC().registerCommand(new HistoryCommand());
getCommand2MC().registerCommand(new InfoCommand());
getCommand2MC().registerCommand(new MWikiCommand());
+ getCommand2MC().registerCommand(new ReloadCommand());
getCommand2MC().registerCommand(new SnapCommand());
}
diff --git a/src/main/java/buttondevteam/chat/VanillaUtils.java b/src/main/java/buttondevteam/chat/VanillaUtils.java
index 68f749b..fbbdbf3 100644
--- a/src/main/java/buttondevteam/chat/VanillaUtils.java
+++ b/src/main/java/buttondevteam/chat/VanillaUtils.java
@@ -1,18 +1,122 @@
package buttondevteam.chat;
-import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
-import org.bukkit.entity.Player;
-
+import buttondevteam.core.MainPlugin;
import buttondevteam.lib.TBMCChatEvent;
import lombok.experimental.UtilityClass;
-import net.minecraft.server.v1_12_R1.EntityHuman.EnumChatVisibility;
+import lombok.val;
+import org.bukkit.entity.Player;
+
+import java.util.function.BiPredicate;
+import java.util.function.Predicate;
@UtilityClass
public class VanillaUtils {
- public int getMCScoreIfChatOn(Player p, TBMCChatEvent e) {
- if (!(p instanceof CraftPlayer) || ((CraftPlayer) p).getHandle().getChatFlags() == EnumChatVisibility.FULL) // Only send if client allows chat
- return e.getMCScore(p);
- else
- return -1;
+ public String getGroupIfChatOn(Player p, TBMCChatEvent e) {
+ try {
+ if (isChatOn(p)) // Only send if client allows chat
+ return e.getGroupID(p);
+ else
+ return null;
+ } catch (NoClassDefFoundError ex) {
+ MainPlugin.Instance.getLogger().warning("Compatibility error, can't check if the chat is hidden by the player.");
+ return e.getGroupID(p);
+ }
+ }
+
+ private Predicate isChatOn;
+
+ private boolean isChatOn(Player p) {
+ try {
+ if (isChatOn == null) {
+ val cl = p.getClass();
+ if (notCraftPlayer(cl)) return true; // p instanceof CraftPlayer
+ val hm = cl.getMethod("getHandle");
+ val handle = hm.invoke(p); //p.getHandle()
+ val vpcl = handle.getClass();
+ val gcfm = vpcl.getMethod("getChatFlags");
+ Class> encl;
+ try {
+ encl = Class.forName(handle.getClass().getPackage().getName() + ".EnumChatVisibility");
+ } catch (ClassNotFoundException e) {
+ encl = Class.forName(handle.getClass().getPackage().getName() + ".EntityHuman$EnumChatVisibility");
+ }
+ val ff = encl.getField("FULL");
+ val full = ff.get(null); // EnumChatVisibility.FULL
+ isChatOn = pl -> {
+ try {
+ if (notCraftPlayer(pl.getClass())) return true; //Need to check each time
+ val ph = hm.invoke(pl); //pl.getHandle()
+ val flags = gcfm.invoke(ph); //handle.getChatFlags()
+ return flags == full;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return true;
+ }
+ };
+ }
+ return isChatOn.test(p);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return true;
+ }
+ }
+
+ /*private String version;
+
+ public short getMCVersion() {
+ if (version != null) return version;
+ val v = ChatUtils.coolSubstring(Bukkit.getServer().getVersion().getClass().getPackage().getName(),
+ "org.bukkit.craftbukkit.v", "_R1").orElse("1_8").replace("_", "");
+ return Short.parseShort(v);
+ }*/
+
+ private BiPredicate tellRaw;
+
+ public boolean tellRaw(Player p, String json) {
+ try {
+ if (tellRaw == null) {
+ val pcl = p.getClass();
+ if (notCraftPlayer(pcl)) return false;
+ val hm = pcl.getMethod("getHandle");
+ val handle = hm.invoke(p);
+ val nms = handle.getClass().getPackage().getName();
+ val chatcompcl = Class.forName(nms + ".IChatBaseComponent");
+ val sendmsg = handle.getClass().getMethod("sendMessage", chatcompcl);
+
+ /*val ccucl = Class.forName(nms + ".ChatComponentUtils");
+ val iclcl = Class.forName(nms + ".ICommandListener");
+ val encl = Class.forName(nms + ".Entity");
+ val ffdm = ccucl.getMethod("filterForDisplay", iclcl, chatcompcl, encl);*/
+
+ val cscl = Class.forName(chatcompcl.getName() + "$ChatSerializer");
+ val am = cscl.getMethod("a", String.class);
+
+ tellRaw = (pl, jsonStr) -> {
+ if (notCraftPlayer(pl.getClass())) return false;
+ try {
+ val hhandle = hm.invoke(pl);
+ val deserialized = am.invoke(null, jsonStr);
+ //val filtered = ffdm.invoke(null, hhandle, deserialized, hhandle);
+ sendmsg.invoke(hhandle, deserialized);
+ return true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ };
+ }
+
+ /*((CraftPlayer) p).getHandle().sendMessage(ChatComponentUtils
+ .filterForDisplay(((CraftPlayer) p).getHandle(),
+ IChatBaseComponent.ChatSerializer.a(json), ((CraftPlayer) p).getHandle()));*/
+ return tellRaw.test(p, json);
+ } catch (Exception e) {
+ PluginMain.Instance.getLogger().warning("Could not use tellRaw: " + e.getMessage());
+ return false;
+ }
+ }
+
+ private boolean notCraftPlayer(Class> cl) {
+ return !cl.getSimpleName().contains("CraftPlayer");
}
}
diff --git a/src/main/java/buttondevteam/chat/commands/ucmds/HelpCommand.java b/src/main/java/buttondevteam/chat/commands/ucmds/HelpCommand.java
index 67d88c5..b7c10fa 100644
--- a/src/main/java/buttondevteam/chat/commands/ucmds/HelpCommand.java
+++ b/src/main/java/buttondevteam/chat/commands/ucmds/HelpCommand.java
@@ -19,7 +19,7 @@ public final class HelpCommand extends UCommandBase {
public boolean def(CommandSender sender, @Command2.TextArg @Command2.OptionalArg String topicOrCommand) {
if (topicOrCommand == null) {
sender.sendMessage(new String[]{
- "§6---- Thorpe Help ----",
+ "§6---- Chroma Help ----",
"Do /u help for more info",
"Do /u help [subcommands] for more info about a command",
"Topics:",
diff --git a/src/main/java/buttondevteam/chat/commands/ucmds/HistoryCommand.java b/src/main/java/buttondevteam/chat/commands/ucmds/HistoryCommand.java
index fde4953..476ab03 100644
--- a/src/main/java/buttondevteam/chat/commands/ucmds/HistoryCommand.java
+++ b/src/main/java/buttondevteam/chat/commands/ucmds/HistoryCommand.java
@@ -5,7 +5,6 @@ import buttondevteam.lib.chat.ChatMessage;
import buttondevteam.lib.chat.Command2;
import buttondevteam.lib.chat.CommandClass;
import lombok.RequiredArgsConstructor;
-import lombok.experimental.var;
import lombok.val;
import org.bukkit.command.CommandSender;
diff --git a/src/main/java/buttondevteam/chat/commands/ucmds/ReloadCommand.java b/src/main/java/buttondevteam/chat/commands/ucmds/ReloadCommand.java
new file mode 100644
index 0000000..2a49259
--- /dev/null
+++ b/src/main/java/buttondevteam/chat/commands/ucmds/ReloadCommand.java
@@ -0,0 +1,20 @@
+package buttondevteam.chat.commands.ucmds;
+
+import buttondevteam.chat.PluginMain;
+import buttondevteam.lib.chat.Command2;
+import buttondevteam.lib.chat.CommandClass;
+import org.bukkit.command.CommandSender;
+
+@CommandClass(helpText = {
+ "Reload",
+ "Reloads the config"
+}, modOnly = true)
+public class ReloadCommand extends UCommandBase {
+ @Command2.Subcommand
+ public void def(CommandSender sender) {
+ if (PluginMain.Instance.tryReloadConfig())
+ sender.sendMessage("§bReloaded config");
+ else
+ sender.sendMessage("§cFailed to reload config.");
+ }
+}
diff --git a/src/main/java/buttondevteam/chat/components/announce/AnnounceCommand.java b/src/main/java/buttondevteam/chat/components/announce/AnnounceCommand.java
index 050687d..d6864d1 100644
--- a/src/main/java/buttondevteam/chat/components/announce/AnnounceCommand.java
+++ b/src/main/java/buttondevteam/chat/components/announce/AnnounceCommand.java
@@ -20,7 +20,7 @@ public class AnnounceCommand extends UCommandBase {
})
public boolean add(CommandSender sender, @Command2.TextArg String text) {
String finalmessage = text.replace('&', '§');
- component.AnnounceMessages().get().add(finalmessage);
+ component.announceMessages().get().add(finalmessage);
sender.sendMessage("§bAnnouncement added.§r");
return true;
}
@@ -34,9 +34,9 @@ public class AnnounceCommand extends UCommandBase {
String finalmessage1 = text.replace('&', '§');
if (index > 100)
return false;
- while (component.AnnounceMessages().get().size() <= index)
- component.AnnounceMessages().get().add("");
- component.AnnounceMessages().get().set(index, finalmessage1);
+ while (component.announceMessages().get().size() <= index)
+ component.announceMessages().get().add("");
+ component.announceMessages().get().set(index, finalmessage1);
sender.sendMessage("Announcement edited.");
return true;
}
@@ -49,10 +49,10 @@ public class AnnounceCommand extends UCommandBase {
sender.sendMessage("§bList of announce messages:§r");
sender.sendMessage("§bFormat: [index] message§r");
int i = 0;
- for (String message : component.AnnounceMessages().get())
+ for (String message : component.announceMessages().get())
sender.sendMessage("[" + i++ + "] " + message);
sender.sendMessage("§bCurrent wait time between announcements: "
- + component.AnnounceTime().get() / 60 / 1000 + " minute(s)§r");
+ + component.announceTime().get() / 60 / 1000 + " minute(s)§r");
return true;
}
@@ -61,7 +61,7 @@ public class AnnounceCommand extends UCommandBase {
"This command removes an announcement"
})
public boolean remove(CommandSender sender, int index) {
- val msgs = component.AnnounceMessages().get();
+ val msgs = component.announceMessages().get();
if (index < 0 || index > msgs.size()) return false;
msgs.remove(index);
sender.sendMessage("Announcement removed.");
@@ -73,7 +73,7 @@ public class AnnounceCommand extends UCommandBase {
"This command sets the time between the announcements"
})
public boolean settime(CommandSender sender, int minutes) {
- component.AnnounceTime().set(minutes * 60 * 1000);
+ component.announceTime().set(minutes * 60 * 1000);
sender.sendMessage("Time set between announce messages to " + minutes + " minutes");
return true;
}
diff --git a/src/main/java/buttondevteam/chat/components/announce/AnnouncerComponent.java b/src/main/java/buttondevteam/chat/components/announce/AnnouncerComponent.java
index cecc285..1d41d62 100644
--- a/src/main/java/buttondevteam/chat/components/announce/AnnouncerComponent.java
+++ b/src/main/java/buttondevteam/chat/components/announce/AnnouncerComponent.java
@@ -11,11 +11,11 @@ import org.bukkit.Bukkit;
import java.util.ArrayList;
public class AnnouncerComponent extends Component implements Runnable {
- public ConfigData> AnnounceMessages() {
+ public ConfigData> announceMessages() {
return getConfig().getData("announceMessages", new ArrayList<>(0));
}
- public ConfigData AnnounceTime() {
+ public ConfigData announceTime() {
return getConfig().getData("announceTime", 15 * 60 * 1000);
}
@@ -27,15 +27,15 @@ public class AnnouncerComponent extends Component implements Runnabl
public void run() {
while (isEnabled()) {
try {
- Thread.sleep(AnnounceTime().get());
+ Thread.sleep(announceTime().get());
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
if (Bukkit.getOnlinePlayers().size() == 0) continue; //Don't post to Discord if nobody is on
- if (AnnounceMessages().get().size() > AnnounceMessageIndex) {
- TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, AnnounceMessages().get().get(AnnounceMessageIndex), target);
+ if (announceMessages().get().size() > AnnounceMessageIndex) {
+ TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, announceMessages().get().get(AnnounceMessageIndex), target);
AnnounceMessageIndex++;
- if (AnnounceMessageIndex == AnnounceMessages().get().size())
+ if (AnnounceMessageIndex == announceMessages().get().size())
AnnounceMessageIndex = 0;
}
}
diff --git a/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java b/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java
index 7f17848..5f012dd 100644
--- a/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java
+++ b/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java
@@ -1,8 +1,8 @@
package buttondevteam.chat.components.chatonly;
import buttondevteam.chat.ChatPlayer;
-import buttondevteam.chat.formatting.TellrawEvent;
-import buttondevteam.chat.formatting.TellrawPart;
+import buttondevteam.chat.components.formatter.formatting.TellrawEvent;
+import buttondevteam.chat.components.formatter.formatting.TellrawPart;
import buttondevteam.core.ComponentManager;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.player.TBMCPlayer;
diff --git a/src/main/java/buttondevteam/chat/components/flair/AcceptCommand.java b/src/main/java/buttondevteam/chat/components/flair/AcceptCommand.java
index 8ebd6ed..1c47167 100644
--- a/src/main/java/buttondevteam/chat/components/flair/AcceptCommand.java
+++ b/src/main/java/buttondevteam/chat/components/flair/AcceptCommand.java
@@ -39,7 +39,7 @@ public class AcceptCommand extends UCommandBase {
}
if (p.FlairState().get().equals(FlairStates.NoComment) || p.UserNames().size() == 0) {
player.sendMessage("§cError: You need to write your username to the reddit thread§r");
- player.sendMessage(component.FlairThreadURL().get());
+ player.sendMessage(component.flairThreadURL().get());
return true;
}
if (username != null && !p.UserNames().contains(username)) {
diff --git a/src/main/java/buttondevteam/chat/components/flair/FlairComponent.java b/src/main/java/buttondevteam/chat/components/flair/FlairComponent.java
index a5f4878..7c8440a 100644
--- a/src/main/java/buttondevteam/chat/components/flair/FlairComponent.java
+++ b/src/main/java/buttondevteam/chat/components/flair/FlairComponent.java
@@ -23,7 +23,7 @@ import java.text.SimpleDateFormat;
import java.util.*;
public class FlairComponent extends Component {
- ConfigData FlairThreadURL() {
+ ConfigData flairThreadURL() {
return getConfig().getData("flairThreadURL", "https://www.reddit.com/r/Chromagamers/comments/51ys94/flair_thread_for_the_mc_server/");
}
@@ -54,7 +54,7 @@ public class FlairComponent extends Component {
int errorcount = 0;
while (isEnabled()) {
try {
- String body = TBMCCoreAPI.DownloadString(FlairThreadURL().get() + ".json?limit=1000");
+ String body = TBMCCoreAPI.DownloadString(flairThreadURL().get() + ".json?limit=1000");
JsonArray json = new JsonParser().parse(body).getAsJsonArray().get(1).getAsJsonObject().get("data")
.getAsJsonObject().get("children").getAsJsonArray();
for (Object obj : json) {
diff --git a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java
new file mode 100644
index 0000000..e94372c
--- /dev/null
+++ b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java
@@ -0,0 +1,348 @@
+package buttondevteam.chat.components.formatter;
+
+import buttondevteam.chat.ChatPlayer;
+import buttondevteam.chat.ChatUtils;
+import buttondevteam.chat.PluginMain;
+import buttondevteam.chat.VanillaUtils;
+import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
+import buttondevteam.chat.components.chatonly.ChatOnlyComponent;
+import buttondevteam.chat.components.formatter.formatting.ChatFormatter;
+import buttondevteam.chat.components.formatter.formatting.TellrawEvent;
+import buttondevteam.chat.components.formatter.formatting.TellrawPart;
+import buttondevteam.chat.components.formatter.formatting.TellrawSerializer;
+import buttondevteam.chat.components.fun.FunComponent;
+import buttondevteam.chat.components.towny.TownyComponent;
+import buttondevteam.chat.listener.PlayerListener;
+import buttondevteam.core.ComponentManager;
+import buttondevteam.core.component.channel.Channel;
+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;
+import buttondevteam.lib.player.TBMCPlayerBase;
+import com.earth2me.essentials.User;
+import com.google.common.collect.Lists;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import lombok.val;
+import org.bukkit.Bukkit;
+import org.bukkit.Sound;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import javax.annotation.Nullable;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
+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]+)?)");
+ 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 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"); //TODO
+ 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+");
+ private static boolean pingedconsole = false;
+
+ public static final ChatFormatter ESCAPE_FORMATTER = ChatFormatter.builder("escape", ESCAPE_PATTERN).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("underlined", UNDERLINED_PATTERN).underlined(true).removeCharCount((short) 1).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)
+ .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(),
+
+ 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());
+ 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 static final String[] testPlayers = {"Koiiev", "iie", "Alisolarflare", "NorbiPeti", "Arsen_Derby_FTW", "carrot_lynx"};
+
+ private ChatProcessing() {
+ }
+
+ public static boolean ProcessChat(TBMCChatEvent e, FormatterComponent component) {
+ Channel channel = e.getChannel();
+ CommandSender sender = e.getSender();
+ String message = e.getMessage();
+ long processstart = System.nanoTime();
+ Player player = (sender instanceof Player ? (Player) sender : null);
+ User user = PluginMain.essentials.getUser(player);
+
+ if (player != null) {
+ user.updateActivity(true); //Could talk in a private channel, so broadcast
+ if (user.isMuted())
+ return true;
+ }
+
+ doFunStuff(sender, e, message);
+
+ final String channelidentifier = getChannelID(channel, e.getOrigin());
+ PluginMain.Instance.getServer().getConsoleSender()
+ .sendMessage(String.format("%s <%s§r> %s", channelidentifier, getSenderName(sender, player), message));
+
+ if (Bukkit.getOnlinePlayers().size() == 0) return false; //Don't try to send to nobody (errors on 1.14)
+
+ ChatPlayer mp;
+ if (player != null)
+ mp = TBMCPlayerBase.getPlayer(player.getUniqueId(), ChatPlayer.class);
+ else //Due to the online player map, getPlayer() can be more efficient than getAs()
+ mp = e.getUser().getAs(ChatPlayer.class); //May be null
+
+ Color colormode = channel.Color().get();
+ if (mp != null && mp.OtherColorMode != null)
+ colormode = mp.OtherColorMode;
+ if (message.startsWith(">"))
+ colormode = Color.Green;
+ // If greentext, ignore channel or player colors
+
+ ArrayList formatters;
+ if (component.allowFormatting().get()) {
+ formatters = addFormatters(colormode, e::shouldSendTo);
+ if (colormode == channel.Color().get() && mp != null && mp.RainbowPresserColorMode) { // Only overwrite channel color
+ final AtomicInteger rpc = new AtomicInteger(0);
+ formatters.add(ChatFormatter.builder("word", WORD_PATTERN).color(colormode).onmatch((match, cf, s) -> {
+ cf.setColor(RainbowPresserColors[rpc.getAndUpdate(i -> ++i < RainbowPresserColors.length ? i : 0)]);
+ return match;
+ }).build());
+ }
+ pingedconsole = false; // Will set it to true onmatch (static constructor)
+ } else
+ formatters = Lists.newArrayList(ChatFormatter.builder("entireMessage", ENTIRE_MESSAGE_PATTERN)
+ .color(Color.White).priority(Priority.Low).build()); //This formatter is necessary
+
+ TellrawPart json = createTellraw(sender, message, player, mp, e.getUser(), channelidentifier, e.getOrigin());
+ long combinetime = System.nanoTime();
+ ChatFormatter.Combine(formatters, message, json, component.getConfig());
+ combinetime = System.nanoTime() - combinetime;
+ String jsonstr = toJson(json);
+ if (jsonstr.length() >= 32767) {
+ sender.sendMessage(
+ "§cError: Message too long. Try shortening it, or remove hashtags and other formatting.");
+ return true;
+ }
+ DebugCommand.SendDebugMessage(jsonstr);
+
+ try {
+ if (!channel.isGlobal()) {
+ String senderGroup = e.getGroupID(sender);
+ if (senderGroup == null) { // Never send messages if the group is null
+ sender.sendMessage("§cYou don't have permission to send this message or something went wrong");
+ return true;
+ }
+ val tc = ComponentManager.getIfEnabled(TownyComponent.class);
+ if (tc != null) tc.handleSpiesInit(channel, json, ChatProcessing::toJson);
+ for (Player p : Bukkit.getOnlinePlayers()) {
+ final String group;
+ if (player != null
+ && PluginMain.essentials.getUser(p).isIgnoredPlayer(PluginMain.essentials.getUser(player)))
+ group = null; // Don't send the message to them
+ else
+ group = VanillaUtils.getGroupIfChatOn(p, e);
+ if (senderGroup.equals(group))
+ VanillaUtils.tellRaw(p, jsonstr);
+ else if (tc != null) tc.handleSpies(channel, p);
+ //Only sends if didn't send normally
+ }
+ } else
+ for (Player p : Bukkit.getOnlinePlayers())
+ VanillaUtils.tellRaw(p, jsonstr);
+ } catch (Exception ex) {
+ TBMCCoreAPI.SendException("An error occured while sending a chat message!", ex);
+ sender.sendMessage("§cAn error occured while sending the message.");
+ return true;
+ }
+ DebugCommand.SendDebugMessage(
+ "-- Full ChatProcessing time: " + (System.nanoTime() - processstart) / 1000000f + " ms");
+ DebugCommand.SendDebugMessage("-- ChatFormatter.Combine time: " + combinetime / 1000000f + " ms");
+ return false;
+ }
+
+ static String toJson(TellrawPart json) {
+ return gson.toJson(json);
+ }
+
+ static TellrawPart createTellraw(CommandSender sender, String message, @Nullable Player player,
+ @Nullable ChatPlayer mp, @Nullable ChromaGamerBase cg, final String channelidentifier,
+ String origin) {
+ TellrawPart json = new TellrawPart("");
+ ChatOnlyComponent.tellrawCreate(mp, json); //TODO: Make nice API
+ json.addExtra(
+ new TellrawPart(channelidentifier)
+ .setHoverEvent(
+ TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT,
+ new TellrawPart((ChatUtils.MCORIGIN.equals(origin) ? "" : "From " + origin + "n")
+ + "Copy message").setColor(Color.Blue)))
+ .setClickEvent(TellrawEvent.create(TellrawEvent.ClickAction.SUGGEST_COMMAND, message)));
+ if (PluginMain.permission.has(sender, "tbmc.badge.diamond"))
+ json.addExtra(new TellrawPart("[P]").setColor(Color.Aqua).setBold(true)
+ .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Diamond Patreon supporter")));
+ else if (PluginMain.permission.has(sender, "tbmc.badge.gold"))
+ json.addExtra(new TellrawPart("[P]").setColor(Color.Gold).setBold(true)
+ .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Gold Patreon supporter")));
+ json.addExtra(new TellrawPart(" <"));
+ TellrawPart hovertp = new TellrawPart("");
+ if (cg != null)
+ hovertp.addExtra(new TellrawPart(cg.getInfo(ChromaGamerBase.InfoTarget.MCHover)));
+ json.addExtra(new TellrawPart(getSenderName(sender, player))
+ .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, hovertp)));
+ json.addExtra(new TellrawPart("> "));
+ return json;
+ }
+
+ private static String getSenderName(CommandSender sender, Player player) {
+ if (player == null)
+ return sender.getName();
+ return player.getDisplayName();
+ }
+
+ static String getChannelID(Channel channel, String origin) {
+ return ("[" + (ChatUtils.MCORIGIN.equals(origin) ? "" : "§8" + origin.substring(0, 1) + "§r|") + channel.DisplayName().get())
+ + "]";
+ }
+
+ static ArrayList addFormatters(Color colormode, Predicate canSee) {
+ @SuppressWarnings("unchecked")
+ ArrayList formatters = (ArrayList) commonFormatters.clone();
+
+ formatters.add(
+ ChatFormatter.builder("entireMessage", ENTIRE_MESSAGE_PATTERN).color(colormode).priority(Priority.Low).build());
+
+ boolean nottest; //Not assigning a default value, so that it can only be used in the if
+ if ((nottest = Bukkit.getOnlinePlayers().size() > 0) || Bukkit.getVersion().equals("test")) {
+ StringBuilder namesb = new StringBuilder("(?i)(");
+ boolean addNameFormatter = false; //Needed because some names may be filtered out if they can't see the channel
+ if (nottest)
+ for (Player p : Bukkit.getOnlinePlayers()) {
+ if (canSee.test(p)) {
+ namesb.append(p.getName()).append("|");
+ addNameFormatter = true;
+ }
+ }
+ else {
+ for (String testPlayer : testPlayers)
+ namesb.append(testPlayer).append("|");
+ addNameFormatter = true;
+ }
+ namesb.deleteCharAt(namesb.length() - 1);
+ namesb.append(")");
+ 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(")");
+
+ Consumer error = message -> {
+ if (PluginMain.Instance != null)
+ PluginMain.Instance.getLogger().warning(message);
+ else
+ System.out.println(message);
+ };
+
+ if (addNameFormatter)
+ formatters.add(ChatFormatter.builder("name", Pattern.compile(namesb.toString())).color(Color.Aqua)
+ .onmatch((match, builder, section) -> {
+ Player p = Bukkit.getPlayer(match);
+ Optional pn = nottest ? Optional.empty()
+ : Arrays.stream(testPlayers).filter(tp -> tp.equalsIgnoreCase(match)).findAny();
+ if (nottest ? p == null : !pn.isPresent()) {
+ error.accept("Error: Can't find player " + match + " but was reported as online.");
+ return "§c" + match + "§r";
+ }
+ ChatPlayer mpp = TBMCPlayer.getPlayer(nottest ? p.getUniqueId() : new UUID(0, 0), ChatPlayer.class);
+ if (nottest) {
+ playPingSound(p);
+ }
+ 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());
+
+ if (addNickFormatter)
+ formatters.add(ChatFormatter.builder("nickname", Pattern.compile(nicksb.toString())).color(Color.Aqua)
+ .onmatch((match, builder, section) -> {
+ if (PlayerListener.nicknames.containsKey(match.toLowerCase())) { //Made a stream and all that but I can actually store it lowercased
+ Player p = Bukkit.getPlayer(PlayerListener.nicknames.get(match.toLowerCase()));
+ if (p == null) {
+ error.accept("Error: Can't find player nicknamed "
+ + match.toLowerCase() + " but was reported as online.");
+ return "§c" + match + "§r";
+ }
+ playPingSound(p);
+ return PluginMain.essentials.getUser(p).getNickname();
+ }
+ 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());
+ }
+ return formatters;
+ }
+
+ private static void playPingSound(Player p) {
+ if (PluginMain.Instance.notificationSound().get().length() == 0)
+ p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1.0f, 0.5f); // TODO: Airhorn
+ else
+ p.playSound(p.getLocation(), PluginMain.Instance.notificationSound().get(), 1.0f,
+ PluginMain.Instance.notificationPitch().get());
+ }
+
+ static void doFunStuff(CommandSender sender, TBMCChatEventBase event, String message) {
+ val fc = ComponentManager.getIfEnabled(FunComponent.class);
+ if (fc != null) fc.onChat(sender, event, message);
+ }
+}
diff --git a/src/main/java/buttondevteam/chat/components/formatter/FormatterComponent.java b/src/main/java/buttondevteam/chat/components/formatter/FormatterComponent.java
new file mode 100644
index 0000000..6789b0d
--- /dev/null
+++ b/src/main/java/buttondevteam/chat/components/formatter/FormatterComponent.java
@@ -0,0 +1,40 @@
+package buttondevteam.chat.components.formatter;
+
+import buttondevteam.chat.PluginMain;
+import buttondevteam.core.ComponentManager;
+import buttondevteam.core.MainPlugin;
+import buttondevteam.lib.TBMCChatEvent;
+import buttondevteam.lib.architecture.Component;
+import buttondevteam.lib.architecture.ConfigData;
+
+/**
+ * This component handles the custom processing of chat messages. If this component is disabled channels won't be supported either in Minecraft.
+ * If you only want to disable the formatting features, set allowFormatting to false.
+ */
+public class FormatterComponent extends Component {
+ ConfigData allowFormatting() {
+ return getConfig().getData("allowFormatting", true);
+ }
+
+ @Override
+ protected void enable() {
+ MainPlugin.Instance.setChatHandlerEnabled(false); //Disable Core chat handler - if this component is disabled then let it do it's job
+ }
+
+ @Override
+ protected void disable() {
+ MainPlugin.Instance.setChatHandlerEnabled(true);
+ }
+
+ /**
+ * Handles the chat if the component is enabled.
+ *
+ * @param event The chat event
+ * @return Whether the chat message shouldn't be sent for some reason
+ */
+ public static boolean handleChat(TBMCChatEvent event) {
+ FormatterComponent component = ComponentManager.getIfEnabled(FormatterComponent.class);
+ if (component == null) return false;
+ return ChatProcessing.ProcessChat(event, component);
+ }
+}
diff --git a/src/main/java/buttondevteam/chat/formatting/ChatFormatter.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java
similarity index 50%
rename from src/main/java/buttondevteam/chat/formatting/ChatFormatter.java
rename to src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java
index aa7eb96..e39eef5 100644
--- a/src/main/java/buttondevteam/chat/formatting/ChatFormatter.java
+++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java
@@ -1,7 +1,9 @@
-package buttondevteam.chat.formatting;
+package buttondevteam.chat.components.formatter.formatting;
-import buttondevteam.chat.ChatProcessing;
import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
+import buttondevteam.chat.components.formatter.ChatProcessing;
+import buttondevteam.lib.architecture.ConfigData;
+import buttondevteam.lib.architecture.IHaveConfig;
import buttondevteam.lib.chat.Color;
import buttondevteam.lib.chat.Priority;
import lombok.Builder;
@@ -15,13 +17,13 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
- * A {@link ChatFormatter} shows what formatting to use based on regular expressions. {@link ChatFormatter#Combine(List, String, TellrawPart)} is used to turn it into a {@link TellrawPart}, combining
+ * A {@link ChatFormatter} shows what formatting to use based on regular expressions. {@link ChatFormatter#Combine(List, String, TellrawPart, IHaveConfig)} is used to turn it into a {@link TellrawPart}, combining
* intersecting parts found, for example when {@code _abc*def*ghi_} is said in chat, it'll turn it into an underlined part, then an underlined and italics part, finally an underlined part
* again.
- *
- * @author NorbiPeti
*
+ * @author NorbiPeti
*/
+@SuppressWarnings("UnusedAssignment")
@Data
@Builder
public final class ChatFormatter {
@@ -39,118 +41,120 @@ public final class ChatFormatter {
@Builder.Default
short removeCharCount = 0;
@Builder.Default
- Type type = Type.Normal;
+ Type type = Type.Normal;
String hoverText;
+ String name;
+
+ public static ChatFormatterBuilder builder(String name, Pattern regex) {
+ return builder().regex(regex).name(name);
+ }
+
+ private static ChatFormatterBuilder builder() {
+ return new ChatFormatterBuilder();
+ }
+
+ private ConfigData enabled(IHaveConfig config) {
+ return config.getData(name + ".enabled", true);
+ }
public enum Type {
- Normal,
- /**
- * Matches a start and an end section which gets converted to one section (for example see italics)
- */
- Range,
- /**
- * Exclude matching area from further processing (besides this formatter)
- */
- Excluder
- }
+ Normal,
+ /**
+ * Matches a start and an end section which gets converted to one section (for example see italics)
+ */
+ Range,
+ /**
+ * Exclude matching area from further processing (besides this formatter)
+ */
+ Excluder
+ }
@FunctionalInterface
public interface TriFunc {
R apply(T1 x1, T2 x2, T3 x3);
}
- public static void Combine(List formatters, String str, TellrawPart tp) {
+ public static void Combine(List formatters, String str, TellrawPart tp, IHaveConfig config) {
/*
* This method assumes that there is always a global formatter
- */
- header("ChatFormatter.Combine begin");
- ArrayList sections = new ArrayList();
+ */
+ header("ChatFormatter.Combine begin");
+ ArrayList sections = new ArrayList<>();
- for (ChatFormatter formatter : formatters) {
- if (formatter.type != Type.Excluder)
- continue;
- Matcher matcher = formatter.regex.matcher(str);
- while (matcher.find()) {
- DebugCommand.SendDebugMessage("Found match from " + matcher.start() + " to " + (matcher.end() - 1));
- DebugCommand.SendDebugMessage("With excluder formatter:" + formatter);
- sendMessageWithPointer(str, matcher.start(), matcher.end() - 1);
- if (formatter.regex != ChatProcessing.ENTIRE_MESSAGE_PATTERN && sections.stream().anyMatch(fs -> fs.type == Type.Excluder && (fs.End >= matcher.start() && fs.Start <= matcher.end() - 1))) {
- DebugCommand.SendDebugMessage("Ignoring formatter because of an excluder");
- continue; //Exclude areas matched by excluders - Range sections are correctly handled afterwards
- }
- ArrayList groups = new ArrayList();
- for (int i = 0; i < matcher.groupCount(); i++)
- groups.add(matcher.group(i + 1));
- if (groups.size() > 0)
- DebugCommand.SendDebugMessage("First group: " + groups.get(0));
- FormattedSection section = new FormattedSection(formatter, matcher.start(), matcher.end() - 1, groups,
- formatter.type);
- sections.add(section);
- }
- }
+ 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)");
- for (ChatFormatter formatter : formatters) {
- if (formatter.type == Type.Excluder)
- continue;
- Matcher matcher = formatter.regex.matcher(str);
- while (matcher.find()) {
- DebugCommand.SendDebugMessage("Found match from " + matcher.start() + " to " + (matcher.end() - 1));
- DebugCommand.SendDebugMessage("With formatter:" + formatter);
- sendMessageWithPointer(str, matcher.start(), matcher.end() - 1);
- if (formatter.regex != ChatProcessing.ENTIRE_MESSAGE_PATTERN && sections.stream().anyMatch(fs -> fs.type == Type.Excluder && (fs.End >= matcher.start() && fs.Start <= matcher.end() - 1))) {
- DebugCommand.SendDebugMessage("Ignoring formatter because of an excluder");
- continue; //Exclude areas matched by excluders - Range sections are correctly handled afterwards
- }
- ArrayList groups = new ArrayList();
- for (int i = 0; i < matcher.groupCount(); i++)
- groups.add(matcher.group(i + 1));
- if (groups.size() > 0)
- DebugCommand.SendDebugMessage("First group: " + groups.get(0));
- FormattedSection section = new FormattedSection(formatter, matcher.start(), matcher.end() - 1, groups,
- formatter.type);
- sections.add(section);
- }
- }
- sections.sort(
- (s1, s2) -> s1.Start == s2.Start
- ? s1.End == s2.End ? Integer.compare(s2.Formatters.get(0).priority.GetValue(),
- s1.Formatters.get(0).priority.GetValue()) : Integer.compare(s2.End, s1.End)
- : Integer.compare(s1.Start, s2.Start));
+ header("Section creation (excluders done)");
+ createSections(formatters, str, sections, false);
+ sortSections(sections);
- /**
+ /*
* 0: Start - 1: End index
*/
val remchars = new ArrayList();
header("Range section conversion");
+ sections = convertRangeSections(str, sections, remchars);
+
+ header("Adding remove chars (RC)"); // Important to add after the range section conversion
+ addRemChars(sections, remchars);
+
+ header("Section combining");
+ combineSections(str, sections);
+
+ header("Section applying");
+ applySections(str, tp, sections, remchars);
+ header("ChatFormatter.Combine done");
+ }
+
+ private static void createSections(List formatters, String str, ArrayList sections,
+ boolean excluders) {
+ for (ChatFormatter formatter : formatters) {
+ if (excluders == (formatter.type != Type.Excluder))
+ continue; //If we're looking at excluders and this isn't one, skip - or vica-versa
+ Matcher matcher = formatter.regex.matcher(str);
+ while (matcher.find()) {
+ DebugCommand.SendDebugMessage("Found match from " + matcher.start() + " to " + (matcher.end() - 1));
+ DebugCommand.SendDebugMessage("With " + (excluders ? "excluder " : "") + "formatter: " + formatter);
+ sendMessageWithPointer(str, matcher.start(), matcher.end() - 1);
+ if (formatter.regex != ChatProcessing.ENTIRE_MESSAGE_PATTERN && sections.stream().anyMatch(fs -> fs.type == Type.Excluder && (fs.End >= matcher.start() && fs.Start <= matcher.end() - 1))) {
+ DebugCommand.SendDebugMessage("Ignoring formatter because of an excluder");
+ continue; //Exclude areas matched by excluders - Range sections are correctly handled afterwards
+ }
+ ArrayList groups = new ArrayList<>();
+ for (int i = 0; i < matcher.groupCount(); i++)
+ groups.add(matcher.group(i + 1));
+ if (groups.size() > 0)
+ DebugCommand.SendDebugMessage("First group: " + groups.get(0));
+ FormattedSection section = new FormattedSection(formatter, matcher.start(), matcher.end() - 1, groups,
+ formatter.type);
+ sections.add(section);
+ }
+ }
+ }
+
+ private static ArrayList convertRangeSections(String str, ArrayList sections, ArrayList remchars) {
ArrayList combined = new ArrayList<>();
Map nextSection = new HashMap<>();
boolean escaped = false;
int takenStart = -1, takenEnd = -1;
ChatFormatter takenFormatter = null;
- for (int i = 0; i < sections.size(); i++) {
+ for (final FormattedSection section : sections) {
// Set ending to -1 until closed with another 1 long "section" - only do this if IsRange is true
- final FormattedSection section = sections.get(i);
- if (section.type!=Type.Range) {
+ if (section.type != Type.Range) {
escaped = section.Formatters.contains(ChatProcessing.ESCAPE_FORMATTER) && !escaped; // Enable escaping on first \, disable on second
- if (escaped) {// Don't add the escape character
+ if (escaped) {// Don't add the escape character
remchars.add(new int[]{section.Start, section.Start});
- DebugCommand.SendDebugMessage("Found escaper section: " + section);
- } else {
- combined.add(section); // The above will delete the \
- DebugCommand.SendDebugMessage("Added section: " + section);
- }
+ DebugCommand.SendDebugMessage("Found escaper section: " + section);
+ } else {
+ combined.add(section); // The above will delete the \
+ DebugCommand.SendDebugMessage("Added section: " + section);
+ }
sendMessageWithPointer(str, section.Start, section.End);
continue;
- }
- if (!escaped) {
- if (combined.stream().anyMatch(s -> section.type != Type.Range && (s.Start == section.Start
- || (s.Start < section.Start ? s.End >= section.Start : s.Start <= section.End)))) {
- DebugCommand.SendDebugMessage("Range " + section + " overlaps with a combined section, ignoring.");
- sendMessageWithPointer(str, section.Start, section.End);
- continue;
- }
+ }
+ if (!escaped) {
if (section.Start == takenStart || (section.Start > takenStart && section.Start < takenEnd)) {
/*
* if (nextSection.containsKey(section.Formatters.get(0)) ? section.RemCharFromStart <= takenEnd - takenStart : section.RemCharFromStart > takenEnd - takenStart) {
@@ -183,7 +187,7 @@ public final class ChatFormatter {
nextSection.put(section.Formatters.get(0), section);
}
DebugCommand
- .SendDebugMessage("New area taken: (" + takenStart + "-" + takenEnd + ") " + takenFormatter);
+ .SendDebugMessage("New area taken: (" + takenStart + "-" + takenEnd + ") " + takenFormatter);
sendMessageWithPointer(str, takenStart, takenEnd);
} else {
DebugCommand.SendDebugMessage("Skipping section: " + section); // This will keep the text (character)
@@ -193,24 +197,27 @@ public final class ChatFormatter {
}
//Do not finish unfinished sections, ignore them
sections = combined;
+ return sections;
+ }
- header("Adding remove chars (RC)"); // Important to add after the range section conversion
+ private static void addRemChars(ArrayList sections, ArrayList remchars) {
sections.stream()
- .flatMap(fs -> fs.Formatters.stream().filter(cf -> cf.removeCharCount > 0)
- .mapToInt(cf -> cf.removeCharCount).mapToObj(rcc -> new int[]{fs.Start, fs.Start + rcc - 1}))
- .forEach(rc -> remchars.add(rc));
+ .flatMap(fs -> fs.Formatters.stream().filter(cf -> cf.removeCharCount > 0)
+ .mapToInt(cf -> cf.removeCharCount).mapToObj(rcc -> new int[]{fs.Start, fs.Start + rcc - 1}))
+ .forEach(remchars::add);
sections.stream()
- .flatMap(fs -> fs.Formatters.stream().filter(cf -> cf.removeCharCount > 0)
- .mapToInt(cf -> cf.removeCharCount).mapToObj(rcc -> new int[]{fs.End - rcc + 1, fs.End}))
- .forEach(rc -> remchars.add(rc));
+ .flatMap(fs -> fs.Formatters.stream().filter(cf -> cf.removeCharCount > 0)
+ .mapToInt(cf -> cf.removeCharCount).mapToObj(rcc -> new int[]{fs.End - rcc + 1, fs.End}))
+ .forEach(remchars::add);
DebugCommand.SendDebugMessage("Added remchars:");
DebugCommand
- .SendDebugMessage(remchars.stream().map(rc -> Arrays.toString(rc)).collect(Collectors.joining("; ")));
+ .SendDebugMessage(remchars.stream().map(Arrays::toString).collect(Collectors.joining("; ")));
+ }
- header("Section combining");
+ private static void combineSections(String str, ArrayList sections) {
boolean cont = true;
boolean found = false;
- for (int i = 1; cont;) {
+ for (int i = 1; cont; ) {
int nextindex = i + 1;
if (sections.size() < 2)
break;
@@ -218,47 +225,40 @@ public final class ChatFormatter {
FormattedSection firstSection = sections.get(i - 1);
DebugCommand.SendDebugMessage("Combining sections " + firstSection);
sendMessageWithPointer(str, firstSection.Start, firstSection.End);
- DebugCommand.SendDebugMessage(" and " + sections.get(i));
- sendMessageWithPointer(str, sections.get(i).Start, sections.get(i).End);
- if (firstSection.Start == sections.get(i).Start && firstSection.End == sections.get(i).End) {
- firstSection.Formatters.addAll(sections.get(i).Formatters);
- firstSection.Matches.addAll(sections.get(i).Matches);
+ final FormattedSection lastSection = sections.get(i);
+ DebugCommand.SendDebugMessage(" and " + lastSection);
+ sendMessageWithPointer(str, lastSection.Start, lastSection.End);
+ if (firstSection.Start == lastSection.Start && firstSection.End == lastSection.End) {
+ firstSection.Formatters.addAll(lastSection.Formatters);
+ firstSection.Matches.addAll(lastSection.Matches);
DebugCommand.SendDebugMessage("To section " + firstSection);
sendMessageWithPointer(str, firstSection.Start, firstSection.End);
sections.remove(i);
found = true;
- } else if (firstSection.End > sections.get(i).Start && firstSection.Start < sections.get(i).End) {
- int origend = firstSection.End;
- firstSection.End = sections.get(i).Start - 1;
- int origend2 = sections.get(i).End;
- boolean switchends;
- if (switchends = origend2 < origend) {
- int tmp = origend;
- origend = origend2;
- origend2 = tmp;
- }
- FormattedSection section = new FormattedSection(firstSection.Formatters, sections.get(i).Start, origend,
- firstSection.Matches, Type.Normal);
- section.Formatters.addAll(sections.get(i).Formatters);
- section.Matches.addAll(sections.get(i).Matches); // TODO: Clean
+ } else if (firstSection.End > lastSection.Start && firstSection.Start < lastSection.End) {
+ int origend2 = firstSection.End;
+ firstSection.End = lastSection.Start - 1;
+ int origend = lastSection.End;
+ FormattedSection section = new FormattedSection(firstSection.Formatters, lastSection.Start, origend,
+ firstSection.Matches, Type.Normal);
+ section.Formatters.addAll(lastSection.Formatters);
+ section.Matches.addAll(lastSection.Matches); // TODO: Clean
sections.add(i, section);
nextindex++;
- FormattedSection thirdFormattedSection = sections.get(i + 1);
- if (switchends) { // Use the properties of the first section not the second one
- thirdFormattedSection.Formatters.clear();
- thirdFormattedSection.Formatters.addAll(firstSection.Formatters);
- thirdFormattedSection.Matches.clear();
- thirdFormattedSection.Matches.addAll(firstSection.Matches);
- }
- thirdFormattedSection.Start = origend + 1;
- thirdFormattedSection.End = origend2;
+ // Use the properties of the first section not the second one
+ lastSection.Formatters.clear();
+ lastSection.Formatters.addAll(firstSection.Formatters);
+ lastSection.Matches.clear();
+ lastSection.Matches.addAll(firstSection.Matches);
+
+ lastSection.Start = origend + 1;
+ lastSection.End = origend2;
- ArrayList sts = sections;
Predicate removeIfNeeded = s -> {
if (s.Start < 0 || s.End < 0 || s.Start > s.End) {
DebugCommand.SendDebugMessage("Removing section: " + s);
sendMessageWithPointer(str, s.Start, s.End);
- sts.remove(s);
+ sections.remove(s);
return true;
}
return false;
@@ -273,9 +273,9 @@ public final class ChatFormatter {
DebugCommand.SendDebugMessage(" 2:" + section + "");
sendMessageWithPointer(str, section.Start, section.End);
}
- if (!removeIfNeeded.test(thirdFormattedSection)) {
- DebugCommand.SendDebugMessage(" 3:" + thirdFormattedSection);
- sendMessageWithPointer(str, thirdFormattedSection.Start, thirdFormattedSection.End);
+ if (!removeIfNeeded.test(lastSection)) {
+ DebugCommand.SendDebugMessage(" 3:" + lastSection);
+ sendMessageWithPointer(str, lastSection.Start, lastSection.End);
}
found = true;
}
@@ -294,48 +294,44 @@ public final class ChatFormatter {
if (found) {
i = 1;
found = false;
- sections.sort(
- (s1, s2) -> s1.Start == s2.Start
- ? s1.End == s2.End
- ? Integer.compare(s2.Formatters.get(0).priority.GetValue(),
- s1.Formatters.get(0).priority.GetValue())
- : Integer.compare(s2.End, s1.End)
- : Integer.compare(s1.Start, s2.Start));
+ sortSections(sections);
} else
cont = false;
}
}
+ }
- header("Section applying");
- TellrawPart lasttp = null; String lastlink = null;
- for (FormattedSection section : sections) {
+ private static void applySections(String str, TellrawPart tp, ArrayList sections, ArrayList remchars) {
+ TellrawPart lasttp = null;
+ String lastlink = null;
+ for (FormattedSection section : sections) {
DebugCommand.SendDebugMessage("Applying section: " + section);
String originaltext;
int start = section.Start, end = section.End;
DebugCommand.SendDebugMessage("Start: " + start + " - End: " + end);
sendMessageWithPointer(str, start, end);
- val rcs = remchars.stream().filter(rc -> rc[0] <= start && start <= rc[1]).findAny();
- val rce = remchars.stream().filter(rc -> rc[0] <= end && end <= rc[1]).findAny();
- val rci = remchars.stream().filter(rc -> start < rc[0] && rc[1] < end).toArray(int[][]::new);
+ val rcs = remchars.stream().filter(rc -> rc[0] <= start && start <= rc[1]).findAny();
+ val rce = remchars.stream().filter(rc -> rc[0] <= end && end <= rc[1]).findAny();
+ val rci = remchars.stream().filter(rc -> start < rc[0] && rc[1] < end).toArray(int[][]::new);
int s = start, e = end;
if (rcs.isPresent())
s = rcs.get()[1] + 1;
if (rce.isPresent())
e = rce.get()[0] - 1;
DebugCommand.SendDebugMessage("After RC - Start: " + s + " - End: " + e);
- if (e - s < 0) { //e-s==0 means the end char is the same as start char, so one char message
- DebugCommand.SendDebugMessage("Skipping section because of remchars (length would be " + (e - s + 1) + ")");
+ if (e - s < 0) { //e-s==0 means the end char is the same as start char, so one char message
+ DebugCommand.SendDebugMessage("Skipping section because of remchars (length would be " + (e - s + 1) + ")");
continue;
}
originaltext = str.substring(s, e + 1);
- val sb = new StringBuilder(originaltext);
- for (int x = rci.length - 1; x >= 0; x--)
- sb.delete(rci[x][0] - start - 1, rci[x][1] - start); //Delete going backwards
- originaltext = sb.toString();
+ val sb = new StringBuilder(originaltext);
+ for (int x = rci.length - 1; x >= 0; x--)
+ sb.delete(rci[x][0] - start - 1, rci[x][1] - start); //Delete going backwards
+ originaltext = sb.toString();
DebugCommand.SendDebugMessage("Section text: " + originaltext);
- String openlink = null;
- section.Formatters.sort(Comparator.comparing(cf2 -> cf2.priority.GetValue())); //Apply the highest last, to overwrite previous ones
- TellrawPart newtp = new TellrawPart("");
+ String openlink = null;
+ section.Formatters.sort(Comparator.comparing(cf2 -> cf2.priority.GetValue())); //Apply the highest last, to overwrite previous ones
+ TellrawPart newtp = new TellrawPart("");
for (ChatFormatter formatter : section.Formatters) {
DebugCommand.SendDebugMessage("Applying formatter: " + formatter);
if (formatter.onmatch != null)
@@ -343,42 +339,50 @@ public final class ChatFormatter {
if (formatter.color != null)
newtp.setColor(formatter.color);
if (formatter.bold)
- newtp.setBold(formatter.bold);
+ newtp.setBold(true);
if (formatter.italic)
- newtp.setItalic(formatter.italic);
+ newtp.setItalic(true);
if (formatter.underlined)
- newtp.setUnderlined(formatter.underlined);
+ newtp.setUnderlined(true);
if (formatter.strikethrough)
- newtp.setStrikethrough(formatter.strikethrough);
+ newtp.setStrikethrough(true);
if (formatter.obfuscated)
- newtp.setObfuscated(formatter.obfuscated);
+ newtp.setObfuscated(true);
if (formatter.openlink != null)
openlink = formatter.openlink;
if (formatter.hoverText != null)
newtp.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, formatter.hoverText));
}
- if (lasttp != null && newtp.getColor() == lasttp.getColor()
- && newtp.isBold() == lasttp.isBold()
- && newtp.isItalic() == lasttp.isItalic()
- && newtp.isUnderlined() == lasttp.isUnderlined()
- && newtp.isStrikethrough() == lasttp.isStrikethrough()
- && newtp.isObfuscated() == lasttp.isObfuscated()
- && Objects.equals(openlink, lastlink)) {
- DebugCommand.SendDebugMessage("This part has the same properties as the previous one, combining.");
- lasttp.setText(lasttp.getText() + originaltext);
- continue; //Combine parts with the same properties
- }
+ if (lasttp != null && newtp.getColor() == lasttp.getColor()
+ && newtp.isBold() == lasttp.isBold()
+ && newtp.isItalic() == lasttp.isItalic()
+ && newtp.isUnderlined() == lasttp.isUnderlined()
+ && newtp.isStrikethrough() == lasttp.isStrikethrough()
+ && newtp.isObfuscated() == lasttp.isObfuscated()
+ && Objects.equals(openlink, lastlink)) {
+ DebugCommand.SendDebugMessage("This part has the same properties as the previous one, combining.");
+ lasttp.setText(lasttp.getText() + originaltext);
+ continue; //Combine parts with the same properties
+ }
+ lastlink = openlink;
newtp.setText(originaltext);
if (openlink != null && openlink.length() > 0) {
newtp.setClickEvent(TellrawEvent.create(TellrawEvent.ClickAction.OPEN_URL,
- (section.Matches.size() > 0 ? openlink.replace("$1", section.Matches.get(0)) : openlink)))
- .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT,
- new TellrawPart("Click to open").setColor(Color.Blue)));
+ (section.Matches.size() > 0 ? openlink.replace("$1", section.Matches.get(0)) : openlink)))
+ .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT,
+ new TellrawPart("Click to open").setColor(Color.Blue)));
}
tp.addExtra(newtp);
- lasttp = newtp;
+ lasttp = newtp;
}
- header("ChatFormatter.Combine done");
+ }
+
+ private static void sortSections(ArrayList sections) {
+ sections.sort(
+ (s1, s2) -> s1.Start == s2.Start
+ ? s1.End == s2.End ? Integer.compare(s2.Formatters.get(0).priority.GetValue(),
+ s1.Formatters.get(0).priority.GetValue()) : Integer.compare(s2.End, s1.End)
+ : Integer.compare(s1.Start, s2.Start));
}
private static void sendMessageWithPointer(String str, int... pointer) {
diff --git a/src/main/java/buttondevteam/chat/formatting/FormattedSection.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java
similarity index 94%
rename from src/main/java/buttondevteam/chat/formatting/FormattedSection.java
rename to src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java
index 15101c4..c609e58 100644
--- a/src/main/java/buttondevteam/chat/formatting/FormattedSection.java
+++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java
@@ -1,4 +1,4 @@
-package buttondevteam.chat.formatting;
+package buttondevteam.chat.components.formatter.formatting;
import java.util.ArrayList;
import java.util.Collection;
diff --git a/src/main/java/buttondevteam/chat/formatting/TellrawEvent.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawEvent.java
similarity index 93%
rename from src/main/java/buttondevteam/chat/formatting/TellrawEvent.java
rename to src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawEvent.java
index 8f43d63..4c532e5 100644
--- a/src/main/java/buttondevteam/chat/formatting/TellrawEvent.java
+++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawEvent.java
@@ -1,76 +1,76 @@
-package buttondevteam.chat.formatting;
-
-import java.io.Serializable;
-
-import buttondevteam.lib.chat.TellrawSerializableEnum;
-
-public final class TellrawEvent implements Serializable {
- private static final long serialVersionUID = -1681364161210561505L;
- private transient boolean hoverEvent;
- private T action;
- private Object value;
-
- private TellrawEvent(T action, String value) {
- this.hoverEvent = action instanceof HoverAction;
- this.action = action;
- this.value = value;
- }
-
- private TellrawEvent(T action, TellrawPart value) {
- this.hoverEvent = action instanceof HoverAction;
- this.action = action;
- this.value = value;
- }
-
- public static TellrawEvent create(V action, String value) {
- return new TellrawEvent<>(action, value);
- }
-
- public static TellrawEvent create(V action, TellrawPart value) {
- return new TellrawEvent<>(action, value);
- }
-
- public boolean isHoverEvent() {
- return hoverEvent;
- }
-
- public T getAction() {
- return action;
- }
-
- public Object getValue() {
- return value;
- }
-
- public enum ClickAction implements Action {
- OPEN_URL("open_url"), RUN_COMMAND("run_command"), SUGGEST_COMMAND("suggest_command");
- private String action;
-
- ClickAction(String action) {
- this.action = action;
- }
-
- @Override
- public String getName() {
- return action;
- }
- }
-
- public enum HoverAction implements Action {
- SHOW_TEXT("show_text"), SHOW_ITEM("show_item"), SHOW_ACHIEVEMENT("show_achievement"), SHOW_ENTITY(
- "show_entity");
- private String action;
-
- HoverAction(String action) {
- this.action = action;
- }
-
- @Override
- public String getName() {
- return action;
- }
- }
-
- public static interface Action extends TellrawSerializableEnum {
- }
-}
+package buttondevteam.chat.components.formatter.formatting;
+
+import buttondevteam.lib.chat.TellrawSerializableEnum;
+
+import java.io.Serializable;
+
+public final class TellrawEvent implements Serializable {
+ private static final long serialVersionUID = -1681364161210561505L;
+ private transient boolean hoverEvent;
+ private T action;
+ private Object value;
+
+ private TellrawEvent(T action, String value) {
+ this.hoverEvent = action instanceof HoverAction;
+ this.action = action;
+ this.value = value;
+ }
+
+ private TellrawEvent(T action, TellrawPart value) {
+ this.hoverEvent = action instanceof HoverAction;
+ this.action = action;
+ this.value = value;
+ }
+
+ public static TellrawEvent create(V action, String value) {
+ return new TellrawEvent<>(action, value);
+ }
+
+ public static TellrawEvent create(V action, TellrawPart value) {
+ return new TellrawEvent<>(action, value);
+ }
+
+ public boolean isHoverEvent() {
+ return hoverEvent;
+ }
+
+ public T getAction() {
+ return action;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ public enum ClickAction implements Action {
+ OPEN_URL("open_url"), RUN_COMMAND("run_command"), SUGGEST_COMMAND("suggest_command");
+ private String action;
+
+ ClickAction(String action) {
+ this.action = action;
+ }
+
+ @Override
+ public String getName() {
+ return action;
+ }
+ }
+
+ public enum HoverAction implements Action {
+ SHOW_TEXT("show_text"), SHOW_ITEM("show_item"), SHOW_ACHIEVEMENT("show_achievement"), SHOW_ENTITY(
+ "show_entity");
+ private String action;
+
+ HoverAction(String action) {
+ this.action = action;
+ }
+
+ @Override
+ public String getName() {
+ return action;
+ }
+ }
+
+ public static interface Action extends TellrawSerializableEnum {
+ }
+}
diff --git a/src/main/java/buttondevteam/chat/formatting/TellrawPart.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawPart.java
similarity index 92%
rename from src/main/java/buttondevteam/chat/formatting/TellrawPart.java
rename to src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawPart.java
index 0e7dc72..2425574 100644
--- a/src/main/java/buttondevteam/chat/formatting/TellrawPart.java
+++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawPart.java
@@ -1,115 +1,115 @@
-package buttondevteam.chat.formatting;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-import buttondevteam.lib.chat.*;
-
-public final class TellrawPart implements Serializable {
- private static final long serialVersionUID = 4125357644462144024L;
- private Color color;
- private boolean italic;
- private boolean bold;
- private boolean underlined;
- private boolean strikethrough;
- private boolean obfuscated;
- private List extra = new ArrayList<>();
- private String text;
- private TellrawEvent hoverEvent;
- private TellrawEvent clickEvent;
-
- public TellrawPart(String text) {
- this.text = text;
- }
-
- public Color getColor() {
- return color;
- }
-
- public TellrawPart setColor(Color color) {
- this.color = color;
- return this;
- }
-
- public boolean isItalic() {
- return italic;
- }
-
- public TellrawPart setItalic(boolean italic) {
- this.italic = italic;
- return this;
- }
-
- public boolean isBold() {
- return bold;
- }
-
- public TellrawPart setBold(boolean bold) {
- this.bold = bold;
- return this;
- }
-
- public boolean isUnderlined() {
- return underlined;
- }
-
- public TellrawPart setUnderlined(boolean underlined) {
- this.underlined = underlined;
- return this;
- }
-
- public boolean isStrikethrough() {
- return strikethrough;
- }
-
- public TellrawPart setStrikethrough(boolean strikethrough) {
- this.strikethrough = strikethrough;
- return this;
- }
-
- public boolean isObfuscated() {
- return obfuscated;
- }
-
- public TellrawPart setObfuscated(boolean obfuscated) {
- this.obfuscated = obfuscated;
- return this;
- }
-
- public Iterable getExtra() {
- return extra;
- }
-
- public TellrawPart addExtra(TellrawPart extra) {
- this.extra.add(extra);
- return this;
- }
-
- public String getText() {
- return text;
- }
-
- public TellrawPart setText(String text) {
- this.text = text;
- return this;
- }
-
- public TellrawEvent getHoverEvent() {
- return hoverEvent;
- }
-
- public TellrawPart setHoverEvent(TellrawEvent hoverEvent) {
- this.hoverEvent = hoverEvent;
- return this;
- }
-
- public TellrawEvent getClickEvent() {
- return clickEvent;
- }
-
- public TellrawPart setClickEvent(TellrawEvent clickEvent) {
- this.clickEvent = clickEvent;
- return this;
- }
-}
+package buttondevteam.chat.components.formatter.formatting;
+
+import buttondevteam.lib.chat.Color;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public final class TellrawPart implements Serializable {
+ private static final long serialVersionUID = 4125357644462144024L;
+ private Color color;
+ private boolean italic;
+ private boolean bold;
+ private boolean underlined;
+ private boolean strikethrough;
+ private boolean obfuscated;
+ private List extra = new ArrayList<>();
+ private String text;
+ private TellrawEvent hoverEvent;
+ private TellrawEvent clickEvent;
+
+ public TellrawPart(String text) {
+ this.text = text;
+ }
+
+ public Color getColor() {
+ return color;
+ }
+
+ public TellrawPart setColor(Color color) {
+ this.color = color;
+ return this;
+ }
+
+ public boolean isItalic() {
+ return italic;
+ }
+
+ public TellrawPart setItalic(boolean italic) {
+ this.italic = italic;
+ return this;
+ }
+
+ public boolean isBold() {
+ return bold;
+ }
+
+ public TellrawPart setBold(boolean bold) {
+ this.bold = bold;
+ return this;
+ }
+
+ public boolean isUnderlined() {
+ return underlined;
+ }
+
+ public TellrawPart setUnderlined(boolean underlined) {
+ this.underlined = underlined;
+ return this;
+ }
+
+ public boolean isStrikethrough() {
+ return strikethrough;
+ }
+
+ public TellrawPart setStrikethrough(boolean strikethrough) {
+ this.strikethrough = strikethrough;
+ return this;
+ }
+
+ public boolean isObfuscated() {
+ return obfuscated;
+ }
+
+ public TellrawPart setObfuscated(boolean obfuscated) {
+ this.obfuscated = obfuscated;
+ return this;
+ }
+
+ public Iterable getExtra() {
+ return extra;
+ }
+
+ public TellrawPart addExtra(TellrawPart extra) {
+ this.extra.add(extra);
+ return this;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public TellrawPart setText(String text) {
+ this.text = text;
+ return this;
+ }
+
+ public TellrawEvent getHoverEvent() {
+ return hoverEvent;
+ }
+
+ public TellrawPart setHoverEvent(TellrawEvent hoverEvent) {
+ this.hoverEvent = hoverEvent;
+ return this;
+ }
+
+ public TellrawEvent getClickEvent() {
+ return clickEvent;
+ }
+
+ public TellrawPart setClickEvent(TellrawEvent clickEvent) {
+ this.clickEvent = clickEvent;
+ return this;
+ }
+}
diff --git a/src/main/java/buttondevteam/chat/formatting/TellrawSerializer.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawSerializer.java
similarity index 90%
rename from src/main/java/buttondevteam/chat/formatting/TellrawSerializer.java
rename to src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawSerializer.java
index f8b591e..b1a36fd 100644
--- a/src/main/java/buttondevteam/chat/formatting/TellrawSerializer.java
+++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawSerializer.java
@@ -1,59 +1,59 @@
-package buttondevteam.chat.formatting;
-
-import java.io.IOException;
-import java.lang.reflect.Type;
-import java.util.Collection;
-
-import com.google.gson.*;
-import com.google.gson.stream.*;
-
-import buttondevteam.lib.chat.TellrawSerializableEnum;
-
-public abstract class TellrawSerializer {
- public static class TwEnum extends TypeAdapter {
- @Override
- public TellrawSerializableEnum read(JsonReader reader) throws IOException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void write(JsonWriter writer, TellrawSerializableEnum enumval) throws IOException {
- if (enumval == null)
- writer.nullValue();
- else
- writer.value(enumval.getName());
- }
- }
-
- public static class TwCollection implements JsonSerializer> {
- @Override
- public JsonElement serialize(Collection> src, Type typeOfSrc, JsonSerializationContext context) {
- if (src == null || src.isEmpty())
- return null;
-
- JsonArray array = new JsonArray();
-
- for (Object child : src) {
- JsonElement element = context.serialize(child);
- array.add(element);
- }
-
- return array;
- }
- }
-
- public static class TwBool extends TypeAdapter {
- @Override
- public Boolean read(JsonReader reader) throws IOException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void write(JsonWriter writer, Boolean val) throws IOException {
- if (val)
- writer.value(val);
- else
- writer.nullValue();
- }
- }
-}
+package buttondevteam.chat.components.formatter.formatting;
+
+import buttondevteam.lib.chat.TellrawSerializableEnum;
+import com.google.gson.*;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.Collection;
+
+public abstract class TellrawSerializer {
+ public static class TwEnum extends TypeAdapter {
+ @Override
+ public TellrawSerializableEnum read(JsonReader reader) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void write(JsonWriter writer, TellrawSerializableEnum enumval) throws IOException {
+ if (enumval == null)
+ writer.nullValue();
+ else
+ writer.value(enumval.getName());
+ }
+ }
+
+ public static class TwCollection implements JsonSerializer> {
+ @Override
+ public JsonElement serialize(Collection> src, Type typeOfSrc, JsonSerializationContext context) {
+ if (src == null || src.isEmpty())
+ return null;
+
+ JsonArray array = new JsonArray();
+
+ for (Object child : src) {
+ JsonElement element = context.serialize(child);
+ array.add(element);
+ }
+
+ return array;
+ }
+ }
+
+ public static class TwBool extends TypeAdapter {
+ @Override
+ public Boolean read(JsonReader reader) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void write(JsonWriter writer, Boolean val) throws IOException {
+ if (val)
+ writer.value(val);
+ else
+ writer.nullValue();
+ }
+ }
+}
diff --git a/src/main/java/buttondevteam/chat/components/fun/CCommand.java b/src/main/java/buttondevteam/chat/components/fun/CCommand.java
index 3cd8e27..42acb07 100644
--- a/src/main/java/buttondevteam/chat/components/fun/CCommand.java
+++ b/src/main/java/buttondevteam/chat/components/fun/CCommand.java
@@ -6,6 +6,9 @@ import buttondevteam.lib.chat.*;
import buttondevteam.lib.player.TBMCPlayer;
import org.bukkit.entity.Player;
+import java.util.Arrays;
+import java.util.Optional;
+
@CommandClass(path = "u c", helpText = {
"Rainbow mode",
"This command allows you to talk in rainbow colors"
@@ -16,7 +19,7 @@ public class CCommand extends ICommand2MC {
public boolean def(Player player, @Command2.OptionalArg String color) {
ChatPlayer p = TBMCPlayer.getPlayer(player.getUniqueId(), ChatPlayer.class);
if (color == null) {
- if (PluginMain.permission.has(player, "thorpe.color.rainbow")) {
+ if (PluginMain.permission.has(player, "chroma.color.rainbow")) {
p.RainbowPresserColorMode = !p.RainbowPresserColorMode;
p.OtherColorMode = null;
if (p.RainbowPresserColorMode)
@@ -28,19 +31,23 @@ public class CCommand extends ICommand2MC {
return true;
}
} else {
- if (PluginMain.permission.has(player, "thorpe.color.custom")) {
- p.RainbowPresserColorMode = false;
- p.OtherColorMode = null;
- try {
- p.OtherColorMode = Color.valueOf(color.toLowerCase());
- } catch (Exception e) {
+ if (PluginMain.permission.has(player, "chroma.color.custom")) {
+ String x = color.toLowerCase();
+ if ("off".equals(x)) {
+ p.OtherColorMode = null;
+ player.sendMessage("§eMessage color reset.");
+ return true;
+ }
+ Optional oc = Arrays.stream(Color.values()).filter(c -> c.getName().equals(x)).findAny();
+ if (!oc.isPresent()) {
player.sendMessage("§cUnknown message color: " + color);
player.sendMessage("§cUse color names, like blue, or dark_aqua");
+ player.sendMessage("§cOr use 'off' to disable");
+ return true;
}
- if (p.OtherColorMode != null)
- player.sendMessage(String.format("§eMessage color set to %s", p.OtherColorMode));
- else
- player.sendMessage("§eMessage color reset.");
+ p.RainbowPresserColorMode = false;
+ p.OtherColorMode = oc.get();
+ player.sendMessage(String.format("§eMessage color set to %s", p.OtherColorMode));
} else {
player.sendMessage("§cYou don't have permission for this command.");
return true;
diff --git a/src/main/java/buttondevteam/chat/components/fun/FunComponent.java b/src/main/java/buttondevteam/chat/components/fun/FunComponent.java
index 4b726b8..82b1229 100644
--- a/src/main/java/buttondevteam/chat/components/fun/FunComponent.java
+++ b/src/main/java/buttondevteam/chat/components/fun/FunComponent.java
@@ -3,10 +3,10 @@ package buttondevteam.chat.components.fun;
import buttondevteam.chat.ChatPlayer;
import buttondevteam.chat.PluginMain;
import buttondevteam.core.component.channel.Channel;
+import buttondevteam.lib.ChromaUtils;
import buttondevteam.lib.TBMCChatEventBase;
import buttondevteam.lib.TBMCCommandPreprocessEvent;
import buttondevteam.lib.TBMCSystemChatEvent;
-import buttondevteam.lib.ThorpeUtils;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.architecture.ConfigData;
import buttondevteam.lib.chat.TBMCChatAPI;
@@ -139,15 +139,15 @@ public class FunComponent extends Component implements Listener {
if (ht.getName().equalsIgnoreCase(cmd))
return;
}
- if (PluginMain.permission.has(event.getSender(), "thorpe.unanything")) {
+ if (PluginMain.permission.has(event.getSender(), "chroma.unanything")) {
event.setCancelled(true);
- String s = cmd.substring(3);
- int index = event.getMessage().indexOf(' ');
+ int index = cmd.lastIndexOf(' ');
if (index == -1) {
- event.getSender().sendMessage("§cUsage: /un" + s + " ");
+ event.getSender().sendMessage("§cUsage: " + cmd + " ");
return;
}
- Player target = Bukkit.getPlayer(event.getMessage().substring(index + 1));
+ String s = cmd.substring(3, index);
+ Player target = Bukkit.getPlayer(cmd.substring(index + 1));
if (target == null) {
event.getSender().sendMessage("§cError: Player not found. (/un" + s + " )");
return;
@@ -155,7 +155,7 @@ public class FunComponent extends Component implements Listener {
val user = ChromaGamerBase.getFromSender(event.getSender());
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 10 * 20, 5, false, false));
val chan = user.channel().get();
- TBMCChatAPI.SendSystemMessage(chan, chan.getRTR(event.getSender()), ThorpeUtils.getDisplayName(event.getSender()) + " un" + s
+ TBMCChatAPI.SendSystemMessage(chan, chan.getRTR(event.getSender()), ChromaUtils.getDisplayName(event.getSender()) + " un" + s
+ "'d " + target.getDisplayName(), unlolTarget);
}
}
diff --git a/src/main/java/buttondevteam/chat/components/fun/PressCommand.java b/src/main/java/buttondevteam/chat/components/fun/PressCommand.java
index 123aab5..e675d20 100644
--- a/src/main/java/buttondevteam/chat/components/fun/PressCommand.java
+++ b/src/main/java/buttondevteam/chat/components/fun/PressCommand.java
@@ -1,15 +1,13 @@
package buttondevteam.chat.components.fun;
import buttondevteam.core.component.channel.Channel;
-import buttondevteam.core.component.restart.RestartComponent;
import buttondevteam.core.component.restart.ScheduledRestartCommand;
+import buttondevteam.lib.ChromaUtils;
import buttondevteam.lib.ScheduledServerRestartEvent;
-import buttondevteam.lib.ThorpeUtils;
import buttondevteam.lib.chat.Command2;
import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.ICommand2MC;
import buttondevteam.lib.chat.TBMCChatAPI;
-import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -33,7 +31,7 @@ public class PressCommand extends ICommand2MC implements Listener {
return;
}
pressers.add(sender);
- TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, String.format("§b-- %s §bpressed at %.0fs", ThorpeUtils.getDisplayName(sender), command.getRestartCounter() / 20f), command.getComponent().getRestartBroadcast());
+ TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, String.format("§b-- %s §bpressed at %.0fs", ChromaUtils.getDisplayName(sender), command.getRestartCounter() / 20f), command.getComponent().getRestartBroadcast());
command.setRestartCounter(startTicks);
}
diff --git a/src/main/java/buttondevteam/chat/components/fun/UnlolCommand.java b/src/main/java/buttondevteam/chat/components/fun/UnlolCommand.java
index 8de6c9e..8a0ea93 100644
--- a/src/main/java/buttondevteam/chat/components/fun/UnlolCommand.java
+++ b/src/main/java/buttondevteam/chat/components/fun/UnlolCommand.java
@@ -1,13 +1,15 @@
package buttondevteam.chat.components.fun;
import buttondevteam.core.component.channel.Channel;
+import buttondevteam.lib.ChromaUtils;
import buttondevteam.lib.TBMCChatEventBase;
import buttondevteam.lib.TBMCSystemChatEvent;
-import buttondevteam.lib.ThorpeUtils;
-import buttondevteam.lib.chat.*;
+import buttondevteam.lib.chat.Command2;
+import buttondevteam.lib.chat.CommandClass;
+import buttondevteam.lib.chat.ICommand2MC;
+import buttondevteam.lib.chat.TBMCChatAPI;
import lombok.Data;
import lombok.RequiredArgsConstructor;
-import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
@@ -39,9 +41,9 @@ public final class UnlolCommand extends ICommand2MC {
if (lol.Lolowner instanceof Player)
((Player) lol.Lolowner)
.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 2 * 20, 5, false, false));
- String msg = ThorpeUtils.getDisplayName(sender)
+ String msg = ChromaUtils.getDisplayName(sender)
+ (lol.Lolornot ? " unlolled " : " unlaughed ")
- + ThorpeUtils.getDisplayName(lol.Lolowner);
+ + ChromaUtils.getDisplayName(lol.Lolowner);
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, msg, target);
Lastlol.remove(lol.Chatevent.getChannel());
return true;
diff --git a/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java b/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java
index ab41374..d685030 100644
--- a/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java
+++ b/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java
@@ -15,7 +15,6 @@ import com.earth2me.essentials.User;
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
import com.palmergames.bukkit.towny.object.Nation;
import lombok.Getter;
-import lombok.experimental.var;
import lombok.val;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@@ -113,6 +112,7 @@ public class TownColorComponent extends Component implements Listene
if (useNationColors().get())
registerCommand(new buttondevteam.chat.components.towncolors.admin.NationColorCommand());
registerCommand(new TCCount());
+ registerCommand(new NColorCommand());
registerListener(new TownyListener());
registerListener(this);
}
diff --git a/src/main/java/buttondevteam/chat/components/towncolors/admin/NationColorCommand.java b/src/main/java/buttondevteam/chat/components/towncolors/admin/NationColorCommand.java
index 963cb05..77bba40 100644
--- a/src/main/java/buttondevteam/chat/components/towncolors/admin/NationColorCommand.java
+++ b/src/main/java/buttondevteam/chat/components/towncolors/admin/NationColorCommand.java
@@ -35,7 +35,7 @@ public class NationColorCommand extends AdminCommandBase {
if (!c.get().getName().equals(Color.White.getName())) { //Default nation color
for (val e : TownColorComponent.NationColor.entrySet()) {
if (e.getValue().getName().equals(c.get().getName())) {
- sender.sendMessage("§The nation " + e.getKey() + " already uses this color!");
+ sender.sendMessage("§cThe nation " + e.getKey() + " already uses this color!");
return true;
}
}
diff --git a/src/main/java/buttondevteam/chat/components/towny/TownyAnnouncer.java b/src/main/java/buttondevteam/chat/components/towny/TownyAnnouncer.java
index 55702c7..1283a3d 100644
--- a/src/main/java/buttondevteam/chat/components/towny/TownyAnnouncer.java
+++ b/src/main/java/buttondevteam/chat/components/towny/TownyAnnouncer.java
@@ -1,23 +1,33 @@
package buttondevteam.chat.components.towny;
-import buttondevteam.chat.ChatProcessing;
+import buttondevteam.chat.ChatUtils;
import buttondevteam.core.component.channel.Channel;
import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.chat.TBMCChatAPI;
-import com.palmergames.bukkit.towny.TownyLogger;
import lombok.val;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.Logger;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.AbstractAppender;
+import org.apache.logging.log4j.core.filter.LevelRangeFilter;
+import org.apache.logging.log4j.core.layout.PatternLayout;
-import java.util.logging.Handler;
-import java.util.logging.LogRecord;
import java.util.regex.Pattern;
public class TownyAnnouncer {
private static final Pattern LOG_TYPE_PATTERN = Pattern.compile("\\[(\\w+) (?:Msg|Message)](?: (\\w+):)?");
- private static final Handler HANDLER = new Handler() {
+ private static final String APPENDER_NAME = "Chroma";
+ private static final AbstractAppender HANDLER = new AbstractAppender(APPENDER_NAME,
+ LevelRangeFilter.createFilter(Level.INFO, Level.INFO, Filter.Result.ACCEPT, Filter.Result.ACCEPT),
+ PatternLayout.createDefaultLayout()) {
@Override
- public void publish(LogRecord logRecord) {
+ public void append(LogEvent logRecord) {
if (logRecord.getMessage() == null) return;
- val m = LOG_TYPE_PATTERN.matcher(logRecord.getMessage());
+ String message = logRecord.getMessage().getFormattedMessage();
+ val m = LOG_TYPE_PATTERN.matcher(message);
if (!m.find()) return;
String groupID = m.group(2); //The group ID is correctly cased
switch (String.valueOf(m.group(1))) { //valueOf: Handles null
@@ -25,31 +35,21 @@ public class TownyAnnouncer {
if (townChannel == null) return;
TBMCChatAPI.SendSystemMessage(townChannel,
new Channel.RecipientTestResult(TownyComponent.getTownNationIndex(groupID, false), groupID),
- logRecord.getMessage(), target, ChatProcessing.MCORIGIN);
+ message, target, ChatUtils.MCORIGIN);
break;
case "Nation":
if (nationChannel == null) return;
TBMCChatAPI.SendSystemMessage(nationChannel,
new Channel.RecipientTestResult(TownyComponent.getTownNationIndex(groupID, true), groupID),
- logRecord.getMessage(), target, ChatProcessing.MCORIGIN);
+ message, target, ChatUtils.MCORIGIN);
break;
case "Global":
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat,
Channel.RecipientTestResult.ALL,
- logRecord.getMessage(), target, ChatProcessing.MCORIGIN);
+ message, target, ChatUtils.MCORIGIN);
break;
}
}
-
- @Override
- public void flush() {
-
- }
-
- @Override
- public void close() throws SecurityException {
-
- }
};
private static TBMCSystemChatEvent.BroadcastTarget target;
@@ -60,7 +60,23 @@ public class TownyAnnouncer {
target = TBMCSystemChatEvent.BroadcastTarget.add("towny");
TownyAnnouncer.townChannel = townChannel;
TownyAnnouncer.nationChannel = nationChannel;
- TownyLogger.log.addHandler(HANDLER);
+ /*System.out.println(LogManager.getLogger("com.palmergames.bukkit.towny"));
+ ((Logger) LogManager.getLogger("com.palmergames.bukkit.towny")).getContext().getConfiguration().addAppender(HANDLER);
+ System.out.println(((Logger) LogManager.getLogger("com.palmergames.bukkit.towny")).getAppenders());
+ ((LoggerContext)LogManager.getContext(false)).updateLoggers();
+ System.out.println(((Logger) LogManager.getLogger("com.palmergames.bukkit.towny")).getAppenders());
+ ((Logger) LogManager.getLogger("com.palmergames.bukkit.towny")).getContext().updateLoggers();
+ System.out.println(((Logger) LogManager.getLogger("com.palmergames.bukkit.towny")).getAppenders());*/
+ val lc = (LoggerContext) LogManager.getContext(false);
+ HANDLER.start();
+ lc.getConfiguration().addAppender(HANDLER);
+ Logger logger = lc.getLogger("com.palmergames.bukkit.towny");
+ //System.out.println(logger);
+ //System.out.println(lc.getConfiguration().getAppender(HANDLER.getName())); //T defaults to String because of the context which results in a cast exception
+ logger.addAppender(lc.getConfiguration().getAppender(HANDLER.getName()));
+ logger.get().addAppender(HANDLER, Level.INFO, HANDLER.getFilter());
+ lc.updateLoggers();
+ //System.out.println(logger.getAppenders());
}
public static void setdown() {
@@ -68,6 +84,6 @@ public class TownyAnnouncer {
target = null;
TownyAnnouncer.townChannel = null;
TownyAnnouncer.nationChannel = null;
- TownyLogger.log.removeHandler(HANDLER);
+ ((Logger) LogManager.getLogger("com.palmergames.bukkit.towny")).getAppenders().remove(APPENDER_NAME);
}
}
diff --git a/src/main/java/buttondevteam/chat/components/towny/TownyComponent.java b/src/main/java/buttondevteam/chat/components/towny/TownyComponent.java
index dbfe93c..a77bc83 100644
--- a/src/main/java/buttondevteam/chat/components/towny/TownyComponent.java
+++ b/src/main/java/buttondevteam/chat/components/towny/TownyComponent.java
@@ -1,24 +1,24 @@
package buttondevteam.chat.components.towny;
import buttondevteam.chat.PluginMain;
-import buttondevteam.chat.formatting.TellrawPart;
+import buttondevteam.chat.VanillaUtils;
+import buttondevteam.chat.components.formatter.formatting.TellrawPart;
import buttondevteam.core.component.channel.Channel;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.chat.Color;
import buttondevteam.lib.chat.TBMCChatAPI;
-import com.palmergames.bukkit.towny.Towny;
+import com.palmergames.bukkit.towny.TownyUniverse;
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
import com.palmergames.bukkit.towny.object.Nation;
import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.Town;
-import com.palmergames.bukkit.towny.object.TownyUniverse;
import lombok.val;
-import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -32,7 +32,7 @@ public class TownyComponent extends Component {
@Override
protected void enable() {
- TU = ((Towny) Bukkit.getPluginManager().getPlugin("Towny")).getTownyUniverse();
+ TU = TownyUniverse.getInstance();
Towns = TU.getTownsMap().values().stream().map(Town::getName).collect(Collectors.toCollection(ArrayList::new)); // Creates a snapshot of towns, new towns will be added when needed
Nations = TU.getNationsMap().values().stream().map(Nation::getName).collect(Collectors.toCollection(ArrayList::new)); // Same here but with nations
TBMCChatAPI.RegisterChatChannel(
@@ -47,12 +47,20 @@ public class TownyComponent extends Component {
TownyAnnouncer.setdown();
}
- public void handleSpies(Channel channel, TellrawPart json, Function toJson) {
+ public void handleSpiesInit(Channel channel, TellrawPart json, Function toJson) {
if (channel.ID.equals(TownChat.ID) || channel.ID.equals(NationChat.ID)) {
((List) json.getExtra()).add(0, new TellrawPart("[SPY]"));
- String jsonstr = toJson.apply(json);
- Bukkit.getServer().dispatchCommand(PluginMain.Console, String.format(
- "tellraw @a[score_%s=1000,score_%s_min=1000] %s", channel.ID, channel.ID, jsonstr));
+ jsonstr = toJson.apply(json);
+ }
+ }
+
+ private String jsonstr;
+
+ public void handleSpies(Channel channel, Player p) {
+ if (channel.ID.equals(TownChat.ID) || channel.ID.equals(NationChat.ID)) {
+ if (Optional.ofNullable(TU.getResidentMap().get(p.getName().toLowerCase()))
+ .filter(r -> r.hasMode("spy")).isPresent())
+ VanillaUtils.tellRaw(p, jsonstr);
}
}
diff --git a/src/main/java/buttondevteam/chat/listener/PlayerListener.java b/src/main/java/buttondevteam/chat/listener/PlayerListener.java
index 84f7fc1..eb3aaf9 100644
--- a/src/main/java/buttondevteam/chat/listener/PlayerListener.java
+++ b/src/main/java/buttondevteam/chat/listener/PlayerListener.java
@@ -1,19 +1,19 @@
package buttondevteam.chat.listener;
import buttondevteam.chat.ChatPlayer;
-import buttondevteam.chat.ChatProcessing;
+import buttondevteam.chat.ChatUtils;
import buttondevteam.chat.PluginMain;
import buttondevteam.chat.commands.ucmds.HistoryCommand;
import buttondevteam.chat.components.flair.FlairComponent;
+import buttondevteam.chat.components.formatter.FormatterComponent;
import buttondevteam.chat.components.towncolors.TownColorComponent;
import buttondevteam.core.ComponentManager;
import buttondevteam.core.component.channel.Channel;
-import buttondevteam.core.component.channel.ChatChannelRegisterEvent;
import buttondevteam.core.component.channel.ChatRoom;
+import buttondevteam.lib.ChromaUtils;
import buttondevteam.lib.TBMCChatEvent;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.TBMCSystemChatEvent;
-import buttondevteam.lib.ThorpeUtils;
import buttondevteam.lib.chat.ChatMessage;
import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.player.ChromaGamerBase;
@@ -52,7 +52,8 @@ public class PlayerListener implements Listener {
if (event.isCancelled())
return;
//The custom event is called in the core, but doesn't cancel the MC event
- event.setCancelled(true); // The custom event should only be cancelled when muted or similar
+ if (ComponentManager.isEnabled(FormatterComponent.class)) //If not enabled, then let the other plugins deal with the message
+ event.setCancelled(true); // The custom event should only be cancelled when muted or similar
}
@EventHandler(priority = EventPriority.HIGHEST)
@@ -95,11 +96,11 @@ public class PlayerListener implements Listener {
Player player = Bukkit.getPlayer(message.substring(index + 1));
if (player != null && sender instanceof Player)
player.sendMessage("§b" + ((Player) sender).getDisplayName() + " §bis in this world: " //TODO: Move to the Core
- + ((Player) sender).getWorld().getName());
+ + ((Player) sender).getWorld().getName());
} else if (cmd.equalsIgnoreCase("minecraft:me")) {
if (!(sender instanceof Player) || !PluginMain.essentials.getUser((Player) sender).isMuted()) {
String msg = message.substring(index + 1);
- TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, String.format("* %s %s", ThorpeUtils.getDisplayName(sender), msg), TBMCSystemChatEvent.BroadcastTarget.ALL); //TODO: Don't send to all
+ TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, String.format("* %s %s", ChromaUtils.getDisplayName(sender), msg), TBMCSystemChatEvent.BroadcastTarget.ALL); //TODO: Don't send to all
return true;
} else {
sender.sendMessage("§cCan't use /minecraft:me while muted.");
@@ -131,7 +132,7 @@ public class PlayerListener implements Listener {
String name = e.getLastToken();
for (Entry nicknamekv : nicknames.entrySet()) {
if (nicknamekv.getKey().startsWith(name.toLowerCase()))
- e.getTabCompletions().add(PluginMain.essentials.getUser(Bukkit.getPlayer(nicknamekv.getValue())).getNick(true)); //Tabcomplete with the correct case
+ e.getTabCompletions().add(PluginMain.essentials.getUser(Bukkit.getPlayer(nicknamekv.getValue())).getNick(true)); //Tabcomplete with the correct case
}
}
@@ -154,7 +155,7 @@ public class PlayerListener implements Listener {
if (flair.length() > 0)
e.addInfo("/r/TheButton flair: " + flair);
}
- e.addInfo(String.format("Respect: %.2f", cp.getF()));
+ e.addInfo(String.format("Respect: %.2f", cp.getF()));
} catch (Exception ex) {
TBMCCoreAPI.SendException("Error while providing chat info for player " + e.getPlayer().getFileName(), ex);
}
@@ -166,31 +167,20 @@ public class PlayerListener implements Listener {
if (e.isCancelled())
return;
HistoryCommand.addChatMessage(e.getCm(), e.getChannel());
- e.setCancelled(ChatProcessing.ProcessChat(e));
+ e.setCancelled(FormatterComponent.handleChat(e));
} catch (NoClassDefFoundError | Exception ex) { // Weird things can happen
- val str = "§c!§r[" + e.getChannel().DisplayName().get() + "] <"
- + ThorpeUtils.getDisplayName(e.getSender()) + "> " + e.getMessage();
- for (Player p : Bukkit.getOnlinePlayers())
- if (e.shouldSendTo(p))
- p.sendMessage(str);
- Bukkit.getConsoleSender().sendMessage(str);
+ ChatUtils.sendChatMessage(e, s -> "§c!§r" + s);
TBMCCoreAPI.SendException("An error occured while processing a chat message!", ex);
}
}
- @EventHandler
- public void onChannelRegistered(ChatChannelRegisterEvent e) {
- if (!e.getChannel().isGlobal() && PluginMain.SB.getObjective(e.getChannel().ID) == null) // Not global chat and doesn't exist yet
- PluginMain.SB.registerNewObjective(e.getChannel().ID, "dummy");
- }
-
@EventHandler
public void onNickChange(NickChangeEvent e) {
- String nick = e.getValue();
- if (nick == null)
- nicknames.inverse().remove(e.getAffected().getBase().getUniqueId());
- else
- nicknames.inverse().forcePut(e.getAffected().getBase().getUniqueId(), ChatColor.stripColor(nick).toLowerCase());
+ String nick = e.getValue();
+ if (nick == null)
+ nicknames.inverse().remove(e.getAffected().getBase().getUniqueId());
+ else
+ nicknames.inverse().forcePut(e.getAffected().getBase().getUniqueId(), ChatColor.stripColor(nick).toLowerCase());
Bukkit.getScheduler().runTaskLater(PluginMain.Instance, () -> {
TownColorComponent.updatePlayerColors(e.getAffected().getBase()); //Won't fire this event again
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index d618f6b..105abc9 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -1,4 +1,4 @@
-name: Thorpe-Chat
+name: Chroma-Chat
main: buttondevteam.chat.PluginMain
version: 4.0
commands:
@@ -34,7 +34,7 @@ author: NorbiPeti
depend:
- Essentials
- Vault
-- ThorpeCore
+- ChromaCore
soft-depend:
- Minigames
- Dynmap-Towny
diff --git a/src/test/java/buttondevteam/chat/ChatFormatIT.java b/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java
similarity index 86%
rename from src/test/java/buttondevteam/chat/ChatFormatIT.java
rename to src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java
index 839942f..438155d 100644
--- a/src/test/java/buttondevteam/chat/ChatFormatIT.java
+++ b/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java
@@ -1,17 +1,21 @@
-package buttondevteam.chat;
+package buttondevteam.chat.components.formatter;
+import buttondevteam.chat.ChatUtils;
+import buttondevteam.chat.ObjectTestRunner;
import buttondevteam.chat.ObjectTestRunner.Objects;
+import buttondevteam.chat.PluginMain;
import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
-import buttondevteam.chat.formatting.ChatFormatter;
-import buttondevteam.chat.formatting.TellrawEvent;
-import buttondevteam.chat.formatting.TellrawEvent.ClickAction;
-import buttondevteam.chat.formatting.TellrawEvent.HoverAction;
-import buttondevteam.chat.formatting.TellrawPart;
+import buttondevteam.chat.components.formatter.formatting.ChatFormatter;
+import buttondevteam.chat.components.formatter.formatting.TellrawEvent;
+import buttondevteam.chat.components.formatter.formatting.TellrawEvent.ClickAction;
+import buttondevteam.chat.components.formatter.formatting.TellrawEvent.HoverAction;
+import buttondevteam.chat.components.formatter.formatting.TellrawPart;
import buttondevteam.core.TestPrepare;
import buttondevteam.core.component.channel.Channel;
import buttondevteam.lib.chat.Color;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.command.CommandSender;
+import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
@@ -19,8 +23,6 @@ import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.List;
-import static org.junit.Assert.assertEquals;
-
@RunWith(ObjectTestRunner.class)
public class ChatFormatIT {
@Objects
@@ -91,16 +93,16 @@ public class ChatFormatIT {
@Test
public void testMessage() {
- ArrayList cfs = ChatProcessing.addFormatters(Color.White);
- final String chid = ChatProcessing.getChannelID(Channel.GlobalChat, ChatProcessing.MCORIGIN);
- final TellrawPart tp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatProcessing.MCORIGIN);
- ChatFormatter.Combine(cfs, message, tp);
+ ArrayList cfs = ChatProcessing.addFormatters(Color.White, p -> true);
+ final String chid = ChatProcessing.getChannelID(Channel.GlobalChat, ChatUtils.MCORIGIN);
+ final TellrawPart tp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatUtils.MCORIGIN);
+ ChatFormatter.Combine(cfs, message, tp, null);
System.out.println("Testing: " + message);
// System.out.println(ChatProcessing.toJson(tp));
- final TellrawPart expectedtp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatProcessing.MCORIGIN);
+ final TellrawPart expectedtp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatUtils.MCORIGIN);
// System.out.println("Raw: " + ChatProcessing.toJson(expectedtp));
for (TellrawPart extra : extras)
expectedtp.addExtra(extra);
- assertEquals(ChatProcessing.toJson(expectedtp), ChatProcessing.toJson(tp));
+ Assert.assertEquals(ChatProcessing.toJson(expectedtp), ChatProcessing.toJson(tp));
}
}