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
This commit is contained in:
Norbi Peti 2020-01-31 22:01:29 +01:00
parent cda2a36da1
commit 2d874d7bc9
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
23 changed files with 179 additions and 181 deletions

View file

@ -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 <query>" });
sender.sendMessage(new String[]{"§bMinecraft Wiki link: http://minecraft.gamepedia.com/",
"You can also search on it using /mwiki <query>"});
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();
}

View file

@ -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<String> text = new ArrayList<String>();
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", //

View file

@ -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;
}
}

View file

@ -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 {
}

View file

@ -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;

View file

@ -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<PluginMain> implements Runnabl
/**
* The messages to display to players.
*/
public ConfigData<ArrayList<String>> announceMessages() {
return getConfig().getData("announceMessages", new ArrayList<>(0));
public ListConfigData<String> announceMessages() {
return getConfig().getListData("announceMessages");
}
/**

View file

@ -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() {

View file

@ -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 ----", //

View file

@ -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 <username> 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 <username>");

View file

@ -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<PluginMain> {
/**
* The Reddit thread to check for account connections. Re-enable the component if this was empty.

View file

@ -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.");

View file

@ -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<ChatFormatter> 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);
}

View file

@ -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) {

View file

@ -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;

View file

@ -57,9 +57,9 @@ public class FunComponent extends Component<PluginMain> 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<Boolean> unlol() {
return getConfig().getData("unlol", true);

View file

@ -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.", //

View file

@ -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) {

View file

@ -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;

View file

@ -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<PluginMain> 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<PluginMain> 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<PluginMain> 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<Color, Integer> c2i = c -> c.getRed() << 16 | c.getGreen() << 8 | c.getBlue();
try {
DTBridge.setTownColor(dtp, town, c2i.apply(nationcolor == null ? colors[0] : nationcolor),

View file

@ -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<String, Color[]> 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<String, Color[]> 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<Color> 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();
}
}
}

View file

@ -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<String, Object>) 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 <T> 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);

View file

@ -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

View file

@ -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<ChatFormatter> 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);