From 2d874d7bc9232ba7053b86b93e334ef7b85a126f Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Fri, 31 Jan 2020 22:01:29 +0100 Subject: [PATCH] Clickable announcements and some fixes Fixed announcement storage (#112) Disabled some components by default Made announcements clickable and copiable (#95) Fixed /mwiki (#110) Fixed /u info (#111) Added test for rainbow chat (#103) Fixed crash if Dynmap-Towny isn't present Removed old command annotations --- .../chat/commands/MWikiCommand.java | 8 +- .../chat/commands/ucmds/HelpCommand.java | 20 +---- .../chat/commands/ucmds/InfoCommand.java | 22 +++-- .../chat/commands/ucmds/UCommandBase.java | 2 - .../components/announce/AnnounceCommand.java | 25 ++++-- .../announce/AnnouncerComponent.java | 7 +- .../chatonly/ChatOnlyComponent.java | 2 + .../components/chatonly/ChatonlyCommand.java | 8 +- .../chat/components/flair/AcceptCommand.java | 6 +- .../chat/components/flair/FlairComponent.java | 2 + .../chat/components/flair/IgnoreCommand.java | 6 +- .../components/formatter/ChatProcessing.java | 20 +++-- .../chat/components/fun/CCommand.java | 6 +- .../chat/components/fun/FTopCommand.java | 1 - .../chat/components/fun/FunComponent.java | 4 +- .../components/towncolors/NColorCommand.java | 2 - .../towncolors/NationColorCommand.java | 2 - .../towncolors/TownColorCommand.java | 2 - .../towncolors/TownColorComponent.java | 47 ++++++----- .../towncolors/admin/TownColorCommand.java | 83 +++++++++---------- src/main/java/org/dynmap/towny/DTBridge.java | 32 ++++--- src/main/resources/plugin.yml | 4 - .../components/formatter/ChatFormatIT.java | 49 +++++++---- 23 files changed, 179 insertions(+), 181 deletions(-) diff --git a/src/main/java/buttondevteam/chat/commands/MWikiCommand.java b/src/main/java/buttondevteam/chat/commands/MWikiCommand.java index 2a7ad02..6be49d0 100644 --- a/src/main/java/buttondevteam/chat/commands/MWikiCommand.java +++ b/src/main/java/buttondevteam/chat/commands/MWikiCommand.java @@ -16,14 +16,14 @@ import java.net.URLEncoder; }) public class MWikiCommand extends ICommand2MC { @Command2.Subcommand - public boolean def(CommandSender sender, @Command2.OptionalArg String query) { + public boolean def(CommandSender sender, @Command2.OptionalArg @Command2.TextArg String query) { try { if (query == null) - sender.sendMessage(new String[] { "§bMinecraft Wiki link: http://minecraft.gamepedia.com/", - "You can also search on it using /mwiki " }); + sender.sendMessage(new String[]{"§bMinecraft Wiki link: http://minecraft.gamepedia.com/", + "You can also search on it using /mwiki "}); else sender.sendMessage("§bMinecraft Wiki link: http://minecraft.gamepedia.com/index.php?search=" - + URLEncoder.encode(query, "UTF-8") + "&title=Special%3ASearch&go=Go"); + + URLEncoder.encode(query, "UTF-8") + "&title=Special%3ASearch&go=Go"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } diff --git a/src/main/java/buttondevteam/chat/commands/ucmds/HelpCommand.java b/src/main/java/buttondevteam/chat/commands/ucmds/HelpCommand.java index b7c10fa..94f22f5 100644 --- a/src/main/java/buttondevteam/chat/commands/ucmds/HelpCommand.java +++ b/src/main/java/buttondevteam/chat/commands/ucmds/HelpCommand.java @@ -1,14 +1,8 @@ package buttondevteam.chat.commands.ucmds; -import buttondevteam.chat.PluginMain; import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.CommandClass; -import buttondevteam.lib.chat.TBMCChatAPI; -import buttondevteam.lib.chat.TBMCCommandBase; import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -import java.util.ArrayList; @CommandClass(modOnly = false, helpText = { "Help", @@ -36,19 +30,7 @@ public final class HelpCommand extends UCommandBase { "- Playernames: Hover over them to get some player info", "-- Respect: This is the number of paid respects divided by eliglble deaths. This is a reference to CoD:AW's \"Press F to pay respects\""}); else if (topicOrCommand.equalsIgnoreCase("commands")) { - ArrayList text = new ArrayList(); - text.add("§6---- Command list ----"); - for (TBMCCommandBase cmd : TBMCChatAPI.GetCommands().values()) - if (!cmd.getClass().getAnnotation(CommandClass.class).modOnly() || PluginMain.permission.has(sender, "tbmc.admin")) - if (!cmd.isPlayerOnly() || sender instanceof Player) - if (!cmd.GetCommandPath().contains(" ")) - text.add("/" + cmd.GetCommandPath()); - else { - final String topcmd = cmd.GetCommandPath().substring(0, cmd.GetCommandPath().indexOf(' ')); - if (!text.contains("/" + topcmd)) - text.add("/" + topcmd); - } - sender.sendMessage(text.toArray(new String[0])); + sender.sendMessage(getManager().getCommandsText()); } else if (topicOrCommand.equalsIgnoreCase("colors")) { sender.sendMessage(new String[]{"§6---- Chat colors/formats ----", // "Tellraw name - Code | Tellraw name - Code", // diff --git a/src/main/java/buttondevteam/chat/commands/ucmds/InfoCommand.java b/src/main/java/buttondevteam/chat/commands/ucmds/InfoCommand.java index def4928..0dd0859 100644 --- a/src/main/java/buttondevteam/chat/commands/ucmds/InfoCommand.java +++ b/src/main/java/buttondevteam/chat/commands/ucmds/InfoCommand.java @@ -1,11 +1,13 @@ package buttondevteam.chat.commands.ucmds; +import buttondevteam.chat.PluginMain; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.player.ChromaGamerBase.InfoTarget; import buttondevteam.lib.player.TBMCPlayer; import buttondevteam.lib.player.TBMCPlayerBase; +import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; @CommandClass(modOnly = false, helpText = { @@ -20,16 +22,18 @@ public class InfoCommand extends UCommandBase { sender.sendMessage("The server console."); return true; } - try (TBMCPlayer p = TBMCPlayerBase.getFromName(player, TBMCPlayer.class)) { - if (p == null) { - sender.sendMessage("§cThe specified player cannot be found"); - return true; + Bukkit.getScheduler().runTaskAsynchronously(PluginMain.Instance, () -> { + try (TBMCPlayer p = TBMCPlayerBase.getFromName(player, TBMCPlayer.class)) { + if (p == null) { + sender.sendMessage("§cThe specified player cannot be found"); + return; + } + sender.sendMessage(p.getInfo(InfoTarget.MCCommand)); + } catch (Exception e) { + TBMCCoreAPI.SendException("Error while getting player information!", e); + sender.sendMessage("§cError while getting player information!"); } - sender.sendMessage(p.getInfo(InfoTarget.MCCommand)); - } catch (Exception e) { - TBMCCoreAPI.SendException("Error while getting player information!", e); - sender.sendMessage("§cError while getting player information!"); - } + }); return true; } } diff --git a/src/main/java/buttondevteam/chat/commands/ucmds/UCommandBase.java b/src/main/java/buttondevteam/chat/commands/ucmds/UCommandBase.java index d9be50a..ae85e1e 100644 --- a/src/main/java/buttondevteam/chat/commands/ucmds/UCommandBase.java +++ b/src/main/java/buttondevteam/chat/commands/ucmds/UCommandBase.java @@ -2,9 +2,7 @@ package buttondevteam.chat.commands.ucmds; import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.chat.ICommand2MC; -import buttondevteam.lib.chat.OptionallyPlayerCommandClass; @CommandClass(modOnly = false, path = "u") -@OptionallyPlayerCommandClass(playerOnly = false) public abstract class UCommandBase extends ICommand2MC { } diff --git a/src/main/java/buttondevteam/chat/components/announce/AnnounceCommand.java b/src/main/java/buttondevteam/chat/components/announce/AnnounceCommand.java index d6864d1..5b79ef5 100644 --- a/src/main/java/buttondevteam/chat/components/announce/AnnounceCommand.java +++ b/src/main/java/buttondevteam/chat/components/announce/AnnounceCommand.java @@ -1,15 +1,19 @@ package buttondevteam.chat.components.announce; import buttondevteam.chat.commands.ucmds.UCommandBase; +import buttondevteam.chat.components.formatter.ChatProcessing; +import buttondevteam.chat.components.formatter.FormatterComponent; +import buttondevteam.chat.components.formatter.formatting.TellrawEvent; +import buttondevteam.chat.components.formatter.formatting.TellrawPart; +import buttondevteam.core.ComponentManager; import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.CommandClass; -import buttondevteam.lib.chat.OptionallyPlayerCommandClass; import lombok.RequiredArgsConstructor; import lombok.val; +import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; @CommandClass(modOnly = true) -@OptionallyPlayerCommandClass(playerOnly = false) @RequiredArgsConstructor public class AnnounceCommand extends UCommandBase { private final AnnouncerComponent component; @@ -28,7 +32,7 @@ public class AnnounceCommand extends UCommandBase { @Command2.Subcommand(helpText = { "Edit announcement", "This command lets you edit an announcement by its index.", - "Shouldn't be used directly, use either command blocks or click on an announcement in /u announce list (WIP) instead." //TODO: <-- + "Shouldn't be used directly, use either command blocks or click on an announcement in /u announce list instead." }) public boolean edit(CommandSender sender, byte index, @Command2.TextArg String text) { String finalmessage1 = text.replace('&', '§'); @@ -49,8 +53,19 @@ 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()) - sender.sendMessage("[" + i++ + "] " + message); + for (String message : component.announceMessages().get()) { + String msg = "[" + i++ + "] " + message; + //noinspection SuspiciousMethodCalls + if (!ComponentManager.isEnabled(FormatterComponent.class) || !Bukkit.getOnlinePlayers().contains(sender)) { + sender.sendMessage(msg); + continue; + } + String json = ChatProcessing.toJson(new TellrawPart(msg) + .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Click to edit")) + .setClickEvent(TellrawEvent.create(TellrawEvent.ClickAction.SUGGEST_COMMAND, + "/" + getCommandPath() + " edit " + (i - 1) + " " + message.replace('§', '&')))); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName() + " " + json); + } sender.sendMessage("§bCurrent wait time between announcements: " + component.announceTime().get() / 60 / 1000 + " minute(s)§r"); 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 10aa1ac..c621410 100644 --- a/src/main/java/buttondevteam/chat/components/announce/AnnouncerComponent.java +++ b/src/main/java/buttondevteam/chat/components/announce/AnnouncerComponent.java @@ -5,11 +5,10 @@ import buttondevteam.core.component.channel.Channel; import buttondevteam.lib.TBMCSystemChatEvent; import buttondevteam.lib.architecture.Component; import buttondevteam.lib.architecture.ConfigData; +import buttondevteam.lib.architecture.ListConfigData; import buttondevteam.lib.chat.TBMCChatAPI; import org.bukkit.Bukkit; -import java.util.ArrayList; - /** * Displays the configured messages at the set interval when someone is online. */ @@ -17,8 +16,8 @@ public class AnnouncerComponent extends Component implements Runnabl /** * The messages to display to players. */ - public ConfigData> announceMessages() { - return getConfig().getData("announceMessages", new ArrayList<>(0)); + public ListConfigData announceMessages() { + return getConfig().getListData("announceMessages"); } /** diff --git a/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java b/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java index 6aa9763..2aca8df 100644 --- a/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java +++ b/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java @@ -5,6 +5,7 @@ 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.architecture.ComponentMetadata; import buttondevteam.lib.player.TBMCPlayer; import buttondevteam.lib.player.TBMCPlayerJoinEvent; import lombok.val; @@ -18,6 +19,7 @@ import org.bukkit.event.player.PlayerTeleportEvent; /** * Allows players to enter chat-only mode which puts them into spectator mode and disallows everything besides chatting. */ +@ComponentMetadata(enabledByDefault = false) public class ChatOnlyComponent extends Component implements Listener { @Override protected void enable() { diff --git a/src/main/java/buttondevteam/chat/components/chatonly/ChatonlyCommand.java b/src/main/java/buttondevteam/chat/components/chatonly/ChatonlyCommand.java index 9af57be..5add48d 100644 --- a/src/main/java/buttondevteam/chat/components/chatonly/ChatonlyCommand.java +++ b/src/main/java/buttondevteam/chat/components/chatonly/ChatonlyCommand.java @@ -1,13 +1,11 @@ package buttondevteam.chat.components.chatonly; -import buttondevteam.lib.chat.ICommand2MC; -import org.bukkit.GameMode; -import org.bukkit.entity.Player; - import buttondevteam.chat.ChatPlayer; import buttondevteam.lib.chat.CommandClass; -import buttondevteam.lib.chat.PlayerCommandBase; +import buttondevteam.lib.chat.ICommand2MC; import buttondevteam.lib.player.TBMCPlayer; +import org.bukkit.GameMode; +import org.bukkit.entity.Player; @CommandClass(modOnly = false, helpText = { "§6---- Chat-only mode ----", // diff --git a/src/main/java/buttondevteam/chat/components/flair/AcceptCommand.java b/src/main/java/buttondevteam/chat/components/flair/AcceptCommand.java index 1c47167..2da58b0 100644 --- a/src/main/java/buttondevteam/chat/components/flair/AcceptCommand.java +++ b/src/main/java/buttondevteam/chat/components/flair/AcceptCommand.java @@ -6,10 +6,8 @@ import buttondevteam.chat.commands.ucmds.UCommandBase; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.CommandClass; -import buttondevteam.lib.chat.OptionallyPlayerCommandClass; import buttondevteam.lib.player.TBMCPlayer; import lombok.RequiredArgsConstructor; -import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import java.util.Timer; @@ -19,14 +17,12 @@ import java.util.Timer; "Accepts a flair from Reddit", // "Use /u accept if you commented from multiple accounts" }) -@OptionallyPlayerCommandClass(playerOnly = true) @RequiredArgsConstructor public class AcceptCommand extends UCommandBase { private final FlairComponent component; @Command2.Subcommand - public boolean def(CommandSender sender, @Command2.OptionalArg String username) { - final Player player = (Player) sender; + public boolean def(Player player, @Command2.OptionalArg String username) { ChatPlayer p = TBMCPlayer.getPlayer(player.getUniqueId(), ChatPlayer.class); if (username == null && p.UserNames().size() > 1) { player.sendMessage("§9Multiple users commented your name. §bPlease pick one using /u accept "); diff --git a/src/main/java/buttondevteam/chat/components/flair/FlairComponent.java b/src/main/java/buttondevteam/chat/components/flair/FlairComponent.java index 38948fb..9372ac5 100644 --- a/src/main/java/buttondevteam/chat/components/flair/FlairComponent.java +++ b/src/main/java/buttondevteam/chat/components/flair/FlairComponent.java @@ -4,6 +4,7 @@ import buttondevteam.chat.ChatPlayer; import buttondevteam.chat.PluginMain; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.architecture.Component; +import buttondevteam.lib.architecture.ComponentMetadata; import buttondevteam.lib.architecture.ConfigData; import buttondevteam.lib.player.TBMCPlayerBase; import com.google.gson.JsonArray; @@ -26,6 +27,7 @@ import java.util.*; * This component checks a specific Reddit thread every 10 seconds for comments such as "IGN: NorbiPeti" to link Reddit accounts and to determine their /r/thebutton flair. * This was the original goal of this plugin when it was made. */ +@ComponentMetadata(enabledByDefault = false) public class FlairComponent extends Component { /** * The Reddit thread to check for account connections. Re-enable the component if this was empty. diff --git a/src/main/java/buttondevteam/chat/components/flair/IgnoreCommand.java b/src/main/java/buttondevteam/chat/components/flair/IgnoreCommand.java index 3639587..f2f441a 100644 --- a/src/main/java/buttondevteam/chat/components/flair/IgnoreCommand.java +++ b/src/main/java/buttondevteam/chat/components/flair/IgnoreCommand.java @@ -4,20 +4,16 @@ import buttondevteam.chat.ChatPlayer; import buttondevteam.chat.commands.ucmds.UCommandBase; import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.CommandClass; -import buttondevteam.lib.chat.OptionallyPlayerCommandClass; import buttondevteam.lib.player.TBMCPlayer; -import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @CommandClass(modOnly = false, helpText = { "Ignore flair", "Stop the \"write your name in the thread\" message from showing up" }) -@OptionallyPlayerCommandClass(playerOnly = true) public final class IgnoreCommand extends UCommandBase { @Command2.Subcommand - public boolean def(CommandSender sender) { - final Player player = (Player) sender; + public boolean def(Player player) { ChatPlayer p = TBMCPlayer.getPlayer(player.getUniqueId(), ChatPlayer.class); if (p.FlairState().get().equals(FlairStates.Accepted)) { player.sendMessage("§cYou can only ignore the \"write your name in the thread\" message."); diff --git a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java index fa14b21..f83933d 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java +++ b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java @@ -56,7 +56,7 @@ public class ChatProcessing { 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 SOMEONE_PATTERN = Pattern.compile("@someone"); private static final Pattern STRIKETHROUGH_PATTERN = Pattern.compile("~~"); private static final Pattern SPOILER_PATTERN = Pattern.compile("\\|\\|"); private static final Color[] RainbowPresserColors = new Color[]{Color.Red, Color.Gold, Color.Yellow, Color.Green, @@ -108,7 +108,7 @@ public class ChatProcessing { var playerC = new Random().nextInt(players.size()); var player = players.get(playerC); playPingSound(player, ComponentManager.getIfEnabled(FormatterComponent.class)); - return "@someone (" + player.getDisplayName() + ")"; + return "@someone (" + player.getDisplayName() + "§r)"; }).build()); private static Gson gson = new GsonBuilder() .registerTypeHierarchyAdapter(TellrawSerializableEnum.class, new TellrawSerializer.TwEnum()) @@ -159,11 +159,7 @@ public class ChatProcessing { if (component.allowFormatting().get()) { formatters = addFormatters(colormode, e::shouldSendTo, component); 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()); + createRPC(colormode, formatters); } pingedconsole = false; // Will set it to true onmatch (static constructor) } else @@ -217,7 +213,15 @@ public class ChatProcessing { return false; } - static String toJson(TellrawPart json) { + static void createRPC(Color colormode, ArrayList formatters) { + final AtomicInteger rpc = new AtomicInteger(0); + formatters.add(ChatFormatter.builder("rpc", WORD_PATTERN).color(colormode).onmatch((match, cf, s) -> { + cf.setColor(RainbowPresserColors[rpc.getAndUpdate(i -> ++i < RainbowPresserColors.length ? i : 0)]); + return match; + }).build()); + } + + public static String toJson(TellrawPart json) { return gson.toJson(json); } diff --git a/src/main/java/buttondevteam/chat/components/fun/CCommand.java b/src/main/java/buttondevteam/chat/components/fun/CCommand.java index 42acb07..1cd5f67 100644 --- a/src/main/java/buttondevteam/chat/components/fun/CCommand.java +++ b/src/main/java/buttondevteam/chat/components/fun/CCommand.java @@ -2,7 +2,10 @@ package buttondevteam.chat.components.fun; import buttondevteam.chat.ChatPlayer; import buttondevteam.chat.PluginMain; -import buttondevteam.lib.chat.*; +import buttondevteam.lib.chat.Color; +import buttondevteam.lib.chat.Command2; +import buttondevteam.lib.chat.CommandClass; +import buttondevteam.lib.chat.ICommand2MC; import buttondevteam.lib.player.TBMCPlayer; import org.bukkit.entity.Player; @@ -13,7 +16,6 @@ import java.util.Optional; "Rainbow mode", "This command allows you to talk in rainbow colors" }) -@OptionallyPlayerCommandClass(playerOnly = true) public class CCommand extends ICommand2MC { @Command2.Subcommand public boolean def(Player player, @Command2.OptionalArg String color) { diff --git a/src/main/java/buttondevteam/chat/components/fun/FTopCommand.java b/src/main/java/buttondevteam/chat/components/fun/FTopCommand.java index 037811e..4c3f99f 100644 --- a/src/main/java/buttondevteam/chat/components/fun/FTopCommand.java +++ b/src/main/java/buttondevteam/chat/components/fun/FTopCommand.java @@ -5,7 +5,6 @@ import buttondevteam.chat.PluginMain; import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.chat.ICommand2MC; -import buttondevteam.lib.chat.TBMCCommandBase; import buttondevteam.lib.player.TBMCPlayerBase; import lombok.val; import org.bukkit.Bukkit; diff --git a/src/main/java/buttondevteam/chat/components/fun/FunComponent.java b/src/main/java/buttondevteam/chat/components/fun/FunComponent.java index 3eff9cd..29df8b5 100644 --- a/src/main/java/buttondevteam/chat/components/fun/FunComponent.java +++ b/src/main/java/buttondevteam/chat/components/fun/FunComponent.java @@ -57,9 +57,9 @@ public class FunComponent extends Component implements Listener { } /** - * This is a sort of inside joke between me and Ghostise, who said "no, it was very unlol" after I said lol. + * This is an inside joke on our server. * It keeps track of laughs (lols and what's defined in laughStrings) and if someone does /unlol or /unlaugh it will unlaugh the last person who laughed. - * This action can only be performed once per laugh. + * Which also blinds the laughing person for a few seconds. This action can only be performed once per laugh. */ private ConfigData unlol() { return getConfig().getData("unlol", true); diff --git a/src/main/java/buttondevteam/chat/components/towncolors/NColorCommand.java b/src/main/java/buttondevteam/chat/components/towncolors/NColorCommand.java index d9a7792..41f830f 100644 --- a/src/main/java/buttondevteam/chat/components/towncolors/NColorCommand.java +++ b/src/main/java/buttondevteam/chat/components/towncolors/NColorCommand.java @@ -6,7 +6,6 @@ import buttondevteam.chat.components.towny.TownyComponent; import buttondevteam.lib.chat.Color; import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.CommandClass; -import buttondevteam.lib.chat.OptionallyPlayerCommandClass; import com.palmergames.bukkit.towny.object.Resident; import com.palmergames.bukkit.towny.object.Town; import org.bukkit.ChatColor; @@ -16,7 +15,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.stream.Collectors; -@OptionallyPlayerCommandClass(playerOnly = true) @CommandClass(helpText = { "Name color", // "This command allows you to set how the town colors look on your name.", // diff --git a/src/main/java/buttondevteam/chat/components/towncolors/NationColorCommand.java b/src/main/java/buttondevteam/chat/components/towncolors/NationColorCommand.java index c6789e9..f31ee40 100644 --- a/src/main/java/buttondevteam/chat/components/towncolors/NationColorCommand.java +++ b/src/main/java/buttondevteam/chat/components/towncolors/NationColorCommand.java @@ -5,7 +5,6 @@ import buttondevteam.chat.components.towny.TownyComponent; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.CommandClass; -import buttondevteam.lib.chat.OptionallyPlayerCommandClass; import com.palmergames.bukkit.towny.exceptions.NotRegisteredException; import com.palmergames.bukkit.towny.object.Nation; import com.palmergames.bukkit.towny.object.Resident; @@ -17,7 +16,6 @@ import org.bukkit.entity.Player; "Each town in the nation will have it's first color (border) set to this color.", // "See the help text for /u towncolor for more details.", // }) -@OptionallyPlayerCommandClass(playerOnly = true) public class NationColorCommand extends UCommandBase { @Command2.Subcommand public boolean def(Player player, String color) { diff --git a/src/main/java/buttondevteam/chat/components/towncolors/TownColorCommand.java b/src/main/java/buttondevteam/chat/components/towncolors/TownColorCommand.java index 88151bf..0bfdcd6 100644 --- a/src/main/java/buttondevteam/chat/components/towncolors/TownColorCommand.java +++ b/src/main/java/buttondevteam/chat/components/towncolors/TownColorCommand.java @@ -5,7 +5,6 @@ import buttondevteam.chat.components.towny.TownyComponent; import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.CommandClass; -import buttondevteam.lib.chat.OptionallyPlayerCommandClass; import com.palmergames.bukkit.towny.exceptions.NotRegisteredException; import com.palmergames.bukkit.towny.object.Resident; import com.palmergames.bukkit.towny.object.Town; @@ -21,7 +20,6 @@ import java.lang.reflect.Method; "The town will be shown with this color on Dynmap and all players in the town will appear in chat with these colors.", // "The colors will split the name evenly but residents can override that with /u ncolor.", // }) // TODO: /u u when annotation not present -@OptionallyPlayerCommandClass(playerOnly = true) @RequiredArgsConstructor public class TownColorCommand extends UCommandBase { private final TownColorComponent component; diff --git a/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java b/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java index c41e86a..d6d0886 100644 --- a/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java +++ b/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java @@ -23,8 +23,8 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.bukkit.plugin.Plugin; import org.dynmap.towny.DTBridge; -import org.dynmap.towny.DynmapTownyPlugin; import java.io.File; import java.util.*; @@ -95,25 +95,7 @@ public class TownColorComponent extends Component implements Listene if (usenc) NationColor.keySet().removeIf(n -> !TownyComponent.TU.getNationsMap().containsKey(n)); // Removes nation colors for deleted/renamed nations - Bukkit.getScheduler().runTask(getPlugin(), () -> { - val dtp = (DynmapTownyPlugin) Bukkit.getPluginManager().getPlugin("Dynmap-Towny"); - if (dtp == null) - return; - for (val entry : TownColors.entrySet()) { - try { - val town = TownyComponent.TU.getTownsMap().get(entry.getKey()); - Nation nation; - Color nc; - if (!useNationColors().get()) - nc = null; - else if (!town.hasNation() || (nation = town.getNation()) == null || (nc = NationColor.get(nation.getName().toLowerCase())) == null) - nc = Color.White; - setTownColor(dtp, buttondevteam.chat.components.towncolors.admin.TownColorCommand.getTownNameCased(entry.getKey()), entry.getValue(), nc); - } catch (Exception e) { - TBMCCoreAPI.SendException("Error while setting town color for town " + entry.getKey() + "!", e); - } - } - }); + initDynmap(); registerCommand(new TownColorCommand(this)); if (useNationColors().get()) @@ -136,6 +118,28 @@ public class TownColorComponent extends Component implements Listene v -> v.getValue().toString()))); } + private void initDynmap() { + Bukkit.getScheduler().runTask(getPlugin(), () -> { + val dtp = Bukkit.getPluginManager().getPlugin("Dynmap-Towny"); + if (dtp == null) + return; + for (val entry : TownColors.entrySet()) { + try { + val town = TownyComponent.TU.getTownsMap().get(entry.getKey()); + Nation nation; + Color nc; + if (!useNationColors().get()) + nc = null; + else if (!town.hasNation() || (nation = town.getNation()) == null || (nc = NationColor.get(nation.getName().toLowerCase())) == null) + nc = Color.White; + setTownColor(dtp, buttondevteam.chat.components.towncolors.admin.TownColorCommand.getTownNameCased(entry.getKey()), entry.getValue(), nc); + } catch (Exception e) { + TBMCCoreAPI.SendException("Error while setting town color for town " + entry.getKey() + "!", e); + } + } + }); + } + /** * Sets a town's color on Dynmap. * @@ -143,8 +147,7 @@ public class TownColorComponent extends Component implements Listene * @param town The town's name using the correct casing * @param colors The town's colors */ - - public static void setTownColor(DynmapTownyPlugin dtp, String town, Color[] colors, Color nationcolor) { + public static void setTownColor(Plugin dtp, String town, Color[] colors, Color nationcolor) { Function c2i = c -> c.getRed() << 16 | c.getGreen() << 8 | c.getBlue(); try { DTBridge.setTownColor(dtp, town, c2i.apply(nationcolor == null ? colors[0] : nationcolor), diff --git a/src/main/java/buttondevteam/chat/components/towncolors/admin/TownColorCommand.java b/src/main/java/buttondevteam/chat/components/towncolors/admin/TownColorCommand.java index 288447e..88cade9 100644 --- a/src/main/java/buttondevteam/chat/components/towncolors/admin/TownColorCommand.java +++ b/src/main/java/buttondevteam/chat/components/towncolors/admin/TownColorCommand.java @@ -11,7 +11,6 @@ import com.palmergames.bukkit.towny.object.Town; import lombok.val; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; -import org.dynmap.towny.DynmapTownyPlugin; import java.util.Arrays; import java.util.Map; @@ -39,52 +38,52 @@ public class TownColorCommand extends AdminCommandBase { //TODO: Command path al Color[] clrs = new Color[colors.length]; for (int i = 0; i < colors.length; i++) { val c = getColorOrSendError(colors[i], sender); - if (!c.isPresent()) - return true; + if (!c.isPresent()) + return true; clrs[i] = c.get(); - } - Color tnc; - boolean usenc = TownColorComponent.getComponent().useNationColors().get(); - if (usenc) { - try { - tnc = TownColorComponent.NationColor.get(town.getNation().getName().toLowerCase()); - } catch (Exception e) { - tnc = null; - } - if (tnc == null) tnc = Color.White; //Default nation color - TODO: Make configurable - } else tnc = null; - for (Map.Entry other : TownColorComponent.TownColors.entrySet()) { - Color nc; - if (usenc) { - try { - nc = TownColorComponent.NationColor.get(TownyComponent.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 - } else nc = null; - if (!usenc || 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; - } - } - } + } + Color tnc; + boolean usenc = TownColorComponent.getComponent().useNationColors().get(); + if (usenc) { + try { + tnc = TownColorComponent.NationColor.get(town.getNation().getName().toLowerCase()); + } catch (Exception e) { + tnc = null; + } + if (tnc == null) tnc = Color.White; //Default nation color - TODO: Make configurable + } else tnc = null; + for (Map.Entry other : TownColorComponent.TownColors.entrySet()) { + Color nc; + if (usenc) { + try { + nc = TownColorComponent.NationColor.get(TownyComponent.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 + } else nc = null; + if (!usenc || 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; + } + } + } TownColorComponent.TownColors.put(town.getName().toLowerCase(), clrs); TownyListener.updateTownMembers(town); - val dtp = (DynmapTownyPlugin) Bukkit.getPluginManager().getPlugin("Dynmap-Towny"); + val dtp = Bukkit.getPluginManager().getPlugin("Dynmap-Towny"); if (dtp != null) //If it's not found then it's not loaded, it'll be noticed by the admins if needed TownColorComponent.setTownColor(dtp, town.getName(), clrs, tnc); - sender.sendMessage("§bColor(s) set."); - return true; - } + sender.sendMessage("§bColor(s) set."); + return true; + } public static Optional getColorOrSendError(String name, CommandSender sender) { val c = Arrays.stream(Color.values()).skip(1).filter(cc -> cc.getName().equalsIgnoreCase(name)).findAny(); @@ -102,5 +101,5 @@ public class TownColorCommand extends AdminCommandBase { //TODO: Command path al public static String getTownNameCased(String name) { return TownyComponent.TU.getTownsMap().get(name.toLowerCase()).getName(); - } + } } diff --git a/src/main/java/org/dynmap/towny/DTBridge.java b/src/main/java/org/dynmap/towny/DTBridge.java index ee427b0..c6a3aa7 100644 --- a/src/main/java/org/dynmap/towny/DTBridge.java +++ b/src/main/java/org/dynmap/towny/DTBridge.java @@ -3,6 +3,7 @@ package org.dynmap.towny; import lombok.val; import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.plugin.Plugin; import org.dynmap.bukkit.DynmapPlugin; import org.dynmap.markers.MarkerAPI; @@ -14,32 +15,27 @@ import java.util.Map; public class DTBridge { /** * Sets the town color on Dynmap. - * - * @param dtp - * The Dynmap-Towny plugin - * @param townname - * The name of the town, using correct casing - * @param strokecolor - * The stroke color in RGB format - * @param fillcolor - * The fill color in RGB format - * @throws Exception - * When couldn't set the town color + * + * @param dtp The Dynmap-Towny plugin + * @param townname The name of the town, using correct casing + * @param strokecolor The stroke color in RGB format + * @param fillcolor The fill color in RGB format + * @throws Exception When couldn't set the town color */ - public static void setTownColor(DynmapTownyPlugin dtp, String townname, int strokecolor, int fillcolor) - throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, // Keeping these because why not - IllegalAccessException, NoSuchMethodException, InstantiationException, InvocationTargetException { + public static void setTownColor(Plugin dtp, String townname, int strokecolor, int fillcolor) + throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, // Keeping these because why not + IllegalAccessException, NoSuchMethodException, InstantiationException, InvocationTargetException { Class cl = Class.forName(DynmapTownyPlugin.class.getName() + "$AreaStyle"); Field field = DynmapTownyPlugin.class.getDeclaredField("cusstyle"); - field.setAccessible(true); // Doesn't allow accessing it from the same package, if it's from a different plugin + field.setAccessible(true); // Doesn't allow accessing it from the same package, if it's from a different plugin @SuppressWarnings("unchecked") val map = (Map) field.get(dtp); Object style = map.get(townname); if (style == null) { Constructor c = cl.getDeclaredConstructor(FileConfiguration.class, String.class, MarkerAPI.class); c.setAccessible(true); - style = c.newInstance(dtp.getConfig(), "custstyle." + townname, - ((DynmapPlugin) Bukkit.getPluginManager().getPlugin("dynmap")).getMarkerAPI()); + style = c.newInstance(dtp.getConfig(), "custstyle." + townname, + ((DynmapPlugin) Bukkit.getPluginManager().getPlugin("dynmap")).getMarkerAPI()); map.put(townname, style); } set(cl, style, "fillcolor", fillcolor); @@ -47,7 +43,7 @@ public class DTBridge { } private static void set(Class cl, Object style, String fieldname, T value) - throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { Field field = cl.getDeclaredField(fieldname); field.setAccessible(true); field.set(style, value); diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 105abc9..20f270a 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -40,10 +40,6 @@ soft-depend: - Dynmap-Towny - Towny permissions: - tbmc.admin: - description: Gives access to /un- commands and /u admin commands - tbmc.rainbow: - description: Gives access to rainbow colors (/u c). tbmc.badge.gold: description: Gives a patron badge. default: false diff --git a/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java b/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java index cf8c43d..8b39810 100644 --- a/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java +++ b/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java @@ -37,34 +37,34 @@ public class ChatFormatIT { list.add(new ChatFormatIT(sender, "*test*", new TellrawPart("test").setItalic(true).setColor(Color.White))); list.add(new ChatFormatIT(sender, "**test**", new TellrawPart("test").setBold(true).setColor(Color.White))); list.add(new ChatFormatIT(sender, "***test***", - new TellrawPart("test").setBold(true).setItalic(true).setColor(Color.White))); + new TellrawPart("test").setBold(true).setItalic(true).setColor(Color.White))); list.add(new ChatFormatIT(sender, "***__test__***", - new TellrawPart("test").setBold(true).setItalic(true).setUnderlined(true).setColor(Color.White))); + new TellrawPart("test").setBold(true).setItalic(true).setUnderlined(true).setColor(Color.White))); list.add(new ChatFormatIT(sender, "***__~~test~~__***", new TellrawPart("test").setBold(true).setItalic(true) - .setUnderlined(true).setStrikethrough(true).setColor(Color.White))); - list.add(new ChatFormatIT(sender, "¯\\\\\\_(ツ)\\_/¯", new TellrawPart("¯\\_(ツ)_/¯").setColor(Color.White))); + .setUnderlined(true).setStrikethrough(true).setColor(Color.White))); + list.add(new ChatFormatIT(sender, "¯\\\\\\_(ツ)\\_/¯", new TellrawPart("¯\\_(ツ)_/¯").setColor(Color.White))); list.add(new ChatFormatIT(sender, "https://google.hu/", - new TellrawPart("https://google.hu/").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://google.hu/")))); - list.add(new ChatFormatIT(sender, "*test", new TellrawPart("*test").setColor(Color.White))); + new TellrawPart("https://google.hu/").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://google.hu/")))); + list.add(new ChatFormatIT(sender, "*test", new TellrawPart("*test").setColor(Color.White))); list.add(new ChatFormatIT(sender, "**test*", new TellrawPart("**test*").setColor(Color.White))); list.add(new ChatFormatIT(sender, "***test", new TellrawPart("***test").setColor(Color.White))); - list.add(new ChatFormatIT(sender, "Koiiev", new TellrawPart("§bKoiiev§r").setColor(Color.Aqua))); + list.add(new ChatFormatIT(sender, "Koiiev", new TellrawPart("§bKoiiev§r").setColor(Color.Aqua))); list.add(new ChatFormatIT(sender, "norbipeti", new TellrawPart("§bNorbiPeti§r").setColor(Color.Aqua))); - list.add(new ChatFormatIT(sender, "Arsen_Derby_FTW", new TellrawPart("§bArsen_Derby_FTW§r").setColor(Color.Aqua))); + list.add(new ChatFormatIT(sender, "Arsen_Derby_FTW", new TellrawPart("§bArsen_Derby_FTW§r").setColor(Color.Aqua))); list.add(new ChatFormatIT(sender, "carrot_lynx", new TellrawPart("§bcarrot_lynx§r").setColor(Color.Aqua))); list.add(new ChatFormatIT(sender, "*carrot_lynx*", new TellrawPart("§bcarrot_lynx§r").setItalic(true).setColor(Color.Aqua))); list.add(new ChatFormatIT(sender, "https://norbipeti.github.io/", new TellrawPart("https://norbipeti.github.io/") - .setColor(Color.White).setUnderlined(true) - .setHoverEvent(TellrawEvent.create(HoverAction.SHOW_TEXT, - new TellrawPart("Click to open").setColor(Color.Blue))) - .setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://norbipeti.github.io/")))); + .setColor(Color.White).setUnderlined(true) + .setHoverEvent(TellrawEvent.create(HoverAction.SHOW_TEXT, + new TellrawPart("Click to open").setColor(Color.Blue))) + .setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://norbipeti.github.io/")))); list.add(new ChatFormatIT(sender, "*https://norbipeti.github.io/ heh*", new TellrawPart("https://norbipeti.github.io/").setItalic(true).setUnderlined(true) - .setHoverEvent(TellrawEvent.create(HoverAction.SHOW_TEXT, - new TellrawPart("Click to open").setColor(Color.Blue))) - .setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://norbipeti.github.io/")), new TellrawPart(" heh").setItalic(true))); + .setHoverEvent(TellrawEvent.create(HoverAction.SHOW_TEXT, + new TellrawPart("Click to open").setColor(Color.Blue))) + .setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://norbipeti.github.io/")), new TellrawPart(" heh").setItalic(true))); list.add(new ChatFormatIT(sender, "*test _test_ test*", new TellrawPart("test test test").setItalic(true).setColor(Color.White))); list.add(new ChatFormatIT(sender, "*test __test__ test*", new TellrawPart("test ").setItalic(true).setColor(Color.White), new TellrawPart("test").setItalic(true).setUnderlined(true).setColor(Color.White), new TellrawPart(" test").setItalic(true).setColor(Color.White))); @@ -82,6 +82,11 @@ public class ChatFormatIT { .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")))); + TellrawPart space = new TellrawPart(" ").setColor(Color.White); + list.add(new ChatFormatIT(sender, "A rainbow text for testing. O", new TellrawPart("A").setColor(Color.Red), + space, new TellrawPart("rainbow").setColor(Color.Gold), space, new TellrawPart("text").setColor(Color.Yellow), + space, new TellrawPart("for").setColor(Color.Green), space, new TellrawPart("testing.").setColor(Color.Blue), + space, new TellrawPart("O").setColor(Color.DarkPurple)).setRainbowMode()); return list; } @@ -89,6 +94,7 @@ public class ChatFormatIT { private final CommandSender sender; private final String message; private final TellrawPart[] extras; + private boolean rainbowMode; public ChatFormatIT(CommandSender sender, String message, TellrawPart... expectedextras) { this.sender = sender; @@ -96,10 +102,17 @@ public class ChatFormatIT { this.extras = expectedextras; } + private ChatFormatIT setRainbowMode() { + rainbowMode = true; + return this; + } + @Test public void testMessage() { ArrayList cfs = ChatProcessing.addFormatters(Color.White, p -> true, null); final String chid = ChatProcessing.getChannelID(Channel.GlobalChat, ChatUtils.MCORIGIN); + if (rainbowMode) + ChatProcessing.createRPC(Color.White, cfs); final TellrawPart tp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatUtils.MCORIGIN); ChatFormatter.Combine(cfs, message, tp, null); System.out.println("Testing: " + message);