Pull into dev for pushing upstream
This PR pretty much just adds more support for using formatted chat without ChatColor.RED concatenation hell. This is provided in places where brigadier accepts the Message type, which is tooltips and WrapperCommandSyntaxException. Some utility methods for working with tooltips on safe suggestions are also provided (see below).
Method overrides using strings are still provided for convenience.
Methods provided in Tooltip.java
//Methods for creating a tooltip (the same also exist in StringTooltip)
public static <S> Tooltip<S> of(S object, String tooltip) {
return of(object, toMessage(tooltip));
}
public static <S> Tooltip<S> of(S object, Message tooltip) {
return new Tooltip<S>(object, tooltip);
}
public static <S> Tooltip<S> of(S object, BaseComponent... tooltip) {
return of(object, toMessage(tooltip));
}
//Methods for creating messages from strings or bungee chat components
public static Message toMessage(String string) {
return new LiteralMessage(string);
}
public static Message toMessage(BaseComponent... components) {
return CommandAPIHandler.getInstance().getNMS().componentsToMessage(components);
}
The advantage of using this brigadier Message type is that the adventure chat api components implement Message directly so no conversion is necessary.
An NMS method called componentsToMessage is also provided which will convert bungee BaseComponent[] chat components into a native nms component which also implements Message. Although the bungee chat api seems to be deprecated so supporting it might be necessary...
In addition to this, methods for generating tooltips using a mapping function are provided. This is mainly aimed at SafeSuggestions where it may be useful to programatically generate the tooltips. I would still argue that implementing IStringTooltip is preferable if possible as It follows OOP, but this is not possible for builtin types.
more methods provided in Tooltip.java
@SafeVarargs
public static <S> Tooltip<S>[] generateStrings(Function<S, String> tooltipGenerator, S... suggestions) {
return generate(tooltipGenerator, Tooltip::of, suggestions);
}
@SafeVarargs
public static <S> Tooltip<S>[] generateMessages(Function<S, Message> tooltipGenerator, S... suggestions) {
return generate(tooltipGenerator, Tooltip::of, suggestions);
}
@SafeVarargs
public static <S> Tooltip<S>[] generateComponents(Function<S, BaseComponent[]> tooltipGenerator, S... suggestions) {
return generate(tooltipGenerator, Tooltip::of, suggestions);
}
//Base method for the above 3 methods
@SafeVarargs
private static <S, T> Tooltip<S>[] generate(Function<S, T> tooltipGenerator, BiFunction<S, T, Tooltip<S>> tooltipWrapper, S... suggestions) {
Tooltip<?>[] tooltips = new Tooltip<?>[suggestions.length];
for(int i = 0; i < suggestions.length; i++) {
S suggestion = suggestions[i];
tooltips[i] = tooltipWrapper.apply(suggestion, tooltipGenerator.apply(suggestion));
}
return (Tooltip<S>[]) tooltips;
}
The same 3 methods have been provided in StringTooltip.java for parity, but this is probably less useful than generic suggestions.
In short this PR aims to expand the control over tooltips and how they're formatted, while also providing better ways to work with them.
This is a relatively large PR and plan to release 8.5.1 soon (due on Friday 12th at the latest). As such, I won't be able to get round to this for 8.5.1's release, but I'll certainly have a look in more detail for a 8.5.2 (or even a 8.6.0 if this PR is deemed large enough) release.
I've updated the PR with the latest changes (8.5.1's release). I've begun drafting a review of this PR and will get back to you when I'm done. For all intents and purposes, the next version of the CommandAPI will be 8.6.0.
The advantage of using this brigadier Message type is that the adventure chat api components implement Message directly so no conversion is necessary.
I might be missing something, but can you prove this for me? I've not been able to confirm that Adventure's components implement Message when using the following test code:
StringTooltip.ofMessage("text", Component.text("hello"));
The advantage of using this brigadier Message type is that the adventure chat api components implement Message directly so no conversion is necessary.
I might be missing something, but can you prove this for me? I've not been able to confirm that Adventure's components implement Message when using the following test code:
StringTooltip.ofMessage("text", Component.text("hello"));
Apologies I was incorrect in stating this. I'm not sure how I got this into my head.
I've provided proper implementation for this in commit 4eb0e45
Looks very promising. I should be able to have a test of this PR this time tomorrow or the day after and hopefully we can get this merged over!
I've addressed all of the changes requested. I hope this is what was wanted.
The BaseComponent API is deprecated according to the sources downloaded in IntelliJ.
/**
* @deprecated BungeeCord Chat API has been deprecated in favor of Adventure API. For help with migrating your code, see <a href="https://docs.adventure.kyori.net/migration/bungeecord-chat-api.html">https://docs.adventure.kyori.net/migration/bungeecord-chat-api.html</a>
*/
Is it actually worth adding new support for an API which is already deprecated? Code-wise both bungee's BaseComponent and adventure's Component are serialised into JSON which is then turned into native components using NMS#generateMessageFromJson(String json) so the only real overhead from supporting BaseComponent is the additional method overloads.
The BaseComponent API is deprecated according to the sources downloaded in IntelliJ.
The BaseComponent API is deprecated according to Paper, which makes sense because paper has the Adventure API. For non-paper servers (i.e. plain old Spigot), the BaseComponent API is the only thing they have and in the Spigot API, it is not deprecated. It is imperative that we add support for the BaseComponent API because the CommandAPI is a Spigot plugin that is distributed on the Spigot website - if there were some sort of Paper-specific plugin distribution platform, then it wouldn't be necessary.
I've tested everything and everything's looking fantastic. There's just the one last point about BukkitComponentSerializer which should be GsonComponentSerializer and once that's completed we're good to merge!
I've tested everything and everything's looking fantastic. There's just the one last point about
BukkitComponentSerializerwhich should beGsonComponentSerializerand once that's completed we're good to merge!
Done in 5ed2de3
@469512345 This feature has already surpassed my expectations and has made a number of developers in my community happy, thanks very much for this PR! ❤️
Myself included. Happy to contribute as always