diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..4b9e6ec
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,19 @@
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = false
+indent_style = space
+indent_size = 4
+
+[*.json]
+indent_style = space
+indent_size = 2
+
+[*.java]
+indent_style = tab
+tab_width = 4
+
+[{*.yml, *.yaml}]
+indent_style = space
+indent_size = 2
+
diff --git a/Notes.txt b/Notes.txt
deleted file mode 100644
index 78af086..0000000
--- a/Notes.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-Expected:
-
-***test***
-||- ||-
-
-||: bold
--: italic
-
-
-Actual:
-
-***test***
-||- ||-
--|| -||
- - -
-
-nextSection:
-*: italic(0)
-**:
-Either italic(0), bold(0) - Delete italic
- bold(0), italic(1) - Delete italic
- bold(0)
-Or bold(0), italic(0) - Delete italic?
- italic, italic - 0-length section as result, delete?
-
-takenStart, takenEnd
-because it's ordered, the indexes will be either the same or ascending
-
-
-^^ Implemented
-
-**test**
-^ ^ <-- !
-start end
-RemChar: 2
-tes*
diff --git a/lombok.config b/lombok.config
new file mode 100644
index 0000000..d959b09
--- /dev/null
+++ b/lombok.config
@@ -0,0 +1 @@
+lombok.var.flagUsage = ALLOW
diff --git a/pom.xml b/pom.xml
index f9ca404..67ca3b2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -96,6 +96,46 @@
+
@@ -143,7 +183,7 @@
com.github.TBMCPlugins.ButtonCore
ButtonCore
- master-SNAPSHOT
+ ${env.TRAVIS_BRANCH}-SNAPSHOT
diff --git a/src/main/java/buttondevteam/chat/AnnouncerThread.java b/src/main/java/buttondevteam/chat/AnnouncerThread.java
index b1b11da..60d40e7 100644
--- a/src/main/java/buttondevteam/chat/AnnouncerThread.java
+++ b/src/main/java/buttondevteam/chat/AnnouncerThread.java
@@ -13,6 +13,7 @@ public class AnnouncerThread implements Runnable {
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
+ if (Bukkit.getOnlinePlayers().size() == 0) continue; //Don't post to Discord if nobody is on
if (PluginMain.AnnounceMessages.size() > AnnounceMessageIndex) {
Bukkit.broadcastMessage(PluginMain.AnnounceMessages.get(AnnounceMessageIndex));
AnnounceMessageIndex++;
diff --git a/src/main/java/buttondevteam/chat/ChatProcessing.java b/src/main/java/buttondevteam/chat/ChatProcessing.java
index 6591cd6..77d1f03 100644
--- a/src/main/java/buttondevteam/chat/ChatProcessing.java
+++ b/src/main/java/buttondevteam/chat/ChatProcessing.java
@@ -1,343 +1,345 @@
-package buttondevteam.chat;
-
-import buttondevteam.chat.commands.UnlolCommand;
-import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
-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.lib.TBMCChatEvent;
-import buttondevteam.lib.TBMCChatEventBase;
-import buttondevteam.lib.TBMCCoreAPI;
-import buttondevteam.lib.chat.*;
-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:/?=$\\-_.+!*'(),]+)");
- 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 Color[] RainbowPresserColors = new Color[]{Color.Red, Color.Gold, Color.Yellow, Color.Green,
- Color.Blue, Color.DarkPurple};
- 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(),
- ESCAPE_FORMATTER, ChatFormatter.builder().regex(URL_PATTERN).underlined(true).openlink("$1").type(ChatFormatter.Type.Excluder).build(),
- ChatFormatter.builder().regex(NULL_MENTION_PATTERN).color(Color.DarkRed).build(), // Properly added a bug as a feature
- ChatFormatter.builder().regex(CONSOLE_PING_PATTERN).color(Color.Aqua).onmatch((match, builder) -> {
- 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) -> {
- return match; // TODO!
- }).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) {
- 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;
- 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 && mp != null && mp.RainbowPresserColorMode) { // Only overwrite channel color
- final AtomicInteger rpc = new AtomicInteger(0);
- formatters.add(ChatFormatter.builder().color(colormode).onmatch((match, cf) -> {
- 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, sender);
-
- TellrawPart json = createTellraw(sender, message, player, mp, e.getUser(), channelidentifier);
- 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.filteranderrormsg != null) {
- 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));
- if (e.getChannel().ID.equals(PluginMain.TownChat.ID)
- || e.getChannel().ID.equals(PluginMain.NationChat.ID)) {
- ((List) json.getExtra()).add(0, new TellrawPart("[SPY]"));
- jsonstr = toJson(json);
- Bukkit.getServer().dispatchCommand(PluginMain.Console, String.format(
- "tellraw @a[score_%s=1000,score_%s_min=1000] %s", channel.ID, channel.ID, jsonstr));
- }
- }
- } 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) {
- TellrawPart json = new TellrawPart("");
- if (mp != null && mp.ChatOnly) {
- json.addExtra(new TellrawPart("[C]")
- .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Chat only")));
- }
- json.addExtra(
- new TellrawPart(channelidentifier)
- .setHoverEvent(
- TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT,
- new TellrawPart((sender instanceof IDiscordSender ? "From Discord\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, CommandSender sender) {
- return ("[" + (sender instanceof IDiscordSender ? "§8D§r|" : "") + channel.DisplayName)
- + "]";
- }
-
- 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;
- final int size = Bukkit.getOnlinePlayers().size();
- int index = 0;
- for (Player p : Bukkit.getOnlinePlayers()) {
- final String nick = PlayerListener.nicknames.inverse().get(p.getUniqueId());
- if (nick != null) {
- nicksb.append(nick);
- if (index < size - 1) {
- nicksb.append("|");
- addNickFormatter = true;
- }
- }
- index++;
- }
- 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) -> {
- 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) {
- if (PlayerListener.NotificationSound == null)
- p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1.0f, 0.5f); // TODO: Airhorn
- else
- p.playSound(p.getLocation(), PlayerListener.NotificationSound, 1.0f,
- (float) PlayerListener.NotificationPitch);
- }
- 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) -> {
- 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";
- }
- if (PlayerListener.NotificationSound == null)
- p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1.0f, 0.5f);
- else
- p.playSound(p.getLocation(), PlayerListener.NotificationSound, 1.0f,
- (float) PlayerListener.NotificationPitch);
- 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;
- }
-
- static void doFunStuff(CommandSender sender, TBMCChatEventBase event, String message) {
- if (PlayerListener.ActiveF && !PlayerListener.Fs.contains(sender) && message.equalsIgnoreCase("F"))
- PlayerListener.Fs.add(sender);
-
- String msg = message.toLowerCase();
- val lld = new UnlolCommand.LastlolData(sender, event, System.nanoTime());
- boolean add;
- if (add = msg.contains("lol"))
- lld.setLolornot(true);
- else {
- for (int i = 0; i < PlayerListener.LaughStrings.length; i++) {
- if (add = msg.contains(PlayerListener.LaughStrings[i])) {
- lld.setLolornot(false);
- break;
- }
- }
- }
- if (add)
- UnlolCommand.Lastlol.put(event.getChannel(), lld);
- }
-}
+package buttondevteam.chat;
+
+import buttondevteam.chat.commands.UnlolCommand;
+import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
+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.lib.TBMCChatEvent;
+import buttondevteam.lib.TBMCChatEventBase;
+import buttondevteam.lib.TBMCCoreAPI;
+import buttondevteam.lib.chat.Channel;
+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 Color[] RainbowPresserColors = new Color[]{Color.Red, Color.Gold, Color.Yellow, Color.Green,
+ Color.Blue, Color.DarkPurple};
+ 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(),
+ ESCAPE_FORMATTER, ChatFormatter.builder().regex(URL_PATTERN).underlined(true).openlink("$1").type(ChatFormatter.Type.Excluder).build(),
+ ChatFormatter.builder().regex(NULL_MENTION_PATTERN).color(Color.DarkRed).build(), // Properly added a bug as a feature
+ ChatFormatter.builder().regex(CONSOLE_PING_PATTERN).color(Color.Aqua).onmatch((match, builder) -> {
+ 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) -> {
+ return match; // TODO!
+ }).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"};
+ 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;
+ 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 && mp != null && mp.RainbowPresserColorMode) { // Only overwrite channel color
+ final AtomicInteger rpc = new AtomicInteger(0);
+ formatters.add(ChatFormatter.builder().color(colormode).onmatch((match, cf) -> {
+ 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, sender, 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));
+ if (e.getChannel().ID.equals(PluginMain.TownChat.ID)
+ || e.getChannel().ID.equals(PluginMain.NationChat.ID)) {
+ ((List) json.getExtra()).add(0, new TellrawPart("[SPY]"));
+ jsonstr = toJson(json);
+ Bukkit.getServer().dispatchCommand(PluginMain.Console, String.format(
+ "tellraw @a[score_%s=1000,score_%s_min=1000] %s", channel.ID, channel.ID, jsonstr));
+ }
+ }
+ } 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("");
+ if (mp != null && mp.ChatOnly) {
+ json.addExtra(new TellrawPart("[C]")
+ .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Chat only")));
+ }
+ 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, CommandSender sender, String origin) {
+ return ("[" + (MCORIGIN.equals(origin) ? "" : "§8" + origin.substring(0, 1) + "§r|") + channel.DisplayName)
+ + "]";
+ }
+
+ 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;
+ int index = 0;
+ 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)
+ }
+ index++;
+ }
+ 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) -> {
+ 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) {
+ if (PlayerListener.NotificationSound == null)
+ p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1.0f, 0.5f); // TODO: Airhorn
+ else
+ p.playSound(p.getLocation(), PlayerListener.NotificationSound, 1.0f,
+ (float) PlayerListener.NotificationPitch);
+ }
+ 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) -> {
+ 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";
+ }
+ if (PlayerListener.NotificationSound == null)
+ p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1.0f, 0.5f);
+ else
+ p.playSound(p.getLocation(), PlayerListener.NotificationSound, 1.0f,
+ (float) PlayerListener.NotificationPitch);
+ 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;
+ }
+
+ static void doFunStuff(CommandSender sender, TBMCChatEventBase event, String message) {
+ if (PlayerListener.ActiveF && !PlayerListener.Fs.contains(sender) && message.equalsIgnoreCase("F"))
+ PlayerListener.Fs.add(sender);
+
+ String msg = message.toLowerCase();
+ val lld = new UnlolCommand.LastlolData(sender, event, System.nanoTime());
+ boolean add;
+ if (add = msg.contains("lol"))
+ lld.setLolornot(true);
+ else {
+ for (int i = 0; i < PlayerListener.LaughStrings.length; i++) {
+ if (add = msg.contains(PlayerListener.LaughStrings[i])) {
+ lld.setLolornot(false);
+ break;
+ }
+ }
+ }
+ if (add)
+ UnlolCommand.Lastlol.put(event.getChannel(), lld);
+ }
+}
diff --git a/src/main/java/buttondevteam/chat/PluginMain.java b/src/main/java/buttondevteam/chat/PluginMain.java
index 7ad1825..b02f678 100644
--- a/src/main/java/buttondevteam/chat/PluginMain.java
+++ b/src/main/java/buttondevteam/chat/PluginMain.java
@@ -2,6 +2,7 @@ package buttondevteam.chat;
import buttondevteam.chat.commands.YeehawCommand;
import buttondevteam.chat.commands.ucmds.TownColorCommand;
+import buttondevteam.chat.listener.PlayerJoinLeaveListener;
import buttondevteam.chat.listener.PlayerListener;
import buttondevteam.chat.listener.TownyListener;
import buttondevteam.lib.TBMCCoreAPI;
@@ -81,6 +82,7 @@ public class PluginMain extends JavaPlugin { // Translated to Java: 2015.07.15.
PluginMain.essentials = (Essentials) (Bukkit.getPluginManager().getPlugin("Essentials"));
TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this);
+ TBMCCoreAPI.RegisterEventsForExceptions(new PlayerJoinLeaveListener(), this);
TBMCCoreAPI.RegisterEventsForExceptions(new TownyListener(), this);
TBMCChatAPI.AddCommands(this, YeehawCommand.class);
Console = this.getServer().getConsoleSender();
diff --git a/src/main/java/buttondevteam/chat/commands/ucmds/HistoryCommand.java b/src/main/java/buttondevteam/chat/commands/ucmds/HistoryCommand.java
new file mode 100644
index 0000000..e39600a
--- /dev/null
+++ b/src/main/java/buttondevteam/chat/commands/ucmds/HistoryCommand.java
@@ -0,0 +1,83 @@
+package buttondevteam.chat.commands.ucmds;
+
+import buttondevteam.lib.chat.Channel;
+import buttondevteam.lib.chat.ChatMessage;
+import buttondevteam.lib.chat.CommandClass;
+import lombok.RequiredArgsConstructor;
+import lombok.experimental.var;
+import lombok.val;
+import org.bukkit.command.CommandSender;
+
+import javax.annotation.Nullable;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+@CommandClass
+public class HistoryCommand extends UCommandBase {
+ /**
+ * Key: ChannelID_groupID
+ */
+ private static HashMap> messages = new HashMap<>();
+
+ @Override
+ public String[] GetHelpText(String alias) {
+ return new String[]{ //
+ "§6--- Chat History ----", //
+ "Returns the last 10 messages the player can see." //
+ };
+ }
+
+ @Override
+ public boolean OnCommand(CommandSender sender, String alias, String[] args) {
+ return showHistory(sender, alias, args, this);
+ }
+
+ public static boolean showHistory(CommandSender sender, String alias, String[] args, @Nullable HistoryCommand hc) {
+ Function> getThem = ch -> messages.get(ch.ID + "_" + ch.getGroupID(sender)); //If can't see, groupID is null, and that shouldn't be in the map
+ sender.sendMessage("§6---- Chat History ----");
+ Stream stream;
+ if (args.length == 0) {
+ stream = Channel.getChannels().stream();
+ } else {
+ Optional och = Channel.getChannels().stream().filter(chan -> chan.ID.equalsIgnoreCase(args[0])).findAny();
+ if (!och.isPresent()) {
+ sender.sendMessage("§cChannel not found. Use the ID, for example: /" + (hc == null ? "u history" : hc.GetCommandPath()) + " ooc");
+ return true;
+ }
+ stream = Stream.of(och.get());
+ }
+ AtomicBoolean sent = new AtomicBoolean();
+ val arr = stream.map(getThem).filter(Objects::nonNull).flatMap(Collection::stream)
+ .sorted(Comparator.comparingLong(he -> he.timestamp)).toArray(HistoryEntry[]::new);
+ for (int i = Math.max(0, arr.length - 10); i < arr.length; i++) {
+ HistoryEntry e = arr[i];
+ val cm = e.chatMessage;
+ sender.sendMessage("[" + e.channel.DisplayName + "] " + cm.getSender().getName() + ": " + cm.getMessage());
+ sent.set(true);
+ }
+ if (!sent.get())
+ sender.sendMessage("No messages can be found.");
+ return true;
+ }
+
+ @RequiredArgsConstructor
+ private static class HistoryEntry {
+ /**
+ * System.nanoTime()
+ */
+ private final long timestamp;
+ private final ChatMessage chatMessage;
+ private final Channel channel;
+ }
+
+ public static void addChatMessage(ChatMessage chatMessage, Channel channel) {
+ val groupID = channel.getGroupID(chatMessage.getPermCheck());
+ if (groupID == null) return; //Just to be sure
+ var ll = messages.computeIfAbsent(channel.ID + "_" + groupID, k -> new LinkedList<>()); //<-- TIL
+ ll.add(new HistoryEntry(System.nanoTime(), chatMessage, channel)); //Adds as last element
+ while (ll.size() > 10)
+ ll.remove(); //Removes the first element
+ }
+}
diff --git a/src/main/java/buttondevteam/chat/commands/ucmds/NColorCommand.java b/src/main/java/buttondevteam/chat/commands/ucmds/NColorCommand.java
index 9ac3cff..88403b1 100644
--- a/src/main/java/buttondevteam/chat/commands/ucmds/NColorCommand.java
+++ b/src/main/java/buttondevteam/chat/commands/ucmds/NColorCommand.java
@@ -58,16 +58,16 @@ public class NColorCommand extends UCommandBase {
player.sendMessage("§cYour town doesn't have a color set. The town mayor can set it using /u towncolor.");
return true;
}
- if (nameparts.length < towncolors.length) {
- player.sendMessage("§cYou need more vertical lines (|) or colons (:) in your name. (Should have " + (towncolors.length - 1) + ")");
+ if (nameparts.length < towncolors.length + 1) { //+1: Nation color
+ player.sendMessage("§cYou need more vertical lines (|) or colons (:) in your name. (Should have " + (towncolors.length - 1 + 1) + ")"); //Nation color
return true;
}
- if (nameparts.length > towncolors.length * 2) {
- player.sendMessage("§cYou have waay too many vertical lines (|) or colons (:) in your name. (Should have " + (towncolors.length - 1) + ")");
+ if (nameparts.length > (towncolors.length + 1) * 2) {
+ player.sendMessage("§cYou have waay too many vertical lines (|) or colons (:) in your name. (Should have " + (towncolors.length - 1 + 1) + ")");
return true;
}
- if (nameparts.length > towncolors.length) {
- player.sendMessage("§cYou have too many vertical lines (|) or colons (:) in your name. (Should have " + (towncolors.length - 1) + ")");
+ if (nameparts.length > towncolors.length + 1) {
+ player.sendMessage("§cYou have too many vertical lines (|) or colons (:) in your name. (Should have " + (towncolors.length - 1 + 1) + ")");
return true;
}
ChatPlayer.getPlayer(player.getUniqueId(), ChatPlayer.class).NameColorLocations()
diff --git a/src/main/java/buttondevteam/chat/commands/ucmds/admin/NationColorCommand.java b/src/main/java/buttondevteam/chat/commands/ucmds/admin/NationColorCommand.java
index 60564c5..ddc8e5b 100644
--- a/src/main/java/buttondevteam/chat/commands/ucmds/admin/NationColorCommand.java
+++ b/src/main/java/buttondevteam/chat/commands/ucmds/admin/NationColorCommand.java
@@ -2,6 +2,7 @@ package buttondevteam.chat.commands.ucmds.admin;
import buttondevteam.chat.PluginMain;
import buttondevteam.chat.listener.TownyListener;
+import buttondevteam.lib.chat.Color;
import com.palmergames.bukkit.towny.object.Nation;
import com.palmergames.bukkit.towny.object.Town;
import lombok.val;
@@ -37,6 +38,14 @@ public class NationColorCommand extends AdminCommandBase {
}
val c = TownColorCommand.getColorOrSendError(args[1], sender);
if (!c.isPresent()) return true;
+ if (!c.get().getName().equals(Color.White.getName())) { //Default nation color
+ for (val nc : PluginMain.NationColor.values()) {
+ if (nc.getName().equals(c.get().getName())) {
+ sender.sendMessage("§cAnother nation already uses this color!");
+ return true;
+ }
+ }
+ }
PluginMain.NationColor.put(args[0].toLowerCase(), c.get());
Bukkit.getScheduler().runTaskAsynchronously(PluginMain.Instance, () -> {
for (Town t : nation.getTowns())
diff --git a/src/main/java/buttondevteam/chat/commands/ucmds/admin/TownColorCommand.java b/src/main/java/buttondevteam/chat/commands/ucmds/admin/TownColorCommand.java
index e1cd357..97224ad 100644
--- a/src/main/java/buttondevteam/chat/commands/ucmds/admin/TownColorCommand.java
+++ b/src/main/java/buttondevteam/chat/commands/ucmds/admin/TownColorCommand.java
@@ -10,6 +10,7 @@ import org.bukkit.command.CommandSender;
import org.dynmap.towny.DynmapTownyPlugin;
import java.util.Arrays;
+import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -46,6 +47,33 @@ public class TownColorCommand extends AdminCommandBase {
return true;
clrs[i - 1] = c.get();
}
+ for (Map.Entry other : PluginMain.TownColors.entrySet()) {
+ Color nc, tnc;
+ try {
+ nc = PluginMain.NationColor.get(PluginMain.TU.getTownsMap().get(other.getKey()).getNation().getName().toLowerCase());
+ } catch (Exception e) { //Too lazy for lots of null-checks and it may throw exceptions anyways
+ nc = null;
+ }
+ if (nc == null) nc = Color.White; //Default nation color
+ try {
+ tnc = PluginMain.NationColor.get(targetTown.getNation().getName().toLowerCase());
+ } catch (Exception e) {
+ tnc = null;
+ }
+ if (tnc == null) tnc = Color.White; //Default nation color - TODO: Make configurable
+ if (nc.getName().equals(tnc.getName())) {
+ int C = 0;
+ if (clrs.length == other.getValue().length)
+ for (int i = 0; i < clrs.length; i++)
+ if (clrs[i].getName().equals(other.getValue()[i].getName()))
+ C++;
+ else break;
+ if (C == clrs.length) {
+ sender.sendMessage("§cThis town color combination is already used!");
+ return true;
+ }
+ }
+ }
PluginMain.TownColors.put(args[0].toLowerCase(), clrs);
TownyListener.updateTownMembers(targetTown);
diff --git a/src/main/java/buttondevteam/chat/commands/ucmds/admin/UpdatePlugin.java b/src/main/java/buttondevteam/chat/commands/ucmds/admin/UpdatePlugin.java
index b60690e..be6f274 100644
--- a/src/main/java/buttondevteam/chat/commands/ucmds/admin/UpdatePlugin.java
+++ b/src/main/java/buttondevteam/chat/commands/ucmds/admin/UpdatePlugin.java
@@ -1,12 +1,11 @@
package buttondevteam.chat.commands.ucmds.admin;
+import buttondevteam.chat.PluginMain;
+import buttondevteam.component.updater.PluginUpdater;
+import buttondevteam.lib.TBMCCoreAPI;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
-import buttondevteam.chat.PluginMain;
-import buttondevteam.lib.PluginUpdater;
-import buttondevteam.lib.TBMCCoreAPI;
-
public class UpdatePlugin extends AdminCommandBase {
@Override
diff --git a/src/main/java/buttondevteam/chat/components/TownColorComponent.java b/src/main/java/buttondevteam/chat/components/TownColorComponent.java
new file mode 100644
index 0000000..b731ea7
--- /dev/null
+++ b/src/main/java/buttondevteam/chat/components/TownColorComponent.java
@@ -0,0 +1,24 @@
+package buttondevteam.chat.components;
+
+import buttondevteam.lib.architecture.Component;
+import buttondevteam.lib.architecture.ConfigData;
+
+public class TownColorComponent extends Component {
+ public ConfigData colorCount() { //TODO
+ return getData("colorCount", (byte) 1, cc -> (byte) cc, cc -> (int) cc);
+ }
+
+ public ConfigData useNationColors() { //TODO
+ return getData("useNationColors", true);
+ }
+
+ @Override
+ protected void enable() {
+ //TODO: Don't register all commands automatically (welp)
+ }
+
+ @Override
+ protected void disable() {
+
+ }
+}
diff --git a/src/main/java/buttondevteam/chat/listener/PlayerJoinLeaveListener.java b/src/main/java/buttondevteam/chat/listener/PlayerJoinLeaveListener.java
index 0c57e7c..3a49a4a 100644
--- a/src/main/java/buttondevteam/chat/listener/PlayerJoinLeaveListener.java
+++ b/src/main/java/buttondevteam/chat/listener/PlayerJoinLeaveListener.java
@@ -5,6 +5,7 @@ import buttondevteam.chat.FlairStates;
import buttondevteam.chat.PlayerJoinTimerTask;
import buttondevteam.chat.PluginMain;
import buttondevteam.chat.commands.UnlolCommand;
+import buttondevteam.chat.commands.ucmds.HistoryCommand;
import buttondevteam.lib.chat.Color;
import buttondevteam.lib.player.TBMCPlayerJoinEvent;
import buttondevteam.lib.player.TBMCPlayerLoadEvent;
@@ -64,14 +65,14 @@ public class PlayerJoinLeaveListener implements Listener {
nwithoutformatting = p.getName();
PlayerListener.nicknames.forcePut(nwithoutformatting.toLowerCase(), p.getUniqueId());
- Bukkit.getScheduler().runTaskLater(PluginMain.Instance, () -> {
- updatePlayerColors(p, cp); //TODO: Doesn't have effect
- }, 5);
+ updatePlayerColors(p, cp); //TO!DO: Doesn't have effect - It can help to register the listener
if (cp.ChatOnly || p.getGameMode().equals(GameMode.SPECTATOR)) {
cp.ChatOnly = false;
p.setGameMode(GameMode.SURVIVAL);
}
+
+ HistoryCommand.showHistory(e.getPlayer(), "u history", new String[0], null);
}
@EventHandler
diff --git a/src/main/java/buttondevteam/chat/listener/PlayerListener.java b/src/main/java/buttondevteam/chat/listener/PlayerListener.java
index 4997347..fd8dfb5 100644
--- a/src/main/java/buttondevteam/chat/listener/PlayerListener.java
+++ b/src/main/java/buttondevteam/chat/listener/PlayerListener.java
@@ -3,6 +3,7 @@ package buttondevteam.chat.listener;
import buttondevteam.chat.ChatPlayer;
import buttondevteam.chat.ChatProcessing;
import buttondevteam.chat.PluginMain;
+import buttondevteam.chat.commands.ucmds.HistoryCommand;
import buttondevteam.lib.TBMCChatEvent;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.*;
@@ -258,6 +259,7 @@ public class PlayerListener implements Listener {
try {
if (e.isCancelled())
return;
+ HistoryCommand.addChatMessage(e.getCm(), e.getChannel());
e.setCancelled(ChatProcessing.ProcessChat(e));
} catch (NoClassDefFoundError | Exception ex) { // Weird things can happen
for (Player p : Bukkit.getOnlinePlayers())
@@ -272,7 +274,7 @@ public class PlayerListener implements Listener {
@EventHandler
public void onChannelRegistered(ChatChannelRegisterEvent e) {
- if (e.getChannel().filteranderrormsg != null && PluginMain.SB.getObjective(e.getChannel().ID) == null) // Not global chat and doesn't exist yet
+ 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");
}
diff --git a/src/test/java/buttondevteam/chat/ChatFormatIT.java b/src/test/java/buttondevteam/chat/ChatFormatIT.java
index a1831cd..bb508cc 100644
--- a/src/test/java/buttondevteam/chat/ChatFormatIT.java
+++ b/src/test/java/buttondevteam/chat/ChatFormatIT.java
@@ -65,6 +65,11 @@ public class ChatFormatIT {
.setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://norbipeti.github.io/")), new TellrawPart(" heh").setItalic(true)));
list.add(new ChatFormatIT(sender, "*test _test_ test*", new TellrawPart("test ").setItalic(true).setColor(Color.White),
new TellrawPart("test").setItalic(true).setUnderlined(true).setColor(Color.White), new TellrawPart(" test").setItalic(true).setColor(Color.White)));
+ list.add(new ChatFormatIT(sender, "https://norbipeti.github.io/test?test&test#test", new TellrawPart("https://norbipeti.github.io/test?test&test#test")
+ .setColor(Color.White).setUnderlined(true)
+ .setHoverEvent(TellrawEvent.create(HoverAction.SHOW_TEXT,
+ new TellrawPart("Click to open").setColor(Color.Blue)))
+ .setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://norbipeti.github.io/test?test&test#test"))));
return list;
}
@@ -82,12 +87,12 @@ public class ChatFormatIT {
@Test
public void testMessage() {
ArrayList cfs = ChatProcessing.addFormatters(Color.White);
- final String chid = ChatProcessing.getChannelID(Channel.GlobalChat, sender);
- final TellrawPart tp = ChatProcessing.createTellraw(sender, message, null, null, null, chid);
+ final String chid = ChatProcessing.getChannelID(Channel.GlobalChat, sender, ChatProcessing.MCORIGIN);
+ final TellrawPart tp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatProcessing.MCORIGIN);
ChatFormatter.Combine(cfs, message, tp);
System.out.println("Testing: " + message);
// System.out.println(ChatProcessing.toJson(tp));
- final TellrawPart expectedtp = ChatProcessing.createTellraw(sender, message, null, null, null, chid);
+ final TellrawPart expectedtp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatProcessing.MCORIGIN);
// System.out.println("Raw: " + ChatProcessing.toJson(expectedtp));
for (TellrawPart extra : extras)
expectedtp.addExtra(extra);