Compare commits
36 Commits
Author | SHA1 | Date | |
---|---|---|---|
34809d4618 | |||
843d9c3509 | |||
1716e0b5a8 | |||
254b885648 | |||
e2c0098eb9 | |||
2fc3eb50f5 | |||
fc44151f2b | |||
f8a7c5f1e7 | |||
a9ea8c3038 | |||
e611d06987 | |||
638e57bb7f | |||
0009dd22cd | |||
79474b14d2 | |||
ee4812bdbb | |||
7d2a5e7862 | |||
c09362c75e | |||
457262049d | |||
ebbbc3a1f0 | |||
8c0db895da | |||
5943b10d16 | |||
cda7ebadcc | |||
dbdf1eeb7c | |||
500163d8f4 | |||
9374f8d280 | |||
f5194334de | |||
21777d4b9e | |||
3b4cf63c48 | |||
e2b2ab466d | |||
50e21896ba | |||
07af67b33f | |||
f4d0ccca51 | |||
51bc0bd6e8 | |||
c229b14779 | |||
49942b35da | |||
0ffe3198e6 | |||
ace34fc0e8 |
@@ -9,11 +9,11 @@ that are detailed in their respective Readme file (if any).
|
||||
- `pandalib-util` General purpose utility and helper classes;
|
||||
- `pandalib-chat` A chat API working on top of the Adventure API;
|
||||
- `pandalib-db` An ORM working with a MySQL server through JDBC;
|
||||
- `pandalib-bungee` Utility and helper classes to use in Bungeecord plugins. Also provides platform implementation for `pandalib-players` and `pandalib-commands`;
|
||||
- `pandalib-bungee` Utility and helper classes to use in BungeeCord plugins. Also provides platform implementation for `pandalib-players` and `pandalib-commands`;
|
||||
- `pandalib-paper` Utility and helper classes to use in Spigot/Paper plugins. Also provides platform implementation for `pandalib-players` and `pandalib-commands`;
|
||||
- `pandalib-reflect` A reflection wrapper to make reflective operation easier;
|
||||
- `pandalib-permissions` A general purpose permission system;
|
||||
- `pandalib-bungee-permissions` Integration of the permission system `pandalib-permissions` into Bungeecord;
|
||||
- `pandalib-bungee-permissions` Integration of the permission system `pandalib-permissions` into BungeeCord;
|
||||
- `pandalib-paper-permissions` Integration of the permission system `pandalib-permissions` into Bukkit, Vault and WEPIF permission systems;
|
||||
- `pandalib-players` A library to handle classes representing online or offline players;
|
||||
- `pandalib-players-permissible` An extension of `pandalib-players` with support for the permission system `pandalib-permissions`;
|
||||
|
@@ -21,11 +21,6 @@
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>fr.pandacube.lib</groupId>
|
||||
<artifactId>pandalib-util</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>fr.pandacube.lib</groupId>
|
||||
<artifactId>pandalib-chat</artifactId>
|
||||
|
@@ -1,7 +1,7 @@
|
||||
package fr.pandacube.lib.bungee.chat;
|
||||
|
||||
import fr.pandacube.lib.chat.Chat;
|
||||
import fr.pandacube.lib.chat.Chat.FormatableChat;
|
||||
import fr.pandacube.lib.chat.Chat.FormattableChat;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.ComponentLike;
|
||||
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
|
||||
@@ -15,22 +15,22 @@ public class ChatBungee {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} from the provided Bungee {@link BaseComponent}.
|
||||
* Creates a {@link FormattableChat} from the provided Bungee {@link BaseComponent}.
|
||||
* @param c the {@link BaseComponent}.
|
||||
* @return a new {@link FormatableChat}.
|
||||
* @return a new {@link FormattableChat}.
|
||||
*/
|
||||
public static FormatableChat chatComponent(BaseComponent c) {
|
||||
public static FormattableChat chatComponent(BaseComponent c) {
|
||||
return Chat.chatComponent(toAdventure(c));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} from the provided Bungee {@link BaseComponent BaseComponent[]}.
|
||||
* Creates a {@link FormattableChat} from the provided Bungee {@link BaseComponent BaseComponent[]}.
|
||||
* @param c the array of {@link BaseComponent}.
|
||||
* @return a new {@link FormatableChat}.
|
||||
* @return a new {@link FormattableChat}.
|
||||
*/
|
||||
public static FormatableChat chatComponent(BaseComponent[] c) {
|
||||
public static FormattableChat chatComponent(BaseComponent[] c) {
|
||||
return Chat.chatComponent(toAdventure(c));
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
package fr.pandacube.lib.bungee;
|
||||
|
||||
import fr.pandacube.lib.bungee.util.BungeeDailyLogRotateFileHandler;
|
||||
import fr.pandacube.lib.bungee.util.PluginMessagePassthrough;
|
||||
import fr.pandacube.lib.bungee.util.PluginMessagePassThrough;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
/**
|
||||
@@ -24,7 +24,7 @@ public class PandaLibBungee {
|
||||
* Method to be called in {@link Plugin#onEnable()} method.
|
||||
*/
|
||||
public static void onEnable() {
|
||||
PluginMessagePassthrough.init(plugin);
|
||||
PluginMessagePassThrough.init(plugin);
|
||||
BungeeDailyLogRotateFileHandler.init(true);
|
||||
}
|
||||
|
||||
|
@@ -7,7 +7,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Class that holds the configuration varables for {@link BungeeBackupManager}.
|
||||
* Class that holds the configuration variables for {@link BungeeBackupManager}.
|
||||
*/
|
||||
@SuppressWarnings("CanBeFinal")
|
||||
public class BungeeBackupConfig {
|
||||
|
@@ -7,14 +7,14 @@ import fr.pandacube.lib.core.backup.RotatedLogsBackupProcess;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Handles the backup processes for a Bungeecord instance.
|
||||
* Handles the backup processes for a BungeeCord instance.
|
||||
*/
|
||||
public class BungeeBackupManager extends BackupManager {
|
||||
|
||||
BungeeBackupConfig config;
|
||||
|
||||
/**
|
||||
* Instanciate a new {@link BungeeBackupManager}.
|
||||
* Creates a new {@link BungeeBackupManager}.
|
||||
* @param config the configuration.
|
||||
*/
|
||||
public BungeeBackupManager(BungeeBackupConfig config) {
|
||||
|
@@ -6,7 +6,7 @@ import java.io.File;
|
||||
import java.util.function.BiPredicate;
|
||||
|
||||
/**
|
||||
* The backup process responsible for the working directory of the current Bungeecord instance.
|
||||
* The backup process responsible for the working directory of the current BungeeCord instance.
|
||||
*/
|
||||
public class BungeeWorkdirProcess extends BackupProcess {
|
||||
|
||||
|
@@ -6,7 +6,7 @@ import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import fr.pandacube.lib.players.standalone.AbstractOffPlayer;
|
||||
|
||||
/**
|
||||
* Represents any player on a Bungeecord proxy, either offline or online.
|
||||
* Represents any player on a BungeeCord proxy, either offline or online.
|
||||
*/
|
||||
public interface BungeeOffPlayer extends AbstractOffPlayer {
|
||||
|
||||
|
@@ -20,7 +20,7 @@ import net.md_5.bungee.protocol.packet.PluginMessage;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Represents any online player on a Bungeecord proxy.
|
||||
* Represents any online player on a BungeeCord proxy.
|
||||
*/
|
||||
public interface BungeeOnlinePlayer extends BungeeOffPlayer, AbstractOnlinePlayer {
|
||||
|
||||
|
@@ -19,16 +19,16 @@ import net.md_5.bungee.event.EventHandler;
|
||||
* <p>
|
||||
* Usage example, in your plugin init code:
|
||||
* <pre>{@code
|
||||
* PluginMessagePassthrough.init(yourPluginInstance);
|
||||
* PluginMessagePassthrough.register("worldedit:cui"); // plugin message used by WorldEdit
|
||||
* PluginMessagePassThrough.init(yourPluginInstance);
|
||||
* PluginMessagePassThrough.register("worldedit:cui"); // plugin message used by WorldEdit
|
||||
* }</pre>
|
||||
*/
|
||||
public class PluginMessagePassthrough implements Listener {
|
||||
public class PluginMessagePassThrough implements Listener {
|
||||
private static final List<String> channels = Collections.synchronizedList(new ArrayList<>());
|
||||
private static final PluginMessagePassthrough instance = new PluginMessagePassthrough();
|
||||
private static final PluginMessagePassThrough instance = new PluginMessagePassThrough();
|
||||
|
||||
/**
|
||||
* Initialize the {@link PluginMessagePassthrough}.
|
||||
* Initialize the {@link PluginMessagePassThrough}.
|
||||
* It registers the required event listener.
|
||||
* @param plugin the plugin instance.
|
||||
*/
|
||||
@@ -92,7 +92,7 @@ public class PluginMessagePassthrough implements Listener {
|
||||
}
|
||||
|
||||
|
||||
private PluginMessagePassthrough() { }
|
||||
private PluginMessagePassThrough() { }
|
||||
|
||||
|
||||
/**
|
@@ -54,7 +54,7 @@
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.10.1</version>
|
||||
<version>${gson.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
@@ -35,8 +35,8 @@ import java.util.function.UnaryOperator;
|
||||
* This class implements {@link ComponentLike} and {@link HoverEventSource} so they can be used directly in
|
||||
* Adventure API and its implementation without using the final methods of this builder.
|
||||
* <p>
|
||||
* The unique possible concrete subclass of this class, {@link FormatableChat}, takes care of the formatting of the
|
||||
* built component. The rationale for this design is explained in the documentation of {@link FormatableChat}.
|
||||
* The unique possible concrete subclass of this class, {@link FormattableChat}, takes care of the formatting of the
|
||||
* built component. The rationale for this design is explained in the documentation of {@link FormattableChat}.
|
||||
*/
|
||||
public abstract sealed class Chat extends ChatStatic implements HoverEventSource<Component>, ComponentLike {
|
||||
|
||||
@@ -296,7 +296,7 @@ public abstract sealed class Chat extends ChatStatic implements HoverEventSource
|
||||
* @param key the keybinding to display.
|
||||
* @return this.
|
||||
*/
|
||||
public Chat thenKeyBind(String key) { return then(keybind(key)); }
|
||||
public Chat thenKeyBind(String key) { return then(keyBind(key)); }
|
||||
|
||||
/**
|
||||
* Appends a component with the provided score name and objective.
|
||||
@@ -454,7 +454,7 @@ public abstract sealed class Chat extends ChatStatic implements HoverEventSource
|
||||
* Appends a component filling a chat line with the configured decoration character and
|
||||
* color and a left-aligned text.
|
||||
* @param leftText the text aligned to the left.
|
||||
* @return a new {@link FormatableChat} filling a chat line with the configured decoration character
|
||||
* @return a new {@link FormattableChat} filling a chat line with the configured decoration character
|
||||
* and color and a left-aligned text.
|
||||
*/
|
||||
public Chat thenLeftText(ComponentLike leftText) { return then(leftText(leftText, console)); }
|
||||
@@ -463,7 +463,7 @@ public abstract sealed class Chat extends ChatStatic implements HoverEventSource
|
||||
* Appends a component filling a chat line with the configured decoration character and
|
||||
* color and a right-aligned text.
|
||||
* @param rightText the text aligned to the right.
|
||||
* @return a new {@link FormatableChat} filling a chat line with the configured decoration character
|
||||
* @return a new {@link FormattableChat} filling a chat line with the configured decoration character
|
||||
* and color and a right-aligned text.
|
||||
*/
|
||||
public Chat thenRightText(ComponentLike rightText) { return then(rightText(rightText, console)); }
|
||||
@@ -472,7 +472,7 @@ public abstract sealed class Chat extends ChatStatic implements HoverEventSource
|
||||
* Appends a component filling a chat line with the configured decoration character and
|
||||
* color and a centered text.
|
||||
* @param centerText the text aligned to the center.
|
||||
* @return a new {@link FormatableChat} filling a chat line with the configured decoration character
|
||||
* @return a new {@link FormattableChat} filling a chat line with the configured decoration character
|
||||
* and color and a centered text.
|
||||
*/
|
||||
public Chat thenCenterText(ComponentLike centerText) {
|
||||
@@ -481,7 +481,7 @@ public abstract sealed class Chat extends ChatStatic implements HoverEventSource
|
||||
|
||||
/**
|
||||
* Appends a component filling a chat line with the configured decoration character and color.
|
||||
* @return a new {@link FormatableChat} filling a chat line with a decoration character and color.
|
||||
* @return a new {@link FormattableChat} filling a chat line with a decoration character and color.
|
||||
*/
|
||||
public Chat thenFilledLine() { return then(filledLine(console)); }
|
||||
|
||||
@@ -520,10 +520,10 @@ public abstract sealed class Chat extends ChatStatic implements HoverEventSource
|
||||
* .thenText("!"); // short for .then(Chat.text("!"))
|
||||
* // the red color for "!" is not needed because the parent component is already red.
|
||||
* }</pre>
|
||||
* When calling {@link #then(Component) #then(...)} on a {@link FormatableChat}, the method returns itself, cast
|
||||
* When calling {@link #then(Component) #then(...)} on a {@link FormattableChat}, the method returns itself, cast
|
||||
* to {@link Chat}, to prevent future formatting (that the programmer would think it formats the previously appended
|
||||
* subcomponent). If the formatting of the currently built component is needed, since {@link Chat} is a sealed
|
||||
* class which only subclass is {@link FormatableChat}, you can cast the builder, and use the format methods again.
|
||||
* class which only subclass is {@link FormattableChat}, you can cast the builder, and use the format methods again.
|
||||
* <pre>{@code
|
||||
* Chat component = Chat.text("Hello ").red()
|
||||
* .then(Chat.text("world").darkRed().bold())
|
||||
@@ -532,8 +532,8 @@ public abstract sealed class Chat extends ChatStatic implements HoverEventSource
|
||||
* ((FormatableChat)component).underlined(); // this will not format only the last appended text.
|
||||
* }</pre>
|
||||
*/
|
||||
public static final class FormatableChat extends Chat {
|
||||
/* package */ FormatableChat(ComponentBuilder<?, ?> c) {
|
||||
public static final class FormattableChat extends Chat {
|
||||
/* package */ FormattableChat(ComponentBuilder<?, ?> c) {
|
||||
super(c);
|
||||
}
|
||||
|
||||
@@ -543,33 +543,33 @@ public abstract sealed class Chat extends ChatStatic implements HoverEventSource
|
||||
* @param c true for console, false for game UI.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat console(boolean c) { console = c; return this; }
|
||||
public FormattableChat console(boolean c) { console = c; return this; }
|
||||
/**
|
||||
* Configure the width of the line.
|
||||
* @param w the width to consider when rendering the line. In pixel for game UI rendering, n character for
|
||||
* console rendering.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat maxWidth(int w) { maxWidth = w; return this; }
|
||||
public FormattableChat maxWidth(int w) { maxWidth = w; return this; }
|
||||
|
||||
/**
|
||||
* Sets the color of this component.
|
||||
* @param c the color.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat color(TextColor c) { builder.color(c); return this; }
|
||||
public FormattableChat color(TextColor c) { builder.color(c); return this; }
|
||||
/**
|
||||
* Sets the color of this component.
|
||||
* @param c the color.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat color(Color c) { return color(c == null ? null : TextColor.color(c.getRGB())); }
|
||||
public FormattableChat color(Color c) { return color(c == null ? null : TextColor.color(c.getRGB())); }
|
||||
/**
|
||||
* Sets the color of this component.
|
||||
* @param c the color.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat color(String c) {
|
||||
public FormattableChat color(String c) {
|
||||
if (c == null)
|
||||
return color((TextColor) null);
|
||||
TextColor tc = c.startsWith("#")
|
||||
@@ -585,138 +585,138 @@ public abstract sealed class Chat extends ChatStatic implements HoverEventSource
|
||||
* Sets the color of this component to {@link NamedTextColor#BLACK}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat black() { return color(NamedTextColor.BLACK); }
|
||||
public FormattableChat black() { return color(NamedTextColor.BLACK); }
|
||||
/**
|
||||
* Sets the color of this component to {@link NamedTextColor#DARK_BLUE}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat darkBlue() { return color(NamedTextColor.DARK_BLUE); }
|
||||
public FormattableChat darkBlue() { return color(NamedTextColor.DARK_BLUE); }
|
||||
/**
|
||||
* Sets the color of this component to {@link NamedTextColor#DARK_GREEN}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat darkGreen() { return color(NamedTextColor.DARK_GREEN); }
|
||||
public FormattableChat darkGreen() { return color(NamedTextColor.DARK_GREEN); }
|
||||
/**
|
||||
* Sets the color of this component to {@link NamedTextColor#DARK_AQUA}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat darkAqua() { return color(NamedTextColor.DARK_AQUA); }
|
||||
public FormattableChat darkAqua() { return color(NamedTextColor.DARK_AQUA); }
|
||||
/**
|
||||
* Sets the color of this component to {@link NamedTextColor#DARK_RED}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat darkRed() { return color(NamedTextColor.DARK_RED); }
|
||||
public FormattableChat darkRed() { return color(NamedTextColor.DARK_RED); }
|
||||
/**
|
||||
* Sets the color of this component to {@link NamedTextColor#DARK_PURPLE}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat darkPurple() { return color(NamedTextColor.DARK_PURPLE); }
|
||||
public FormattableChat darkPurple() { return color(NamedTextColor.DARK_PURPLE); }
|
||||
/**
|
||||
* Sets the color of this component to {@link NamedTextColor#GOLD}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat gold() { return color(NamedTextColor.GOLD); }
|
||||
public FormattableChat gold() { return color(NamedTextColor.GOLD); }
|
||||
/**
|
||||
* Sets the color of this component to {@link NamedTextColor#GRAY}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat gray() { return color(NamedTextColor.GRAY); }
|
||||
public FormattableChat gray() { return color(NamedTextColor.GRAY); }
|
||||
/**
|
||||
* Sets the color of this component to {@link NamedTextColor#DARK_GRAY}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat darkGray() { return color(NamedTextColor.DARK_GRAY); }
|
||||
public FormattableChat darkGray() { return color(NamedTextColor.DARK_GRAY); }
|
||||
/**
|
||||
* Sets the color of this component to {@link NamedTextColor#BLUE}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat blue() { return color(NamedTextColor.BLUE); }
|
||||
public FormattableChat blue() { return color(NamedTextColor.BLUE); }
|
||||
/**
|
||||
* Sets the color of this component to {@link NamedTextColor#GREEN}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat green() { return color(NamedTextColor.GREEN); }
|
||||
public FormattableChat green() { return color(NamedTextColor.GREEN); }
|
||||
/**
|
||||
* Sets the color of this component to {@link NamedTextColor#AQUA}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat aqua() { return color(NamedTextColor.AQUA); }
|
||||
public FormattableChat aqua() { return color(NamedTextColor.AQUA); }
|
||||
/**
|
||||
* Sets the color of this component to {@link NamedTextColor#RED}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat red() { return color(NamedTextColor.RED); }
|
||||
public FormattableChat red() { return color(NamedTextColor.RED); }
|
||||
/**
|
||||
* Sets the color of this component to {@link NamedTextColor#LIGHT_PURPLE}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat lightPurple() { return color(NamedTextColor.LIGHT_PURPLE); }
|
||||
public FormattableChat lightPurple() { return color(NamedTextColor.LIGHT_PURPLE); }
|
||||
/**
|
||||
* Sets the color of this component to {@link NamedTextColor#YELLOW}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat yellow() { return color(NamedTextColor.YELLOW); }
|
||||
public FormattableChat yellow() { return color(NamedTextColor.YELLOW); }
|
||||
/**
|
||||
* Sets the color of this component to {@link NamedTextColor#WHITE}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat white() { return color(NamedTextColor.WHITE); }
|
||||
public FormattableChat white() { return color(NamedTextColor.WHITE); }
|
||||
|
||||
|
||||
/**
|
||||
* Sets the color of this component to {@link ChatConfig#successColor}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat successColor() { return color(ChatConfig.successColor); }
|
||||
public FormattableChat successColor() { return color(ChatConfig.successColor); }
|
||||
/**
|
||||
* Sets the color of this component to {@link ChatConfig#failureColor}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat failureColor() { return color(ChatConfig.failureColor); }
|
||||
public FormattableChat failureColor() { return color(ChatConfig.failureColor); }
|
||||
/**
|
||||
* Sets the color of this component to {@link ChatConfig#infoColor}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat infoColor() { return color(ChatConfig.infoColor); }
|
||||
public FormattableChat infoColor() { return color(ChatConfig.infoColor); }
|
||||
/**
|
||||
* Sets the color of this component to {@link ChatConfig#warningColor}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat warningColor() { return color(ChatConfig.warningColor); }
|
||||
public FormattableChat warningColor() { return color(ChatConfig.warningColor); }
|
||||
/**
|
||||
* Sets the color of this component to {@link ChatConfig#dataColor}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat dataColor() { return color(ChatConfig.dataColor); }
|
||||
public FormattableChat dataColor() { return color(ChatConfig.dataColor); }
|
||||
/**
|
||||
* Sets the color of this component to {@link ChatConfig#decorationColor}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat decorationColor() { return color(ChatConfig.decorationColor); }
|
||||
public FormattableChat decorationColor() { return color(ChatConfig.decorationColor); }
|
||||
/**
|
||||
* Sets the color of this component to {@link ChatConfig#urlColor}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat urlColor() { return color(ChatConfig.urlColor); }
|
||||
public FormattableChat urlColor() { return color(ChatConfig.urlColor); }
|
||||
/**
|
||||
* Sets the color of this component to {@link ChatConfig#commandColor}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat commandColor() { return color(ChatConfig.commandColor); }
|
||||
public FormattableChat commandColor() { return color(ChatConfig.commandColor); }
|
||||
/**
|
||||
* Sets the color of this component to {@link ChatConfig#highlightedCommandColor}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat highlightedCommandColor() { return color(ChatConfig.highlightedCommandColor); }
|
||||
public FormattableChat highlightedCommandColor() { return color(ChatConfig.highlightedCommandColor); }
|
||||
/**
|
||||
* Sets the color of this component to {@link ChatConfig#broadcastColor}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat broadcastColor() { return color(ChatConfig.broadcastColor); }
|
||||
public FormattableChat broadcastColor() { return color(ChatConfig.broadcastColor); }
|
||||
|
||||
|
||||
private FormatableChat setStyle(Consumer<Style.Builder> styleOp) { builder.style(styleOp); return this; }
|
||||
private FormatableChat setDecoration(TextDecoration deco, Boolean state) {
|
||||
private FormattableChat setStyle(Consumer<Style.Builder> styleOp) { builder.style(styleOp); return this; }
|
||||
private FormattableChat setDecoration(TextDecoration deco, Boolean state) {
|
||||
return setStyle(b -> b.decoration(deco, State.byBoolean(state)));
|
||||
}
|
||||
|
||||
@@ -726,56 +726,56 @@ public abstract sealed class Chat extends ChatStatic implements HoverEventSource
|
||||
* @param b true to enable, false to disable, or null to inherit from parent.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat bold(Boolean b) { return setDecoration(TextDecoration.BOLD, b); }
|
||||
public FormattableChat bold(Boolean b) { return setDecoration(TextDecoration.BOLD, b); }
|
||||
/**
|
||||
* Enables the bold status of this component.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat bold() { return bold(true); }
|
||||
public FormattableChat bold() { return bold(true); }
|
||||
/**
|
||||
* Sets the italic status of this component.
|
||||
* @param i true to enable, false to disable, or null to inherit from parent.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat italic(Boolean i) { return setDecoration(TextDecoration.ITALIC, i); }
|
||||
public FormattableChat italic(Boolean i) { return setDecoration(TextDecoration.ITALIC, i); }
|
||||
/**
|
||||
* Enables the italic status of this component.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat italic() { return italic(true); }
|
||||
public FormattableChat italic() { return italic(true); }
|
||||
/**
|
||||
* Sets the underlined status of this component.
|
||||
* @param u true to enable, false to disable, or null to inherit from parent.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat underlined(Boolean u) { return setDecoration(TextDecoration.UNDERLINED, u); }
|
||||
public FormattableChat underlined(Boolean u) { return setDecoration(TextDecoration.UNDERLINED, u); }
|
||||
/**
|
||||
* Enables the underlined status of this component.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat underlined() { return underlined(true); }
|
||||
public FormattableChat underlined() { return underlined(true); }
|
||||
/**
|
||||
* Sets the strikethrough status of this component.
|
||||
* @param s true to enable, false to disable, or null to inherit from parent.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat strikethrough(Boolean s) { return setDecoration(TextDecoration.STRIKETHROUGH, s); }
|
||||
public FormattableChat strikethrough(Boolean s) { return setDecoration(TextDecoration.STRIKETHROUGH, s); }
|
||||
/**
|
||||
* Enables the strikethrough status of this component.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat strikethrough() { return strikethrough(true); }
|
||||
public FormattableChat strikethrough() { return strikethrough(true); }
|
||||
/**
|
||||
* Sets the obfuscated status of this component.
|
||||
* @param o true to enable, false to disable, or null to inherit from parent.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat obfuscated(Boolean o) { return setDecoration(TextDecoration.OBFUSCATED, o); }
|
||||
public FormattableChat obfuscated(Boolean o) { return setDecoration(TextDecoration.OBFUSCATED, o); }
|
||||
/**
|
||||
* Enables the obfuscated status of this component.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat obfuscated() { return obfuscated(true); }
|
||||
public FormattableChat obfuscated() { return obfuscated(true); }
|
||||
|
||||
|
||||
/**
|
||||
@@ -783,7 +783,7 @@ public abstract sealed class Chat extends ChatStatic implements HoverEventSource
|
||||
* @param f the font namespaced key.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat font(Key f) { return setStyle(s -> s.font(f)); }
|
||||
public FormattableChat font(Key f) { return setStyle(s -> s.font(f)); }
|
||||
|
||||
|
||||
/**
|
||||
@@ -791,7 +791,7 @@ public abstract sealed class Chat extends ChatStatic implements HoverEventSource
|
||||
* @param i the text to insert.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat shiftClickInsertion(String i) { builder.insertion(i); return this; }
|
||||
public FormattableChat shiftClickInsertion(String i) { builder.insertion(i); return this; }
|
||||
|
||||
|
||||
/**
|
||||
@@ -799,37 +799,37 @@ public abstract sealed class Chat extends ChatStatic implements HoverEventSource
|
||||
* @param e the {@link ClickEvent}.
|
||||
* @return this.
|
||||
*/
|
||||
private FormatableChat click(ClickEvent e) { builder.clickEvent(e); return this; }
|
||||
private FormattableChat click(ClickEvent e) { builder.clickEvent(e); return this; }
|
||||
/**
|
||||
* Configure this component to execute the specified command when clicked.
|
||||
* @param cmdWithSlash the command to execute.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat clickCommand(String cmdWithSlash) { return click(ClickEvent.runCommand(cmdWithSlash)); }
|
||||
public FormattableChat clickCommand(String cmdWithSlash) { return click(ClickEvent.runCommand(cmdWithSlash)); }
|
||||
/**
|
||||
* Configure this component to insert in the chat-box the specified command when clicked.
|
||||
* @param cmdWithSlash the command to suggest.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat clickSuggest(String cmdWithSlash) { return click(ClickEvent.suggestCommand(cmdWithSlash)); }
|
||||
public FormattableChat clickSuggest(String cmdWithSlash) { return click(ClickEvent.suggestCommand(cmdWithSlash)); }
|
||||
/**
|
||||
* Configure this component to copy into clipboard the specified text when clicked.
|
||||
* @param value the text to copy.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat clickClipboard(String value) { return click(ClickEvent.copyToClipboard(value)); }
|
||||
public FormattableChat clickClipboard(String value) { return click(ClickEvent.copyToClipboard(value)); }
|
||||
/**
|
||||
* Configure this component to open the specified URL when clicked.
|
||||
* @param url the URL to open.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat clickURL(String url) { return click(ClickEvent.openUrl(url)); }
|
||||
public FormattableChat clickURL(String url) { return click(ClickEvent.openUrl(url)); }
|
||||
/**
|
||||
* Configure this component to change the page of the opened book when clicked.
|
||||
* @param page the page to go to.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat clickBookPage(int page) { return click(ClickEvent.changePage(page)); }
|
||||
public FormattableChat clickBookPage(int page) { return click(ClickEvent.changePage(page)); }
|
||||
|
||||
|
||||
/**
|
||||
@@ -837,31 +837,31 @@ public abstract sealed class Chat extends ChatStatic implements HoverEventSource
|
||||
* @param e the {@link HoverEventSource}.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat hover(HoverEventSource<?> e) { builder.hoverEvent(e); return this; }
|
||||
public FormattableChat hover(HoverEventSource<?> e) { builder.hoverEvent(e); return this; }
|
||||
/**
|
||||
* Configure this component to show the provided component when hovered.
|
||||
* @param v the component to show.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat hover(Component v) { return hover((HoverEventSource<Component>) v); }
|
||||
public FormattableChat hover(Component v) { return hover((HoverEventSource<Component>) v); }
|
||||
/**
|
||||
* Configure this component to show the provided component when hovered.
|
||||
* @param v the component to show.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat hover(Chat v) { return hover((HoverEventSource<Component>) v); }
|
||||
public FormattableChat hover(Chat v) { return hover((HoverEventSource<Component>) v); }
|
||||
/**
|
||||
* Configure this component to show the provided component when hovered.
|
||||
* @param v the component to show.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat hover(ComponentLike v) { return hover(v.asComponent()); }
|
||||
public FormattableChat hover(ComponentLike v) { return hover(v.asComponent()); }
|
||||
/**
|
||||
* Configure this component to show the provided legacy text when hovered.
|
||||
* @param legacyText the legacy text to show.
|
||||
* @return this.
|
||||
*/
|
||||
public FormatableChat hover(String legacyText) { return hover(legacyText(legacyText)); }
|
||||
public FormattableChat hover(String legacyText) { return hover(legacyText(legacyText)); }
|
||||
|
||||
}
|
||||
|
||||
@@ -932,14 +932,14 @@ public abstract sealed class Chat extends ChatStatic implements HoverEventSource
|
||||
|
||||
/**
|
||||
* Force the italic formatting to be set to false if it is not explicitly set in the component.
|
||||
* This is useful for item lores that defaults to italic in the game UI.
|
||||
* This is useful for item lore that defaults to italic in the game UI.
|
||||
* @param c the {@link Chat} in which to set the italic property if needed.
|
||||
* @return the provided {@link Chat} instance.
|
||||
*/
|
||||
public static Chat italicFalseIfNotSet(Chat c) {
|
||||
c.builder.style(b -> {
|
||||
if (b.build().decoration(TextDecoration.ITALIC) == State.NOT_SET) {
|
||||
((FormatableChat) c).italic(false);
|
||||
((FormattableChat) c).italic(false);
|
||||
}
|
||||
});
|
||||
return c;
|
||||
|
@@ -5,7 +5,7 @@ import net.kyori.adventure.text.ComponentLike;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import fr.pandacube.lib.chat.Chat.FormatableChat;
|
||||
import fr.pandacube.lib.chat.Chat.FormattableChat;
|
||||
|
||||
/**
|
||||
* Builder for a {@link Chat} component for filling a chat line, with decoration and eventual aligned text.
|
||||
@@ -150,10 +150,10 @@ public class ChatFilledLine implements ComponentLike {
|
||||
|
||||
|
||||
/**
|
||||
* Renders this line to a {@link FormatableChat}.
|
||||
* @return a new {@link FormatableChat} built by this {@link ChatFilledLine}.
|
||||
* Renders this line to a {@link FormattableChat}.
|
||||
* @return a new {@link FormattableChat} built by this {@link ChatFilledLine}.
|
||||
*/
|
||||
public FormatableChat toChat() {
|
||||
public FormattableChat toChat() {
|
||||
int maxWidth = (this.maxWidth != null)
|
||||
? this.maxWidth
|
||||
: console ? ChatUtil.CONSOLE_NB_CHAR_DEFAULT : ChatUtil.DEFAULT_CHAT_WIDTH;
|
||||
@@ -170,7 +170,7 @@ public class ChatFilledLine implements ComponentLike {
|
||||
int textWidth = ChatUtil.componentWidth(text.asComponent(), console);
|
||||
|
||||
if (textWidth > maxWidth)
|
||||
return (FormatableChat) text;
|
||||
return (FormattableChat) text;
|
||||
|
||||
int repeatedCharWidth = ChatUtil.charW(decorationChar, console, decorationBold);
|
||||
int nbCharLeft = 0, nbCharRight = 0;
|
||||
@@ -179,12 +179,12 @@ public class ChatFilledLine implements ComponentLike {
|
||||
case CENTER -> {
|
||||
nbCharLeft = nbCharRight = (maxWidth - textWidth) / 2 / repeatedCharWidth;
|
||||
if (nbCharLeft == 0)
|
||||
return (FormatableChat) text;
|
||||
return (FormattableChat) text;
|
||||
}
|
||||
case LEFT, RIGHT -> {
|
||||
int remWidth = textWidth + nbSide * repeatedCharWidth;
|
||||
if (remWidth > maxWidth)
|
||||
return (FormatableChat) text;
|
||||
return (FormattableChat) text;
|
||||
boolean left = alignment == Alignment.LEFT;
|
||||
int nbOtherSide = (maxWidth - remWidth) / repeatedCharWidth;
|
||||
nbCharLeft = left ? nbSide : nbOtherSide;
|
||||
@@ -197,7 +197,7 @@ public class ChatFilledLine implements ComponentLike {
|
||||
.then(text);
|
||||
if (decorationChar != ' ' || spacesDecorationRightSide)
|
||||
d.then(Chat.text(ChatUtil.repeatedChar(decorationChar, nbCharRight)).color(decorationColor).bold(decorationBold));
|
||||
return (FormatableChat) d;
|
||||
return (FormattableChat) d;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
package fr.pandacube.lib.chat;
|
||||
|
||||
import fr.pandacube.lib.chat.Chat.FormatableChat;
|
||||
import fr.pandacube.lib.chat.Chat.FormattableChat;
|
||||
import net.kyori.adventure.text.BlockNBTComponent;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.ComponentBuilder;
|
||||
@@ -27,27 +27,27 @@ public abstract class ChatStatic {
|
||||
|
||||
|
||||
|
||||
private static FormatableChat chatComponent(Component c) {
|
||||
return new FormatableChat(componentToBuilder(c));
|
||||
private static FormattableChat chatComponent(Component c) {
|
||||
return new FormattableChat(componentToBuilder(c));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} from the provided {@link ComponentLike}.
|
||||
* Creates a {@link FormattableChat} from the provided {@link ComponentLike}.
|
||||
* If the provided component is an instance of {@link Chat}, its content will be duplicated, and the provided one
|
||||
* will be untouched.
|
||||
* @param c the {@link ComponentLike}.
|
||||
* @return a new {@link FormatableChat}.
|
||||
* @return a new {@link FormattableChat}.
|
||||
*/
|
||||
public static FormatableChat chatComponent(ComponentLike c) {
|
||||
public static FormattableChat chatComponent(ComponentLike c) {
|
||||
return chatComponent(c.asComponent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} with an empty main text content.
|
||||
* @return a new empty {@link FormatableChat}.
|
||||
* Creates a {@link FormattableChat} with an empty main text content.
|
||||
* @return a new empty {@link FormattableChat}.
|
||||
*/
|
||||
public static FormatableChat chat() {
|
||||
return new FormatableChat(Component.text());
|
||||
public static FormattableChat chat() {
|
||||
return new FormattableChat(Component.text());
|
||||
}
|
||||
|
||||
|
||||
@@ -56,60 +56,60 @@ public abstract class ChatStatic {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} with the provided plain text as its main text content.
|
||||
* Creates a {@link FormattableChat} with the provided plain text as its main text content.
|
||||
* @param plainText the text to use as the content.
|
||||
* @return a new {@link FormatableChat} with the provided text as its main text content.
|
||||
* @return a new {@link FormattableChat} with the provided text as its main text content.
|
||||
* @throws IllegalArgumentException if the {@code plainText} parameter is instance of {@link Chat} or
|
||||
* {@link Component}. The caller should use {@link #chatComponent(ComponentLike)}
|
||||
* instead.
|
||||
*/
|
||||
public static FormatableChat text(Object plainText) {
|
||||
public static FormattableChat text(Object plainText) {
|
||||
if (plainText instanceof ComponentLike) {
|
||||
throw new IllegalArgumentException("Expected any object except instance of " + ComponentLike.class + ". Received " + plainText + ". Please use ChatStatic.chatComponent(ComponentLike) instead.");
|
||||
}
|
||||
return new FormatableChat(Component.text().content(Objects.toString(plainText)));
|
||||
return new FormattableChat(Component.text().content(Objects.toString(plainText)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} with the provided legacy text as its content, using the section {@code "§"}
|
||||
* Creates a {@link FormattableChat} with the provided legacy text as its content, using the section {@code "§"}
|
||||
* character.
|
||||
* @param legacyText the legacy text to use as the content, that uses the {@code "§"} character.
|
||||
* @return a new {@link FormatableChat} with the provided text as its content.
|
||||
* @return a new {@link FormattableChat} with the provided text as its content.
|
||||
* @throws IllegalArgumentException If the {@code legacyText} parameter is instance of {@link Chat} or
|
||||
* {@link Component}. The caller should use {@link #chatComponent(ComponentLike)}
|
||||
* instead.
|
||||
*/
|
||||
public static FormatableChat legacyText(Object legacyText) {
|
||||
public static FormattableChat legacyText(Object legacyText) {
|
||||
return legacyText(legacyText, LegacyComponentSerializer.SECTION_CHAR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} with the provided legacy text as its content, using the ampersand {@code "&"}
|
||||
* Creates a {@link FormattableChat} with the provided legacy text as its content, using the ampersand {@code "&"}
|
||||
* character.
|
||||
* @param legacyText the legacy text to use as the content, that uses the {@code "&"} character.
|
||||
* @return a new {@link FormatableChat} with the provided text as its content.
|
||||
* @return a new {@link FormattableChat} with the provided text as its content.
|
||||
* @throws IllegalArgumentException If the {@code legacyText} parameter is instance of {@link Chat} or
|
||||
* {@link Component}. The caller should use {@link #chatComponent(ComponentLike)}
|
||||
* instead.
|
||||
*/
|
||||
public static FormatableChat legacyAmpersandText(Object legacyText) {
|
||||
public static FormattableChat legacyAmpersandText(Object legacyText) {
|
||||
return legacyText(legacyText, LegacyComponentSerializer.AMPERSAND_CHAR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} with the provided legacy text as its content, using the specified
|
||||
* Creates a {@link FormattableChat} with the provided legacy text as its content, using the specified
|
||||
* legacyCharacter.
|
||||
* @param legacyText the legacy text to use as the content.
|
||||
* @param legacyCharacter the character used in the provided text to prefix color and format code.
|
||||
* @return a new {@link FormatableChat} with the provided text as its content.
|
||||
* @return a new {@link FormattableChat} with the provided text as its content.
|
||||
* @throws IllegalArgumentException If the {@code legacyText} parameter is instance of {@link Chat} or
|
||||
* {@link Component}. The caller should use {@link #chatComponent(ComponentLike)}
|
||||
* instead.
|
||||
*/
|
||||
private static FormatableChat legacyText(Object legacyText, char legacyCharacter) {
|
||||
private static FormattableChat legacyText(Object legacyText, char legacyCharacter) {
|
||||
if (legacyText instanceof ComponentLike) {
|
||||
throw new IllegalArgumentException("Expected any object except instance of " + ComponentLike.class + ". Received " + legacyText + ". Please use ChatStatic.chatComponent(ComponentLike) instead.");
|
||||
}
|
||||
@@ -118,118 +118,118 @@ public abstract class ChatStatic {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} with the provided MiniMessage text as its content.
|
||||
* Creates a {@link FormattableChat} with the provided MiniMessage text as its content.
|
||||
* @param miniMessageText the MiniMessage text to use as the content.
|
||||
* @return a new {@link FormatableChat} with the provided text as its content.
|
||||
* @return a new {@link FormattableChat} with the provided text as its content.
|
||||
*/
|
||||
public static FormatableChat miniMessageText(String miniMessageText) {
|
||||
public static FormattableChat miniMessageText(String miniMessageText) {
|
||||
return chatComponent(MiniMessage.miniMessage().deserialize(miniMessageText));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} with the provided plain text as its main text content, and colored using the
|
||||
* Creates a {@link FormattableChat} with the provided plain text as its main text content, and colored using the
|
||||
* {@link ChatConfig#infoColor configured info color}.
|
||||
* @param plainText the text to use as the content.
|
||||
* @return a new {@link FormatableChat} with the provided text as its main text content, and the configured color.
|
||||
* @return a new {@link FormattableChat} with the provided text as its main text content, and the configured color.
|
||||
* @throws IllegalArgumentException if the {@code plainText} parameter is instance of {@link Chat} or
|
||||
* {@link Component}. The caller should use {@link #chatComponent(ComponentLike)} and
|
||||
* {@link FormatableChat#infoColor()} instead.
|
||||
* {@link FormattableChat#infoColor()} instead.
|
||||
*/
|
||||
public static FormatableChat infoText(Object plainText) {
|
||||
public static FormattableChat infoText(Object plainText) {
|
||||
return text(plainText).infoColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} with the provided plain text as its main text content, and colored using the
|
||||
* Creates a {@link FormattableChat} with the provided plain text as its main text content, and colored using the
|
||||
* {@link ChatConfig#warningColor configured warning color}.
|
||||
* @param plainText the text to use as the content.
|
||||
* @return a new {@link FormatableChat} with the provided text as its main text content, and the configured color.
|
||||
* @return a new {@link FormattableChat} with the provided text as its main text content, and the configured color.
|
||||
* @throws IllegalArgumentException if the {@code plainText} parameter is instance of {@link Chat} or
|
||||
* {@link Component}. The caller should use {@link #chatComponent(ComponentLike)} and
|
||||
* {@link FormatableChat#warningColor()} instead.
|
||||
* {@link FormattableChat#warningColor()} instead.
|
||||
*/
|
||||
public static FormatableChat warningText(Object plainText) {
|
||||
public static FormattableChat warningText(Object plainText) {
|
||||
return text(plainText).warningColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} with the provided plain text as its main text content, and colored using the
|
||||
* Creates a {@link FormattableChat} with the provided plain text as its main text content, and colored using the
|
||||
* {@link ChatConfig#dataColor configured data color}.
|
||||
* @param plainText the text to use as the content.
|
||||
* @return a new {@link FormatableChat} with the provided text as its main text content, and the configured color.
|
||||
* @return a new {@link FormattableChat} with the provided text as its main text content, and the configured color.
|
||||
* @throws IllegalArgumentException if the {@code plainText} parameter is instance of {@link Chat} or
|
||||
* {@link Component}. The caller should use {@link #chatComponent(ComponentLike)} and
|
||||
* {@link FormatableChat#dataColor()} instead.
|
||||
* {@link FormattableChat#dataColor()} instead.
|
||||
*/
|
||||
public static FormatableChat dataText(Object plainText) {
|
||||
public static FormattableChat dataText(Object plainText) {
|
||||
return text(plainText).dataColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} with the provided plain text as its main text content, and colored using the
|
||||
* Creates a {@link FormattableChat} with the provided plain text as its main text content, and colored using the
|
||||
* {@link ChatConfig#decorationColor configured decorationColor color}.
|
||||
* @param plainText the text to use as the content.
|
||||
* @return a new {@link FormatableChat} with the provided text as its main text content, and the configured color.
|
||||
* @return a new {@link FormattableChat} with the provided text as its main text content, and the configured color.
|
||||
* @throws IllegalArgumentException if the {@code plainText} parameter is instance of {@link Chat} or
|
||||
* {@link Component}. The caller should use {@link #chatComponent(ComponentLike)} and
|
||||
* {@link FormatableChat#decorationColor()} instead.
|
||||
* {@link FormattableChat#decorationColor()} instead.
|
||||
*/
|
||||
public static FormatableChat decorationText(Object plainText) {
|
||||
public static FormattableChat decorationText(Object plainText) {
|
||||
return text(plainText).decorationColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} with the provided plain text as its main text content, and colored using the
|
||||
* Creates a {@link FormattableChat} with the provided plain text as its main text content, and colored using the
|
||||
* {@link ChatConfig#successColor configured success color}.
|
||||
* @param plainText the text to use as the content.
|
||||
* @return a new {@link FormatableChat} with the provided text as its main text content, and the configured color.
|
||||
* @return a new {@link FormattableChat} with the provided text as its main text content, and the configured color.
|
||||
* @throws IllegalArgumentException if the {@code plainText} parameter is instance of {@link Chat} or
|
||||
* {@link Component}. The caller should use {@link #chatComponent(ComponentLike)} and
|
||||
* {@link FormatableChat#successColor()} instead.
|
||||
* {@link FormattableChat#successColor()} instead.
|
||||
*/
|
||||
public static FormatableChat successText(Object plainText) {
|
||||
public static FormattableChat successText(Object plainText) {
|
||||
return text(plainText).successColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} with the provided plain text as its main text content, and colored using the
|
||||
* Creates a {@link FormattableChat} with the provided plain text as its main text content, and colored using the
|
||||
* {@link ChatConfig#failureColor configured failure color}.
|
||||
* @param plainText the text to use as the content.
|
||||
* @return a new {@link FormatableChat} with the provided text as its main text content, and the configured color.
|
||||
* @return a new {@link FormattableChat} with the provided text as its main text content, and the configured color.
|
||||
* @throws IllegalArgumentException if the {@code plainText} parameter is instance of {@link Chat} or
|
||||
* {@link Component}. The caller should use {@link #chatComponent(ComponentLike)} and
|
||||
* {@link FormatableChat#failureColor()} instead.
|
||||
* {@link FormattableChat#failureColor()} instead.
|
||||
*/
|
||||
public static FormatableChat failureText(Object plainText) {
|
||||
public static FormattableChat failureText(Object plainText) {
|
||||
return text(plainText).failureColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} with the provided legacy text as its main text content, and colored in white in
|
||||
* Creates a {@link FormattableChat} with the provided legacy text as its main text content, and colored in white in
|
||||
* case there is no color on the generated parent component.
|
||||
* @param legacyText the legacy text to use as the content.
|
||||
* @return a new {@link FormatableChat} with the provided text as its main text content, and the configured color.
|
||||
* @return a new {@link FormattableChat} with the provided text as its main text content, and the configured color.
|
||||
* @throws IllegalArgumentException if the {@code plainText} parameter is instance of {@link Chat} or
|
||||
* {@link Component}. The caller should use {@link #chatComponent(ComponentLike)} and
|
||||
* {@link FormatableChat#failureColor()} instead.
|
||||
* {@link FormattableChat#failureColor()} instead.
|
||||
*/
|
||||
public static FormatableChat playerNameText(String legacyText) {
|
||||
FormatableChat fc = legacyText(legacyText);
|
||||
public static FormattableChat playerNameText(String legacyText) {
|
||||
FormattableChat fc = legacyText(legacyText);
|
||||
fc.builder.colorIfAbsent(NamedTextColor.WHITE);
|
||||
return fc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} from the provided {@link Component}, coloring in white the generated parent
|
||||
* Creates a {@link FormattableChat} from the provided {@link Component}, coloring in white the generated parent
|
||||
* component in case there is no color defined.
|
||||
* If the provided component is an instance of {@link Chat}, its content will be duplicated, and the provided one
|
||||
* will be untouched.
|
||||
* @param c the {@link Component}.
|
||||
* @return a new {@link FormatableChat}.
|
||||
* @return a new {@link FormattableChat}.
|
||||
*/
|
||||
public static FormatableChat playerNameComponent(ComponentLike c) {
|
||||
FormatableChat fc = chatComponent(c);
|
||||
public static FormattableChat playerNameComponent(ComponentLike c) {
|
||||
FormattableChat fc = chatComponent(c);
|
||||
fc.builder.colorIfAbsent(NamedTextColor.WHITE);
|
||||
return fc;
|
||||
}
|
||||
@@ -238,32 +238,32 @@ public abstract class ChatStatic {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} with the provided translation key and parameters.
|
||||
* Creates a {@link FormattableChat} with the provided translation key and parameters.
|
||||
* @param key the translation key.
|
||||
* @param with the translation parameters.
|
||||
* @return a new {@link FormatableChat} with the provided translation key and parameters.
|
||||
* @return a new {@link FormattableChat} with the provided translation key and parameters.
|
||||
*/
|
||||
public static FormatableChat translation(String key, Object... with) {
|
||||
return new FormatableChat(Component.translatable().key(key).arguments(Chat.filterObjToTranslationArgumentLike(with)));
|
||||
public static FormattableChat translation(String key, Object... with) {
|
||||
return new FormattableChat(Component.translatable().key(key).arguments(Chat.filterObjToTranslationArgumentLike(with)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} with the provided keybinding.
|
||||
* Creates a {@link FormattableChat} with the provided keybinding.
|
||||
* @param key the keybinding to display.
|
||||
* @return a new {@link FormatableChat} with the provided keybinding.
|
||||
* @return a new {@link FormattableChat} with the provided keybinding.
|
||||
*/
|
||||
public static FormatableChat keybind(String key) {
|
||||
return new FormatableChat(Component.keybind().keybind(key));
|
||||
public static FormattableChat keyBind(String key) {
|
||||
return new FormattableChat(Component.keybind().keybind(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} with the provided score name and objective.
|
||||
* Creates a {@link FormattableChat} with the provided score name and objective.
|
||||
* @param name the score name.
|
||||
* @param objective the score objective.
|
||||
* @return a new {@link FormatableChat} with the provided score name and objective.
|
||||
* @return a new {@link FormattableChat} with the provided score name and objective.
|
||||
*/
|
||||
public static FormatableChat score(String name, String objective) {
|
||||
return new FormatableChat(Component.score().name(name).objective(objective));
|
||||
public static FormattableChat score(String name, String objective) {
|
||||
return new FormattableChat(Component.score().name(name).objective(objective));
|
||||
}
|
||||
|
||||
|
||||
@@ -272,49 +272,49 @@ public abstract class ChatStatic {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} that leads to a URL when clicked.
|
||||
* Creates a {@link FormattableChat} that leads to a URL when clicked.
|
||||
* @param inner the component to make clickable.
|
||||
* @param url the target url. Must start with {@code "http://"} or {@code "https://"}.
|
||||
* @param hover the content to display when hovering the component.
|
||||
* @return a new {@link FormatableChat} that leads to a URL when clicked.
|
||||
* @return a new {@link FormattableChat} that leads to a URL when clicked.
|
||||
*/
|
||||
public static FormatableChat clickableURL(ComponentLike inner, String url, HoverEventSource<?> hover) {
|
||||
public static FormattableChat clickableURL(ComponentLike inner, String url, HoverEventSource<?> hover) {
|
||||
Objects.requireNonNull(url, "url");
|
||||
if (inner == null)
|
||||
inner = text(url);
|
||||
if (hover == null)
|
||||
hover = text(ChatUtil.wrapInLimitedPixels(url, 240));
|
||||
return (FormatableChat) chat().clickURL(url).urlColor().hover(hover).then(inner);
|
||||
return (FormattableChat) chat().clickURL(url).urlColor().hover(hover).then(inner);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} that leads to a URL when clicked.
|
||||
* Creates a {@link FormattableChat} that leads to a URL when clicked.
|
||||
* <p>
|
||||
* When hovered, the component will display the url. To customize the hover content, use
|
||||
* {@link #clickableURL(ComponentLike, String, HoverEventSource)}.
|
||||
* @param inner the component to make clickable.
|
||||
* @param url the target url. Must start with {@code "http://"} or {@code "https://"}.
|
||||
* @return a new {@link FormatableChat} that leads to a URL when clicked.
|
||||
* @return a new {@link FormattableChat} that leads to a URL when clicked.
|
||||
*/
|
||||
public static FormatableChat clickableURL(ComponentLike inner, String url) {
|
||||
public static FormattableChat clickableURL(ComponentLike inner, String url) {
|
||||
return clickableURL(inner, url, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} that leads to a URL when clicked.
|
||||
* Creates a {@link FormattableChat} that leads to a URL when clicked.
|
||||
* <p>
|
||||
* The text on which to click will be the URL itself. To configure the clicked text, use
|
||||
* {@link #clickableURL(ComponentLike, String, HoverEventSource)}.
|
||||
* @param url the target url. Must start with {@code "http://"} or {@code "https://"}.
|
||||
* @param hover the content to display when hovering the component.
|
||||
* @return a new {@link FormatableChat} that leads to a URL when clicked.
|
||||
* @return a new {@link FormattableChat} that leads to a URL when clicked.
|
||||
*/
|
||||
public static FormatableChat clickableURL(String url, HoverEventSource<?> hover) {
|
||||
public static FormattableChat clickableURL(String url, HoverEventSource<?> hover) {
|
||||
return clickableURL(null, url, hover);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} that leads to a URL when clicked.
|
||||
* Creates a {@link FormattableChat} that leads to a URL when clicked.
|
||||
* <p>
|
||||
* The text on which to click will be the URL itself. To configure the clicked text, use
|
||||
* {@link #clickableURL(ComponentLike, String)}.
|
||||
@@ -322,9 +322,9 @@ public abstract class ChatStatic {
|
||||
* When hovered, the component will display the url. To customize the hover content, use
|
||||
* {@link #clickableURL(String, HoverEventSource)}.
|
||||
* @param url the target url. Must start with {@code "http://"} or {@code "https://"}.
|
||||
* @return a new {@link FormatableChat} that leads to a URL when clicked.
|
||||
* @return a new {@link FormattableChat} that leads to a URL when clicked.
|
||||
*/
|
||||
public static FormatableChat clickableURL(String url) {
|
||||
public static FormattableChat clickableURL(String url) {
|
||||
return clickableURL(null, url, null);
|
||||
}
|
||||
|
||||
@@ -334,14 +334,14 @@ public abstract class ChatStatic {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} that runs a command when clicked.
|
||||
* Creates a {@link FormattableChat} that runs a command when clicked.
|
||||
* @param inner the component to make clickable.
|
||||
* @param commandWithSlash the command to run. Must start with {@code "/"}.
|
||||
* @param hover the content to display when hovering the component.
|
||||
* @return a new {@link FormatableChat} that runs a command when clicked.
|
||||
* @return a new {@link FormattableChat} that runs a command when clicked.
|
||||
* @throws IllegalArgumentException if {@code commandWithSlash} does not start with a {@code "/"}.
|
||||
*/
|
||||
public static FormatableChat clickableCommand(ComponentLike inner, String commandWithSlash, HoverEventSource<?> hover) {
|
||||
public static FormattableChat clickableCommand(ComponentLike inner, String commandWithSlash, HoverEventSource<?> hover) {
|
||||
Objects.requireNonNull(commandWithSlash, "commandWithSlash");
|
||||
if (!commandWithSlash.startsWith("/"))
|
||||
throw new IllegalArgumentException("commandWithSlash must start with a '/' character.");
|
||||
@@ -349,39 +349,39 @@ public abstract class ChatStatic {
|
||||
inner = text(commandWithSlash);
|
||||
if (hover == null)
|
||||
hover = text(ChatUtil.wrapInLimitedPixels(commandWithSlash, 240));
|
||||
return (FormatableChat) chat().clickCommand(commandWithSlash).commandColor().hover(hover).then(inner);
|
||||
return (FormattableChat) chat().clickCommand(commandWithSlash).commandColor().hover(hover).then(inner);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} that runs a command when clicked.
|
||||
* Creates a {@link FormattableChat} that runs a command when clicked.
|
||||
* <p>
|
||||
* When hovered, the component will display the command itself. To customize the hover content, use
|
||||
* {@link #clickableCommand(ComponentLike, String, HoverEventSource)}.
|
||||
* @param inner the component to make clickable.
|
||||
* @param commandWithSlash the command to run. Must start with {@code "/"}.
|
||||
* @return a new {@link FormatableChat} that runs a command when clicked.
|
||||
* @return a new {@link FormattableChat} that runs a command when clicked.
|
||||
* @throws IllegalArgumentException if {@code commandWithSlash} does not start with a {@code "/"}.
|
||||
*/
|
||||
public static FormatableChat clickableCommand(ComponentLike inner, String commandWithSlash) {
|
||||
public static FormattableChat clickableCommand(ComponentLike inner, String commandWithSlash) {
|
||||
return clickableCommand(inner, commandWithSlash, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} that runs a command when clicked.
|
||||
* Creates a {@link FormattableChat} that runs a command when clicked.
|
||||
* <p>
|
||||
* The text on which to click will be the command itself. To configure the clicked text, use
|
||||
* {@link #clickableCommand(ComponentLike, String, HoverEventSource)}.
|
||||
* @param commandWithSlash the command to run. Must start with {@code "/"}.
|
||||
* @param hover the content to display when hovering the component.
|
||||
* @return a new {@link FormatableChat} that runs a command when clicked.
|
||||
* @return a new {@link FormattableChat} that runs a command when clicked.
|
||||
* @throws IllegalArgumentException if {@code commandWithSlash} does not start with a {@code "/"}.
|
||||
*/
|
||||
public static FormatableChat clickableCommand(String commandWithSlash, HoverEventSource<?> hover) {
|
||||
public static FormattableChat clickableCommand(String commandWithSlash, HoverEventSource<?> hover) {
|
||||
return clickableCommand(null, commandWithSlash, hover);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} that runs a command when clicked.
|
||||
* Creates a {@link FormattableChat} that runs a command when clicked.
|
||||
* <p>
|
||||
* The text on which to click will be the command itself. To configure the clicked text, use
|
||||
* {@link #clickableCommand(ComponentLike, String)}.
|
||||
@@ -389,10 +389,10 @@ public abstract class ChatStatic {
|
||||
* When hovered, the component will display the command itself. To customize the hover content, use
|
||||
* {@link #clickableCommand(String, HoverEventSource)}.
|
||||
* @param commandWithSlash the command to run. Must start with {@code "/"}.
|
||||
* @return a new {@link FormatableChat} that runs a command when clicked.
|
||||
* @return a new {@link FormattableChat} that runs a command when clicked.
|
||||
* @throws IllegalArgumentException if {@code commandWithSlash} does not start with a {@code "/"}.
|
||||
*/
|
||||
public static FormatableChat clickableCommand(String commandWithSlash) {
|
||||
public static FormattableChat clickableCommand(String commandWithSlash) {
|
||||
return clickableCommand(null, commandWithSlash, null);
|
||||
}
|
||||
|
||||
@@ -402,14 +402,14 @@ public abstract class ChatStatic {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} that pre-fill the chat box with a command when clicked.
|
||||
* Creates a {@link FormattableChat} that pre-fill the chat box with a command when clicked.
|
||||
* @param inner the component to make clickable.
|
||||
* @param commandWithSlash the command to suggest. Must start with {@code "/"}.
|
||||
* @param hover the content to display when hovering the component.
|
||||
* @return a new {@link FormatableChat} that pre-fill the chat box with a command when clicked.
|
||||
* @return a new {@link FormattableChat} that pre-fill the chat box with a command when clicked.
|
||||
* @throws IllegalArgumentException if {@code commandWithSlash} does not start with a {@code "/"}.
|
||||
*/
|
||||
public static FormatableChat clickableSuggest(ComponentLike inner, String commandWithSlash, HoverEventSource<?> hover) {
|
||||
public static FormattableChat clickableSuggest(ComponentLike inner, String commandWithSlash, HoverEventSource<?> hover) {
|
||||
Objects.requireNonNull(commandWithSlash, "commandWithSlash");
|
||||
if (!commandWithSlash.startsWith("/"))
|
||||
throw new IllegalArgumentException("commandWithSlash must start with a '/' character.");
|
||||
@@ -417,39 +417,39 @@ public abstract class ChatStatic {
|
||||
inner = text(commandWithSlash);
|
||||
if (hover == null)
|
||||
hover = text(ChatUtil.wrapInLimitedPixels(commandWithSlash, 240));
|
||||
return (FormatableChat) chat().clickSuggest(commandWithSlash).commandColor().hover(hover).then(inner);
|
||||
return (FormattableChat) chat().clickSuggest(commandWithSlash).commandColor().hover(hover).then(inner);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} that pre-fill the chat box with a command when clicked.
|
||||
* Creates a {@link FormattableChat} that pre-fill the chat box with a command when clicked.
|
||||
* <p>
|
||||
* When hovered, the component will display the command itself. To customize the hover content, use
|
||||
* {@link #clickableSuggest(ComponentLike, String, HoverEventSource)}.
|
||||
* @param inner the component to make clickable.
|
||||
* @param commandWithSlash the command to suggest. Must start with {@code "/"}.
|
||||
* @return a new {@link FormatableChat} that pre-fill the chat box with a command when clicked.
|
||||
* @return a new {@link FormattableChat} that pre-fill the chat box with a command when clicked.
|
||||
* @throws IllegalArgumentException if {@code commandWithSlash} does not start with a {@code "/"}.
|
||||
*/
|
||||
public static FormatableChat clickableSuggest(ComponentLike inner, String commandWithSlash) {
|
||||
public static FormattableChat clickableSuggest(ComponentLike inner, String commandWithSlash) {
|
||||
return clickableSuggest(inner, commandWithSlash, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} that pre-fill the chat box with a command when clicked.
|
||||
* Creates a {@link FormattableChat} that pre-fill the chat box with a command when clicked.
|
||||
* <p>
|
||||
* The text on which to click will be the command itself. To configure the clicked text, use
|
||||
* {@link #clickableSuggest(ComponentLike, String, HoverEventSource)}.
|
||||
* @param commandWithSlash the command to suggest. Must start with {@code "/"}.
|
||||
* @param hover the content to display when hovering the component.
|
||||
* @return a new {@link FormatableChat} that pre-fill the chat box with a command when clicked.
|
||||
* @return a new {@link FormattableChat} that pre-fill the chat box with a command when clicked.
|
||||
* @throws IllegalArgumentException if {@code commandWithSlash} does not start with a {@code "/"}.
|
||||
*/
|
||||
public static FormatableChat clickableSuggest(String commandWithSlash, HoverEventSource<?> hover) {
|
||||
public static FormattableChat clickableSuggest(String commandWithSlash, HoverEventSource<?> hover) {
|
||||
return clickableSuggest(null, commandWithSlash, hover);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} that pre-fill the chat box with a command when clicked.
|
||||
* Creates a {@link FormattableChat} that pre-fill the chat box with a command when clicked.
|
||||
* <p>
|
||||
* The text on which to click will be the command itself. To configure the clicked text, use
|
||||
* {@link #clickableSuggest(ComponentLike, String)}.
|
||||
@@ -457,10 +457,10 @@ public abstract class ChatStatic {
|
||||
* When hovered, the component will display the command itself. To customize the hover content, use
|
||||
* {@link #clickableSuggest(String, HoverEventSource)}.
|
||||
* @param commandWithSlash the command to suggest. Must start with {@code "/"}.
|
||||
* @return a new {@link FormatableChat} that pre-fill the chat box with a command when clicked.
|
||||
* @return a new {@link FormattableChat} that pre-fill the chat box with a command when clicked.
|
||||
* @throws IllegalArgumentException if {@code commandWithSlash} does not start with a {@code "/"}.
|
||||
*/
|
||||
public static FormatableChat clickableSuggest(String commandWithSlash) {
|
||||
public static FormattableChat clickableSuggest(String commandWithSlash) {
|
||||
return clickableSuggest(null, commandWithSlash, null);
|
||||
}
|
||||
|
||||
@@ -472,112 +472,112 @@ public abstract class ChatStatic {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} filling a chat line with decoration and a left-aligned text.
|
||||
* Creates a {@link FormattableChat} filling a chat line with decoration and a left-aligned text.
|
||||
* @param text the text aligned to the left.
|
||||
* @param decorationChar the character used for decoration around the text.
|
||||
* @param decorationColor the color used for the decoration characters.
|
||||
* @param console if the line is rendered on console (true) or IG (false).
|
||||
* @return a new {@link FormatableChat} filling a chat line with decoration and a left-aligned text.
|
||||
* @return a new {@link FormattableChat} filling a chat line with decoration and a left-aligned text.
|
||||
* @see ChatFilledLine#leftText(ComponentLike)
|
||||
*/
|
||||
public static FormatableChat leftText(ComponentLike text, char decorationChar, TextColor decorationColor, boolean console) {
|
||||
public static FormattableChat leftText(ComponentLike text, char decorationChar, TextColor decorationColor, boolean console) {
|
||||
return ChatFilledLine.leftText(text).decoChar(decorationChar).decoColor(decorationColor).spacesAroundText().console(console).toChat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} filling a chat line with the configured decoration character and
|
||||
* Creates a {@link FormattableChat} filling a chat line with the configured decoration character and
|
||||
* color and a left-aligned text.
|
||||
* @param text the text aligned to the left.
|
||||
* @param console if the line is rendered on console (true) or IG (false).
|
||||
* @return a new {@link FormatableChat} filling a chat line with the configured decoration character
|
||||
* @return a new {@link FormattableChat} filling a chat line with the configured decoration character
|
||||
* and color and a left-aligned text.
|
||||
* @see ChatFilledLine#leftText(ComponentLike)
|
||||
* @see ChatConfig#decorationChar
|
||||
* @see ChatConfig#decorationColor
|
||||
*/
|
||||
public static FormatableChat leftText(ComponentLike text, boolean console) {
|
||||
public static FormattableChat leftText(ComponentLike text, boolean console) {
|
||||
return ChatFilledLine.leftText(text).spacesAroundText().console(console).toChat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} filling a chat line with decoration and a right-aligned text.
|
||||
* Creates a {@link FormattableChat} filling a chat line with decoration and a right-aligned text.
|
||||
* @param text the text aligned to the right.
|
||||
* @param decorationChar the character used for decoration around the text.
|
||||
* @param decorationColor the color used for the decoration characters.
|
||||
* @param console if the line is rendered on console (true) or IG (false).
|
||||
* @return a new {@link FormatableChat} filling a chat line with decoration and a right-aligned
|
||||
* @return a new {@link FormattableChat} filling a chat line with decoration and a right-aligned
|
||||
* text.
|
||||
* @see ChatFilledLine#rightText(ComponentLike)
|
||||
*/
|
||||
public static FormatableChat rightText(ComponentLike text, char decorationChar, TextColor decorationColor, boolean console) {
|
||||
public static FormattableChat rightText(ComponentLike text, char decorationChar, TextColor decorationColor, boolean console) {
|
||||
return ChatFilledLine.rightText(text).decoChar(decorationChar).decoColor(decorationColor).spacesAroundText().console(console).toChat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} filling a chat line with the configured decoration character and
|
||||
* Creates a {@link FormattableChat} filling a chat line with the configured decoration character and
|
||||
* color and a right-aligned text.
|
||||
* @param text the text aligned to the right.
|
||||
* @param console if the line is rendered on console (true) or IG (false).
|
||||
* @return a new {@link FormatableChat} filling a chat line with the configured decoration character
|
||||
* @return a new {@link FormattableChat} filling a chat line with the configured decoration character
|
||||
* and color and a right-aligned text.
|
||||
* @see ChatFilledLine#rightText(ComponentLike)
|
||||
* @see ChatConfig#decorationChar
|
||||
* @see ChatConfig#decorationColor
|
||||
*/
|
||||
public static FormatableChat rightText(ComponentLike text, boolean console) {
|
||||
public static FormattableChat rightText(ComponentLike text, boolean console) {
|
||||
return ChatFilledLine.rightText(text).spacesAroundText().console(console).toChat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} filling a chat line with decoration and a centered text.
|
||||
* Creates a {@link FormattableChat} filling a chat line with decoration and a centered text.
|
||||
* @param text the text aligned to the center.
|
||||
* @param decorationChar the character used for decoration around the text.
|
||||
* @param decorationColor the color used for the decoration characters.
|
||||
* @param console if the line is rendered on console (true) or IG (false).
|
||||
* @return a new {@link FormatableChat} filling a chat line with decoration and a centered text.
|
||||
* @return a new {@link FormattableChat} filling a chat line with decoration and a centered text.
|
||||
* @see ChatFilledLine#centerText(ComponentLike)
|
||||
*/
|
||||
public static FormatableChat centerText(ComponentLike text, char decorationChar, TextColor decorationColor, boolean console) {
|
||||
public static FormattableChat centerText(ComponentLike text, char decorationChar, TextColor decorationColor, boolean console) {
|
||||
return ChatFilledLine.centerText(text).decoChar(decorationChar).decoColor(decorationColor).spacesAroundText().console(console).toChat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} filling a chat line with the configured decoration character and
|
||||
* Creates a {@link FormattableChat} filling a chat line with the configured decoration character and
|
||||
* color and a centered text.
|
||||
* @param text the text aligned to the center.
|
||||
* @param console if the line is rendered on console (true) or IG (false).
|
||||
* @return a new {@link FormatableChat} filling a chat line with the configured decoration character
|
||||
* @return a new {@link FormattableChat} filling a chat line with the configured decoration character
|
||||
* and color and a centered text.
|
||||
* @see ChatFilledLine#centerText(ComponentLike)
|
||||
* @see ChatConfig#decorationChar
|
||||
* @see ChatConfig#decorationColor
|
||||
*/
|
||||
public static FormatableChat centerText(ComponentLike text, boolean console) {
|
||||
public static FormattableChat centerText(ComponentLike text, boolean console) {
|
||||
return ChatFilledLine.centerText(text).spacesAroundText().console(console).toChat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} filling a chat line with a decoration character and color.
|
||||
* Creates a {@link FormattableChat} filling a chat line with a decoration character and color.
|
||||
* @param decorationChar the character used for decoration.
|
||||
* @param decorationColor the color used for the decoration characters.
|
||||
* @param console if the line is rendered on console (true) or IG (false).
|
||||
* @return a new {@link FormatableChat} filling a chat line with a decoration character and color.
|
||||
* @return a new {@link FormattableChat} filling a chat line with a decoration character and color.
|
||||
* @see ChatFilledLine#filled()
|
||||
*/
|
||||
public static FormatableChat filledLine(char decorationChar, TextColor decorationColor, boolean console) {
|
||||
public static FormattableChat filledLine(char decorationChar, TextColor decorationColor, boolean console) {
|
||||
return ChatFilledLine.filled().decoChar(decorationChar).decoColor(decorationColor).console(console).toChat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link FormatableChat} filling a chat line with the configured decoration character and
|
||||
* Creates a {@link FormattableChat} filling a chat line with the configured decoration character and
|
||||
* color.
|
||||
* @param console if the line is rendered on console (true) or IG (false).
|
||||
* @return a new {@link FormatableChat} filling a chat line with a decoration character and color.
|
||||
* @return a new {@link FormattableChat} filling a chat line with a decoration character and color.
|
||||
* @see ChatFilledLine#filled()
|
||||
* @see ChatConfig#decorationChar
|
||||
* @see ChatConfig#decorationColor
|
||||
*/
|
||||
public static FormatableChat filledLine(boolean console) {
|
||||
public static FormattableChat filledLine(boolean console) {
|
||||
return ChatFilledLine.filled().console(console).toChat();
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
package fr.pandacube.lib.chat;
|
||||
|
||||
import fr.pandacube.lib.chat.Chat.FormatableChat;
|
||||
import fr.pandacube.lib.chat.Chat.FormattableChat;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.ComponentLike;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
@@ -152,7 +152,7 @@ public class ChatUtil {
|
||||
else
|
||||
first = false;
|
||||
|
||||
FormatableChat pDisplay = Chat.clickableCommand(Chat.text(page), String.format(cmdFormat, page), Chat.text("Aller à la page " + page));
|
||||
FormattableChat pDisplay = Chat.clickableCommand(Chat.text(page), String.format(cmdFormat, page), Chat.text("Aller à la page " + page));
|
||||
if (page == currentPage) {
|
||||
pDisplay.highlightedCommandColor();
|
||||
}
|
||||
@@ -180,12 +180,12 @@ public class ChatUtil {
|
||||
* @param elements the components to join.
|
||||
* @return a new {@link Chat} instance with all the provided {@code component} joined using the separators.
|
||||
*/
|
||||
public static FormatableChat joinGrammatically(ComponentLike regularSeparator, ComponentLike finalSeparator, List<? extends ComponentLike> elements) {
|
||||
public static FormattableChat joinGrammatically(ComponentLike regularSeparator, ComponentLike finalSeparator, List<? extends ComponentLike> elements) {
|
||||
int size = elements == null ? 0 : elements.size();
|
||||
int last = size - 1;
|
||||
return switch (size) {
|
||||
case 0, 1, 2 -> join(finalSeparator, elements);
|
||||
default -> (FormatableChat) join(regularSeparator, elements.subList(0, last))
|
||||
default -> (FormattableChat) join(regularSeparator, elements.subList(0, last))
|
||||
.then(finalSeparator)
|
||||
.then(elements.get(last));
|
||||
};
|
||||
@@ -202,8 +202,8 @@ public class ChatUtil {
|
||||
* @param elements the components to join.
|
||||
* @return a new {@link Chat} instance with all the provided {@code component} joined using the separators.
|
||||
*/
|
||||
public static FormatableChat join(ComponentLike separator, Iterable<? extends ComponentLike> elements) {
|
||||
FormatableChat c = chat();
|
||||
public static FormattableChat join(ComponentLike separator, Iterable<? extends ComponentLike> elements) {
|
||||
FormattableChat c = chat();
|
||||
if (elements == null)
|
||||
return c;
|
||||
boolean first = true;
|
||||
@@ -596,7 +596,7 @@ public class ChatUtil {
|
||||
for (int i = 0; i < sizes.length; i++) {
|
||||
sumSizes += sizes[i];
|
||||
|
||||
FormatableChat subC = ChatStatic.text(repeatedChar(PROGRESS_BAR_FULL_CHAR, sizes[i]));
|
||||
FormattableChat subC = ChatStatic.text(repeatedChar(PROGRESS_BAR_FULL_CHAR, sizes[i]));
|
||||
|
||||
if (colors != null && i < colors.length && colors[i] != null)
|
||||
subC.color(colors[i]);
|
||||
|
@@ -27,21 +27,11 @@
|
||||
<artifactId>pandalib-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>fr.pandacube.lib</groupId>
|
||||
<artifactId>pandalib-reflect</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>fr.pandacube.lib</groupId>
|
||||
<artifactId>pandalib-commands</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>fr.pandacube.lib</groupId>
|
||||
<artifactId>pandalib-config</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-log</artifactId>
|
||||
|
@@ -1,22 +1,25 @@
|
||||
package fr.pandacube.lib.cli;
|
||||
|
||||
import fr.pandacube.lib.cli.commands.CLIBrigadierDispatcher;
|
||||
import fr.pandacube.lib.cli.log.CLILogger;
|
||||
import fr.pandacube.lib.util.log.Log;
|
||||
import org.jline.reader.EndOfFileException;
|
||||
import org.jline.reader.LineReader;
|
||||
import org.jline.reader.LineReaderBuilder;
|
||||
import org.jline.reader.UserInterruptException;
|
||||
import org.jline.terminal.Terminal;
|
||||
import org.jline.terminal.TerminalBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import fr.pandacube.lib.cli.commands.CLIBrigadierDispatcher;
|
||||
import fr.pandacube.lib.cli.log.CLILogger;
|
||||
import jline.console.ConsoleReader;
|
||||
import org.fusesource.jansi.AnsiConsole;
|
||||
|
||||
import fr.pandacube.lib.util.log.Log;
|
||||
|
||||
/**
|
||||
* Class to handle general standard IO operation for a CLI application. It uses Jline’s {@link ConsoleReader} for the
|
||||
* Class to handle general standard IO operation for a CLI application. It uses Jline’s {@link LineReader} for the
|
||||
* console rendering, a JUL {@link Logger} for logging, and Brigadier to handle commands.
|
||||
*/
|
||||
public class CLI extends Thread {
|
||||
|
||||
private final ConsoleReader reader;
|
||||
private final LineReader reader;
|
||||
private final Logger logger;
|
||||
|
||||
|
||||
@@ -28,10 +31,11 @@ public class CLI extends Thread {
|
||||
super("Console Thread");
|
||||
setDaemon(true);
|
||||
|
||||
AnsiConsole.systemInstall();
|
||||
reader = new ConsoleReader();
|
||||
reader.setPrompt(">");
|
||||
reader.addCompleter(CLIBrigadierDispatcher.instance);
|
||||
Terminal terminal = TerminalBuilder.builder().build();
|
||||
reader = LineReaderBuilder.builder().terminal(terminal)
|
||||
.completer(CLIBrigadierDispatcher.instance)
|
||||
.build()
|
||||
;
|
||||
|
||||
// configure logger's formatter
|
||||
System.setProperty("net.md_5.bungee.log-date-format", "yyyy-MM-dd HH:mm:ss");
|
||||
@@ -40,10 +44,10 @@ public class CLI extends Thread {
|
||||
|
||||
|
||||
/**
|
||||
* Gets the Jline {@link ConsoleReader} of this CLI instance.
|
||||
* @return the Jline {@link ConsoleReader} of this CLI instance.
|
||||
* Gets the Jline {@link LineReader} of this CLI instance.
|
||||
* @return the Jline {@link LineReader} of this CLI instance.
|
||||
*/
|
||||
public ConsoleReader getConsoleReader() {
|
||||
public LineReader getConsoleReader() {
|
||||
return reader;
|
||||
}
|
||||
|
||||
@@ -65,15 +69,14 @@ public class CLI extends Thread {
|
||||
int i = 0;
|
||||
String line;
|
||||
try {
|
||||
while((line = reader.readLine()) != null) {
|
||||
if (line.trim().equals(""))
|
||||
while((line = reader.readLine(">")) != null) {
|
||||
if (line.trim().isEmpty())
|
||||
continue;
|
||||
String cmdLine = line;
|
||||
new Thread(() -> CLIBrigadierDispatcher.instance.execute(cmdLine), "CLICmdThread #"+(i++)).start();
|
||||
Thread.ofVirtual().name("CLICmdThread #"+(i++))
|
||||
.start(() -> CLIBrigadierDispatcher.instance.execute(cmdLine));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.severe(e);
|
||||
}
|
||||
} catch (UserInterruptException | EndOfFileException ignore) { }
|
||||
|
||||
}
|
||||
|
||||
|
@@ -32,6 +32,7 @@ public abstract class CLIApplication {
|
||||
/**
|
||||
* Creates a new application instance.
|
||||
*/
|
||||
@SuppressWarnings("CallToPrintStackTrace")
|
||||
protected CLIApplication() {
|
||||
instance = this;
|
||||
CLI tmpCLI = null;
|
||||
|
@@ -38,16 +38,9 @@ public abstract class CLIBrigadierCommand extends BrigadierCommand<CLICommandSen
|
||||
}
|
||||
|
||||
protected abstract LiteralArgumentBuilder<CLICommandSender> buildCommand();
|
||||
|
||||
protected String[] getAliases() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public boolean isPlayer(CLICommandSender sender) {
|
||||
public boolean isPlayer(CLICommandSender sender) {
|
||||
return sender.isPlayer();
|
||||
}
|
||||
|
||||
|
@@ -3,8 +3,11 @@ package fr.pandacube.lib.cli.commands;
|
||||
import com.mojang.brigadier.suggestion.Suggestion;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import fr.pandacube.lib.commands.BrigadierDispatcher;
|
||||
import jline.console.completer.Completer;
|
||||
import net.kyori.adventure.text.ComponentLike;
|
||||
import org.jline.reader.Candidate;
|
||||
import org.jline.reader.Completer;
|
||||
import org.jline.reader.LineReader;
|
||||
import org.jline.reader.ParsedLine;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -39,17 +42,15 @@ public class CLIBrigadierDispatcher extends BrigadierDispatcher<CLICommandSender
|
||||
|
||||
|
||||
@Override
|
||||
public int complete(String buffer, int cursor, List<CharSequence> candidates) {
|
||||
|
||||
String bufferBeforeCursor = buffer.substring(0, cursor);
|
||||
|
||||
public void complete(LineReader lineReader, ParsedLine parsedLine, List<Candidate> candidates) {
|
||||
String bufferBeforeCursor = parsedLine.line().substring(0, parsedLine.cursor());
|
||||
|
||||
Suggestions completeResult = getSuggestions(bufferBeforeCursor);
|
||||
|
||||
|
||||
completeResult.getList().stream()
|
||||
.map(Suggestion::getText)
|
||||
.map(Candidate::new)
|
||||
.forEach(candidates::add);
|
||||
|
||||
return completeResult.getRange().getStart();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -41,6 +41,9 @@ public interface CLICommandSender extends Audience {
|
||||
*/
|
||||
void sendMessage(String message);
|
||||
|
||||
@SuppressWarnings({"UnstableApiUsage", "deprecation"})
|
||||
@Override // force implementation of super-interface default method
|
||||
void sendMessage(@NotNull Identity source, @NotNull Component message, @NotNull MessageType type);
|
||||
|
||||
|
||||
}
|
||||
|
@@ -38,7 +38,7 @@ public class CLIConsoleCommandSender implements CLICommandSender {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(@NotNull Identity source, @NotNull Component message, @NotNull MessageType type) {
|
||||
public void sendMessage(@NotNull Identity source, @NotNull Component message, @SuppressWarnings({"UnstableApiUsage", "deprecation"}) @NotNull MessageType type) {
|
||||
sendMessage(Chat.chatComponent(message).getLegacyText());
|
||||
}
|
||||
}
|
||||
|
@@ -14,7 +14,7 @@ import com.mojang.brigadier.tree.CommandNode;
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import com.mojang.brigadier.tree.RootCommandNode;
|
||||
import fr.pandacube.lib.chat.Chat;
|
||||
import fr.pandacube.lib.chat.Chat.FormatableChat;
|
||||
import fr.pandacube.lib.chat.Chat.FormattableChat;
|
||||
import fr.pandacube.lib.chat.ChatTreeNode;
|
||||
import fr.pandacube.lib.cli.CLIApplication;
|
||||
import fr.pandacube.lib.util.log.Log;
|
||||
@@ -195,13 +195,13 @@ public class CommandAdmin extends CLIBrigadierCommand {
|
||||
private Component displayCurrentNode(CommandNode<CLICommandSender> node, boolean redirectTarget, CLICommandSender sender) {
|
||||
if (node == null)
|
||||
throw new IllegalArgumentException("node must not be null");
|
||||
FormatableChat d;
|
||||
FormattableChat d;
|
||||
if (node instanceof RootCommandNode) {
|
||||
d = text("(root)").italic()
|
||||
.hover("Root command node");
|
||||
}
|
||||
else if (node instanceof ArgumentCommandNode) {
|
||||
ArgumentType<?> type = ((ArgumentCommandNode<?, ?>) node).getType();
|
||||
else if (node instanceof ArgumentCommandNode<?, ?> argNode) {
|
||||
ArgumentType<?> type = argNode.getType();
|
||||
String typeStr = type.getClass().getSimpleName();
|
||||
if (type instanceof IntegerArgumentType
|
||||
|| type instanceof LongArgumentType
|
||||
@@ -260,10 +260,10 @@ public class CommandAdmin extends CLIBrigadierCommand {
|
||||
return d.get();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private static class DisplayCommandNode {
|
||||
final List<CommandNode<CLICommandSender>> nodes = new ArrayList<>();
|
||||
final List<DisplayCommandNode> children = new ArrayList<>();
|
||||
|
@@ -45,7 +45,7 @@
|
||||
<dependency>
|
||||
<groupId>com.mojang</groupId>
|
||||
<artifactId>brigadier</artifactId>
|
||||
<version>1.0.18</version>
|
||||
<version>${brigadier.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
@@ -3,8 +3,8 @@ package fr.pandacube.lib.commands;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Throw an instance of this exception to indicate to the plugin command handler that the user has missused the command.
|
||||
* The message, if provided, must indicate the reason of the mussusage of the command. It will be displayed on the
|
||||
* Throw an instance of this exception to indicate to the plugin command handler that the user has badly used the command.
|
||||
* The message, if provided, must indicate the reason of the bad usage of the command. It will be displayed on the
|
||||
* screen with eventual indications of how to use the command (help command for example).
|
||||
* If a {@link Throwable} cause is provided, it will be relayed to the plugin {@link Logger}.
|
||||
*
|
||||
|
@@ -223,14 +223,14 @@ public abstract class BrigadierCommand<S> {
|
||||
/**
|
||||
* Wraps the provided {@link SuggestionsSupplier} into a Brigadier’s {@link SuggestionProvider}.
|
||||
* @param suggestions the suggestions to wrap.
|
||||
* @param senderUnwrapper function to convert the command sender provided by brigadier into the command sender
|
||||
* @param senderUnWrapper function to convert the command sender provided by brigadier into the command sender
|
||||
* supported by {@link SuggestionsSupplier}.
|
||||
* @return a {@link SuggestionProvider} generating the suggestions from the provided {@link SuggestionsSupplier}.
|
||||
* @param <AS> the type of command sender supported by the {@link SuggestionsSupplier}.
|
||||
*/
|
||||
protected <AS> SuggestionProvider<S> wrapSuggestions(SuggestionsSupplier<AS> suggestions, Function<S, AS> senderUnwrapper) {
|
||||
protected <AS> SuggestionProvider<S> wrapSuggestions(SuggestionsSupplier<AS> suggestions, Function<S, AS> senderUnWrapper) {
|
||||
return (context, builder) -> {
|
||||
AS sender = senderUnwrapper.apply(context.getSource());
|
||||
AS sender = senderUnWrapper.apply(context.getSource());
|
||||
String message = builder.getInput();
|
||||
try {
|
||||
int tokenStartPos = builder.getStart();
|
||||
|
@@ -241,7 +241,7 @@ public interface SuggestionsSupplier<S> {
|
||||
return (s, ti, token, a) -> {
|
||||
try {
|
||||
List<Long> proposedValues = new ArrayList<>();
|
||||
if (token.length() == 0) {
|
||||
if (token.isEmpty()) {
|
||||
long start = Math.max(Math.max(Math.min(-4, max - 9), min), -9);
|
||||
long end = Math.min(Math.min(start + 9, max), 9);
|
||||
ListUtil.addLongRangeToList(proposedValues, start, end);
|
||||
@@ -399,7 +399,7 @@ public interface SuggestionsSupplier<S> {
|
||||
*/
|
||||
default SuggestionsSupplier<S> quotableString() {
|
||||
return (s, ti, token, a) -> {
|
||||
boolean startWithQuote = token.length() > 0 && (token.charAt(0) == '"' || token.charAt(0) == '\'');
|
||||
boolean startWithQuote = !token.isEmpty() && (token.charAt(0) == '"' || token.charAt(0) == '\'');
|
||||
String realToken = startWithQuote ? unescapeBrigadierQuotable(token.substring(1), token.charAt(0)) : token;
|
||||
String[] argsCopy = Arrays.copyOf(a, a.length);
|
||||
argsCopy[a.length - 1] = realToken;
|
||||
|
@@ -32,7 +32,7 @@ public class Json {
|
||||
boolean isFloat = value.contains(".");
|
||||
|
||||
if (isFloat) {
|
||||
// if float, will only parse to Double
|
||||
// if is float, will only parse to Double
|
||||
// (see org.yaml.snakeyaml.constructor.SafeConstructor.ConstructYamlFloat)
|
||||
try {
|
||||
Double d = Double.valueOf(value);
|
||||
|
@@ -134,30 +134,30 @@ public class ThrowableAdapter implements JsonSerializer<Throwable>, JsonDeserial
|
||||
}
|
||||
|
||||
private static <T extends Throwable> ThrowableSubAdapter<T> defaultSubAdapter(Class<T> clazz) {
|
||||
BiFunction<String, Throwable, T> constructor = null;
|
||||
BiFunction<String, Throwable, T> constructionFunction = null;
|
||||
|
||||
// try (String, Throwable) constructor
|
||||
try {
|
||||
Constructor<T> constr = clazz.getConstructor(String.class, Throwable.class);
|
||||
if (constr.canAccess(null)) {
|
||||
constructor = (m, t) -> ThrowableUtil.wrapReflectEx(() -> constr.newInstance(m, t));
|
||||
Constructor<T> constructor = clazz.getConstructor(String.class, Throwable.class);
|
||||
if (constructor.canAccess(null)) {
|
||||
constructionFunction = (m, t) -> ThrowableUtil.wrapReflectEx(() -> constructor.newInstance(m, t));
|
||||
}
|
||||
} catch (ReflectiveOperationException ignore) { }
|
||||
|
||||
// try (String) constructor
|
||||
try {
|
||||
Constructor<T> constr = clazz.getConstructor(String.class);
|
||||
if (constr.canAccess(null)) {
|
||||
constructor = ThrowableSubAdapter.messageOnly((m) -> ThrowableUtil.wrapReflectEx(() -> constr.newInstance(m)));
|
||||
Constructor<T> constructor = clazz.getConstructor(String.class);
|
||||
if (constructor.canAccess(null)) {
|
||||
constructionFunction = ThrowableSubAdapter.messageOnly((m) -> ThrowableUtil.wrapReflectEx(() -> constructor.newInstance(m)));
|
||||
}
|
||||
} catch (ReflectiveOperationException ignore) { }
|
||||
|
||||
if (constructor == null) {
|
||||
if (constructionFunction == null) {
|
||||
Log.warning("Provided Throwable class '" + clazz + "' does not have any of those constructors or are not accessible: (String, Throwable), (String).");
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ThrowableSubAdapter<>(constructor);
|
||||
return new ThrowableSubAdapter<>(constructionFunction);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -37,8 +37,8 @@ public class MinecraftVersionUtil {
|
||||
|
||||
/**
|
||||
* Decompose a version string into a series of integers.
|
||||
* @param v a string representation of a version (eg. 1.19.1).
|
||||
* @return an array of int representing the provided version (eg. [1, 19, 1]).
|
||||
* @param v a string representation of a version (e.g. 1.19.1).
|
||||
* @return an array of int representing the provided version (e.g. [1, 19, 1]).
|
||||
*/
|
||||
public static int[] decomposedVersion(String v) {
|
||||
try {
|
||||
@@ -114,7 +114,7 @@ public class MinecraftVersionUtil {
|
||||
else {
|
||||
// merge
|
||||
if (i - firstConsecutive > 1)
|
||||
keptVersions.add(versions.get(firstConsecutive) + "-" + versions.get(i));
|
||||
keptVersions.add(versions.get(firstConsecutive) + " - " + versions.get(i));
|
||||
else {
|
||||
keptVersions.add(versions.get(firstConsecutive));
|
||||
keptVersions.add(versions.get(i));
|
||||
|
@@ -68,12 +68,12 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
|
||||
|
||||
private static void init() {
|
||||
// try online source first
|
||||
try {
|
||||
HttpResponse<String> response = HttpClient.newBuilder()
|
||||
.connectTimeout(Duration.ofSeconds(5))
|
||||
.build()
|
||||
.send(HttpRequest.newBuilder(URI.create(ONLINE_DATA_URL)).build(),
|
||||
BodyHandlers.ofString()
|
||||
try (HttpClient cl = HttpClient.newBuilder()
|
||||
.connectTimeout(Duration.ofSeconds(5))
|
||||
.build()) {
|
||||
HttpResponse<String> response = cl.send(
|
||||
HttpRequest.newBuilder(URI.create(ONLINE_DATA_URL)).build(),
|
||||
BodyHandlers.ofString()
|
||||
);
|
||||
if (response.statusCode() == 200) {
|
||||
MinecraftVersionList data = Json.gson.fromJson(response.body(), MinecraftVersionList.class);
|
||||
@@ -123,7 +123,7 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
|
||||
|
||||
/**
|
||||
* Gets the {@link ProtocolVersion} associated with the provided Minecraft version.
|
||||
* @param version The Minecraft version, in the format "X.X[.X]" (eg. "1.17" or "1.8.8").
|
||||
* @param version The Minecraft version, in the format "X.X[.X]" (e.g. "1.17" or "1.8.8").
|
||||
* @return an instance of {@link ProtocolVersion}.
|
||||
*/
|
||||
public static ProtocolVersion ofVersion(String version) {
|
||||
|
@@ -71,7 +71,11 @@
|
||||
"1.21.1": 767,
|
||||
"1.21.2": 768,
|
||||
"1.21.3": 768,
|
||||
"1.21.4": 769
|
||||
"1.21.4": 769,
|
||||
"1.21.5": 770,
|
||||
"1.21.6": 771,
|
||||
"1.21.7": 772,
|
||||
"1.21.8": 772
|
||||
},
|
||||
"versionsOfProtocol": {
|
||||
"4": [
|
||||
@@ -233,6 +237,16 @@
|
||||
],
|
||||
"769": [
|
||||
"1.21.4"
|
||||
],
|
||||
"770": [
|
||||
"1.21.5"
|
||||
],
|
||||
"771": [
|
||||
"1.21.6"
|
||||
],
|
||||
"772": [
|
||||
"1.21.7",
|
||||
"1.21.8"
|
||||
]
|
||||
}
|
||||
}
|
@@ -227,7 +227,7 @@ public final class DB {
|
||||
*/
|
||||
public static <E extends SQLElement<E>> E getFirst(Class<E> elemClass, SQLWhere<E> where, SQLOrderBy<E> orderBy, Integer offset) throws DBException {
|
||||
SQLElementList<E> elements = getAll(elemClass, where, orderBy, 1, offset);
|
||||
return (elements.size() == 0) ? null : elements.get(0);
|
||||
return (elements.isEmpty()) ? null : elements.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -42,7 +42,7 @@ public class SQLType<T> {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof SQLType o
|
||||
return obj instanceof SQLType<?> o
|
||||
&& toString().equals(o.toString());
|
||||
}
|
||||
|
||||
|
@@ -7,6 +7,7 @@ import net.milkbowl.vault.chat.Chat;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
|
||||
import java.util.List;
|
||||
@@ -120,6 +121,13 @@ import java.util.List;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playerAdd(Player player, String permission) {
|
||||
// override because the super class sets the permission on the current world of the player, that is probably
|
||||
// not intended by the calling plugin
|
||||
return playerAdd(null, player, permission);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public boolean playerRemove(String world, String player, String permission) {
|
||||
@@ -136,6 +144,14 @@ import java.util.List;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean playerRemove(Player player, String permission) {
|
||||
// to stay coherent with the override of #playerAdd(Player, String), we also override this method.
|
||||
// Will try first to remove the permission on the world itself (like super-method), then if it doesn't exist,
|
||||
// removes on the server level.
|
||||
return super.playerRemove(player, permission) || playerRemove(null, player, permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean groupHas(String world, String group, String permission) {
|
||||
checkEnabled();
|
||||
|
@@ -22,6 +22,11 @@
|
||||
<id>fabricmc</id>
|
||||
<url>https://maven.fabricmc.net/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>minecraft-libraries</id>
|
||||
<name>Minecraft Libraries</name>
|
||||
<url>https://libraries.minecraft.net</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
@@ -84,6 +89,12 @@
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mojang</groupId>
|
||||
<artifactId>datafixerupper</artifactId>
|
||||
<version>${datafixerupper.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Paper -->
|
||||
<dependency>
|
||||
<groupId>io.papermc.paper</groupId>
|
||||
|
@@ -18,8 +18,8 @@ import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.CraftVector;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.VanillaCommandWrapper;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.Coordinates;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.Vec3Argument;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.paper.commands.APICommandMeta;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.paper.commands.BukkitCommandNode;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.paper.commands.PluginCommandNode;
|
||||
import fr.pandacube.lib.players.standalone.AbstractOffPlayer;
|
||||
import fr.pandacube.lib.players.standalone.AbstractOnlinePlayer;
|
||||
import fr.pandacube.lib.players.standalone.AbstractPlayerManager;
|
||||
@@ -46,7 +46,6 @@ import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static fr.pandacube.lib.reflect.wrapper.ReflectWrapper.unwrap;
|
||||
import static fr.pandacube.lib.reflect.wrapper.ReflectWrapper.wrap;
|
||||
|
||||
/**
|
||||
@@ -199,6 +198,10 @@ public abstract class PaperBrigadierCommand extends BrigadierCommand<CommandSour
|
||||
registeredAliases = new HashSet<>(event.registrar().register(commandNode, description, List.of(aliases)));
|
||||
doPostRegistrationFixes();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
fr.pandacube.lib.paper.reflect.wrapper.brigadier.CommandNode<CommandSourceStack> registeredNode = wrap(vanillaPaperDispatcher.getRoot().getChild(commandNode.getName()), fr.pandacube.lib.paper.reflect.wrapper.brigadier.CommandNode.class);
|
||||
|
||||
|
||||
if (registrationPolicy == RegistrationPolicy.ALL) {
|
||||
// enforce registration of aliases
|
||||
for (String alias : aliases) {
|
||||
@@ -221,11 +224,12 @@ public abstract class PaperBrigadierCommand extends BrigadierCommand<CommandSour
|
||||
|
||||
for (String aliasToForce : forceRegistrationAgain) {
|
||||
CommandNode<CommandSourceStack> actualNode = vanillaPaperDispatcher.getRoot().getChild(aliasToForce);
|
||||
@SuppressWarnings("unchecked")
|
||||
fr.pandacube.lib.paper.reflect.wrapper.brigadier.CommandNode<CommandSourceStack> wrappedCommandNode = wrap(actualNode, fr.pandacube.lib.paper.reflect.wrapper.brigadier.CommandNode.class);
|
||||
if (actualNode != null) {
|
||||
//Log.info("Forcing registration of alias /" + aliasToForce + " for command /" + commandNode.getName() + ": replacing " + getCommandIdentity(actualNode) + "?");
|
||||
if (PluginCommandNode.REFLECT.get().isInstance(actualNode)) {
|
||||
PluginCommandNode pcn = wrap(actualNode, PluginCommandNode.class);
|
||||
if (pcn.getPlugin().equals(plugin))
|
||||
if (wrappedCommandNode.apiCommandMeta() != null) {
|
||||
APICommandMeta meta = wrappedCommandNode.apiCommandMeta();
|
||||
if (meta.plugin().equals(plugin))
|
||||
return;
|
||||
}
|
||||
else if (BukkitCommandNode.REFLECT.get().isInstance(actualNode)) {
|
||||
@@ -233,12 +237,16 @@ public abstract class PaperBrigadierCommand extends BrigadierCommand<CommandSour
|
||||
if (bcn.getBukkitCommand() instanceof PluginCommand pc && pc.getPlugin().equals(plugin))
|
||||
return;
|
||||
}
|
||||
Log.warning("Forcing registration of alias /" + aliasToForce + " for command /" + commandNode.getName() + ": replacing " + getCommandIdentity(actualNode));
|
||||
vanillaPaperDispatcher.getRoot().getChildren().removeIf(c -> c.getName().equals(aliasToForce));
|
||||
}
|
||||
/*else {
|
||||
Log.info("Forcing registration of alias /" + aliasToForce + " for command /" + commandNode.getName() + ": no command found for alias. Adding alias.");
|
||||
}*/
|
||||
LiteralCommandNode<CommandSourceStack> newPCN = unwrap(new PluginCommandNode(aliasToForce, plugin.getPluginMeta(), commandNode, description));
|
||||
/*else {
|
||||
Log.info("Forcing registration of alias /" + aliasToForce + " for command /" + commandNode.getName() + ": no command found for alias. Adding alias.");
|
||||
}*/
|
||||
LiteralCommandNode<CommandSourceStack> newPCN = getAliasNode(commandNode, aliasToForce);
|
||||
@SuppressWarnings("unchecked")
|
||||
fr.pandacube.lib.paper.reflect.wrapper.brigadier.CommandNode<CommandSourceStack> wrappedNewPCN = wrap(newPCN, fr.pandacube.lib.paper.reflect.wrapper.brigadier.CommandNode.class);
|
||||
wrappedNewPCN.apiCommandMeta(registeredNode.apiCommandMeta());
|
||||
vanillaPaperDispatcher.getRoot().addChild(newPCN);
|
||||
}
|
||||
});
|
||||
@@ -296,11 +304,8 @@ public abstract class PaperBrigadierCommand extends BrigadierCommand<CommandSour
|
||||
}
|
||||
|
||||
private static String getCommandIdentity(CommandNode<CommandSourceStack> command) {
|
||||
if (PluginCommandNode.REFLECT.get().isInstance(command)) {
|
||||
PluginCommandNode wrappedPCN = wrap(command, PluginCommandNode.class);
|
||||
return "Node /" + command.getName() + " from plugin " + wrappedPCN.getPlugin().getName();
|
||||
}
|
||||
else if (BukkitCommandNode.REFLECT.get().isInstance(command)) {
|
||||
|
||||
if (BukkitCommandNode.REFLECT.get().isInstance(command)) {
|
||||
BukkitCommandNode wrappedBCN = wrap(command, BukkitCommandNode.class);
|
||||
Command bukkitCmd = wrappedBCN.getBukkitCommand();
|
||||
if (bukkitCmd instanceof PluginCommand cmd) {
|
||||
@@ -318,16 +323,22 @@ public abstract class PaperBrigadierCommand extends BrigadierCommand<CommandSour
|
||||
return "Node /" + command.getName() + " wrapping " + bukkitCmd.getClass().getName() + " /" + bukkitCmd.getName();
|
||||
}
|
||||
else {
|
||||
return "Node /" + command.getName() + " (unspecific)";
|
||||
@SuppressWarnings("unchecked")
|
||||
fr.pandacube.lib.paper.reflect.wrapper.brigadier.CommandNode<CommandSourceStack> wrappedCommandNode = wrap(command, fr.pandacube.lib.paper.reflect.wrapper.brigadier.CommandNode.class);
|
||||
|
||||
if (wrappedCommandNode.apiCommandMeta() != null) {
|
||||
APICommandMeta meta = wrappedCommandNode.apiCommandMeta();
|
||||
return "Node /" + command.getName() + " from plugin " + meta.plugin().getName();
|
||||
}
|
||||
else {
|
||||
return "Node /" + command.getName() + " (unspecific)";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static Boolean isPluginCommand(CommandNode<CommandSourceStack> command) {
|
||||
if (PluginCommandNode.REFLECT.get().isInstance(command)) {
|
||||
return true;
|
||||
}
|
||||
else if (BukkitCommandNode.REFLECT.get().isInstance(command)) {
|
||||
if (BukkitCommandNode.REFLECT.get().isInstance(command)) {
|
||||
BukkitCommandNode wrappedBCN = wrap(command, BukkitCommandNode.class);
|
||||
Command bukkitCmd = wrappedBCN.getBukkitCommand();
|
||||
if (bukkitCmd instanceof PluginCommand) {
|
||||
@@ -345,7 +356,9 @@ public abstract class PaperBrigadierCommand extends BrigadierCommand<CommandSour
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
@SuppressWarnings("unchecked")
|
||||
fr.pandacube.lib.paper.reflect.wrapper.brigadier.CommandNode<CommandSourceStack> wrappedCommandNode = wrap(command, fr.pandacube.lib.paper.reflect.wrapper.brigadier.CommandNode.class);
|
||||
return wrappedCommandNode.apiCommandMeta() != null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -39,7 +39,7 @@ public class GUIHotBar implements Listener {
|
||||
private final List<Player> currentPlayers = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Setup a new gui hot bar. You should not instantiate more than one hot bar.
|
||||
* Set up a new gui hot bar. You should not instantiate more than one hot bar.
|
||||
* @param defaultSlot the default slot (currently held item) when the player joins the hot bar.
|
||||
*/
|
||||
public GUIHotBar(int defaultSlot) {
|
||||
|
@@ -18,6 +18,11 @@ import java.util.Objects;
|
||||
*/
|
||||
public class DummyPlayerInventory extends InventoryWrapper implements PlayerInventory {
|
||||
|
||||
/**
|
||||
* Total number of item slots in the player inventory.
|
||||
*/
|
||||
public static final int PLAYER_INVENTORY_SIZE = 43; // 36 base inventory + 4 armor slots + 1 off hand + 2 hidden slots (body and saddle)
|
||||
|
||||
private int heldItemSlot;
|
||||
|
||||
/**
|
||||
@@ -27,8 +32,8 @@ public class DummyPlayerInventory extends InventoryWrapper implements PlayerInve
|
||||
*/
|
||||
public DummyPlayerInventory(Inventory base, int heldItemSlot) {
|
||||
super(base);
|
||||
if (base.getSize() < 41)
|
||||
throw new IllegalArgumentException("base inventory should have a size of 41 (" + base.getSize() + " given).");
|
||||
if (base.getSize() < PLAYER_INVENTORY_SIZE)
|
||||
throw new IllegalArgumentException("base inventory should have a size of " + PLAYER_INVENTORY_SIZE + " (" + base.getSize() + " given).");
|
||||
if (heldItemSlot < 0 || heldItemSlot > 8)
|
||||
throw new IllegalArgumentException("heldItemSlot should be between 0 and 8 inclusive.");
|
||||
this.heldItemSlot = heldItemSlot;
|
||||
@@ -114,6 +119,40 @@ public class DummyPlayerInventory extends InventoryWrapper implements PlayerInve
|
||||
setItem(36, boots);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item stack in the SADDLE {@link EquipmentSlot}.
|
||||
* @return the SADDLE item stack.
|
||||
*/
|
||||
public ItemStack getSaddle() {
|
||||
return getItem(42);
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the provided item stack in the SADDLE {@link EquipmentSlot}.
|
||||
* @param saddle the item.
|
||||
*/
|
||||
public void setSaddle(@Nullable ItemStack saddle) {
|
||||
setItem(42, saddle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item stack in the BODY {@link EquipmentSlot}.
|
||||
* @return the BODY item stack.
|
||||
*/
|
||||
public ItemStack getBody() {
|
||||
return getItem(41);
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the provided item stack in the BODY {@link EquipmentSlot}.
|
||||
* @param body the item.
|
||||
*/
|
||||
public void setBody(@Nullable ItemStack body) {
|
||||
setItem(41, body);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void setItem(EquipmentSlot slot, ItemStack item) {
|
||||
Preconditions.checkArgument(slot != null, "slot must not be null");
|
||||
@@ -125,7 +164,8 @@ public class DummyPlayerInventory extends InventoryWrapper implements PlayerInve
|
||||
case LEGS -> this.setLeggings(item);
|
||||
case CHEST -> this.setChestplate(item);
|
||||
case HEAD -> this.setHelmet(item);
|
||||
default -> throw new IllegalArgumentException("Not implemented. This is a bug");
|
||||
case BODY -> this.setBody(item);
|
||||
case SADDLE -> this.setSaddle(item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +178,8 @@ public class DummyPlayerInventory extends InventoryWrapper implements PlayerInve
|
||||
case LEGS -> Objects.requireNonNullElseGet(this.getLeggings(), () -> new ItemStack(Material.AIR));
|
||||
case CHEST -> Objects.requireNonNullElseGet(this.getChestplate(), () -> new ItemStack(Material.AIR));
|
||||
case HEAD -> Objects.requireNonNullElseGet(this.getHelmet(), () -> new ItemStack(Material.AIR));
|
||||
case BODY -> new ItemStack(Material.AIR); // for horses/wolves armor
|
||||
case BODY -> Objects.requireNonNullElseGet(this.getBody(), () -> new ItemStack(Material.AIR)); // for horses/wolves armor
|
||||
case SADDLE -> Objects.requireNonNullElseGet(this.getSaddle(), () -> new ItemStack(Material.AIR));
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -2,9 +2,14 @@ package fr.pandacube.lib.paper.inventory;
|
||||
|
||||
import com.google.common.collect.Streams;
|
||||
import fr.pandacube.lib.chat.Chat;
|
||||
import io.papermc.paper.datacomponent.DataComponentType;
|
||||
import io.papermc.paper.datacomponent.DataComponentType.Valued;
|
||||
import io.papermc.paper.datacomponent.DataComponentTypes;
|
||||
import io.papermc.paper.datacomponent.item.ResolvableProfile;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.ComponentLike;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -12,6 +17,7 @@ import org.bukkit.inventory.meta.Damageable;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
@@ -70,15 +76,10 @@ public class ItemStackBuilder {
|
||||
|
||||
|
||||
private final ItemStack stack;
|
||||
private ItemMeta cachedMeta;
|
||||
|
||||
private ItemStackBuilder(ItemStack base) {
|
||||
stack = base;
|
||||
}
|
||||
|
||||
private ItemMeta getOrInitMeta() {
|
||||
return (cachedMeta != null) ? cachedMeta : (cachedMeta = stack.getItemMeta());
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the provided updater on the {@link ItemMeta} instance of the built stack.
|
||||
@@ -97,10 +98,7 @@ public class ItemStackBuilder {
|
||||
* @return itself.
|
||||
*/
|
||||
public <T extends ItemMeta> ItemStackBuilder meta(Consumer<T> metaUpdater, Class<T> metaType) {
|
||||
stack.editMeta(metaType, m -> {
|
||||
metaUpdater.accept(m);
|
||||
cachedMeta = m;
|
||||
});
|
||||
stack.editMeta(metaType, metaUpdater);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -166,7 +164,7 @@ public class ItemStackBuilder {
|
||||
*/
|
||||
public ItemStackBuilder addLoreAfter(List<? extends ComponentLike> lores) {
|
||||
if (lores != null) {
|
||||
List<Component> baseLore = getOrInitMeta().lore();
|
||||
List<Component> baseLore = stack.getItemMeta().lore();
|
||||
if (baseLore == null) baseLore = Collections.emptyList();
|
||||
return rawLore(
|
||||
Streams.concat(
|
||||
@@ -302,6 +300,107 @@ public class ItemStackBuilder {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets a value for a data component of this item.
|
||||
* @param dataType the data component type.
|
||||
* @param dataValue the data component value.
|
||||
* @return itself.
|
||||
* @param <T> the data component API type.
|
||||
*/
|
||||
public <T> ItemStackBuilder data(Valued<T> dataType, T dataValue) {
|
||||
stack.setData(dataType, dataValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset (set to empty) a value for a data component of this item.
|
||||
* @param dataType the data component type.
|
||||
* @return itself.
|
||||
*/
|
||||
public ItemStackBuilder unsetData(DataComponentType dataType) {
|
||||
stack.unsetData(dataType);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset (act as default) a value for a data component of this item.
|
||||
* @param dataType the data component type.
|
||||
* @return itself.
|
||||
*/
|
||||
public ItemStackBuilder resetData(DataComponentType dataType) {
|
||||
stack.resetData(dataType);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the {@code can_break} data component to the provided list of {@link Material}.
|
||||
* @param canBreak a list of {@link Material}.
|
||||
* @return itself.
|
||||
*/
|
||||
public ItemStackBuilder canBreakMaterials(Collection<Material> canBreak) {
|
||||
return canBreak(canBreak.stream().map(Material::getKey).toList());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the {@code can_break} data component to the provided list of {@link NamespacedKey}.
|
||||
* @param canBreak a list of block predicate. If empty, unsets the data component. If null, reset to default.
|
||||
* @return itself.
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
public ItemStackBuilder canBreak(Collection<NamespacedKey> canBreak) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<com.destroystokyo.paper.Namespaced> nsCanBreak = (Collection<com.destroystokyo.paper.Namespaced>) (Collection<?>) canBreak;
|
||||
return meta(m -> m.setDestroyableKeys(nsCanBreak));
|
||||
|
||||
/*
|
||||
if (canBreak == null)
|
||||
return resetData(DataComponentTypes.CAN_BREAK);
|
||||
else if (canBreak.isEmpty())
|
||||
return unsetData(DataComponentTypes.CAN_BREAK);
|
||||
else
|
||||
return data(DataComponentTypes.CAN_BREAK, ItemAdventurePredicate.itemAdventurePredicate(canBreak));*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@code can_place_on} data component to the provided list of {@link Material}.
|
||||
* @param canPlaceOn a list of {@link Material}.
|
||||
* @return itself.
|
||||
*/
|
||||
public ItemStackBuilder canPlaceOnMaterials(Collection<Material> canPlaceOn) {
|
||||
return canPlaceOn(canPlaceOn.stream().map(Material::getKey).toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@code can_place_on} data component to the provided list of {@link NamespacedKey}.
|
||||
* @param canPlaceOn a list of block predicate. If empty, unsets the data component. If null, reset to default.
|
||||
* @return itself.
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
public ItemStackBuilder canPlaceOn(Collection<NamespacedKey> canPlaceOn) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<com.destroystokyo.paper.Namespaced> nsCanPlaceOn = (Collection<com.destroystokyo.paper.Namespaced>) (Collection<?>) canPlaceOn;
|
||||
return meta(m -> m.setPlaceableKeys(nsCanPlaceOn));
|
||||
|
||||
/* if (canPlaceOn == null)
|
||||
return resetData(DataComponentTypes.CAN_PLACE_ON);
|
||||
else if (canPlaceOn.isEmpty())
|
||||
return unsetData(DataComponentTypes.CAN_PLACE_ON);
|
||||
else
|
||||
return data(DataComponentTypes.CAN_PLACE_ON, ItemAdventurePredicate.itemAdventurePredicate(canPlaceOn)); */
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@code profile} data component to the provided profile.
|
||||
* @param profile the profile to use as the component value.
|
||||
* @return itself.
|
||||
*/
|
||||
public ItemStackBuilder profile(ResolvableProfile profile) {
|
||||
return data(DataComponentTypes.PROFILE, profile);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Build the {@link ItemStack}.
|
||||
* @return the build item stack.
|
||||
|
@@ -0,0 +1,126 @@
|
||||
package fr.pandacube.lib.paper.inventory;
|
||||
|
||||
import com.destroystokyo.paper.profile.ProfileProperty;
|
||||
import io.papermc.paper.datacomponent.item.ResolvableProfile;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Base64;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Represents some special mob heads, also support creating player skulls and custom skulls.
|
||||
*/
|
||||
public enum Skull {
|
||||
|
||||
/** Jungle wood arrow left. */
|
||||
ARROW_LEFT("http://textures.minecraft.net/texture/3625902b389ed6c147574e422da8f8f361c8eb57e7631676a72777e7b1d"),
|
||||
/** Jungle wood arrow right. */
|
||||
ARROW_RIGHT("http://textures.minecraft.net/texture/d4be8aeec11849697adc6fd1f189b16642dff19f2955c05deaba68c9dff1be"),
|
||||
/** Jungle wood arrow up. */
|
||||
ARROW_UP("http://textures.minecraft.net/texture/88c0f37dec764d6e26b57aa8212572fbace5ee8f27f7b61c1fdaa47dd4c893"),
|
||||
/** Jungle wood arrow down. */
|
||||
ARROW_DOWN("http://textures.minecraft.net/texture/751ced2e647366f8f3ad2dfe415cca85651bfaf9739a95cd57b6f21cba053"),
|
||||
/** Jungle wood question mark. */
|
||||
QUESTION("http://textures.minecraft.net/texture/b4d7cc4dca986a53f1d6b52aaf376dc6acc73b8b287f42dc8fef5808bb5d76"),
|
||||
/** Jungle wood exclamation mark. */
|
||||
EXCLAMATION("http://textures.minecraft.net/texture/e869dc405a3155f281c16a3e8d9ff54afc1599153b4d9385c9b7bab88680f0");
|
||||
|
||||
private final String skinUrl;
|
||||
|
||||
Skull(String skinUrl) {
|
||||
this.skinUrl = skinUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the item based on this Skull enum.
|
||||
* @return the item stack.
|
||||
*/
|
||||
public ItemStack get() {
|
||||
return getFromSkinURL(skinUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an item stack builder already containing the skull.
|
||||
* @return an item stack builder already containing the skull.
|
||||
*/
|
||||
public ItemStackBuilder builder() {
|
||||
return ItemStackBuilder.wrap(get());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return a skull of a player based on their name.
|
||||
*
|
||||
* @param name player's name
|
||||
* @return item stack
|
||||
*/
|
||||
public static ItemStack getFromPlayerName(String name) {
|
||||
return getFromProfile(ResolvableProfile.resolvableProfile().name(name).build());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return a skull that has a custom texture specified by url.
|
||||
* @param url skin url.
|
||||
* @return item stack
|
||||
*/
|
||||
public static ItemStack getFromSkinURL(String url) {
|
||||
return getFromProfile(ResolvableProfile.resolvableProfile().addProperty(getTexturesProperty(url)).build());
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static ItemStack getFromProfile(ResolvableProfile profile) {
|
||||
return ItemStackBuilder.of(Material.PLAYER_HEAD).profile(profile).build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The URL prefix for all the player related textures (skin, cape)
|
||||
*/
|
||||
public static final String TEXTURE_URL_PREFIX = "http://textures.minecraft.net/texture/";
|
||||
|
||||
private static final Pattern textureIdMatcher = Pattern.compile("^[0-9a-fA-F]+$");
|
||||
|
||||
/**
|
||||
* Generate the base64 value of the "textures" profile property, based on the provided skin url!
|
||||
* @param skinURL the URL of the skin. The "https" will be replaced by "http" because this is the protocol used in
|
||||
* the profile property url. If only the texture id part is provided, {@link #TEXTURE_URL_PREFIX} is
|
||||
* prepended.
|
||||
* @return the base64 encoded texture data.
|
||||
*/
|
||||
private static String encodeTextureBase64String(String skinURL) {
|
||||
if (skinURL.startsWith("https://")) // secure url is not the url found in texture data (even if it actually works in the browser)
|
||||
skinURL = "http://" + skinURL.substring("https://".length());
|
||||
if (!skinURL.startsWith(TEXTURE_URL_PREFIX)) { // accept taking only the texture id part ()
|
||||
if (textureIdMatcher.matcher(skinURL).matches())
|
||||
skinURL = TEXTURE_URL_PREFIX + skinURL;
|
||||
else
|
||||
throw new IllegalArgumentException("Invalid skin URL. Must be from " + TEXTURE_URL_PREFIX + ".");
|
||||
}
|
||||
return Base64.getEncoder().encodeToString(String.format("{\"textures\":{\"SKIN\":{\"url\":\"%s\"}}}", skinURL).getBytes());
|
||||
}
|
||||
|
||||
|
||||
private static ProfileProperty getTexturesProperty(String skinURL) {
|
||||
return new ProfileProperty("textures", encodeTextureBase64String(skinURL));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@ import java.util.Map;
|
||||
/**
|
||||
* Gson adapter for ConfigurationSerializable, an interface implemented by several classes in the Bukkit API to ease
|
||||
* serialization to YAML.
|
||||
*
|
||||
* <p>
|
||||
* To not reinvent the wheel, this class uses the Bukkit’s Yaml API to convert the objects from/to json.
|
||||
*/
|
||||
/* package */ class ConfigurationSerializableAdapter implements JsonSerializer<ConfigurationSerializable>, JsonDeserializer<ConfigurationSerializable> {
|
||||
|
@@ -9,10 +9,13 @@ import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import com.google.gson.Strictness;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.internal.bind.TreeTypeAdapter;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -28,16 +31,27 @@ import java.util.Map;
|
||||
private static final TypeToken<Map<String, Object>> MAP_STR_OBJ_TYPE = new TypeToken<>() { };
|
||||
|
||||
/** Gson instance with no custom type adapter */
|
||||
private static final Gson vanillaGson = new GsonBuilder().setLenient().create();
|
||||
private static final Gson vanillaGson = new GsonBuilder().setStrictness(Strictness.LENIENT).create();
|
||||
|
||||
@Override
|
||||
public ItemStack deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
if (!(json instanceof JsonObject jsonObj))
|
||||
throw new JsonParseException("Unable to deserialize a ConfigurationSerializable from the provided json structure.");
|
||||
|
||||
// the deserialized json may contain older data compatible with pre 1.21.5 but not compatible after.
|
||||
// if it contains both old and new data, delete the old one introduced for compatibility
|
||||
if (jsonObj.has("DataVersion")) { // it uses the new DataVersion data
|
||||
jsonObj.remove("v");
|
||||
}
|
||||
if (jsonObj.has("id")) {
|
||||
jsonObj.remove("type");
|
||||
}
|
||||
|
||||
if (jsonObj.has(ConfigurationSerialization.SERIALIZED_TYPE_KEY))
|
||||
return context.deserialize(jsonObj, ConfigurationSerializable.class);
|
||||
|
||||
|
||||
|
||||
if (jsonObj.has("meta")
|
||||
&& jsonObj.get("meta") instanceof JsonObject metaJson
|
||||
&& !metaJson.has(ConfigurationSerialization.SERIALIZED_TYPE_KEY)) {
|
||||
@@ -47,6 +61,8 @@ import java.util.Map;
|
||||
Map<String, Object> map = context.deserialize(jsonObj, MAP_STR_OBJ_TYPE.getType());
|
||||
fixDeserializationVersion(map);
|
||||
map.remove("meta");
|
||||
|
||||
|
||||
ItemStack is = ItemStack.deserialize(map);
|
||||
|
||||
Class<? extends ItemMeta> metaClass = is.getItemMeta().getClass();
|
||||
@@ -63,7 +79,17 @@ import java.util.Map;
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(ItemStack src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
return context.serialize(src.serialize(), MAP_STR_OBJ_TYPE.getType());
|
||||
Map<String, Object> serialized = src.serialize();
|
||||
|
||||
// make the generated json compatible with pre 1.21.5 deserializer (temporary fix during the upgrade of the server)
|
||||
if (serialized.containsKey("DataVersion")) {
|
||||
serialized.put("v", serialized.get("DataVersion"));
|
||||
}
|
||||
if (serialized.containsKey("id")) {
|
||||
serialized.put("type", Registry.MATERIAL.getOrThrow(Key.key((String)serialized.get("id"))).name());
|
||||
}
|
||||
|
||||
return context.serialize(serialized, MAP_STR_OBJ_TYPE.getType());
|
||||
}
|
||||
|
||||
|
||||
|
@@ -21,6 +21,7 @@ import net.kyori.adventure.bossbar.BossBar.Color;
|
||||
import net.kyori.adventure.bossbar.BossBar.Overlay;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
@@ -36,6 +37,7 @@ import java.lang.management.ThreadMXBean;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static fr.pandacube.lib.chat.ChatStatic.chat;
|
||||
import static fr.pandacube.lib.chat.ChatStatic.failureText;
|
||||
@@ -317,22 +319,25 @@ public class PerformanceAnalysisManager implements Listener {
|
||||
|
||||
|
||||
int[] tpsHistory = getTPSHistory();
|
||||
|
||||
// keep the legacy text when generating the bar to save space when converting to component
|
||||
StringBuilder s = new StringBuilder();
|
||||
TextColor prevC = null;
|
||||
|
||||
List<Pair<TextColor, AtomicInteger>> barComponents = new ArrayList<>(60);
|
||||
for (int i = 58; i >= 0; i--) {
|
||||
int t = tpsHistory[i];
|
||||
TextColor newC = tps1sGradient.pickColorAt(t);
|
||||
if (!newC.equals(prevC)) {
|
||||
s.append(text("|").color(newC).getLegacyText());
|
||||
prevC = newC;
|
||||
if (barComponents.isEmpty() || !newC.equals(barComponents.get(barComponents.size() - 1).getKey())) {
|
||||
barComponents.add(Pair.of(newC, new AtomicInteger(1)));
|
||||
}
|
||||
else {
|
||||
s.append("|");
|
||||
barComponents.get(barComponents.size() - 1).getValue().incrementAndGet();
|
||||
}
|
||||
}
|
||||
|
||||
Chat history = chat();
|
||||
barComponents.forEach(p -> {
|
||||
history.then(text("|".repeat(p.getValue().get()))
|
||||
.color(p.getKey())
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
|
||||
// tick time measurement
|
||||
@@ -355,7 +360,7 @@ public class PerformanceAnalysisManager implements Listener {
|
||||
: (avgTickCPUTime1s < 50) ? NamedTextColor.RED
|
||||
: NamedTextColor.DARK_RED;
|
||||
|
||||
float avgTickWaitingTime1s = avgTickDuration1s - avgTickCPUTime1s;
|
||||
float avgTickWaitingTime1s = Math.max(0, avgTickDuration1s - avgTickCPUTime1s);
|
||||
TextColor avgTickWaitingTime1sColor = (avgTickDuration1s < 46 || avgTickWaitingTime1s < 20) ? PandaTheme.CHAT_GREEN_1_NORMAL
|
||||
: (avgTickWaitingTime1s < 30) ? NamedTextColor.YELLOW
|
||||
: (avgTickWaitingTime1s < 40) ? NamedTextColor.GOLD
|
||||
@@ -371,16 +376,16 @@ public class PerformanceAnalysisManager implements Listener {
|
||||
: NamedTextColor.RED;
|
||||
|
||||
timings = text("(R/W/S:")
|
||||
.then(text(Math.round(avgTickCPUTime1s)).color(avgTickCPUTime1sColor))
|
||||
.then(text("%02d".formatted(Math.round(avgTickCPUTime1s))).color(avgTickCPUTime1sColor))
|
||||
.thenText("/")
|
||||
.then(text(Math.round(avgTickWaitingTime1s)).color(avgTickWaitingTime1sColor))
|
||||
.then(text("%02d".formatted(Math.round(avgTickWaitingTime1s))).color(avgTickWaitingTime1sColor))
|
||||
.thenText("/")
|
||||
.then(text(Math.round(avgInterTickDuration1s)).color(avgInterTickDuration1sColor))
|
||||
.then(text("%02d".formatted(Math.round(avgInterTickDuration1s))).color(avgInterTickDuration1sColor))
|
||||
.thenText("ms)");
|
||||
}
|
||||
|
||||
title = infoText("TPS [")
|
||||
.thenLegacyText(s.toString())
|
||||
.then(history)
|
||||
.thenText("] ")
|
||||
.then(text(tps1sDisplay + "/" + getTargetTickRate() + " ").color(tps1sGradient.pickColorAt(tps1s)))
|
||||
.then(timings);
|
||||
@@ -493,7 +498,7 @@ public class PerformanceAnalysisManager implements Listener {
|
||||
/**
|
||||
* Runs the garbage collector on the server.
|
||||
* Depending on the server load and the used memory, this can freeze the server for a second.
|
||||
* @param sender the command sender that triggers the garbase collector. Can be null (the report will be sent to the
|
||||
* @param sender the command sender that triggers the garbage collector. Can be null (the report will be sent to the
|
||||
* console)
|
||||
*/
|
||||
public static void gc(CommandSender sender) {
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package fr.pandacube.lib.paper.players;
|
||||
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.util.ProblemReporter;
|
||||
import fr.pandacube.lib.paper.world.PrimaryWorlds;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.CraftServer;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.CompoundTag;
|
||||
@@ -166,7 +167,7 @@ public interface PaperOffPlayer extends AbstractOffPlayer {
|
||||
.getServer()
|
||||
.getPlayerList()
|
||||
.playerIo()
|
||||
.load(getName(), getUniqueId().toString()).orElse(null);
|
||||
.load(getName(), getUniqueId().toString(), ProblemReporter.DISCARDING()).orElse(null);
|
||||
} catch (Exception|LinkageError e) {
|
||||
throw new PlayerDataLoadException(getName(), getUniqueId(), e);
|
||||
}
|
||||
|
@@ -3,9 +3,14 @@ package fr.pandacube.lib.paper.players;
|
||||
import fr.pandacube.lib.paper.inventory.DummyPlayerInventory;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.CraftItemStack;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.CompoundTag;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.ListTag;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.Tag;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.util.ProblemReporter;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.ItemStackWithSlot;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.TagValueInput;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.TagValueOutput;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.ValueInput;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.ValueOutputTypedOutputList;
|
||||
import fr.pandacube.lib.paper.util.ExperienceUtil;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
@@ -14,6 +19,7 @@ import org.bukkit.inventory.PlayerInventory;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
import java.util.function.IntUnaryOperator;
|
||||
@@ -118,17 +124,17 @@ public record PlayerDataWrapper(CompoundTag data) {
|
||||
}
|
||||
|
||||
private Map<Integer, ItemStack> getRawInventoryContent(String key) {
|
||||
if (!data.contains(key, Tag.TAG_LIST()))
|
||||
return Map.of();
|
||||
ListTag list = data.getList(key, Tag.TAG_COMPOUND());
|
||||
if (list == null)
|
||||
return Map.of();
|
||||
|
||||
ValueInput vi = TagValueInput.createGlobal(ProblemReporter.DISCARDING(), data);
|
||||
Iterable<?> listNMSItemStackWithSlot = ReflectWrapper.unwrap(vi.listOrEmpty(key, ItemStackWithSlot.CODEC()));
|
||||
|
||||
Map<Integer, ItemStack> stacks = new TreeMap<>();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
CompoundTag itemTag = list.getCompound(i);
|
||||
int nbtSlot = itemTag.getByte("Slot") & 255;
|
||||
fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.ItemStack.parse(itemTag)
|
||||
|
||||
for (Object nmsISWS : listNMSItemStackWithSlot) {
|
||||
ItemStackWithSlot isws = ReflectWrapper.wrap(nmsISWS, ItemStackWithSlot.class);
|
||||
|
||||
int nbtSlot = isws.slot() & 255;
|
||||
Optional.of(isws.stack())
|
||||
.map(nms -> filterStack(CraftItemStack.asCraftMirror(nms)))
|
||||
.ifPresent(is -> stacks.put(nbtSlot, is));
|
||||
}
|
||||
@@ -153,28 +159,27 @@ public record PlayerDataWrapper(CompoundTag data) {
|
||||
}
|
||||
|
||||
private void setRawInventoryContent(String key, Map<Integer, ItemStack> stacks) {
|
||||
ListTag list = new ListTag();
|
||||
|
||||
TagValueOutput vo = TagValueOutput.createWrappingGlobal(ProblemReporter.DISCARDING(), data);
|
||||
ValueOutputTypedOutputList listNMSItemStackWithSlot = vo.list(key, ItemStackWithSlot.CODEC());
|
||||
|
||||
for (Entry<Integer, ItemStack> is : stacks.entrySet()) {
|
||||
ItemStack stack = filterStack(is.getValue());
|
||||
if (stack == null)
|
||||
continue;
|
||||
CompoundTag itemTag = new CompoundTag();
|
||||
itemTag.putByte("Slot", is.getKey().byteValue());
|
||||
list.add(list.size(), CraftItemStack.asNMSCopy(is.getValue()).save(itemTag));
|
||||
|
||||
listNMSItemStackWithSlot.add(ReflectWrapper.unwrap(new ItemStackWithSlot(is.getKey(), CraftItemStack.asNMSCopy(is.getValue()))));
|
||||
}
|
||||
data.put(key, list);
|
||||
}
|
||||
|
||||
|
||||
private ItemStack filterStack(ItemStack is) {
|
||||
return is == null || is.getType().isEmpty() || is.getAmount() == 0 ? null : is;
|
||||
return is == null || is.isEmpty() || is.getAmount() <= 0 ? null : is;
|
||||
}
|
||||
|
||||
|
||||
private int getHeldItemSlot() {
|
||||
if (!data.contains("SelectedItemSlot"))
|
||||
return 0;
|
||||
return data.getInt("SelectedItemSlot");
|
||||
return data.getInt("SelectedItemSlot").orElse(0);
|
||||
}
|
||||
|
||||
private void setHeldItemSlot(int slot) {
|
||||
@@ -187,9 +192,7 @@ public record PlayerDataWrapper(CompoundTag data) {
|
||||
* @return the value of Score.
|
||||
*/
|
||||
public int getScore() {
|
||||
if (!data.contains("Score"))
|
||||
return 0;
|
||||
return data.getInt("Score");
|
||||
return data.getInt("Score").orElse(0);
|
||||
|
||||
}
|
||||
|
||||
@@ -207,9 +210,7 @@ public record PlayerDataWrapper(CompoundTag data) {
|
||||
* @return the value of XpTotal.
|
||||
*/
|
||||
public int getTotalExperience() {
|
||||
if (!data.contains("XpTotal"))
|
||||
return 0;
|
||||
return data.getInt("XpTotal");
|
||||
return data.getInt("XpTotal").orElse(0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -14,9 +14,7 @@ import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.VanillaCommandWrapper;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.dataconverter.MCDataConverter;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.dataconverter.MCDataType;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.dataconverter.MCTypeRegistry;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.DetectedVersion;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.SharedConstants;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.WorldVersion;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.CommandSourceStack;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.Commands;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.Coordinates;
|
||||
@@ -54,18 +52,25 @@ import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.ServerGamePacketL
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.ServerLevel;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.ServerPlayer;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.Settings;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.util.ProblemReporter;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.util.ProgressListener;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.AABB;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.ChunkPos;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.ChunkStorage;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.DataVersion;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.Entity;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.ItemStack;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.ItemStackWithSlot;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.Level;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.MapItemSavedData;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.PlayerDataStorage;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.RegionFileStorage;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.SavedData;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.TagValueInput;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.TagValueOutput;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.ValueInput;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.ValueInputTypedInputList;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.ValueOutput;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.ValueOutputTypedOutputList;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.Vec3;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.VoxelShape;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.block.BambooStalkBlock;
|
||||
@@ -73,9 +78,9 @@ import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.block.Block;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.netty.ByteBuf;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.netty.Unpooled;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.paper.PaperAdventure;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.paper.commands.APICommandMeta;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.paper.commands.BukkitCommandNode;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.paper.commands.PaperBrigadier;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.paper.commands.PluginCommandNode;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.paper.commands.ShadowBrigNode;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.paper.configuration.FallbackValue_Int;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.paper.configuration.WorldConfiguration;
|
||||
@@ -180,6 +185,7 @@ public class PandalibPaperReflect {
|
||||
thAcc.catchThrowable(() -> initWrapper(ServerPlayer.class, ServerPlayer.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(Settings.class, Settings.REFLECT.get()));
|
||||
// minecraft.util
|
||||
thAcc.catchThrowable(() -> initWrapper(ProblemReporter.class, ProblemReporter.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(ProgressListener.class, ProgressListener.REFLECT.get()));
|
||||
// minecraft.world.block
|
||||
thAcc.catchThrowable(() -> initWrapper(Block.class, Block.REFLECT.get()));
|
||||
@@ -188,29 +194,33 @@ public class PandalibPaperReflect {
|
||||
thAcc.catchThrowable(() -> initWrapper(AABB.class, AABB.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(ChunkPos.class, ChunkPos.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(ChunkStorage.class, ChunkStorage.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(DataVersion.class, DataVersion.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(Entity.class, Entity.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(ItemStack.class, ItemStack.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(ItemStackWithSlot.class, ItemStackWithSlot.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(Level.class, Level.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(MapItemSavedData.class, MapItemSavedData.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(PlayerDataStorage.class, PlayerDataStorage.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(RegionFileStorage.class, RegionFileStorage.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(SavedData.class, SavedData.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(TagValueInput.class, TagValueInput.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(TagValueOutput.class, TagValueOutput.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(ValueInput.class, ValueInput.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(ValueInputTypedInputList.class, ValueInputTypedInputList.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(ValueOutput.class, ValueOutput.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(ValueOutputTypedOutputList.class, ValueOutputTypedOutputList.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(Vec3.class, Vec3.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(VoxelShape.class, VoxelShape.REFLECT.get()));
|
||||
// minecraft
|
||||
thAcc.catchThrowable(() -> initWrapper(DetectedVersion.class, DetectedVersion.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(SharedConstants.class, SharedConstants.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(WorldVersion.class, WorldVersion.REFLECT.get()));
|
||||
|
||||
// netty
|
||||
thAcc.catchThrowable(() -> initWrapper(ByteBuf.class, ByteBuf.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(Unpooled.class, Unpooled.REFLECT.get()));
|
||||
|
||||
// paper.commands
|
||||
thAcc.catchThrowable(() -> initWrapper(APICommandMeta.class, APICommandMeta.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(BukkitCommandNode.class, BukkitCommandNode.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(PaperBrigadier.class, PaperBrigadier.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(PluginCommandNode.class, PluginCommandNode.REFLECT.get()));
|
||||
thAcc.catchThrowable(() -> initWrapper(ShadowBrigNode.class, ShadowBrigNode.REFLECT.get()));
|
||||
// paper.configuration
|
||||
thAcc.catchThrowable(() -> initWrapper(FallbackValue_Int.class, FallbackValue_Int.REFLECT.get()));
|
||||
|
@@ -34,7 +34,7 @@ public final class BedrockBambooCollisionFixer implements Listener {
|
||||
public BedrockBambooCollisionFixer() {
|
||||
// Make the bamboo block have zero collision.
|
||||
try {
|
||||
BambooStalkBlock.COLLISION_SHAPE(Block.box(8, 0, 8, 8, 0, 8));
|
||||
BambooStalkBlock.SHAPE_COLLISION(Block.box(8, 0, 8, 8, 0, 8));
|
||||
Log.info("Bamboo block collision box removed successfully.");
|
||||
} catch (Exception e) {
|
||||
Log.severe("Unable to remove the collision box of the Bamboo block.", e);
|
||||
|
@@ -1,6 +1,8 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.brigadier;
|
||||
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.paper.commands.APICommandMeta;
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectField;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
@@ -11,11 +13,20 @@ import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
public class CommandNode<S> extends ReflectWrapperTyped<com.mojang.brigadier.tree.CommandNode<S>> {
|
||||
public static final ReflectClass<?> REFLECT = Reflect.ofClass(com.mojang.brigadier.tree.CommandNode.class);
|
||||
private static final ReflectMethod<?> removeCommand = wrapEx(() -> REFLECT.method("removeCommand", String.class));
|
||||
private static final ReflectField<?> apiCommandMeta = wrapEx(() -> REFLECT.field("apiCommandMeta"));
|
||||
|
||||
public void removeCommand(String cmd) {
|
||||
wrapReflectEx(() -> removeCommand.invoke(__getRuntimeInstance(), cmd));
|
||||
}
|
||||
|
||||
public APICommandMeta apiCommandMeta() {
|
||||
return wrap(wrapReflectEx(() -> apiCommandMeta.getValue(__getRuntimeInstance())), APICommandMeta.class);
|
||||
}
|
||||
|
||||
public void apiCommandMeta(APICommandMeta meta) {
|
||||
wrapReflectEx(() -> apiCommandMeta.setValue(__getRuntimeInstance(), unwrap(meta)));
|
||||
}
|
||||
|
||||
protected CommandNode(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
@@ -1,12 +1,10 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.craftbukkit;
|
||||
|
||||
import fr.pandacube.lib.paper.reflect.OBCReflect;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.core.BlockPos;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.Vec3;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
|
||||
import fr.pandacube.lib.util.ThrowableUtil;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
@@ -16,26 +14,11 @@ import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
public class CraftVector extends ReflectWrapper {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> OBCReflect.ofClass("util.CraftVector"));
|
||||
public static final ReflectMethod<?> toBukkit_Vec3 = ThrowableUtil.wrapEx(() -> REFLECT.method("toBukkit", Vec3.REFLECT.get()));
|
||||
public static final ReflectMethod<?> toBukkit_BlockPos = ThrowableUtil.wrapEx(() -> REFLECT.method("toBukkit", BlockPos.REFLECT.get()));
|
||||
public static final ReflectMethod<?> toNMS = wrapEx(() -> REFLECT.method("toNMS", Vector.class));
|
||||
public static final ReflectMethod<?> toBlockPos = wrapEx(() -> REFLECT.method("toNMS", Vector.class));
|
||||
|
||||
public static Vector toBukkit(Vec3 nms) {
|
||||
return (Vector) wrapReflectEx(() -> toBukkit_Vec3.invokeStatic(unwrap(nms)));
|
||||
}
|
||||
|
||||
public static Vector toBukkit(BlockPos blockPos) {
|
||||
return (Vector) wrapReflectEx(() -> toBukkit_BlockPos.invokeStatic(unwrap(blockPos)));
|
||||
}
|
||||
|
||||
public static Vec3 toNMS(Vector bukkit) {
|
||||
return wrap(wrapReflectEx(() -> toNMS.invokeStatic(bukkit)), Vec3.class);
|
||||
}
|
||||
|
||||
public static BlockPos toBlockPos(Vector bukkit) {
|
||||
return wrap(wrapReflectEx(() -> toBlockPos.invokeStatic(bukkit)), BlockPos.class);
|
||||
}
|
||||
|
||||
|
||||
protected CraftVector(Object obj) {
|
||||
super(obj);
|
||||
|
@@ -17,13 +17,9 @@ import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
public class VanillaCommandWrapper extends ReflectWrapperTyped<BukkitCommand> {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> OBCReflect.ofClass("command.VanillaCommandWrapper"));
|
||||
public static final ReflectConstructor<?> CONSTRUCTOR = wrapEx(() -> REFLECT.constructor(Commands.REFLECT.get(), CommandNode.class));
|
||||
public static final ReflectField<?> vanillaCommand = wrapEx(() -> REFLECT.field("vanillaCommand"));
|
||||
public static final ReflectMethod<?> getListener = wrapEx(() -> REFLECT.method("getListener", CommandSender.class));
|
||||
|
||||
public VanillaCommandWrapper(Commands dispatcher, CommandNode<CommandSourceStack> vanillaCommand) {
|
||||
this(wrapReflectEx(() -> CONSTRUCTOR.instantiate(unwrap(dispatcher), vanillaCommand)));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public CommandNode<CommandSourceStack> vanillaCommand() {
|
||||
|
@@ -1,15 +0,0 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.minecraft;
|
||||
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
|
||||
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
|
||||
public class DetectedVersion extends ReflectWrapper implements WorldVersion {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.DetectedVersion"));
|
||||
|
||||
protected DetectedVersion(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
}
|
@@ -10,15 +10,10 @@ import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
public class SharedConstants extends ReflectWrapper {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.SharedConstants"));
|
||||
private static final ReflectMethod<?> getCurrentVersion = wrapEx(() -> REFLECT.method("getCurrentVersion"));
|
||||
private static final ReflectMethod<?> getProtocolVersion = wrapEx(() -> REFLECT.method("getProtocolVersion"));
|
||||
|
||||
|
||||
|
||||
public static WorldVersion getCurrentVersion() {
|
||||
return wrap(wrapReflectEx(() -> getCurrentVersion.invokeStatic()), WorldVersion.class);
|
||||
}
|
||||
|
||||
public static int getProtocolVersion() {
|
||||
return (int) wrapReflectEx(() -> getProtocolVersion.invokeStatic());
|
||||
}
|
||||
|
@@ -14,7 +14,7 @@ import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
@ConcreteWrapper(Coordinates.__concrete.class)
|
||||
public interface Coordinates extends ReflectWrapperI {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.commands.arguments.coordinates.Coordinates"));
|
||||
ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.commands.arguments.coordinates.Coordinates"));
|
||||
ReflectMethod<?> getPosition = wrapEx(() -> REFLECT.method("getPosition", CommandSourceStack.REFLECT.get()));
|
||||
|
||||
default Vec3 getPosition(io.papermc.paper.command.brigadier.CommandSourceStack source) {
|
||||
|
@@ -6,10 +6,9 @@ import fr.pandacube.lib.reflect.ReflectConstructor;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
@@ -20,21 +19,16 @@ public class CompoundTag extends ReflectWrapper implements Tag {
|
||||
private static final ReflectMethod<?> putBoolean = wrapEx(() -> REFLECT.method("putBoolean", String.class, boolean.class));
|
||||
private static final ReflectMethod<?> putByte = wrapEx(() -> REFLECT.method("putByte", String.class, byte.class));
|
||||
private static final ReflectMethod<?> putByteArray = wrapEx(() -> REFLECT.method("putByteArray", String.class, byte[].class));
|
||||
private static final ReflectMethod<?> putByteArray_List = wrapEx(() -> REFLECT.method("putByteArray", String.class, List.class));
|
||||
private static final ReflectMethod<?> putDouble = wrapEx(() -> REFLECT.method("putDouble", String.class, double.class));
|
||||
private static final ReflectMethod<?> putFloat = wrapEx(() -> REFLECT.method("putFloat", String.class, float.class));
|
||||
private static final ReflectMethod<?> putInt = wrapEx(() -> REFLECT.method("putInt", String.class, int.class));
|
||||
private static final ReflectMethod<?> putIntArray = wrapEx(() -> REFLECT.method("putIntArray", String.class, int[].class));
|
||||
private static final ReflectMethod<?> putIntArray_List = wrapEx(() -> REFLECT.method("putIntArray", String.class, List.class));
|
||||
private static final ReflectMethod<?> putString = wrapEx(() -> REFLECT.method("putString", String.class, String.class));
|
||||
private static final ReflectMethod<?> putUUID = wrapEx(() -> REFLECT.method("putUUID", String.class, UUID.class));
|
||||
private static final ReflectMethod<?> putLong = wrapEx(() -> REFLECT.method("putLong", String.class, long.class));
|
||||
private static final ReflectMethod<?> putLongArray = wrapEx(() -> REFLECT.method("putLongArray", String.class, long[].class));
|
||||
private static final ReflectMethod<?> putLongArray_List = wrapEx(() -> REFLECT.method("putLongArray", String.class, List.class));
|
||||
private static final ReflectMethod<?> putShort = wrapEx(() -> REFLECT.method("putShort", String.class, short.class));
|
||||
private static final ReflectMethod<?> put = wrapEx(() -> REFLECT.method("put", String.class, Tag.REFLECT.get()));
|
||||
|
||||
private static final ReflectMethod<?> getTagType = wrapEx(() -> REFLECT.method("getTagType", String.class));
|
||||
private static final ReflectMethod<?> getByte = wrapEx(() -> REFLECT.method("getByte", String.class));
|
||||
private static final ReflectMethod<?> getShort = wrapEx(() -> REFLECT.method("getShort", String.class));
|
||||
private static final ReflectMethod<?> getInt = wrapEx(() -> REFLECT.method("getInt", String.class));
|
||||
@@ -47,14 +41,13 @@ public class CompoundTag extends ReflectWrapper implements Tag {
|
||||
private static final ReflectMethod<?> getLongArray = wrapEx(() -> REFLECT.method("getLongArray", String.class));
|
||||
private static final ReflectMethod<?> getCompound = wrapEx(() -> REFLECT.method("getCompound", String.class));
|
||||
private static final ReflectMethod<?> getBoolean = wrapEx(() -> REFLECT.method("getBoolean", String.class));
|
||||
private static final ReflectMethod<?> getList = wrapEx(() -> REFLECT.method("getList", String.class, int.class));
|
||||
private static final ReflectMethod<?> getList = wrapEx(() -> REFLECT.method("getList", String.class));
|
||||
|
||||
private static final ReflectMethod<?> get = wrapEx(() -> REFLECT.method("get", String.class));
|
||||
private static final ReflectMethod<?> getAllKeys = wrapEx(() -> REFLECT.method("getAllKeys"));
|
||||
private static final ReflectMethod<?> keySet = wrapEx(() -> REFLECT.method("keySet"));
|
||||
private static final ReflectMethod<?> entrySet = wrapEx(() -> REFLECT.method("entrySet"));
|
||||
private static final ReflectMethod<?> size = wrapEx(() -> REFLECT.method("size"));
|
||||
private static final ReflectMethod<?> contains = wrapEx(() -> REFLECT.method("contains", String.class));
|
||||
private static final ReflectMethod<?> containsStringInt = wrapEx(() -> REFLECT.method("contains", String.class, int.class));
|
||||
|
||||
public CompoundTag() {
|
||||
this(wrapReflectEx(() -> CONSTRUCTOR.instantiate()));
|
||||
@@ -73,9 +66,6 @@ public class CompoundTag extends ReflectWrapper implements Tag {
|
||||
public void putByteArray(String key, byte[] value) {
|
||||
wrapReflectEx(() -> putByteArray.invoke(__getRuntimeInstance(), key, value));
|
||||
}
|
||||
public void putByteArray(String key, List<Byte> value) {
|
||||
wrapReflectEx(() -> putByteArray_List.invoke(__getRuntimeInstance(), key, value));
|
||||
}
|
||||
public void putDouble(String key, double value) {
|
||||
wrapReflectEx(() -> putDouble.invoke(__getRuntimeInstance(), key, value));
|
||||
}
|
||||
@@ -88,78 +78,79 @@ public class CompoundTag extends ReflectWrapper implements Tag {
|
||||
public void putIntArray(String key, int[] value) {
|
||||
wrapReflectEx(() -> putIntArray.invoke(__getRuntimeInstance(), key, value));
|
||||
}
|
||||
public void putIntArray(String key, List<Integer> value) {
|
||||
wrapReflectEx(() -> putIntArray_List.invoke(__getRuntimeInstance(), key, value));
|
||||
}
|
||||
public void putString(String key, String value) {
|
||||
wrapReflectEx(() -> putString.invoke(__getRuntimeInstance(), key, value));
|
||||
}
|
||||
public void putUUID(String key, UUID value) {
|
||||
wrapReflectEx(() -> putUUID.invoke(__getRuntimeInstance(), key, value));
|
||||
}
|
||||
public void putLong(String key, long value) {
|
||||
wrapReflectEx(() -> putLong.invoke(__getRuntimeInstance(), key, value));
|
||||
}
|
||||
public void putLongArray(String key, long[] value) {
|
||||
wrapReflectEx(() -> putLongArray.invoke(__getRuntimeInstance(), key, value));
|
||||
}
|
||||
public void putLongArray(String key, List<Long> value) {
|
||||
wrapReflectEx(() -> putLongArray_List.invoke(__getRuntimeInstance(), key, value));
|
||||
}
|
||||
public void putShort(String key, short value) {
|
||||
wrapReflectEx(() -> putShort.invoke(__getRuntimeInstance(), key, value));
|
||||
}
|
||||
public void put(String key, Tag value) {
|
||||
wrapReflectEx(() -> put.invoke(__getRuntimeInstance(), key, unwrap(value)));
|
||||
}
|
||||
public byte getTagType(String key) {
|
||||
return (byte) wrapReflectEx(() -> getTagType.invoke(__getRuntimeInstance(), key));
|
||||
@SuppressWarnings("unchecked")
|
||||
public Optional<Byte> getByte(String key) {
|
||||
return (Optional<Byte>) wrapReflectEx(() -> getByte.invoke(__getRuntimeInstance(), key));
|
||||
}
|
||||
public byte getByte(String key) {
|
||||
return (byte) wrapReflectEx(() -> getByte.invoke(__getRuntimeInstance(), key));
|
||||
@SuppressWarnings("unchecked")
|
||||
public Optional<Short> getShort(String key) {
|
||||
return (Optional<Short>) wrapReflectEx(() -> getShort.invoke(__getRuntimeInstance(), key));
|
||||
}
|
||||
public short getShort(String key) {
|
||||
return (short) wrapReflectEx(() -> getShort.invoke(__getRuntimeInstance(), key));
|
||||
@SuppressWarnings("unchecked")
|
||||
public Optional<Integer> getInt(String key) {
|
||||
return (Optional<Integer>) wrapReflectEx(() -> getInt.invoke(__getRuntimeInstance(), key));
|
||||
}
|
||||
public int getInt(String key) {
|
||||
return (int) wrapReflectEx(() -> getInt.invoke(__getRuntimeInstance(), key));
|
||||
@SuppressWarnings("unchecked")
|
||||
public Optional<Long> getLong(String key) {
|
||||
return (Optional<Long>) wrapReflectEx(() -> getLong.invoke(__getRuntimeInstance(), key));
|
||||
}
|
||||
public long getLong(String key) {
|
||||
return (long) wrapReflectEx(() -> getLong.invoke(__getRuntimeInstance(), key));
|
||||
@SuppressWarnings("unchecked")
|
||||
public Optional<Float> getFloat(String key) {
|
||||
return (Optional<Float>) wrapReflectEx(() -> getFloat.invoke(__getRuntimeInstance(), key));
|
||||
}
|
||||
public float getFloat(String key) {
|
||||
return (float) wrapReflectEx(() -> getFloat.invoke(__getRuntimeInstance(), key));
|
||||
@SuppressWarnings("unchecked")
|
||||
public Optional<Double> getDouble(String key) {
|
||||
return (Optional<Double>) wrapReflectEx(() -> getDouble.invoke(__getRuntimeInstance(), key));
|
||||
}
|
||||
public double getDouble(String key) {
|
||||
return (double) wrapReflectEx(() -> getDouble.invoke(__getRuntimeInstance(), key));
|
||||
@SuppressWarnings("unchecked")
|
||||
public Optional<String> getString(String key) {
|
||||
return (Optional<String>) wrapReflectEx(() -> getString.invoke(__getRuntimeInstance(), key));
|
||||
}
|
||||
public String getString(String key) {
|
||||
return (String) wrapReflectEx(() -> getString.invoke(__getRuntimeInstance(), key));
|
||||
@SuppressWarnings("unchecked")
|
||||
public Optional<byte[]> getByteArray(String key) {
|
||||
return (Optional<byte[]>) wrapReflectEx(() -> getByteArray.invoke(__getRuntimeInstance(), key));
|
||||
}
|
||||
public byte[] getByteArray(String key) {
|
||||
return (byte[]) wrapReflectEx(() -> getByteArray.invoke(__getRuntimeInstance(), key));
|
||||
@SuppressWarnings("unchecked")
|
||||
public Optional<int[]> getIntArray(String key) {
|
||||
return (Optional<int[]>) wrapReflectEx(() -> getIntArray.invoke(__getRuntimeInstance(), key));
|
||||
}
|
||||
public int[] getIntArray(String key) {
|
||||
return (int[]) wrapReflectEx(() -> getIntArray.invoke(__getRuntimeInstance(), key));
|
||||
@SuppressWarnings("unchecked")
|
||||
public Optional<long[]> getLongArray(String key) {
|
||||
return (Optional<long[]>) wrapReflectEx(() -> getLongArray.invoke(__getRuntimeInstance(), key));
|
||||
}
|
||||
public long[] getLongArray(String key) {
|
||||
return (long[]) wrapReflectEx(() -> getLongArray.invoke(__getRuntimeInstance(), key));
|
||||
public Optional<CompoundTag> getCompound(String key) {
|
||||
return ((Optional<?>) wrapReflectEx(() -> getCompound.invoke(__getRuntimeInstance(), key)))
|
||||
.map(u -> wrap(u, CompoundTag.class));
|
||||
}
|
||||
public CompoundTag getCompound(String key) {
|
||||
return wrap(wrapReflectEx(() -> getCompound.invoke(__getRuntimeInstance(), key)), CompoundTag.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
public Optional<Boolean> getBoolean(String key) {
|
||||
return (Optional<Boolean>) wrapReflectEx(() -> getBoolean.invoke(__getRuntimeInstance(), key));
|
||||
}
|
||||
public boolean getBoolean(String key) {
|
||||
return (boolean) wrapReflectEx(() -> getBoolean.invoke(__getRuntimeInstance(), key));
|
||||
}
|
||||
public ListTag getList(String key, int type) {
|
||||
return wrap(wrapReflectEx(() -> getList.invoke(__getRuntimeInstance(), key, type)), ListTag.class);
|
||||
public Optional<ListTag> getList(String key) {
|
||||
return ((Optional<?>) wrapReflectEx(() -> getList.invoke(__getRuntimeInstance(), key)))
|
||||
.map(u -> wrap(u, ListTag.class));
|
||||
}
|
||||
public Tag get(String key) {
|
||||
return wrap(wrapReflectEx(() -> get.invoke(__getRuntimeInstance(), key)), Tag.class);
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
public Set<String> getAllKeys() {
|
||||
return (Set<String>) wrapReflectEx(() -> getAllKeys.invoke(__getRuntimeInstance()));
|
||||
public Set<String> keySet() {
|
||||
return (Set<String>) wrapReflectEx(() -> keySet.invoke(__getRuntimeInstance()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,8 +167,5 @@ public class CompoundTag extends ReflectWrapper implements Tag {
|
||||
public boolean contains(String key) {
|
||||
return (boolean) wrapReflectEx(() -> contains.invoke(__getRuntimeInstance(), key));
|
||||
}
|
||||
public boolean contains(String key, int type) {
|
||||
return (boolean) wrapReflectEx(() -> containsStringInt.invoke(__getRuntimeInstance(), key, type));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -8,20 +8,22 @@ import fr.pandacube.lib.reflect.wrapper.ConcreteWrapper;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperI;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
@ConcreteWrapper(Tag.__concrete.class)
|
||||
public interface Tag extends ReflectWrapperI {
|
||||
ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.nbt.Tag"));
|
||||
ReflectMethod<?> getAsString = wrapEx(() -> REFLECT.method("getAsString"));
|
||||
ReflectMethod<?> asString = wrapEx(() -> REFLECT.method("asString"));
|
||||
ReflectField<?> TAG_LIST = wrapEx(() -> REFLECT.field("TAG_LIST"));
|
||||
ReflectField<?> TAG_COMPOUND = wrapEx(() -> REFLECT.field("TAG_COMPOUND"));
|
||||
ReflectField<?> TAG_ANY_NUMERIC = wrapEx(() -> REFLECT.field("TAG_ANY_NUMERIC"));
|
||||
|
||||
|
||||
default String getAsString() {
|
||||
return wrapReflectEx(() -> (String) getAsString.invoke(__getRuntimeInstance()));
|
||||
@SuppressWarnings("unchecked")
|
||||
default Optional<String> asString() {
|
||||
return wrapReflectEx(() -> (Optional<String>) asString.invoke(__getRuntimeInstance()));
|
||||
}
|
||||
|
||||
static byte TAG_LIST() {
|
||||
@@ -32,10 +34,6 @@ public interface Tag extends ReflectWrapperI {
|
||||
return wrapReflectEx(() -> (byte) TAG_COMPOUND.getStaticValue());
|
||||
}
|
||||
|
||||
static byte TAG_ANY_NUMERIC() {
|
||||
return wrapReflectEx(() -> (byte) TAG_ANY_NUMERIC.getStaticValue());
|
||||
}
|
||||
|
||||
|
||||
class __concrete extends ReflectWrapper implements Tag {
|
||||
private __concrete(Object obj) {
|
||||
|
@@ -0,0 +1,31 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.util;
|
||||
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectField;
|
||||
import fr.pandacube.lib.reflect.wrapper.ConcreteWrapper;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperI;
|
||||
|
||||
import static fr.pandacube.lib.reflect.wrapper.ReflectWrapper.wrap;
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
@ConcreteWrapper(ProblemReporter.__concrete.class)
|
||||
public interface ProblemReporter extends ReflectWrapperI {
|
||||
ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.util.ProblemReporter"));
|
||||
ReflectField<?> DISCARDING = wrapEx(() -> REFLECT.field("DISCARDING"));
|
||||
|
||||
static ProblemReporter DISCARDING() {
|
||||
return wrap(wrapReflectEx(DISCARDING::getStaticValue), ProblemReporter.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class __concrete extends ReflectWrapper implements ProblemReporter {
|
||||
protected __concrete(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
|
||||
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
|
||||
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
public class DataVersion extends ReflectWrapper {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.world.level.storage.DataVersion"));
|
||||
private static final ReflectMethod<?> getVersion = wrapEx(() -> REFLECT.method("getVersion"));
|
||||
private static final ReflectMethod<?> getSeries = wrapEx(() -> REFLECT.method("getSeries"));
|
||||
|
||||
|
||||
|
||||
public int getVersion() {
|
||||
return (int) wrapReflectEx(() -> getVersion.invoke(__getRuntimeInstance()));
|
||||
}
|
||||
|
||||
public String getSeries() {
|
||||
return (String) wrapReflectEx(() -> getSeries.invoke(__getRuntimeInstance()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
protected DataVersion(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
}
|
@@ -1,6 +1,5 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
|
||||
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.CompoundTag;
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
@@ -12,16 +11,11 @@ import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
public class Entity extends ReflectWrapper {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.world.entity.Entity"));
|
||||
public static final ReflectMethod<?> getBukkitEntity = wrapEx(() -> REFLECT.method("getBukkitEntity")); // spigot method
|
||||
public static final ReflectMethod<?> serializeEntity = wrapEx(() -> REFLECT.method("serializeEntity", CompoundTag.REFLECT.get())); // paper method
|
||||
|
||||
public org.bukkit.entity.Entity getBukkitEntity() {
|
||||
return (org.bukkit.entity.Entity) wrapReflectEx(() -> getBukkitEntity.invoke(__getRuntimeInstance()));
|
||||
}
|
||||
|
||||
public boolean serializeEntity(CompoundTag nbt) {
|
||||
return wrapReflectEx(() -> (Boolean) serializeEntity.invoke(__getRuntimeInstance(), unwrap(nbt)));
|
||||
}
|
||||
|
||||
protected Entity(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
@@ -1,63 +1,15 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
|
||||
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.CraftServer;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.core.HolderLookupProvider;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.core.RegistryAccess;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.Tag;
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
public class ItemStack extends ReflectWrapper {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.world.item.ItemStack"));
|
||||
private static final ReflectMethod<?> parse = wrapEx(() -> REFLECT.method("parse", HolderLookupProvider.REFLECT.get(), Tag.REFLECT.get()));
|
||||
private static final ReflectMethod<?> saveWithPrefix = wrapEx(() -> REFLECT.method("save", HolderLookupProvider.REFLECT.get(), Tag.REFLECT.get()));
|
||||
private static final ReflectMethod<?> save = wrapEx(() -> REFLECT.method("save", HolderLookupProvider.REFLECT.get()));
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Optional<ItemStack> parse(HolderLookupProvider registries, Tag nbt) {
|
||||
return ((Optional<Object>) wrapReflectEx(() -> parse.invokeStatic(unwrap(registries), unwrap(nbt))))
|
||||
.map(o -> wrap(o, ItemStack.class));
|
||||
}
|
||||
|
||||
|
||||
public static Optional<ItemStack> parse(Tag nbt) {
|
||||
return parse(getRegistries(), nbt);
|
||||
}
|
||||
|
||||
|
||||
protected ItemStack(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
||||
|
||||
public Tag save(HolderLookupProvider registries, Tag prefix) {
|
||||
return wrap(wrapReflectEx(() -> saveWithPrefix.invoke(__getRuntimeInstance(), unwrap(registries), unwrap(prefix))), Tag.class);
|
||||
}
|
||||
|
||||
|
||||
public Tag save(HolderLookupProvider registries) {
|
||||
return wrap(wrapReflectEx(() -> save.invoke(__getRuntimeInstance(), unwrap(registries))), Tag.class);
|
||||
}
|
||||
|
||||
|
||||
public Tag save(Tag prefix) {
|
||||
return save(getRegistries(), prefix);
|
||||
}
|
||||
|
||||
|
||||
public Tag save() {
|
||||
return save(getRegistries());
|
||||
}
|
||||
|
||||
private static RegistryAccess getRegistries() {
|
||||
return wrap(Bukkit.getServer(), CraftServer.class).getServer().registryAccess();
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,44 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectConstructor;
|
||||
import fr.pandacube.lib.reflect.ReflectField;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
|
||||
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
public class ItemStackWithSlot extends ReflectWrapper {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.world.ItemStackWithSlot"));
|
||||
private static final ReflectConstructor<?> CONSTRUCTOR = wrapEx(() -> REFLECT.constructor(int.class, ItemStack.REFLECT.get()));
|
||||
private static final ReflectField<?> CODEC = wrapEx(() -> REFLECT.field("CODEC"));
|
||||
private static final ReflectMethod<?> slot = wrapEx(() -> REFLECT.method("slot"));
|
||||
private static final ReflectMethod<?> stack = wrapEx(() -> REFLECT.method("stack"));
|
||||
|
||||
public static Codec<?> CODEC() {
|
||||
return (Codec<?>) wrapReflectEx(CODEC::getStaticValue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected ItemStackWithSlot(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
||||
public ItemStackWithSlot(int slot, ItemStack stack) {
|
||||
super(wrapReflectEx(() -> CONSTRUCTOR.instantiate(slot, unwrap(stack))));
|
||||
}
|
||||
|
||||
|
||||
public int slot() {
|
||||
return (int) wrapReflectEx(() -> slot.invoke(__getRuntimeInstance()));
|
||||
}
|
||||
|
||||
public ItemStack stack() {
|
||||
return wrap(wrapReflectEx(() -> stack.invoke(__getRuntimeInstance())), ItemStack.class);
|
||||
}
|
||||
|
||||
}
|
@@ -12,17 +12,12 @@ import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
public class Level extends ReflectWrapper {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.world.level.Level"));
|
||||
public static final ReflectMethod<?> getGameTime = wrapEx(() -> REFLECT.method("getGameTime"));
|
||||
public static final ReflectMethod<?> getFreeMapId = wrapEx(() -> REFLECT.method("getFreeMapId"));
|
||||
public static final ReflectMethod<?> paperConfig = wrapEx(() -> REFLECT.method("paperConfig")); // paper method
|
||||
|
||||
public long getGameTime() {
|
||||
return (long) wrapReflectEx(() -> getGameTime.invoke(__getRuntimeInstance()));
|
||||
}
|
||||
|
||||
public int getFreeMapId() {
|
||||
return (int) wrapReflectEx(() -> getFreeMapId.invoke(__getRuntimeInstance()));
|
||||
}
|
||||
|
||||
public WorldConfiguration paperConfig() {
|
||||
return wrap(wrapReflectEx(() -> paperConfig.invoke(__getRuntimeInstance())), WorldConfiguration.class);
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
|
||||
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.CompoundTag;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.util.ProblemReporter;
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
@@ -13,15 +14,15 @@ import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
public class PlayerDataStorage extends ReflectWrapper {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.world.level.storage.PlayerDataStorage"));
|
||||
public static final ReflectMethod<?> load = wrapEx(() -> REFLECT.method("load", String.class, String.class));
|
||||
public static final ReflectMethod<?> load = wrapEx(() -> REFLECT.method("load", String.class, String.class, ProblemReporter.REFLECT.get()));
|
||||
|
||||
/**
|
||||
* @param playerName the name of the player: used for loading error message and for offline UUID generation.
|
||||
* @param playerId UUID of a player as it is used to name the player data file (UUID.toString()).
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Optional<CompoundTag> load(String playerName, String playerId) {
|
||||
return wrapOptional((Optional<Object>) wrapReflectEx(() -> load.invoke(__getRuntimeInstance(), playerName, playerId)), CompoundTag.class);
|
||||
public Optional<CompoundTag> load(String playerName, String playerId, ProblemReporter problemReporter) {
|
||||
return wrapOptional((Optional<Object>) wrapReflectEx(() -> load.invoke(__getRuntimeInstance(), playerName, playerId, unwrap(problemReporter))), CompoundTag.class);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,25 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
|
||||
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.CompoundTag;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.util.ProblemReporter;
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
|
||||
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
public class TagValueInput extends ReflectWrapper implements ValueInput {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.world.level.storage.TagValueInput"));
|
||||
private static final ReflectMethod<?> createGlobal = wrapEx(() -> REFLECT.method("createGlobal", ProblemReporter.REFLECT.get(), CompoundTag.REFLECT.get()));
|
||||
|
||||
public static ValueInput createGlobal(ProblemReporter problemReporter, CompoundTag nbt) {
|
||||
return wrap(wrapReflectEx(() -> createGlobal.invokeStatic(unwrap(problemReporter), unwrap(nbt))), ValueInput.class);
|
||||
}
|
||||
|
||||
protected TagValueInput(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
|
||||
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.CompoundTag;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.util.ProblemReporter;
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
|
||||
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
public class TagValueOutput extends ReflectWrapper implements ValueOutput {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.world.level.storage.TagValueOutput"));
|
||||
private static final ReflectMethod<?> createWrappingGlobal = wrapEx(() -> REFLECT.method("createWrappingGlobal", ProblemReporter.REFLECT.get(), CompoundTag.REFLECT.get()));
|
||||
|
||||
public static TagValueOutput createWrappingGlobal(ProblemReporter problemReporter, CompoundTag nbt) {
|
||||
return wrap(wrapReflectEx(() -> createWrappingGlobal.invokeStatic(unwrap(problemReporter), unwrap(nbt))), TagValueOutput.class);
|
||||
}
|
||||
|
||||
protected TagValueOutput(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
import fr.pandacube.lib.reflect.wrapper.ConcreteWrapper;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperI;
|
||||
|
||||
import static fr.pandacube.lib.reflect.wrapper.ReflectWrapper.wrap;
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
@ConcreteWrapper(ValueInput.__concrete.class)
|
||||
public interface ValueInput extends ReflectWrapperI {
|
||||
ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.world.level.storage.ValueInput"));
|
||||
ReflectMethod<?> listOrEmpty = wrapEx(() -> REFLECT.method("listOrEmpty", String.class, Codec.class));
|
||||
|
||||
|
||||
|
||||
default ValueInputTypedInputList listOrEmpty(String key, Codec<?> elementCodec) {
|
||||
return wrap(wrapReflectEx(() -> listOrEmpty.invoke(__getRuntimeInstance(), key, elementCodec)), ValueInputTypedInputList.class);
|
||||
}
|
||||
|
||||
class __concrete extends ReflectWrapper implements ValueInput {
|
||||
private __concrete(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
|
||||
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.wrapper.ConcreteWrapper;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTypedI;
|
||||
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
|
||||
@ConcreteWrapper(ValueInputTypedInputList.__concrete.class)
|
||||
public interface ValueInputTypedInputList extends ReflectWrapperTypedI<Iterable<?>> {
|
||||
ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.world.level.storage.ValueInput$TypedInputList"));
|
||||
|
||||
|
||||
class __concrete extends ReflectWrapperTyped<Iterable<?>> implements ValueInputTypedInputList {
|
||||
private __concrete(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.minecraft;
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
|
||||
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.DataVersion;
|
||||
import com.mojang.serialization.Codec;
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
@@ -12,18 +12,18 @@ import static fr.pandacube.lib.reflect.wrapper.ReflectWrapper.wrap;
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
@ConcreteWrapper(WorldVersion.__concrete.class)
|
||||
public interface WorldVersion extends ReflectWrapperI {
|
||||
ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.WorldVersion"));
|
||||
ReflectMethod<?> getDataVersion = wrapEx(() -> REFLECT.method("getDataVersion"));
|
||||
@ConcreteWrapper(ValueOutput.__concrete.class)
|
||||
public interface ValueOutput extends ReflectWrapperI {
|
||||
ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.world.level.storage.ValueOutput"));
|
||||
ReflectMethod<?> list = wrapEx(() -> REFLECT.method("list", String.class, Codec.class));
|
||||
|
||||
default DataVersion getDataVersion() {
|
||||
return wrap(wrapReflectEx(() -> getDataVersion.invoke(__getRuntimeInstance())), DataVersion.class);
|
||||
|
||||
|
||||
default ValueOutputTypedOutputList list(String key, Codec<?> elementCodec) {
|
||||
return wrap(wrapReflectEx(() -> list.invoke(__getRuntimeInstance(), key, elementCodec)), ValueOutputTypedOutputList.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
class __concrete extends ReflectWrapper implements WorldVersion {
|
||||
class __concrete extends ReflectWrapper implements ValueOutput {
|
||||
private __concrete(Object obj) {
|
||||
super(obj);
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
|
||||
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
import fr.pandacube.lib.reflect.wrapper.ConcreteWrapper;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperI;
|
||||
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
@ConcreteWrapper(ValueOutputTypedOutputList.__concrete.class)
|
||||
public interface ValueOutputTypedOutputList extends ReflectWrapperI {
|
||||
ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.world.level.storage.ValueOutput$TypedOutputList"));
|
||||
ReflectMethod<?> add = wrapEx(() -> REFLECT.method("add", Object.class));
|
||||
|
||||
default void add(Object rawElement) {
|
||||
wrapReflectEx(() -> add.invoke(__getRuntimeInstance(), rawElement));
|
||||
}
|
||||
|
||||
|
||||
class __concrete extends ReflectWrapper implements ValueOutputTypedOutputList {
|
||||
private __concrete(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
}
|
||||
}
|
@@ -10,14 +10,14 @@ import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
public class BambooStalkBlock extends Block {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("net.minecraft.world.level.block.BambooStalkBlock"));
|
||||
public static final ReflectField<?> COLLISION_SHAPE = wrapEx(() -> REFLECT.field("COLLISION_SHAPE"));
|
||||
public static final ReflectField<?> SHAPE_COLLISION = wrapEx(() -> REFLECT.field("SHAPE_COLLISION"));
|
||||
|
||||
public static VoxelShape COLLISION_SHAPE() {
|
||||
return wrap(wrapReflectEx(COLLISION_SHAPE::getStaticValue), VoxelShape.class);
|
||||
public static VoxelShape SHAPE_COLLISION() {
|
||||
return wrap(wrapReflectEx(SHAPE_COLLISION::getStaticValue), VoxelShape.class);
|
||||
}
|
||||
|
||||
public static void COLLISION_SHAPE(VoxelShape shape) {
|
||||
wrapReflectEx(() -> COLLISION_SHAPE.setStaticValue(unwrap(shape)));
|
||||
public static void SHAPE_COLLISION(VoxelShape shape) {
|
||||
wrapReflectEx(() -> SHAPE_COLLISION.setStaticValue(unwrap(shape)));
|
||||
}
|
||||
|
||||
protected BambooStalkBlock(Object obj) {
|
||||
|
@@ -0,0 +1,39 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.paper.commands;
|
||||
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
public class APICommandMeta extends ReflectWrapper {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("io.papermc.paper.command.brigadier.APICommandMeta"));
|
||||
private static final ReflectMethod<?> plugin = wrapEx(() -> REFLECT.method("plugin"));
|
||||
private static final ReflectMethod<?> description = wrapEx(() -> REFLECT.method("description"));
|
||||
private static final ReflectMethod<?> aliases = wrapEx(() -> REFLECT.method("aliases"));
|
||||
|
||||
|
||||
public Plugin plugin() {
|
||||
return (Plugin) wrapReflectEx(() -> plugin.invoke(__getRuntimeInstance()));
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return (String) wrapReflectEx(() -> description.invoke(__getRuntimeInstance()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<String> aliases() {
|
||||
return (List<String>) wrapReflectEx(() -> aliases.invoke(__getRuntimeInstance()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected APICommandMeta(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
}
|
@@ -1,18 +1,15 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.paper.commands;
|
||||
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.brigadier.CommandNode;
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped;
|
||||
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
public class BukkitCommandNode extends ReflectWrapperTyped<LiteralCommandNode<CommandSourceStack>> {
|
||||
public class BukkitCommandNode<S> extends CommandNode<S> {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("io.papermc.paper.command.brigadier.bukkit.BukkitCommandNode"));
|
||||
private static final ReflectMethod<?> getBukkitCommand = wrapEx(() -> REFLECT.method("getBukkitCommand"));
|
||||
|
||||
|
@@ -1,43 +0,0 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.paper.commands;
|
||||
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.ReflectConstructor;
|
||||
import fr.pandacube.lib.reflect.ReflectMethod;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped;
|
||||
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||
import io.papermc.paper.plugin.configuration.PluginMeta;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
|
||||
|
||||
public class PluginCommandNode extends ReflectWrapperTyped<LiteralCommandNode<CommandSourceStack>> {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("io.papermc.paper.command.brigadier.PluginCommandNode"));
|
||||
private static final ReflectMethod<?> getPlugin = wrapEx(() -> REFLECT.method("getPlugin"));
|
||||
private static final ReflectMethod<?> getDescription = wrapEx(() -> REFLECT.method("getDescription"));
|
||||
private static final ReflectConstructor CONSTRUCTOR = wrapEx(() -> REFLECT.constructor(String.class, PluginMeta.class, LiteralCommandNode.class, String.class));
|
||||
|
||||
|
||||
public PluginCommandNode(@NotNull String literal, @NotNull PluginMeta plugin, @NotNull LiteralCommandNode<CommandSourceStack> rootLiteral, @Nullable String description) {
|
||||
this(wrapReflectEx(() -> CONSTRUCTOR.instantiate(literal, plugin, rootLiteral, description)));
|
||||
}
|
||||
|
||||
|
||||
public Plugin getPlugin() {
|
||||
return (Plugin) wrapReflectEx(() -> getPlugin.invoke(__getRuntimeInstance()));
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return (String) wrapReflectEx(() -> getDescription.invoke(__getRuntimeInstance()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected PluginCommandNode(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
}
|
@@ -1,14 +1,12 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.paper.commands;
|
||||
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.brigadier.CommandNode;
|
||||
import fr.pandacube.lib.reflect.Reflect;
|
||||
import fr.pandacube.lib.reflect.ReflectClass;
|
||||
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped;
|
||||
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||
|
||||
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
|
||||
|
||||
public class ShadowBrigNode extends ReflectWrapperTyped<LiteralCommandNode<CommandSourceStack>> {
|
||||
public class ShadowBrigNode<S> extends CommandNode<S> {
|
||||
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("io.papermc.paper.command.brigadier.ShadowBrigNode"));
|
||||
|
||||
|
||||
|
@@ -57,8 +57,8 @@ public class AutoUpdatedBossBar implements Listener {
|
||||
* Schedule the update of this boss bar with synchronisation with the system clock.
|
||||
* The underlying method called is {@link Timer#schedule(TimerTask, long, long)}.
|
||||
* The updater is executed in a separate Thread.
|
||||
* @param msDelay ms before running the first update of this bossbar
|
||||
* @param msPeriod ms between each call of the updater
|
||||
* @param msDelay ms before running the first update of this boss bar.
|
||||
* @param msPeriod ms between each call of the updater.
|
||||
*/
|
||||
public synchronized void scheduleUpdateTimeSyncThreadAsync(long msDelay, long msPeriod) {
|
||||
if (scheduled)
|
||||
@@ -82,8 +82,8 @@ public class AutoUpdatedBossBar implements Listener {
|
||||
* Schedule the update of this boss bar with synchronisation with the ticking of this Minecraft server.
|
||||
* The underlying method called is {@link BukkitScheduler#runTaskTimer(org.bukkit.plugin.Plugin, Runnable, long, long)}.
|
||||
* The updater is executed by the main Server Thread.
|
||||
* @param tickDelay number of server tick before running the first update of this boss bar
|
||||
* @param tickPeriod number of server tick between each call of the updater
|
||||
* @param tickDelay number of server tick before running the first update of this boss bar.
|
||||
* @param tickPeriod number of server tick between each call of the updater.
|
||||
*/
|
||||
public synchronized void scheduleUpdateTickSyncThreadSync(long tickDelay, long tickPeriod) {
|
||||
if (scheduled)
|
||||
|
@@ -141,7 +141,7 @@ public class BukkitEvent {
|
||||
|
||||
|
||||
/**
|
||||
* An single executor event listener. Used for the {@link #register(Class, EventListener)} static method and the other variants.
|
||||
* A single executor event listener. Used for the {@link #register(Class, EventListener)} static method and the other variants.
|
||||
* @param <E> the event type.
|
||||
*/
|
||||
public interface EventListener<E extends Event> extends Listener, EventExecutor {
|
||||
|
@@ -1,230 +0,0 @@
|
||||
package fr.pandacube.lib.paper.util;
|
||||
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
|
||||
import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
import com.destroystokyo.paper.profile.ProfileProperty;
|
||||
|
||||
import fr.pandacube.lib.chat.Chat;
|
||||
|
||||
/**
|
||||
* Represents some special mob heads, also support creating player skulls and custom skulls.
|
||||
*
|
||||
* @author xigsag, SBPrime
|
||||
*
|
||||
* @see <a href="https://github.com/TigerHix/Hex-Utils/blob/9954159a323d12733b29c287a56980991cee2948/hex/util/Skull.java">github.com/TigerHix/Hex-Utils/hex/util/Skull.java</a>
|
||||
*/
|
||||
public enum Skull {
|
||||
|
||||
/** Standard skull of player MHF_ArrowLeft. */
|
||||
ARROW_LEFT("MHF_ArrowLeft"),
|
||||
/** Standard skull of player MHF_ArrowRight. */
|
||||
ARROW_RIGHT("MHF_ArrowRight"),
|
||||
/** Standard skull of player MHF_ArrowUp. */
|
||||
ARROW_UP("MHF_ArrowUp"),
|
||||
/** Standard skull of player MHF_ArrowDown. */
|
||||
ARROW_DOWN("MHF_ArrowDown"),
|
||||
/** Standard skull of player MHF_Question. */
|
||||
QUESTION("MHF_Question"),
|
||||
/** Standard skull of player MHF_Exclamation. */
|
||||
EXCLAMATION("MHF_Exclamation"),
|
||||
/** Standard skull of player FHG_Cam. */
|
||||
CAMERA("FHG_Cam"),
|
||||
|
||||
/** Standard skull of player MHF_PigZombie. */
|
||||
ZOMBIE_PIGMAN("MHF_PigZombie"),
|
||||
/** Standard skull of player MHF_Pig. */
|
||||
PIG("MHF_Pig"),
|
||||
/** Standard skull of player MHF_Sheep. */
|
||||
SHEEP("MHF_Sheep"),
|
||||
/** Standard skull of player MHF_Blaze. */
|
||||
BLAZE("MHF_Blaze"),
|
||||
/** Standard skull of player MHF_Chicken. */
|
||||
CHICKEN("MHF_Chicken"),
|
||||
/** Standard skull of player MHF_Cow. */
|
||||
COW("MHF_Cow"),
|
||||
/** Standard skull of player MHF_Slime. */
|
||||
SLIME("MHF_Slime"),
|
||||
/** Standard skull of player MHF_Spider. */
|
||||
SPIDER("MHF_Spider"),
|
||||
/** Standard skull of player MHF_Squid. */
|
||||
SQUID("MHF_Squid"),
|
||||
/** Standard skull of player MHF_Villager. */
|
||||
VILLAGER("MHF_Villager"),
|
||||
/** Standard skull of player MHF_Ocelot. */
|
||||
OCELOT("MHF_Ocelot"),
|
||||
/** Standard skull of player MHF_Herobrine. */
|
||||
HEROBRINE("MHF_Herobrine"),
|
||||
/** Standard skull of player MHF_LavaSlime. */
|
||||
LAVA_SLIME("MHF_LavaSlime"),
|
||||
/** Standard skull of player MHF_MushroomCow. */
|
||||
MOOSHROOM("MHF_MushroomCow"),
|
||||
/** Standard skull of player MHF_Golem. */
|
||||
GOLEM("MHF_Golem"),
|
||||
/** Standard skull of player MHF_Ghast. */
|
||||
GHAST("MHF_Ghast"),
|
||||
/** Standard skull of player MHF_Enderman. */
|
||||
ENDERMAN("MHF_Enderman"),
|
||||
/** Standard skull of player MHF_CaveSpider. */
|
||||
CAVE_SPIDER("MHF_CaveSpider"),
|
||||
|
||||
/** Standard skull of player MHF_Cactus. */
|
||||
CACTUS("MHF_Cactus"),
|
||||
/** Standard skull of player MHF_Cake. */
|
||||
CAKE("MHF_Cake"),
|
||||
/** Standard skull of player MHF_Chest. */
|
||||
CHEST("MHF_Chest"),
|
||||
/** Standard skull of player MHF_Melon. */
|
||||
MELON("MHF_Melon"),
|
||||
/** Standard skull of player MHF_OakLog. */
|
||||
LOG("MHF_OakLog"),
|
||||
/** Standard skull of player MHF_Pumpkin. */
|
||||
PUMPKIN("MHF_Pumpkin"),
|
||||
/** Standard skull of player MHF_TNT. */
|
||||
TNT("MHF_TNT"),
|
||||
/** Standard skull of player MHF_TNT2. */
|
||||
DYNAMITE("MHF_TNT2");
|
||||
|
||||
private final String name;
|
||||
|
||||
Skull(String mcName) {
|
||||
name = mcName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the item based on this Skull enum.
|
||||
*
|
||||
* @return item stack
|
||||
*/
|
||||
public ItemStack get() {
|
||||
return get(null, null);
|
||||
}
|
||||
/**
|
||||
* Return the item based on this Skull enum, with the provided display name and lore.
|
||||
* @param displayName the display name to add to the returned skull.
|
||||
* @param lore the lore to add to the returned skull.
|
||||
* @return item stack
|
||||
*/
|
||||
public ItemStack get(Chat displayName, List<Chat> lore) {
|
||||
return getFromPlayerName(name, displayName, lore);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return a skull of a player based on their name.
|
||||
*
|
||||
* @param name player's name
|
||||
* @param displayName the display name to add to the returned skull.
|
||||
* @param lore the lore to add to the returned skull.
|
||||
* @return item stack
|
||||
*/
|
||||
public static ItemStack getFromPlayerName(String name, Chat displayName, List<Chat> lore) {
|
||||
ItemStack itemStack = new ItemStack(Material.PLAYER_HEAD, 1);
|
||||
SkullMeta meta = (SkullMeta) itemStack.getItemMeta();
|
||||
|
||||
@SuppressWarnings({ "deprecation", "unused" })
|
||||
boolean b = meta.setOwner(name);
|
||||
|
||||
if (displayName != null)
|
||||
meta.displayName(displayName.get());
|
||||
|
||||
if (lore != null)
|
||||
meta.lore(lore.stream().map(Chat::get).collect(Collectors.toList()));
|
||||
|
||||
itemStack.setItemMeta(meta);
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return a skull that has a custom texture specified by url.
|
||||
* @param url skin url.
|
||||
* @return item stack
|
||||
*/
|
||||
public static ItemStack getFromSkinURL(String url) {
|
||||
return getFromSkinURL(url, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a skull that has a custom texture specified by url.
|
||||
*
|
||||
* @param url the skin full url.
|
||||
* @param displayName the display name to add to the returned skull.
|
||||
* @param lore the lore to add to the returned skull.
|
||||
* @return item stack
|
||||
*/
|
||||
public static ItemStack getFromSkinURL(String url, Chat displayName, List<Chat> lore) {
|
||||
return getFromBase64String(Base64.getEncoder().encodeToString(String.format("{\"textures\":{\"SKIN\":{\"url\":\"%s\"}}}", url).getBytes()), displayName, lore);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return a skull that has a custom texture specified by a base64 String.
|
||||
*
|
||||
* @param str the base64 string from game profile information.
|
||||
* @return item stack
|
||||
*/
|
||||
public static ItemStack getFromBase64String(String str) {
|
||||
return getFromBase64String(str, null, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a skull that has a custom texture specified by a base64 String.
|
||||
*
|
||||
* @param str the base64 string from game profile information.
|
||||
* @param displayName the display name to add to the returned skull.
|
||||
* @param lore the lore to add to the returned skull.
|
||||
* @return item stack
|
||||
*/
|
||||
public static ItemStack getFromBase64String(String str, Chat displayName, List<Chat> lore) {
|
||||
ItemStack head = new ItemStack(Material.PLAYER_HEAD, 1);
|
||||
|
||||
SkullMeta headMeta = (SkullMeta) head.getItemMeta();
|
||||
|
||||
PlayerProfile profile = Bukkit.createProfile(UUID.nameUUIDFromBytes(str.getBytes()));
|
||||
profile.setProperty(new ProfileProperty("textures", str));
|
||||
headMeta.setPlayerProfile(profile);
|
||||
|
||||
if (displayName != null)
|
||||
headMeta.displayName(displayName.get());
|
||||
|
||||
if (lore != null)
|
||||
headMeta.lore(lore.stream().map(Chat::get).collect(Collectors.toList()));
|
||||
|
||||
head.setItemMeta(headMeta);
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@@ -71,9 +71,7 @@ import fr.pandacube.lib.util.log.Log;
|
||||
try {
|
||||
DB.getAll(SQLPermissions.class, SQLPermissions.type.eq(EntityType.User.getCode()))
|
||||
.stream()
|
||||
.collect(Collectors.groupingBy(el -> el.get(SQLPermissions.name),
|
||||
Collectors.toCollection(() -> new SQLElementList<SQLPermissions>())
|
||||
)
|
||||
.collect(Collectors.groupingBy(el -> el.get(SQLPermissions.name))
|
||||
)
|
||||
.forEach((idStr, pData) -> {
|
||||
try {
|
||||
@@ -100,7 +98,7 @@ import fr.pandacube.lib.util.log.Log;
|
||||
return initPlayer(playerId, playerData);
|
||||
}
|
||||
|
||||
private CachedPlayer initPlayer(UUID playerId, SQLElementList<SQLPermissions> playerData) {
|
||||
private CachedPlayer initPlayer(UUID playerId, List<SQLPermissions> playerData) {
|
||||
|
||||
Map<String, List<SQLPermissions>> playerRawData = playerData.stream()
|
||||
.collect(
|
||||
|
@@ -122,9 +122,11 @@ public final class ReflectField<T> extends ReflectMember<T, String, Field, NoSuc
|
||||
// if the field is final, we have to do some unsafe stuff :/
|
||||
if (sunMiscUnsafeInstance != null) { // Java >= 16
|
||||
// set the value of the field, directly in the memory
|
||||
@SuppressWarnings("deprecation") // no other options yet. VarHandle blocks edition of final fields
|
||||
Object unsafeObjInstance = Modifier.isStatic(realModifiers)
|
||||
? sunMiscUnsafeInstance.staticFieldBase(f)
|
||||
: instance;
|
||||
@SuppressWarnings("deprecation") // no other options yet. VarHandle blocks edition of final fields
|
||||
long offset = Modifier.isStatic(realModifiers)
|
||||
? sunMiscUnsafeInstance.staticFieldOffset(f)
|
||||
: sunMiscUnsafeInstance.objectFieldOffset(f);
|
||||
|
@@ -39,7 +39,7 @@ public class ReflectListWrapper<W extends ReflectWrapperI> extends MappedListVie
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof List l && backend.equals(l instanceof ReflectListWrapper<?> rw ? rw.backend : l);
|
||||
return o instanceof List<?> l && backend.equals(l instanceof ReflectListWrapper<?> rw ? rw.backend : l);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -116,7 +116,7 @@ public abstract class ReflectWrapper implements ReflectWrapperI {
|
||||
}
|
||||
|
||||
if (expectedWrapperClass != null && !expectedWrapperClass.isAssignableFrom(wrapperClass)) {
|
||||
throw new ClassCastException("Wrapper class " + wrapperClass + " is not a sub-class or a sub-interface of expected wrapper class" + expectedWrapperClass);
|
||||
throw new ClassCastException("Wrapper class " + wrapperClass + " is not a sub-class or a sub-interface of expected wrapper class " + expectedWrapperClass);
|
||||
}
|
||||
ReflectConstructor<? extends ReflectWrapperI> constructor = WrapperRegistry.getWrapperConstructorOfWrapperClass(wrapperClass);
|
||||
if (constructor == null) {
|
||||
@@ -198,16 +198,20 @@ public abstract class ReflectWrapper implements ReflectWrapperI {
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof ReflectWrapper wr) {
|
||||
return Objects.equals(reflectObject, wr.reflectObject);
|
||||
return reflectObject.equals(wr.reflectObject);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(reflectObject);
|
||||
return reflectObject.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return reflectObject.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@@ -16,11 +16,6 @@ public abstract class ReflectWrapperTyped<T> extends ReflectWrapper implements R
|
||||
super(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends T> __getRuntimeClass() {
|
||||
return ReflectWrapperTypedI.super.__getRuntimeClass();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public T __getRuntimeInstance() {
|
||||
|
@@ -6,10 +6,10 @@ import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Utility class to track and limit the amount of a specific value for a specified amount of duration.
|
||||
*
|
||||
* <p>
|
||||
* An exemple of application is for rolling expense limit of a debit card: you cannot expense more that {@code $X}
|
||||
* during a rolling period of {@code $Y} time.
|
||||
*
|
||||
* <p>
|
||||
* Here is an example usage of this class:
|
||||
* <pre>
|
||||
* AmountPerTimeLimiter instance = new AmountPerTimeLimiter(X, Y);
|
||||
|
@@ -55,7 +55,7 @@ public class EnumUtil {
|
||||
* Search for a specific enum entry in the provided enum type, using the case-insensitive search string.
|
||||
* unlike {@link #searchEnum(Class, String)}, this method does not statically check the enum type, in case it is not
|
||||
* known at compilation time.
|
||||
*
|
||||
* <p>
|
||||
* For a statically checked enum type, uses {@link #searchEnum(Class, String)} instead.
|
||||
*
|
||||
* @param enumType the class of the enum in which to search
|
||||
|
@@ -15,7 +15,7 @@ public class IteratorIterator<T> implements Iterator<T> {
|
||||
|
||||
/**
|
||||
* Create an {@link IteratorIterator} with the provided {@link Collection} of {@link Iterable}.
|
||||
* The iterables’ iterators will be concatenated in the order of the collection’s iterator.
|
||||
* The iterable's iterators will be concatenated in the order of the collection’s iterator.
|
||||
* @param coll the collection of iterables.
|
||||
* @return a new instance of {@link IteratorIterator} iterating over the elements of the provided iterables.
|
||||
* @param <T> the type of the values in the iterables.
|
||||
@@ -37,7 +37,7 @@ public class IteratorIterator<T> implements Iterator<T> {
|
||||
|
||||
/**
|
||||
* Create an {@link IteratorIterator} with the provided array of {@link Iterable}.
|
||||
* The iterables’ iterators will be concatenated in the order of the array.
|
||||
* The iterable's iterators will be concatenated in the order of the array.
|
||||
* @param arr the array of iterables.
|
||||
* @return a new instance of {@link IteratorIterator} iterating over the elements of the provided iterables.
|
||||
* @param <T> the type of the values in the iterables.
|
||||
|
@@ -1,6 +1,11 @@
|
||||
package fr.pandacube.lib.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -101,7 +106,7 @@ public class RandomUtil {
|
||||
* The probability of each value to be returned depends on the frequencies provided.
|
||||
* @param frequencies the frequencies of each entry
|
||||
* @return the index of an entry, or -1 if it is unable to pick anything (all the frequencies are 0 or there is no provided frequency)
|
||||
* @throws IllegalArgumentException if frequencies is null.
|
||||
* @throws IllegalArgumentException if frequencies is null or one of the values is negative.
|
||||
*/
|
||||
public static int randomIndexOfFrequencies(double... frequencies) {
|
||||
if (frequencies == null)
|
||||
@@ -123,6 +128,30 @@ public class RandomUtil {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new map with the values shuffled, and the key in the same iteration order as the provided map.
|
||||
* @param input the source map, untouched.
|
||||
* @return a new map with shuffled values.
|
||||
* @param <K> the key type.
|
||||
* @param <V> the value type.
|
||||
*/
|
||||
public static <K, V> Map<K, V> shuffleMap(Map<K, V> input) {
|
||||
Map<K, V> ret = new LinkedHashMap<>();
|
||||
|
||||
List<V> values = new ArrayList<>(input.values());
|
||||
Collections.shuffle(values, rand);
|
||||
|
||||
Iterator<K> iK = input.keySet().iterator();
|
||||
Iterator<V> iV = values.iterator();
|
||||
while (iK.hasNext() && iV.hasNext()) {
|
||||
ret.put(iK.next(), iV.next());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A set of characters representing all the lowercase letters of the latin alphabet (only in the ASCII table).
|
||||
*/
|
||||
|
@@ -7,7 +7,7 @@ import java.util.logging.Logger;
|
||||
/**
|
||||
* Utility class to easily log info into a provided logger. This class avoid the needs to fetch the logger everytime it
|
||||
* is needed.
|
||||
*
|
||||
* <p>
|
||||
* For instance, this piece of code:
|
||||
* <pre>
|
||||
* getTheLoggerFromSomewhere().info(message);
|
||||
@@ -22,7 +22,7 @@ import java.util.logging.Logger;
|
||||
* Log.info(message);
|
||||
* </pre>
|
||||
*
|
||||
* This the {@link #setLogger(Logger)} method is not called, thi class will use the logger returned by
|
||||
* If the {@link #setLogger(Logger)} method is not called, this class will use the logger returned by
|
||||
* {@link Logger#getGlobal()}.
|
||||
*/
|
||||
public final class Log {
|
||||
|
@@ -23,6 +23,7 @@ public abstract class AbstractClientWS implements AbstractWS {
|
||||
private final URI uri;
|
||||
private boolean autoReconnect;
|
||||
private boolean isConnecting;
|
||||
private HttpClient httpClient = HttpClient.newHttpClient();
|
||||
private final AtomicReference<WebSocket> socket = new AtomicReference<>();
|
||||
|
||||
|
||||
@@ -114,7 +115,7 @@ public abstract class AbstractClientWS implements AbstractWS {
|
||||
synchronized (socket) {
|
||||
if (autoReconnect && !isConnecting && socket.get() == null) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException ignored) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
@@ -127,8 +128,10 @@ public abstract class AbstractClientWS implements AbstractWS {
|
||||
private void connect() {
|
||||
synchronized (socket) {
|
||||
isConnecting = true;
|
||||
HttpClient.newHttpClient()
|
||||
.newWebSocketBuilder()
|
||||
if (httpClient == null)
|
||||
httpClient = HttpClient.newHttpClient();
|
||||
|
||||
httpClient.newWebSocketBuilder()
|
||||
.connectTimeout(Duration.ofSeconds(5))
|
||||
.buildAsync(uri, receiveListener)
|
||||
.whenCompleteAsync((ws, ex) -> {
|
||||
@@ -145,13 +148,15 @@ public abstract class AbstractClientWS implements AbstractWS {
|
||||
ex = ex.getCause();
|
||||
if (ex instanceof IOException) {
|
||||
reconnectIfNecessary();
|
||||
log("Unable to connect. Trying again...: " + ex);
|
||||
log("Can't connect. Trying again. " + ex);
|
||||
}
|
||||
else {
|
||||
autoReconnect = false;
|
||||
logError("Error connecting (not trying to reconnect even if asked)", ex);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -61,7 +61,7 @@ public abstract class AbstractServerWS extends WebSocketAdapter implements Abstr
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void sendClose(int code, String reason) throws IOException {
|
||||
public final void sendClose(int code, String reason) {
|
||||
getSession().close(code, reason);
|
||||
isClosed = true;
|
||||
}
|
||||
|
11
pom.xml
11
pom.xml
@@ -55,11 +55,14 @@
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
<bungeecord.version>1.21-R0.1-SNAPSHOT</bungeecord.version>
|
||||
<paper.version>1.21.3-R0.1</paper.version>
|
||||
<mc.version>1.21.3</mc.version>
|
||||
<bungeecord.version>1.21-R0.4-SNAPSHOT</bungeecord.version>
|
||||
<paper.version>1.21.8-R0.1</paper.version>
|
||||
<mc.version>1.21.8</mc.version>
|
||||
|
||||
<guava.version>32.1.2-jre</guava.version> <!-- Match the version imported by Paper API/BungeeCord API if possible -->
|
||||
<guava.version>33.3.1-jre</guava.version> <!-- Match the version imported by Paper API/BungeeCord API if possible -->
|
||||
<gson.version>2.11.0</gson.version> <!-- Match the version imported by Paper API/BungeeCord API if possible -->
|
||||
<brigadier.version>1.3.10</brigadier.version> <!-- Match the version imported by Paper API if possible -->
|
||||
<datafixerupper.version>8.0.16</datafixerupper.version> <!-- Match the version used internally in Paper Server -->
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
|
Reference in New Issue
Block a user