diff --git a/bukkit-legacy/pom.xml b/bukkit-legacy/pom.xml
index 782385df2..f4abfb3d5 100644
--- a/bukkit-legacy/pom.xml
+++ b/bukkit-legacy/pom.xml
@@ -47,8 +47,8 @@
me.lucko.luckperms.lib.gson
- io.github.mkremins.fanciful
- me.lucko.luckperms.lib.fanciful
+ net.kyori.text
+ me.lucko.luckperms.lib.text
diff --git a/bukkit/pom.xml b/bukkit/pom.xml
index b97da1c9d..245b139ea 100644
--- a/bukkit/pom.xml
+++ b/bukkit/pom.xml
@@ -46,8 +46,8 @@
false
- io.github.mkremins.fanciful
- me.lucko.luckperms.lib.fanciful
+ net.kyori.text
+ me.lucko.luckperms.lib.text
diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitSenderFactory.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitSenderFactory.java
index 6d5259968..c3fe2ee86 100644
--- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitSenderFactory.java
+++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitSenderFactory.java
@@ -30,11 +30,11 @@ import me.lucko.luckperms.common.commands.sender.SenderFactory;
import me.lucko.luckperms.common.constants.Constants;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
+import net.kyori.text.Component;
+
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import io.github.mkremins.fanciful.FancyMessage;
-
import java.util.UUID;
public class BukkitSenderFactory extends SenderFactory {
@@ -67,7 +67,7 @@ public class BukkitSenderFactory extends SenderFactory {
}
@Override
- protected void sendMessage(CommandSender sender, FancyMessage message) {
+ protected void sendMessage(CommandSender sender, Component message) {
messageHandler.sendJsonMessage(sender, message);
}
diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/compat/MessageHandler.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/compat/MessageHandler.java
index 64f4482ce..467682fd4 100644
--- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/compat/MessageHandler.java
+++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/compat/MessageHandler.java
@@ -25,11 +25,14 @@
package me.lucko.luckperms.bukkit.compat;
+import me.lucko.luckperms.common.constants.Constants;
+
+import net.kyori.text.Component;
+import net.kyori.text.serializer.ComponentSerializer;
+
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import io.github.mkremins.fanciful.FancyMessage;
-
public class MessageHandler {
private final BukkitJsonMessageHandler bukkitHandler;
private final SpigotJsonMessageHandler spigotHandler;
@@ -39,10 +42,10 @@ public class MessageHandler {
spigotHandler = isSpigot() ? new SpigotJsonMessageHandler() : null;
}
- public void sendJsonMessage(CommandSender sender, FancyMessage message) {
+ public void sendJsonMessage(CommandSender sender, Component message) {
if (ReflectionUtil.isChatCompatible() && sender instanceof Player) {
Player player = (Player) sender;
- String json = message.exportToJson();
+ String json = ComponentSerializer.serialize(message);
// Try Bukkit.
if (bukkitHandler.sendJsonMessage(player, json)) {
@@ -56,7 +59,7 @@ public class MessageHandler {
}
// Fallback to Bukkit
- sender.sendMessage(message.toOldMessageFormat());
+ sender.sendMessage(ComponentSerializer.toLegacy(message, Constants.COLOR_CHAR));
}
private static boolean isSpigot() {
diff --git a/bungee/pom.xml b/bungee/pom.xml
index 08a434191..4cc565ec0 100644
--- a/bungee/pom.xml
+++ b/bungee/pom.xml
@@ -46,8 +46,8 @@
false
- io.github.mkremins.fanciful
- me.lucko.luckperms.lib.fanciful
+ net.kyori.text
+ me.lucko.luckperms.lib.text
diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeSenderFactory.java b/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeSenderFactory.java
index 1b297a873..6c570f264 100644
--- a/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeSenderFactory.java
+++ b/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeSenderFactory.java
@@ -29,12 +29,11 @@ import me.lucko.luckperms.common.commands.sender.SenderFactory;
import me.lucko.luckperms.common.constants.Constants;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
+import net.kyori.text.Component;
+import net.kyori.text.serializer.ComponentSerializer;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
-import net.md_5.bungee.chat.ComponentSerializer;
-
-import io.github.mkremins.fanciful.FancyMessage;
import java.util.UUID;
@@ -65,11 +64,11 @@ public class BungeeSenderFactory extends SenderFactory {
}
@Override
- protected void sendMessage(CommandSender sender, FancyMessage message) {
+ protected void sendMessage(CommandSender sender, Component message) {
try {
- sender.sendMessage(ComponentSerializer.parse(message.exportToJson()));
+ sender.sendMessage(net.md_5.bungee.chat.ComponentSerializer.parse(ComponentSerializer.serialize(message)));
} catch (Exception e) {
- sendMessage(sender, message.toOldMessageFormat());
+ sendMessage(sender, ComponentSerializer.toLegacy(message, Constants.COLOR_CHAR));
}
}
diff --git a/common/pom.xml b/common/pom.xml
index bdf95860f..cc1a25612 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -35,11 +35,11 @@
${project.version}
provided
-
+
- io.github.mkremins
- fanciful
- 1.2.5
+ net.kyori
+ text
+ 1.12-SNAPSHOT
compile
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/CommandManager.java b/common/src/main/java/me/lucko/luckperms/common/commands/CommandManager.java
index 0feb52461..0d5a73248 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/CommandManager.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/CommandManager.java
@@ -56,12 +56,16 @@ import me.lucko.luckperms.common.commands.impl.user.UserMainCommand;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
import me.lucko.luckperms.common.commands.utils.Util;
+import me.lucko.luckperms.common.constants.Constants;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
+import me.lucko.luckperms.common.utils.TextUtils;
-import io.github.mkremins.fanciful.ChatColor;
-import io.github.mkremins.fanciful.FancyMessage;
+import net.kyori.text.Component;
+import net.kyori.text.event.ClickEvent;
+import net.kyori.text.event.HoverEvent;
+import net.kyori.text.serializer.ComponentSerializer;
import java.util.ArrayList;
import java.util.Collections;
@@ -127,7 +131,7 @@ public class CommandManager {
return executor.submit(() -> {
try {
return execute(sender, label, args);
- } catch (Exception e) {
+ } catch (Throwable e) {
plugin.getLog().severe("Exception whilst executing command: " + args.toString());
e.printStackTrace();
return null;
@@ -179,7 +183,7 @@ public class CommandManager {
result = main.execute(plugin, sender, null, arguments, label);
} catch (CommandException e) {
result = handleException(e, sender, label, main);
- } catch (Exception e) {
+ } catch (Throwable e) {
e.printStackTrace();
result = CommandResult.FAILURE;
}
@@ -247,23 +251,22 @@ public class CommandManager {
.forEach(c -> {
@SuppressWarnings("unchecked")
String permission = (String) c.getPermission().map(p -> ((Permission) p).getExample()).orElse("None");
- FancyMessage msg = new FancyMessage("> ").color(c('3')).then().text(String.format(c.getUsage(), label)).color(c('a'))
- .formattedTooltip(
- new FancyMessage("Command: ").color(c('b')).then().text(c.getName()).color(c('2')),
- new FancyMessage("Description: ").color(c('b')).then().text(c.getDescription()).color(c('2')),
- new FancyMessage("Usage: ").color(c('b')).then().text(String.format(c.getUsage(), label)).color(c('2')),
- new FancyMessage("Permission: ").color(c('b')).then().text(permission).color(c('2')),
- new FancyMessage(" "),
- new FancyMessage("Click to auto-complete.").color(c('7'))
- )
- .suggest(String.format(c.getUsage(), label));
- sender.sendMessage(msg);
+
+ Component component = ComponentSerializer.parseFromLegacy("&3> &a" + String.format(c.getUsage(), label), Constants.FORMAT_CHAR)
+ .applyRecursively(comp -> {
+ comp.hoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, ComponentSerializer.parseFromLegacy(TextUtils.joinNewline(
+ "&bCommand: &2" + c.getName(),
+ "&bDescription: &2" + c.getDescription(),
+ "&bUsage: &2" + String.format(c.getUsage(), label),
+ "&bPermission: &2" + permission,
+ " ",
+ "&7Click to auto-complete."
+ ), Constants.FORMAT_CHAR)));
+ comp.clickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, String.format(c.getUsage(), label)));
+ });
+ sender.sendMessage(component);
});
}
-
- private static ChatColor c(char c) {
- return ChatColor.getByChar(c);
- }
public static CommandResult handleException(CommandException e, Sender sender, String label, Command command) {
if (e instanceof ArgumentUtils.ArgumentException) {
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/other/HolderEditor.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/other/HolderEditor.java
index ce6be9d55..5c452776f 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/other/HolderEditor.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/other/HolderEditor.java
@@ -46,8 +46,10 @@ import me.lucko.luckperms.common.core.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.Predicates;
-import io.github.mkremins.fanciful.ChatColor;
-import io.github.mkremins.fanciful.FancyMessage;
+import net.kyori.text.Component;
+import net.kyori.text.TextComponent;
+import net.kyori.text.event.ClickEvent;
+import net.kyori.text.event.HoverEvent;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -90,7 +92,12 @@ public class HolderEditor extends SubCommand {
String url = plugin.getConfiguration().get(ConfigKeys.WEB_EDITOR_URL_PATTERN) + id;
Message.EDITOR_URL.send(sender);
- sender.sendMessage(new FancyMessage(url).color(ChatColor.getByChar('b')).link(url));
+
+ Component message = new TextComponent(url).color('b')
+ .clickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url))
+ .hoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent("Click to open the editor.").color('7')));
+
+ sender.sendMessage(message);
return CommandResult.SUCCESS;
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/permission/PermissionInfo.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/permission/PermissionInfo.java
index 66879e362..82eee65ea 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/permission/PermissionInfo.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/permission/PermissionInfo.java
@@ -45,14 +45,19 @@ import me.lucko.luckperms.common.core.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.DateUtil;
import me.lucko.luckperms.common.utils.Predicates;
+import me.lucko.luckperms.common.utils.TextUtils;
-import io.github.mkremins.fanciful.ChatColor;
-import io.github.mkremins.fanciful.FancyMessage;
+import net.kyori.text.Component;
+import net.kyori.text.TextComponent;
+import net.kyori.text.event.ClickEvent;
+import net.kyori.text.event.HoverEvent;
+import net.kyori.text.serializer.ComponentSerializer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
+import java.util.function.Consumer;
public class PermissionInfo extends SharedSubCommand {
public PermissionInfo() {
@@ -86,7 +91,7 @@ public class PermissionInfo extends SharedSubCommand {
} else {
int page = ArgumentUtils.handleIntOrElse(0, args, 1);
- Map.Entry ent = permNodesToMessage(filter, holder.mergePermissionsToSortedSet(), holder, label, page);
+ Map.Entry ent = permNodesToMessage(filter, holder.mergePermissionsToSortedSet(), holder, label, page);
if (ent.getValue() != null) {
Message.LISTNODES_WITH_PAGE.send(sender, holder.getFriendlyName(), ent.getValue());
sender.sendMessage(ent.getKey());
@@ -100,7 +105,7 @@ public class PermissionInfo extends SharedSubCommand {
return CommandResult.SUCCESS;
}
- private static Map.Entry permNodesToMessage(String filter, SortedSet nodes, PermissionHolder holder, String label, int pageNumber) {
+ private static Map.Entry permNodesToMessage(String filter, SortedSet nodes, PermissionHolder holder, String label, int pageNumber) {
List l = new ArrayList<>();
for (Node node : nodes) {
if (filter != null && !node.getPermission().startsWith(filter)) {
@@ -114,7 +119,7 @@ public class PermissionInfo extends SharedSubCommand {
}
if (l.isEmpty()) {
- return Maps.immutableEntry(new FancyMessage("None").color(ChatColor.getByChar('3')), null);
+ return Maps.immutableEntry(new TextComponent("None").color('3'), null);
}
int index = pageNumber - 1;
@@ -127,7 +132,7 @@ public class PermissionInfo extends SharedSubCommand {
List page = pages.get(index);
- FancyMessage message = new FancyMessage("");
+ TextComponent message = new TextComponent("");
String title = "&7(showing page &f" + pageNumber + "&7 of &f" + pages.size() + "&7 - &f" + nodes.size() + "&7 entries";
if (filter != null) {
title += " - filtered by &f\"" + filter + "\"&7)";
@@ -136,24 +141,19 @@ public class PermissionInfo extends SharedSubCommand {
}
for (Node node : page) {
- message.then("> ").color(ChatColor.getByChar('3')).apply(m -> makeFancy(m, holder, label, node))
- .then(Util.color(node.getPermission())).color(node.getValue() ? ChatColor.getByChar('a') : ChatColor.getByChar('c')).apply(m -> makeFancy(m, holder, label, node))
- .apply(node, Util::appendNodeContextDescription)
- .then("\n");
+ String s = "&3> " + (node.getValue() ? "&a" : "&c") + node.getPermission() + Util.getAppendableNodeContextString(node) + "\n";
+ message.append(ComponentSerializer.parseFromLegacy(s, Constants.FORMAT_CHAR).applyRecursively(makeFancy(holder, label, node)));
}
return Maps.immutableEntry(message, title);
}
- private static void makeFancy(FancyMessage message, PermissionHolder holder, String label, Node node) {
- message.formattedTooltip(
- new FancyMessage("> ")
- .color(ChatColor.getByChar('3'))
- .then(node.getPermission())
- .color(node.getValue() ? ChatColor.getByChar('a') : ChatColor.getByChar('c')),
- new FancyMessage(" "),
- new FancyMessage("Click to remove this node from " + holder.getFriendlyName()).color(ChatColor.getByChar('7'))
- );
+ private static Consumer makeFancy(PermissionHolder holder, String label, Node node) {
+ HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, ComponentSerializer.parseFromLegacy(TextUtils.joinNewline(
+ "&3> " + (node.getValue() ? "&a" : "&c") + node.getPermission(),
+ " ",
+ "&7Click to remove this node from " + holder.getFriendlyName()
+ ), Constants.FORMAT_CHAR));
boolean group = !(holder instanceof User);
String command = NodeFactory.nodeAsCommand(node, group ? holder.getObjectName() : holder.getFriendlyName(), group)
@@ -163,7 +163,10 @@ public class PermissionInfo extends SharedSubCommand {
.replace(" true", "")
.replace(" false", "");
- message.suggest(command);
+ return component -> {
+ component.hoverEvent(hoverEvent);
+ component.clickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command));
+ };
}
private static String permNodesToString(String filter, SortedSet nodes) {
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/group/GroupListMembers.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/group/GroupListMembers.java
index a575761b6..ccf84631a 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/group/GroupListMembers.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/group/GroupListMembers.java
@@ -36,6 +36,7 @@ import me.lucko.luckperms.common.commands.abstraction.SubCommand;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
import me.lucko.luckperms.common.commands.utils.Util;
+import me.lucko.luckperms.common.constants.Constants;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.NodeFactory;
@@ -43,9 +44,13 @@ import me.lucko.luckperms.common.core.model.Group;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.DateUtil;
import me.lucko.luckperms.common.utils.Predicates;
+import me.lucko.luckperms.common.utils.TextUtils;
-import io.github.mkremins.fanciful.ChatColor;
-import io.github.mkremins.fanciful.FancyMessage;
+import net.kyori.text.Component;
+import net.kyori.text.TextComponent;
+import net.kyori.text.event.ClickEvent;
+import net.kyori.text.event.HoverEvent;
+import net.kyori.text.serializer.ComponentSerializer;
import java.util.ArrayList;
import java.util.Comparator;
@@ -53,6 +58,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
+import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -90,8 +96,8 @@ public class GroupListMembers extends SubCommand {
return s;
});
- Map.Entry msgUsers = searchUserResultToMessage(matchedUsers, lookupFunc, label, page);
- Map.Entry msgGroups = searchGroupResultToMessage(matchedGroups, label, page);
+ Map.Entry msgUsers = searchUserResultToMessage(matchedUsers, lookupFunc, label, page);
+ Map.Entry msgGroups = searchGroupResultToMessage(matchedGroups, label, page);
if (msgUsers.getValue() != null) {
Message.SEARCH_SHOWING_USERS_WITH_PAGE.send(sender, msgUsers.getValue());
@@ -112,9 +118,9 @@ public class GroupListMembers extends SubCommand {
return CommandResult.SUCCESS;
}
- private static Map.Entry searchUserResultToMessage(List> results, Function uuidLookup, String label, int pageNumber) {
+ private static Map.Entry searchUserResultToMessage(List> results, Function uuidLookup, String label, int pageNumber) {
if (results.isEmpty()) {
- return Maps.immutableEntry(new FancyMessage("None").color(ChatColor.getByChar('3')), null);
+ return Maps.immutableEntry(new TextComponent("None").color('3'), null);
}
List> sorted = new ArrayList<>(results);
@@ -133,23 +139,20 @@ public class GroupListMembers extends SubCommand {
.map(hp -> Maps.immutableEntry(uuidLookup.apply(hp.getHolder()), hp))
.collect(Collectors.toList());
- FancyMessage message = new FancyMessage("");
+ TextComponent message = new TextComponent("");
String title = "&7(page &f" + pageNumber + "&7 of &f" + pages.size() + "&7 - &f" + sorted.size() + "&7 entries)";
for (Map.Entry> ent : uuidMappedPage) {
- message.then("> ").color(ChatColor.getByChar('3')).apply(m -> makeFancy(m, ent.getKey(), false, label, ent.getValue()))
- .then(ent.getKey() + " ").color(ChatColor.getByChar('b')).apply(m -> makeFancy(m, ent.getKey(), false, label, ent.getValue()))
- .apply(ent.getValue().asNode(), GroupListMembers::appendNodeExpiry)
- .apply(ent.getValue().asNode(), Util::appendNodeContextDescription)
- .then("\n");
+ String s = "&3> &b" + ent.getKey() + " " + getNodeExpiryString(ent.getValue().asNode()) + Util.getAppendableNodeContextString(ent.getValue().asNode()) + "\n";
+ message.append(ComponentSerializer.parseFromLegacy(s, Constants.FORMAT_CHAR).applyRecursively(makeFancy(ent.getKey(), false, label, ent.getValue())));
}
return Maps.immutableEntry(message, title);
}
- private static Map.Entry searchGroupResultToMessage(List> results, String label, int pageNumber) {
+ private static Map.Entry searchGroupResultToMessage(List> results, String label, int pageNumber) {
if (results.isEmpty()) {
- return Maps.immutableEntry(new FancyMessage("None").color(ChatColor.getByChar('3')), null);
+ return Maps.immutableEntry(new TextComponent("None").color('3'), null);
}
List> sorted = new ArrayList<>(results);
@@ -165,49 +168,42 @@ public class GroupListMembers extends SubCommand {
List> page = pages.get(index);
- FancyMessage message = new FancyMessage("");
+ TextComponent message = new TextComponent("");
String title = "&7(page &f" + pageNumber + "&7 of &f" + pages.size() + "&7 - &f" + sorted.size() + "&7 entries)";
for (HeldPermission ent : page) {
- message.then("> ").color(ChatColor.getByChar('3')).apply(m -> makeFancy(m, ent.getHolder(), true, label, ent))
- .then(ent.getHolder() + " ").color(ChatColor.getByChar('b')).apply(m -> makeFancy(m, ent.getHolder(), true, label, ent))
- .apply(ent.asNode(), GroupListMembers::appendNodeExpiry)
- .apply(ent.asNode(), Util::appendNodeContextDescription)
- .then("\n");
+ String s = "&3> &b" + ent.getHolder() + " " + getNodeExpiryString(ent.asNode()) + Util.getAppendableNodeContextString(ent.asNode()) + "\n";
+ message.append(ComponentSerializer.parseFromLegacy(s, Constants.FORMAT_CHAR).applyRecursively(makeFancy(ent.getHolder(), true, label, ent)));
}
return Maps.immutableEntry(message, title);
}
- private static void appendNodeExpiry(FancyMessage message, Node node) {
+ private static String getNodeExpiryString(Node node) {
if (!node.isTemporary()) {
- return;
+ return "";
}
- message.then(" (").color(ChatColor.getByChar('8'))
- .then("expires in " + DateUtil.formatDateDiff(node.getExpiryUnixTime())).color(ChatColor.getByChar('7'))
- .then(")").color(ChatColor.getByChar('8'));
+ return " &8(&7expires in " + DateUtil.formatDateDiff(node.getExpiryUnixTime()) + "&8)";
}
- private static void makeFancy(FancyMessage message, String holderName, boolean group, String label, HeldPermission> perm) {
- Node node = perm.asNode();
+ private static Consumer makeFancy(String holderName, boolean group, String label, HeldPermission> perm) {
+ HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, ComponentSerializer.parseFromLegacy(TextUtils.joinNewline(
+ "&3> " + (perm.asNode().getValue() ? "&a" : "&c") + perm.asNode().getGroupName(),
+ " ",
+ "&7Click to remove this parent from " + holderName
+ ), Constants.FORMAT_CHAR));
- message = message.formattedTooltip(
- new FancyMessage("> ")
- .color(ChatColor.getByChar('3'))
- .then(node.getPermission())
- .color(node.getValue() ? ChatColor.getByChar('a') : ChatColor.getByChar('c')),
- new FancyMessage(" "),
- new FancyMessage("Click to remove this parent from " + holderName).color(ChatColor.getByChar('7'))
- );
-
- String command = NodeFactory.nodeAsCommand(node, holderName, group)
+ String command = NodeFactory.nodeAsCommand(perm.asNode(), holderName, group)
.replace("/luckperms", "/" + label)
.replace("permission set", "permission unset")
.replace("parent add", "parent remove")
.replace(" true", "")
.replace(" false", "");
- message.suggest(command);
+ return component -> {
+ component.hoverEvent(hoverEvent);
+ component.clickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command));
+ };
}
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/SearchCommand.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/SearchCommand.java
index cb7674d1c..7251f36bb 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/SearchCommand.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/SearchCommand.java
@@ -37,15 +37,20 @@ import me.lucko.luckperms.common.commands.abstraction.SubCommand;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.commands.utils.ArgumentUtils;
import me.lucko.luckperms.common.commands.utils.Util;
+import me.lucko.luckperms.common.constants.Constants;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.DateUtil;
import me.lucko.luckperms.common.utils.Predicates;
+import me.lucko.luckperms.common.utils.TextUtils;
-import io.github.mkremins.fanciful.ChatColor;
-import io.github.mkremins.fanciful.FancyMessage;
+import net.kyori.text.Component;
+import net.kyori.text.TextComponent;
+import net.kyori.text.event.ClickEvent;
+import net.kyori.text.event.HoverEvent;
+import net.kyori.text.serializer.ComponentSerializer;
import java.util.ArrayList;
import java.util.Comparator;
@@ -53,6 +58,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
+import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -91,8 +97,8 @@ public class SearchCommand extends SingleCommand {
return s;
});
- Map.Entry msgUsers = searchUserResultToMessage(matchedUsers, lookupFunc, label, page);
- Map.Entry msgGroups = searchGroupResultToMessage(matchedGroups, label, page);
+ Map.Entry msgUsers = searchUserResultToMessage(matchedUsers, lookupFunc, label, page);
+ Map.Entry msgGroups = searchGroupResultToMessage(matchedGroups, label, page);
if (msgUsers.getValue() != null) {
Message.SEARCH_SHOWING_USERS_WITH_PAGE.send(sender, msgUsers.getValue());
@@ -118,9 +124,9 @@ public class SearchCommand extends SingleCommand {
return SubCommand.getPermissionTabComplete(args, plugin.getPermissionVault());
}
- private static Map.Entry searchUserResultToMessage(List> results, Function uuidLookup, String label, int pageNumber) {
+ private static Map.Entry searchUserResultToMessage(List> results, Function uuidLookup, String label, int pageNumber) {
if (results.isEmpty()) {
- return Maps.immutableEntry(new FancyMessage("None").color(ChatColor.getByChar('3')), null);
+ return Maps.immutableEntry(new TextComponent("None").color('3'), null);
}
List> sorted = new ArrayList<>(results);
@@ -139,25 +145,20 @@ public class SearchCommand extends SingleCommand {
.map(hp -> Maps.immutableEntry(uuidLookup.apply(hp.getHolder()), hp))
.collect(Collectors.toList());
- FancyMessage message = new FancyMessage("");
+ TextComponent message = new TextComponent("");
String title = "&7(page &f" + pageNumber + "&7 of &f" + pages.size() + "&7 - &f" + sorted.size() + "&7 entries)";
for (Map.Entry> ent : uuidMappedPage) {
- message.then("> ").color(ChatColor.getByChar('3')).apply(m -> makeFancy(m, ent.getKey(), false, label, ent.getValue()))
- .then(ent.getKey()).color(ChatColor.getByChar('b')).apply(m -> makeFancy(m, ent.getKey(), false, label, ent.getValue()))
- .then(" - ").color(ChatColor.getByChar('7')).apply(m -> makeFancy(m, ent.getKey(), false, label, ent.getValue()))
- .then("" + ent.getValue().getValue()).color(ent.getValue().getValue() ? ChatColor.getByChar('a') : ChatColor.getByChar('c')).apply(m -> makeFancy(m, ent.getKey(), false, label, ent.getValue()))
- .apply(ent.getValue().asNode(), SearchCommand::appendNodeExpiry)
- .apply(ent.getValue().asNode(), Util::appendNodeContextDescription)
- .then("\n");
+ String s = "&3> &b" + ent.getKey() + " &7- " + (ent.getValue().getValue() ? "&a" : "&c") + ent.getValue().getValue() + getNodeExpiryString(ent.getValue().asNode()) + Util.getAppendableNodeContextString(ent.getValue().asNode()) + "\n";
+ message.append(ComponentSerializer.parseFromLegacy(s, Constants.FORMAT_CHAR).applyRecursively(makeFancy(ent.getKey(), false, label, ent.getValue())));
}
return Maps.immutableEntry(message, title);
}
- private static Map.Entry searchGroupResultToMessage(List> results, String label, int pageNumber) {
+ private static Map.Entry searchGroupResultToMessage(List> results, String label, int pageNumber) {
if (results.isEmpty()) {
- return Maps.immutableEntry(new FancyMessage("None").color(ChatColor.getByChar('3')), null);
+ return Maps.immutableEntry(new TextComponent("None").color('3'), null);
}
List> sorted = new ArrayList<>(results);
@@ -173,51 +174,42 @@ public class SearchCommand extends SingleCommand {
List> page = pages.get(index);
- FancyMessage message = new FancyMessage("");
+ TextComponent message = new TextComponent("");
String title = "&7(page &f" + pageNumber + "&7 of &f" + pages.size() + "&7 - &f" + sorted.size() + "&7 entries)";
for (HeldPermission ent : page) {
- message.then("> ").color(ChatColor.getByChar('3')).apply(m -> makeFancy(m, ent.getHolder(), true, label, ent))
- .then(ent.getHolder()).color(ChatColor.getByChar('b')).apply(m -> makeFancy(m, ent.getHolder(), true, label, ent))
- .then(" - ").color(ChatColor.getByChar('7')).apply(m -> makeFancy(m, ent.getHolder(), true, label, ent))
- .then("" + ent.getValue()).color(ent.getValue() ? ChatColor.getByChar('a') : ChatColor.getByChar('c')).apply(m -> makeFancy(m, ent.getHolder(), true, label, ent))
- .apply(ent.asNode(), SearchCommand::appendNodeExpiry)
- .apply(ent.asNode(), Util::appendNodeContextDescription)
- .then("\n");
+ String s = "&3> &b" + ent.getHolder() + " &7- " + (ent.getValue() ? "&a" : "&c") + ent.getValue() + getNodeExpiryString(ent.asNode()) + Util.getAppendableNodeContextString(ent.asNode()) + "\n";
+ message.append(ComponentSerializer.parseFromLegacy(s, Constants.FORMAT_CHAR).applyRecursively(makeFancy(ent.getHolder(), true, label, ent)));
}
return Maps.immutableEntry(message, title);
}
- private static void appendNodeExpiry(FancyMessage message, Node node) {
+ private static String getNodeExpiryString(Node node) {
if (!node.isTemporary()) {
- return;
+ return "";
}
- message.then(" (").color(ChatColor.getByChar('8'))
- .then("expires in " + DateUtil.formatDateDiff(node.getExpiryUnixTime())).color(ChatColor.getByChar('7'))
- .then(")").color(ChatColor.getByChar('8'));
+ return " &8(&7expires in " + DateUtil.formatDateDiff(node.getExpiryUnixTime()) + "&8)";
}
- private static void makeFancy(FancyMessage message, String holderName, boolean group, String label, HeldPermission> perm) {
- Node node = perm.asNode();
+ private static Consumer makeFancy(String holderName, boolean group, String label, HeldPermission> perm) {
+ HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, ComponentSerializer.parseFromLegacy(TextUtils.joinNewline(
+ "&3> " + (perm.asNode().getValue() ? "&a" : "&c") + perm.asNode().getPermission(),
+ " ",
+ "&7Click to remove this node from " + holderName
+ ), Constants.FORMAT_CHAR));
- message = message.formattedTooltip(
- new FancyMessage("> ")
- .color(ChatColor.getByChar('3'))
- .then(node.getPermission())
- .color(node.getValue() ? ChatColor.getByChar('a') : ChatColor.getByChar('c')),
- new FancyMessage(" "),
- new FancyMessage("Click to remove this node from " + holderName).color(ChatColor.getByChar('7'))
- );
-
- String command = NodeFactory.nodeAsCommand(node, holderName, group)
+ String command = NodeFactory.nodeAsCommand(perm.asNode(), holderName, group)
.replace("/luckperms", "/" + label)
.replace("permission set", "permission unset")
.replace("parent add", "parent remove")
.replace(" true", "")
.replace(" false", "");
- message.suggest(command);
+ return component -> {
+ component.hoverEvent(hoverEvent);
+ component.clickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command));
+ };
}
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/TreeCommand.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/TreeCommand.java
index ceb2d691a..01b80e0d6 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/TreeCommand.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/TreeCommand.java
@@ -41,8 +41,10 @@ import me.lucko.luckperms.common.treeview.TreeView;
import me.lucko.luckperms.common.treeview.TreeViewBuilder;
import me.lucko.luckperms.common.utils.Predicates;
-import io.github.mkremins.fanciful.ChatColor;
-import io.github.mkremins.fanciful.FancyMessage;
+import net.kyori.text.Component;
+import net.kyori.text.TextComponent;
+import net.kyori.text.event.ClickEvent;
+import net.kyori.text.event.HoverEvent;
import java.util.List;
import java.util.UUID;
@@ -105,7 +107,12 @@ public class TreeCommand extends SingleCommand {
}
Message.TREE_URL.send(sender);
- sender.sendMessage(new FancyMessage(url).color(ChatColor.getByChar('b')).link(url));
+
+ Component message = new TextComponent(url).color('b')
+ .clickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url))
+ .hoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent("Click to open the tree view.").color('7')));
+
+ sender.sendMessage(message);
return CommandResult.SUCCESS;
}
@@ -124,7 +131,12 @@ public class TreeCommand extends SingleCommand {
}
Message.TREE_URL.send(sender);
- sender.sendMessage(new FancyMessage(url).color(ChatColor.getByChar('b')).link(url));
+
+ Component message = new TextComponent(url).color('b')
+ .clickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url))
+ .hoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent("Click to open the tree view.").color('7')));
+
+ sender.sendMessage(message);
return CommandResult.SUCCESS;
}
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/VerboseCommand.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/VerboseCommand.java
index 72171b1d0..4d75e628f 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/VerboseCommand.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/VerboseCommand.java
@@ -37,8 +37,10 @@ import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.Predicates;
import me.lucko.luckperms.common.verbose.VerboseListener;
-import io.github.mkremins.fanciful.ChatColor;
-import io.github.mkremins.fanciful.FancyMessage;
+import net.kyori.text.Component;
+import net.kyori.text.TextComponent;
+import net.kyori.text.event.ClickEvent;
+import net.kyori.text.event.HoverEvent;
import java.util.ArrayList;
import java.util.Collections;
@@ -114,7 +116,12 @@ public class VerboseCommand extends SingleCommand {
}
Message.VERBOSE_RECORDING_URL.send(sender);
- sender.sendMessage(new FancyMessage(url).color(ChatColor.getByChar('b')).link(url));
+
+ Component message = new TextComponent(url).color('b')
+ .clickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url))
+ .hoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent("Click to open the results page.").color('7')));
+
+ sender.sendMessage(message);
return CommandResult.SUCCESS;
}
} else {
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/sender/AbstractSender.java b/common/src/main/java/me/lucko/luckperms/common/commands/sender/AbstractSender.java
index 7bb39f4c8..6065f12d3 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/sender/AbstractSender.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/sender/AbstractSender.java
@@ -34,7 +34,8 @@ import me.lucko.luckperms.common.constants.Constants;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
-import io.github.mkremins.fanciful.FancyMessage;
+import net.kyori.text.Component;
+import net.kyori.text.serializer.ComponentSerializer;
import java.lang.ref.WeakReference;
import java.util.UUID;
@@ -81,9 +82,9 @@ public final class AbstractSender implements Sender {
}
@Override
- public void sendMessage(FancyMessage message) {
+ public void sendMessage(Component message) {
if (isConsole()) {
- sendMessage(message.toOldMessageFormat());
+ sendMessage(ComponentSerializer.toLegacy(message, Constants.COLOR_CHAR));
return;
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/sender/Sender.java b/common/src/main/java/me/lucko/luckperms/common/commands/sender/Sender.java
index be6e28d74..2ef768a42 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/sender/Sender.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/sender/Sender.java
@@ -29,7 +29,7 @@ import me.lucko.luckperms.common.constants.Constants;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
-import io.github.mkremins.fanciful.FancyMessage;
+import net.kyori.text.Component;
import java.util.UUID;
@@ -71,7 +71,7 @@ public interface Sender {
*
* @param message the message to send.
*/
- void sendMessage(FancyMessage message);
+ void sendMessage(Component message);
/**
* Check if the Sender has a permission.
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/sender/SenderFactory.java b/common/src/main/java/me/lucko/luckperms/common/commands/sender/SenderFactory.java
index c56d033fa..89a873189 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/sender/SenderFactory.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/sender/SenderFactory.java
@@ -29,7 +29,7 @@ import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
-import io.github.mkremins.fanciful.FancyMessage;
+import net.kyori.text.Component;
import java.util.UUID;
@@ -48,7 +48,7 @@ public abstract class SenderFactory {
protected abstract void sendMessage(T t, String s);
- protected abstract void sendMessage(T t, FancyMessage message);
+ protected abstract void sendMessage(T t, Component message);
protected abstract boolean hasPermission(T t, String node);
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/utils/Util.java b/common/src/main/java/me/lucko/luckperms/common/commands/utils/Util.java
index 9738a6da4..1883644cc 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/utils/Util.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/utils/Util.java
@@ -27,16 +27,12 @@ package me.lucko.luckperms.common.commands.utils;
import lombok.experimental.UtilityClass;
-import com.google.common.collect.Maps;
-
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.constants.Message;
-import io.github.mkremins.fanciful.FancyMessage;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
@@ -238,18 +234,6 @@ public class Util {
return sb.toString();
}
- public static void appendNodeContextDescription(FancyMessage message, Node node) {
- if (node.isServerSpecific()) {
- message.then(" ").apply(Maps.immutableEntry("server", node.getServer().get()), Util::appendContext);
- }
- if (node.isWorldSpecific()) {
- message.then(" ").apply(Maps.immutableEntry("world", node.getWorld().get()), Util::appendContext);
- }
- for (Map.Entry c : node.getContexts().toSet()) {
- message.then(" ").apply(c, Util::appendContext);
- }
- }
-
/**
* Converts a context pair to a formatted string, surrounded by ( ) brackets.
*
@@ -261,10 +245,6 @@ public class Util {
return Message.CONTEXT_PAIR.asString(null, key, value);
}
- public static void appendContext(FancyMessage message, Map.Entry ent) {
- message.addAll(FancyMessage.fromLegacyText(contextToString(ent.getKey(), ent.getValue())));
- }
-
public static String contextSetToString(ContextSet set) {
if (set.isEmpty()) {
return Message.CONTEXT_PAIR__GLOBAL_INLINE.asString(null);
diff --git a/common/src/main/java/me/lucko/luckperms/common/constants/Constants.java b/common/src/main/java/me/lucko/luckperms/common/constants/Constants.java
index 7123527a6..a07285465 100644
--- a/common/src/main/java/me/lucko/luckperms/common/constants/Constants.java
+++ b/common/src/main/java/me/lucko/luckperms/common/constants/Constants.java
@@ -37,5 +37,7 @@ public class Constants {
public static final UUID IMPORT_UUID = UUID.fromString("11111111-1111-1111-1111-111111111111");
public static final String IMPORT_NAME = "Import";
public static final String LOG_FORMAT = "&8(&e%s&8) [&a%s&8] (&b%s&8) &7--> &f%s";
+ public static final char COLOR_CHAR = '\u00A7';
+ public static final char FORMAT_CHAR = '&';
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/data/Importer.java b/common/src/main/java/me/lucko/luckperms/common/data/Importer.java
index eccd5382c..44b8dc4ea 100644
--- a/common/src/main/java/me/lucko/luckperms/common/data/Importer.java
+++ b/common/src/main/java/me/lucko/luckperms/common/data/Importer.java
@@ -42,7 +42,8 @@ import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.DateUtil;
-import io.github.mkremins.fanciful.FancyMessage;
+import net.kyori.text.Component;
+import net.kyori.text.serializer.ComponentSerializer;
import java.util.ArrayList;
import java.util.HashMap;
@@ -203,8 +204,8 @@ public class Importer implements Runnable {
}
@Override
- public void sendMessage(FancyMessage message) {
- logMessage(message.toOldMessageFormat());
+ public void sendMessage(Component message) {
+ logMessage(ComponentSerializer.toLegacy(message, Constants.COLOR_CHAR));
}
@Override
diff --git a/common/src/main/java/me/lucko/luckperms/common/utils/TextUtils.java b/common/src/main/java/me/lucko/luckperms/common/utils/TextUtils.java
new file mode 100644
index 000000000..0eb0bcf03
--- /dev/null
+++ b/common/src/main/java/me/lucko/luckperms/common/utils/TextUtils.java
@@ -0,0 +1,15 @@
+package me.lucko.luckperms.common.utils;
+
+import lombok.experimental.UtilityClass;
+
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+@UtilityClass
+public class TextUtils {
+
+ public String joinNewline(String... strings) {
+ return Arrays.stream(strings).collect(Collectors.joining("\n"));
+ }
+
+}
diff --git a/sponge/pom.xml b/sponge/pom.xml
index abe074e10..c7cfa933b 100644
--- a/sponge/pom.xml
+++ b/sponge/pom.xml
@@ -46,8 +46,8 @@
false
- io.github.mkremins.fanciful
- me.lucko.luckperms.lib.fanciful
+ net.kyori.text
+ me.lucko.luckperms.lib.text
diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeSenderFactory.java b/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeSenderFactory.java
index 2aa0b2f79..f046e0bc1 100644
--- a/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeSenderFactory.java
+++ b/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeSenderFactory.java
@@ -29,12 +29,13 @@ import me.lucko.luckperms.common.commands.sender.SenderFactory;
import me.lucko.luckperms.common.constants.Constants;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
+import net.kyori.text.Component;
+import net.kyori.text.serializer.ComponentSerializer;
+
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.text.serializer.TextSerializers;
-import io.github.mkremins.fanciful.FancyMessage;
-
import java.util.UUID;
public class SpongeSenderFactory extends SenderFactory {
@@ -65,11 +66,11 @@ public class SpongeSenderFactory extends SenderFactory {
}
@Override
- protected void sendMessage(CommandSource source, FancyMessage message) {
+ protected void sendMessage(CommandSource source, Component message) {
try {
- source.sendMessage(TextSerializers.JSON.deserialize(message.exportToJson()));
+ source.sendMessage(TextSerializers.JSON.deserialize(ComponentSerializer.serialize(message)));
} catch (Exception e) {
- sendMessage(source, message.toOldMessageFormat());
+ sendMessage(source, ComponentSerializer.toLegacy(message, Constants.COLOR_CHAR));
}
}