Begin removing deprecated usages

This commit is contained in:
Kieran Wallbanks 2021-03-03 19:27:33 +00:00
parent 82820bc40b
commit 522367dd78
31 changed files with 1086 additions and 188 deletions

View File

@ -1,5 +1,7 @@
package net.minestom.server.advancements;
import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.entity.Player;
import net.minestom.server.item.ItemStack;
@ -23,8 +25,8 @@ public class Advancement {
private boolean achieved;
private JsonMessage title;
private JsonMessage description;
private Component title;
private Component description;
private ItemStack icon;
@ -42,9 +44,29 @@ public class Advancement {
// Packet
private AdvancementsPacket.Criteria criteria;
/**
* @deprecated Use {@link #Advancement(Component, Component, ItemStack, FrameType, float, float)}
*/
@Deprecated
public Advancement(@NotNull JsonMessage title, JsonMessage description,
@NotNull ItemStack icon, @NotNull FrameType frameType,
float x, float y) {
this(title.asComponent(), description.asComponent(), icon, frameType, x, y);
}
/**
* @deprecated Use {@link #Advancement(Component, Component, Material, FrameType, float, float)}
*/
@Deprecated
public Advancement(@NotNull JsonMessage title, @NotNull JsonMessage description,
@NotNull Material icon, @NotNull FrameType frameType,
float x, float y) {
this(title, description, new ItemStack(icon, (byte) 1), frameType, x, y);
}
public Advancement(@NotNull Component title, Component description,
@NotNull ItemStack icon, @NotNull FrameType frameType,
float x, float y) {
this.title = title;
this.description = description;
this.icon = icon;
@ -53,7 +75,7 @@ public class Advancement {
this.y = y;
}
public Advancement(@NotNull JsonMessage title, @NotNull JsonMessage description,
public Advancement(@NotNull Component title, @NotNull Component description,
@NotNull Material icon, @NotNull FrameType frameType,
float x, float y) {
this(title, description, new ItemStack(icon, (byte) 1), frameType, x, y);
@ -94,14 +116,24 @@ public class Advancement {
this.tab = tab;
}
/**
* Gets the title of the advancement.
*
* @return the title
*/
public Component getTitle() {
return title;
}
/**
* Gets the title of the advancement.
*
* @return the advancement title
* @deprecated Use {@link #getTitle()}
*/
@NotNull
public JsonMessage getTitle() {
return title;
public JsonMessage getTitleJson() {
return JsonMessage.fromComponent(title);
}
/**
@ -109,31 +141,67 @@ public class Advancement {
*
* @param title the new title
*/
public void setTitle(@NotNull JsonMessage title) {
public void setTitle(@NotNull Component title) {
this.title = title;
update();
}
/**
* Changes the advancement title.
*
* @param title the new title
* @deprecated Use {@link #setTitle(Component)}
*/
@Deprecated
public void setTitle(@NotNull JsonMessage title) {
this.title = title.asComponent();
update();
}
/**
* Gets the description of the advancement.
*
* @return the description title
*/
@NotNull
public JsonMessage getDescription() {
public Component getDescription() {
return description;
}
/**
* Gets the description of the advancement.
*
* @return the description title
* @deprecated Use {@link #getDescription()}
*/
@NotNull
@Deprecated
public JsonMessage getDescriptionJson() {
return JsonMessage.fromComponent(description);
}
/**
* Changes the description title.
*
* @param description the new description
*/
public void setDescription(@NotNull JsonMessage description) {
public void setDescription(@NotNull Component description) {
this.description = description;
update();
}
/**
* Changes the description title.
*
* @param description the new description
* @deprecated Use {@link #setDescription(Component)}
*/
@Deprecated
public void setDescription(@NotNull JsonMessage description) {
this.description = description.asComponent();
update();
}
/**
* Gets the advancement icon.
*
@ -306,8 +374,8 @@ public class Advancement {
AdvancementsPacket.DisplayData displayData = new AdvancementsPacket.DisplayData();
displayData.x = x;
displayData.y = y;
displayData.title = title;
displayData.description = description;
displayData.title = MinecraftServer.getSerializationManager().serialize(title);
displayData.description = MinecraftServer.getSerializationManager().serialize(description);
displayData.icon = icon;
displayData.frameType = frameType;
displayData.flags = getFlags();

View File

@ -1,5 +1,6 @@
package net.minestom.server.advancements;
import net.kyori.adventure.text.Component;
import net.minestom.server.chat.ColoredText;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.item.ItemStack;
@ -15,6 +16,10 @@ import org.jetbrains.annotations.Nullable;
*/
public class AdvancementRoot extends Advancement {
/**
* @deprecated Use {@link #AdvancementRoot(Component, Component, ItemStack, FrameType, float, float, String)}
*/
@Deprecated
public AdvancementRoot(@NotNull JsonMessage title, @NotNull JsonMessage description,
@NotNull ItemStack icon, @NotNull FrameType frameType,
float x, float y,
@ -23,6 +28,10 @@ public class AdvancementRoot extends Advancement {
setBackground(background);
}
/**
* @deprecated Use {@link #AdvancementRoot(Component, Component, Material, FrameType, float, float, String)}
*/
@Deprecated
public AdvancementRoot(@NotNull JsonMessage title, @NotNull JsonMessage description,
@NotNull Material icon, FrameType frameType,
float x, float y,
@ -31,4 +40,20 @@ public class AdvancementRoot extends Advancement {
setBackground(background);
}
public AdvancementRoot(@NotNull Component title, @NotNull Component description,
@NotNull ItemStack icon, @NotNull FrameType frameType,
float x, float y,
@Nullable String background) {
super(title, description, icon, frameType, x, y);
setBackground(background);
}
public AdvancementRoot(@NotNull Component title, @NotNull Component description,
@NotNull Material icon, FrameType frameType,
float x, float y,
@Nullable String background) {
super(title, description, icon, frameType, x, y);
setBackground(background);
}
}

View File

@ -1,5 +1,6 @@
package net.minestom.server.advancements.notifications;
import net.kyori.adventure.text.Component;
import net.minestom.server.advancements.FrameType;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.item.ItemStack;
@ -11,20 +12,46 @@ import org.jetbrains.annotations.NotNull;
*/
public class Notification {
private final JsonMessage title;
private final Component title;
private final FrameType frameType;
private final ItemStack icon;
/**
* @deprecated Use {@link #Notification(Component, FrameType, ItemStack)}
*/
@Deprecated
public Notification(@NotNull JsonMessage title, @NotNull FrameType frameType, @NotNull ItemStack icon) {
this(title.asComponent(), frameType, icon);
}
/**
* @deprecated Use {@link #Notification(Component, FrameType, Material)}
*/
@Deprecated
public Notification(@NotNull JsonMessage title, @NotNull FrameType frameType, @NotNull Material icon) {
this(title.asComponent(), frameType, icon);
}
public Notification(@NotNull Component title, @NotNull FrameType frameType, @NotNull Material icon) {
this(title, frameType, new ItemStack(icon, (byte) 1));
}
public Notification(@NotNull Component title, @NotNull FrameType frameType, @NotNull ItemStack icon) {
this.title = title;
this.frameType = frameType;
this.icon = icon;
}
public Notification(@NotNull JsonMessage title, @NotNull FrameType frameType, @NotNull Material icon) {
this.title = title;
this.frameType = frameType;
this.icon = new ItemStack(icon, (byte) 1);
/**
* Gets the title of the notification.
*
* @return the notification title
*
* @deprecated Use {@link #getTitle()}
*/
@NotNull
public JsonMessage getTitleJson() {
return JsonMessage.fromComponent(title);
}
/**
@ -32,8 +59,7 @@ public class Notification {
*
* @return the notification title
*/
@NotNull
public JsonMessage getTitle() {
public Component getTitle() {
return title;
}

View File

@ -1,6 +1,6 @@
package net.minestom.server.advancements.notifications;
import net.minestom.server.chat.ColoredText;
import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.Player;
import net.minestom.server.network.packet.server.play.AdvancementsPacket;
import net.minestom.server.network.player.PlayerConnection;
@ -82,9 +82,9 @@ public class NotificationCenter {
// Setup display data for the advancement
AdvancementsPacket.DisplayData displayData = new AdvancementsPacket.DisplayData();
{
displayData.title = notification.getTitle();
displayData.title = MinecraftServer.getSerializationManager().serialize(notification.getTitle());
// Description is required, but never shown/seen so, small Easter egg.
displayData.description = ColoredText.of("Articdive was here. #Minestom");
displayData.description = "Articdive was here. #Minestom";
displayData.icon = notification.getIcon();
displayData.frameType = notification.getFrameType();
displayData.flags = 0x6;

View File

@ -6,9 +6,12 @@ import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.translation.GlobalTranslator;
import net.kyori.adventure.translation.TranslationRegistry;
import net.kyori.adventure.translation.Translator;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.Function;
@ -123,7 +126,8 @@ public class SerializationManager {
*
* @return the serialized string
*/
public @NotNull String serialize(@NotNull Component component) {
@Contract("null -> null")
public @Nullable String serialize(@Nullable Component component) {
return this.serialize(component, this.defaultLocale);
}
@ -138,8 +142,9 @@ public class SerializationManager {
*
* @return the serialized string
*/
public @NotNull String serialize(@NotNull Component component, @NotNull Localizable localizable) {
return this.serialize(component, localizable.getLocale());
@Contract("null, _ -> null")
public @Nullable String serialize(@Nullable Component component, @NotNull Localizable localizable) {
return this.serialize(component, Objects.requireNonNullElse(localizable.getLocale(), this.defaultLocale));
}
/**
@ -153,7 +158,12 @@ public class SerializationManager {
*
* @return the serialized string
*/
public @NotNull String serialize(@NotNull Component component, @NotNull Locale locale) {
@Contract("null, _ -> null")
public @Nullable String serialize(@Nullable Component component, @NotNull Locale locale) {
if (component == null) {
return null;
}
// apply renderers
for (Function<Component, Component> renderer : this.renderers) {
component = renderer.apply(component);

View File

@ -2,8 +2,10 @@ package net.minestom.server.benchmark;
import it.unimi.dsi.fastutil.longs.Long2LongMap;
import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.MinecraftServer;
import net.minestom.server.chat.ChatColor;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.time.UpdateOption;
import net.minestom.server.utils.validate.Check;
@ -106,20 +108,25 @@ public final class BenchmarkManager {
@NotNull
public String getCpuMonitoringMessage() {
Check.stateCondition(!enabled, "CPU monitoring is only possible when the benchmark manager is enabled.");
StringBuilder benchmarkMessage = new StringBuilder();
TextComponent.Builder benchmarkMessage = Component.text();
for (Map.Entry<String, ThreadResult> resultEntry : resultMap.entrySet()) {
final String name = resultEntry.getKey();
final ThreadResult result = resultEntry.getValue();
benchmarkMessage.append(ChatColor.GRAY).append(name);
benchmarkMessage.append(": ");
benchmarkMessage.append(ChatColor.YELLOW.toString()).append(MathUtils.round(result.getCpuPercentage(), 2)).append("% CPU ");
benchmarkMessage.append(ChatColor.RED.toString()).append(MathUtils.round(result.getUserPercentage(), 2)).append("% USER ");
benchmarkMessage.append(ChatColor.PINK.toString()).append(MathUtils.round(result.getBlockedPercentage(), 2)).append("% BLOCKED ");
benchmarkMessage.append(ChatColor.BRIGHT_GREEN.toString()).append(MathUtils.round(result.getWaitedPercentage(), 2)).append("% WAITED ");
benchmarkMessage.append("\n");
benchmarkMessage.append(Component.text(name, NamedTextColor.GRAY));
benchmarkMessage.append(Component.text(": "));
benchmarkMessage.append(Component.text(MathUtils.round(result.getCpuPercentage(), 2), NamedTextColor.YELLOW));
benchmarkMessage.append(Component.text("% CPU "));
benchmarkMessage.append(Component.text(MathUtils.round(result.getUserPercentage(), 2), NamedTextColor.RED));
benchmarkMessage.append(Component.text("% USER "));
benchmarkMessage.append(Component.text(MathUtils.round(result.getBlockedPercentage(), 2), NamedTextColor.LIGHT_PURPLE));
benchmarkMessage.append(Component.text("% BLOCKED "));
benchmarkMessage.append(Component.text(MathUtils.round(result.getWaitedPercentage(), 2), NamedTextColor.GREEN));
benchmarkMessage.append(Component.text("% WAITED "));
benchmarkMessage.append(Component.newline());
}
return benchmarkMessage.toString();
return MinecraftServer.getSerializationManager().serialize(benchmarkMessage.build());
}
private void refreshData() {

View File

@ -4,7 +4,10 @@ import it.unimi.dsi.fastutil.chars.Char2ObjectMap;
import it.unimi.dsi.fastutil.chars.Char2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.kyori.adventure.text.format.TextColor;
import net.minestom.server.color.Color;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -273,6 +276,18 @@ public final class ChatColor {
return id;
}
/**
* Gets the Adventure text color from this chat color.
* @return the text color
*/
public @NotNull TextColor asTextColor() {
return TextColor.color(red, blue, green);
}
public @NotNull Color asColor() {
return new Color(red, green, blue);
}
@NotNull
@Override
public String toString() {

View File

@ -0,0 +1,205 @@
package net.minestom.server.color;
import net.kyori.adventure.text.format.TextColor;
import net.minestom.server.chat.ChatColor;
import org.apache.commons.lang3.Validate;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
/**
* A general purpose class for representing colors.
*/
public class Color {
private static final int BIT_MASK = 0xff;
private int red, green, blue;
/**
* Creates a color from an integer. This is done by reading each color component
* from the lowest order 24 bits of the integer, and creating a color from those
* components.
*
* @param rgb the integer
*/
public Color(int rgb) {
this((rgb >> 16) & BIT_MASK, (rgb >> 8) & BIT_MASK, rgb & BIT_MASK);
}
/**
* Creates a color from an Adventure text color.
*
* @param textColor the text color
*/
public Color(TextColor textColor) {
this(textColor.red(), textColor.blue(), textColor.green());
}
/**
* Creates a color from red, green, and blue components.
*
* @param red the red component
* @param green the green component
* @param blue the blue component
*
* @throws IllegalArgumentException if any component value is not between 0-255 (inclusive)
*/
public Color(int red, int green, int blue) {
Validate.isTrue(red >= 0 && red <= 255, "Red is not between 0-255: ", red);
Validate.isTrue(green >= 0 && green <= 255, "Green is not between 0-255: ", green);
Validate.isTrue(blue >= 0 && blue <= 255, "Blue is not between 0-255: ", blue);
this.red = red;
this.green = green;
this.blue = blue;
}
/**
* Gets the red component.
*
* @return red component, between 0-255 (inclusive)
*/
public int getRed() {
return this.red;
}
/**
* Creates a new Color object with specified component
*
* @param red the red component, from 0 to 255
*/
public void setRed(int red) {
Validate.isTrue(red >= 0 && red <= 255, "Red is not between 0-255: ", red);
this.red = red;
}
/**
* Gets the green component
*
* @return green component, from 0 to 255
*/
public int getGreen() {
return this.green;
}
/**
* Creates a new Color object with specified component
*
* @param green the red component, from 0 to 255
*/
public void setGreen(int green) {
Validate.isTrue(green >= 0 && green <= 255, "Green is not between 0-255: ", green);
this.green = green;
}
/**
* Gets the blue component
*
* @return blue component, from 0 to 255
*/
public int getBlue() {
return this.blue;
}
/**
* Sets the blue component of this color.
*
* @param blue the red component, from 0 to 255
*/
public void setBlue(int blue) {
Validate.isTrue(blue >= 0 && blue <= 255, "Blue is not between 0-255: ", blue);
this.blue = blue;
}
/**
* Gets the color as an RGB integer.
*
* @return An integer representation of this color, as 0xRRGGBB
*/
public int asRGB() {
int rgb = red;
rgb = (rgb << 8) + green;
return (rgb << 8) + blue;
}
/**
* Shorthand method for {@link #mixWith(Color...)}. This method converts each dye
* color to a color and then mixes this color with the new colors.
*
* @param dyeColors the dye colors
*/
public void mixWith(@NotNull DyeColor... dyeColors) {
Validate.noNullElements(dyeColors, "Colors cannot be null");
Color[] colors = new Color[dyeColors.length];
for (int i = 0; i < colors.length; i++) {
colors[i] = dyeColors[i].getColor();
}
this.mixWith(colors);
}
/**
* Mixes this color with a series of other colors, as if they were combined in a
* crafting table. This function works out the average of each RGB component and then
* multiplies the components by a scale factor that is calculated from the average
* of all maximum values divided by the maximum of each average value. This is how
* Minecraft mixes colors.
*
* @param colors the colors
*/
public void mixWith(@NotNull Color... colors) {
Validate.noNullElements(colors, "Colors cannot be null");
// store the current highest component
int max = Math.max(Math.max(this.red, this.green), this.blue);
// now combine all of the color components, adding to the max
for (Color color : colors) {
this.red += color.getRed();
this.green += color.getGreen();
this.blue += color.getBlue();
max += Math.max(Math.max(color.getRed(), color.getGreen()), color.getBlue());
}
// work out the averages
float count = colors.length + 1;
float averageRed = this.red / count;
float averageGreen = this.green / count;
float averageBlue = this.blue / count;
float averageMax = max / count;
// work out the scale factor
float maximumOfAverages = Math.max(Math.max(averageRed, averageGreen), averageBlue);
float gainFactor = averageMax / maximumOfAverages;
// round and multiply
this.red = Math.round(averageRed * gainFactor);
this.blue = Math.round(averageBlue * gainFactor);
this.green = Math.round(averageGreen * gainFactor);
}
/**
* Gets the ChatColor representation of this color.
*
* @return the chat color
* @deprecated ChatColor is deprecated and should not be used
*/
@Deprecated
public ChatColor asLegacyChatColor() {
return ChatColor.fromRGB((byte) red, (byte) blue, (byte) green);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Color color = (Color) o;
return red == color.red && green == color.green && blue == color.blue;
}
@Override
public int hashCode() {
return Objects.hash(red, green, blue);
}
}

View File

@ -0,0 +1,53 @@
package net.minestom.server.color;
import org.jetbrains.annotations.NotNull;
/**
* Color values for dyes, wool and cloth items.
*/
public enum DyeColor {
WHITE(new Color(0xF9FFFE), new Color(0xF0F0F0)),
ORANGE(new Color(0xF9801D), new Color(0xEB8844)),
MAGENTA(new Color(0xC74EBD), new Color(0xC354CD)),
LIGHT_BLUE(new Color(0x3AB3DA), new Color(0x6689D3)),
YELLOW(new Color(0xFED83D), new Color(0xDECF2A)),
LIME(new Color(0x80C71F), new Color(0x41CD34)),
PINK(new Color(0xF38BAA), new Color(0xD88198)),
GRAY(new Color(0x474F52), new Color(0x434343)),
LIGHT_GRAY(new Color(0x9D9D97), new Color(0xABABAB)),
CYAN(new Color(0x169C9C), new Color(0x287697)),
PURPLE(new Color(0x8932B8), new Color(0x7B2FBE)),
BLUE(new Color(0x3C44AA), new Color(0x253192)),
BROWN(new Color(0x835432), new Color(0x51301A)),
GREEN(new Color(0x5E7C16), new Color(0x3B511A)),
RED(new Color(0xB02E26), new Color(0xB3312C)),
BLACK(new Color(0x1D1D21), new Color(0x1E1B1B));
private final Color color;
private final Color firework;
DyeColor(Color color, Color firework) {
this.color = color;
this.firework = firework;
}
/**
* Gets the color that this dye represents.
*
* @return The {@link Color} that this dye represents
*/
@NotNull
public Color getColor() {
return this.color;
}
/**
* Gets the firework color that this dye represents.
*
* @return The {@link Color} that this dye represents
*/
@NotNull
public Color getFireworkColor() {
return this.firework;
}
}

View File

@ -107,12 +107,21 @@ public class ArgumentType {
// Minecraft specific arguments
/**
* @see ArgumentColor
* @deprecated Use {@link #TextColor} for colors and {@link #TextDecoration} for styles.
*/
@Deprecated
public static ArgumentColor Color(@NotNull String id) {
return new ArgumentColor(id);
}
public static ArgumentTextColor TextColor(@NotNull String id) {
return new ArgumentTextColor(id);
}
public static ArgumentTextDecoration TextDecoration(@NotNull String id) {
return new ArgumentTextDecoration(id);
}
/**
* @see ArgumentTime
*/

View File

@ -11,7 +11,9 @@ import org.jetbrains.annotations.NotNull;
* Represents an argument which will give you a {@link ChatColor}.
* <p>
* Example: red, white, reset
* @deprecated Use {@link ArgumentTextColor} for colors and {@link ArgumentTextDecoration} for styles.
*/
@Deprecated
public class ArgumentColor extends Argument<ChatColor> {
public static final int UNDEFINED_COLOR = -2;

View File

@ -0,0 +1,65 @@
package net.minestom.server.command.builder.arguments.minecraft;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
import net.minestom.server.command.builder.NodeMaker;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.network.packet.server.play.DeclareCommandsPacket;
import net.minestom.server.utils.MathUtils;
import org.jetbrains.annotations.NotNull;
/**
* Represents an argument that will give you a {@link TextColor}. Input is parsed
* first as a hex string ({@code #int}), then as a CSS hex string ({@code #rrggbb} or
* {@code #rgb}), then as an integer and finally as a named text colour. The values for
* the named text colours can be found in {@link NamedTextColor}.
*/
public class ArgumentTextColor extends Argument<TextColor> {
public static final int UNDEFINED_COLOR = -2;
public ArgumentTextColor(@NotNull String id) {
super(id);
}
@Override
public @NotNull TextColor parse(@NotNull String input) throws ArgumentSyntaxException {
TextColor textColor = null;
// first try standard hex
textColor = TextColor.fromHexString(input);
if (textColor != null) {
return textColor;
}
// now try CSS hex
textColor = TextColor.fromCSSHexString(input);
if (textColor != null) {
return textColor;
}
// now try int
Integer number = MathUtils.tryParse(input);
if (number != null) {
return TextColor.color(number);
}
// fallback to legacy colour names
textColor = NamedTextColor.NAMES.value(input.toLowerCase());
if (textColor != null) {
return textColor;
}
// throw an error
throw new ArgumentSyntaxException("Undefined color", input, UNDEFINED_COLOR);
}
@Override
public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) {
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(this, executable, false, false);
argumentNode.parser = "minecraft:text_decoration";
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
}

View File

@ -0,0 +1,40 @@
package net.minestom.server.command.builder.arguments.minecraft;
import net.kyori.adventure.text.format.TextDecoration;
import net.minestom.server.command.builder.NodeMaker;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.network.packet.server.play.DeclareCommandsPacket;
import org.jetbrains.annotations.NotNull;
/**
* Represents an argument that will give you a {@link TextDecoration}. Valid values can
* be found in the text decoration class. Values are case-insensitive.
*/
public class ArgumentTextDecoration extends Argument<TextDecoration> {
public static final int UNDEFINED_DECORATION = -2;
public ArgumentTextDecoration(@NotNull String id) {
super(id);
}
@NotNull
@Override
public TextDecoration parse(@NotNull String input) throws ArgumentSyntaxException {
TextDecoration decoration = TextDecoration.NAMES.value(input.toLowerCase());
if (decoration != null) {
return decoration;
}
throw new ArgumentSyntaxException("Undefined text decoration", input, UNDEFINED_DECORATION);
}
@Override
public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) {
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(this, executable, false, false);
argumentNode.parser = "minecraft:text_color";
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
}

View File

@ -1,6 +1,7 @@
package net.minestom.server.entity;
import com.google.common.collect.Queues;
import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer;
import net.minestom.server.Viewable;
import net.minestom.server.chat.JsonMessage;
@ -1189,13 +1190,25 @@ public class Entity implements Viewable, EventHandler, DataContainer, Permission
this.entityMeta.setPose(pose);
}
/**
* Gets the entity custom name.
*
* @return the custom name of the entity, null if there is not
* @deprecated Use {@link #getCustomName()}
*/
@Deprecated
@Nullable
public JsonMessage getCustomNameJson() {
return this.entityMeta.getCustomNameJson();
}
/**
* Gets the entity custom name.
*
* @return the custom name of the entity, null if there is not
*/
@Nullable
public JsonMessage getCustomName() {
public Component getCustomName() {
return this.entityMeta.getCustomName();
}
@ -1203,11 +1216,22 @@ public class Entity implements Viewable, EventHandler, DataContainer, Permission
* Changes the entity custom name.
*
* @param customName the custom name of the entity, null to remove it
* @deprecated Use {@link #setCustomName(Component)}
*/
@Deprecated
public void setCustomName(@Nullable JsonMessage customName) {
this.entityMeta.setCustomName(customName);
}
/**
* Changes the entity custom name.
*
* @param customName the custom name of the entity, null to remove it
*/
public void setCustomName(@Nullable Component customName) {
this.entityMeta.setCustomName(customName);
}
/**
* Gets the custom name visible metadata field.
*

View File

@ -1,5 +1,6 @@
package net.minestom.server.entity;
import net.kyori.adventure.sound.Sound.Source;
import net.minestom.server.attribute.Attribute;
import net.minestom.server.attribute.AttributeInstance;
import net.minestom.server.attribute.Attributes;
@ -20,7 +21,6 @@ import net.minestom.server.network.packet.server.play.*;
import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.scoreboard.Team;
import net.minestom.server.sound.Sound;
import net.minestom.server.sound.SoundCategory;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.Vector;
@ -388,12 +388,12 @@ public class LivingEntity extends Entity implements EquipmentHandler {
// play damage sound
final Sound sound = type.getSound(this);
if (sound != null) {
SoundCategory soundCategory;
Source soundCategory;
if (this instanceof Player) {
soundCategory = SoundCategory.PLAYERS;
soundCategory = Source.PLAYER;
} else {
// TODO: separate living entity categories
soundCategory = SoundCategory.HOSTILE;
soundCategory = Source.HOSTILE;
}
SoundEffectPacket damageSoundPacket =

View File

@ -1,5 +1,7 @@
package net.minestom.server.entity;
import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.packet.server.play.EntityMetaDataPacket;
@ -36,10 +38,12 @@ public class Metadata {
return new Value<>(TYPE_STRING, value, writer -> writer.writeSizedString(value));
}
@Deprecated
public static Value<JsonMessage> Chat(@NotNull JsonMessage value) {
return new Value<>(TYPE_CHAT, value, writer -> writer.writeSizedString(value.toString()));
}
@Deprecated
public static Value<JsonMessage> OptChat(@Nullable JsonMessage value) {
return new Value<>(TYPE_OPTCHAT, value, writer -> {
final boolean present = value != null;
@ -50,6 +54,20 @@ public class Metadata {
});
}
public static Value<Component> Chat(@NotNull Component value) {
return new Value<>(TYPE_CHAT, value, writer -> writer.writeSizedString(MinecraftServer.getSerializationManager().serialize(value)));
}
public static Value<Component> OptChat(@Nullable Component value) {
return new Value<>(TYPE_OPTCHAT, value, writer -> {
final boolean present = value != null;
writer.writeBoolean(present);
if (present) {
writer.writeSizedString(MinecraftServer.getSerializationManager().serialize(value));
}
});
}
public static Value<ItemStack> Slot(@NotNull ItemStack value) {
return new Value<>(TYPE_SLOT, value, writer -> writer.writeItemStack(value));
}

View File

@ -96,7 +96,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
protected final Set<Entity> viewableEntities = ConcurrentHashMap.newKeySet();
private int latency;
private JsonMessage displayName;
private Component displayName;
private PlayerSkin skin;
private DimensionType dimensionType;
@ -475,15 +475,15 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
public void kill() {
if (!isDead()) {
JsonMessage deathText;
JsonMessage chatMessage;
Component deathText;
Component chatMessage;
// get death screen text to the killed player
{
if (lastDamageSource != null) {
deathText = lastDamageSource.buildDeathScreenText(this);
} else { // may happen if killed by the server without applying damage
deathText = ColoredText.of("Killed by poor programming.");
deathText = Component.text("Killed by poor programming.");
}
}
@ -492,7 +492,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
if (lastDamageSource != null) {
chatMessage = lastDamageSource.buildDeathMessage(this);
} else { // may happen if killed by the server without applying damage
chatMessage = ColoredText.of(getUsername() + " was killed by poor programming.");
chatMessage = Component.text(getUsername() + " was killed by poor programming.");
}
}
@ -505,13 +505,13 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
// #buildDeathScreenText can return null, check here
if (deathText != null) {
CombatEventPacket deathPacket = CombatEventPacket.death(this, null, deathText);
CombatEventPacket deathPacket = CombatEventPacket.death(this, null, MinecraftServer.getSerializationManager().serialize(deathText, this));
playerConnection.sendPacket(deathPacket);
}
// #buildDeathMessage can return null, check here
if (chatMessage != null) {
MinecraftServer.getConnectionManager().broadcastMessage(chatMessage);
MinecraftServer.getConnectionManager().sendMessage(chatMessage);
}
}
@ -766,22 +766,6 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
sendPluginMessage(channel, bytes);
}
@Override
public void sendMessage(@NotNull String message) {
sendMessage(ColoredText.of(message));
}
/**
* Sends a message to the player.
*
* @param message the message to send,
* you can use {@link ColoredText} and/or {@link RichMessage} to create it easily
*/
@Override
public void sendMessage(@NotNull JsonMessage message) {
sendJsonMessage(message.toString());
}
/**
* Sends a legacy message with the specified color char.
*
@ -819,7 +803,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
@Override
public void sendMessage(@NotNull Identity source, @NotNull Component message, @NotNull MessageType type) {
ChatMessagePacket chatMessagePacket = new ChatMessagePacket(MinecraftServer.getSerializationManager().serialize(message), type, source.uuid());
ChatMessagePacket chatMessagePacket = new ChatMessagePacket(MinecraftServer.getSerializationManager().serialize(message, this), type, source.uuid());
playerConnection.sendPacket(chatMessagePacket);
}
@ -1023,8 +1007,8 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
@Override
public void sendPlayerListHeaderAndFooter(@NotNull Component header, @NotNull Component footer) {
PlayerListHeaderAndFooterPacket packet = new PlayerListHeaderAndFooterPacket();
packet.header = MinecraftServer.getSerializationManager().serialize(header);
packet.footer = MinecraftServer.getSerializationManager().serialize(footer);
packet.header = MinecraftServer.getSerializationManager().serialize(header, this);
packet.footer = MinecraftServer.getSerializationManager().serialize(footer, this);
playerConnection.sendPacket(packet);
}
@ -1105,7 +1089,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
@Override
public void sendActionBar(@NotNull Component message) {
TitlePacket titlePacket = new TitlePacket(TitlePacket.Action.SET_ACTION_BAR, MinecraftServer.getSerializationManager().serialize(message));
TitlePacket titlePacket = new TitlePacket(TitlePacket.Action.SET_ACTION_BAR, MinecraftServer.getSerializationManager().serialize(message, this));
playerConnection.sendPacket(titlePacket);
}
@ -1313,9 +1297,20 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
* Gets the player display name in the tab-list.
*
* @return the player display name, null means that {@link #getUsername()} is displayed
* @deprecated Use {@link #getDisplayName()}
*/
@Nullable
public JsonMessage getDisplayName() {
public JsonMessage getDisplayNameJson() {
return JsonMessage.fromComponent(displayName);
}
/**
* Gets the player display name in the tab-list.
*
* @return the player display name, null means that {@link #getUsername()} is displayed
*/
@Nullable
public Component getDisplayName() {
return displayName;
}
@ -1325,12 +1320,25 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
* Sets to null to show the player username.
*
* @param displayName the display name, null to display the username
* @deprecated Use {@link #setDisplayName(Component)}
*/
@Deprecated
public void setDisplayName(@Nullable JsonMessage displayName) {
this.setDisplayName(displayName == null ? null : displayName.asComponent());
}
/**
* Changes the player display name in the tab-list.
* <p>
* Sets to null to show the player username.
*
* @param displayName the display name, null to display the username
*/
public void setDisplayName(@Nullable Component displayName) {
this.displayName = displayName;
PlayerInfoPacket infoPacket = new PlayerInfoPacket(PlayerInfoPacket.Action.UPDATE_DISPLAY_NAME);
infoPacket.playerInfos.add(new PlayerInfoPacket.UpdateDisplayName(getUuid(), displayName));
infoPacket.playerInfos.add(new PlayerInfoPacket.UpdateDisplayName(getUuid(), MinecraftServer.getSerializationManager().serialize(displayName)));
sendPacketToViewersAndSelf(infoPacket);
}
@ -1909,9 +1917,9 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
// Packet type depends on the current player connection state
final ServerPacket disconnectPacket;
if (connectionState == ConnectionState.LOGIN) {
disconnectPacket = new LoginDisconnectPacket(MinecraftServer.getSerializationManager().serialize(component));
disconnectPacket = new LoginDisconnectPacket(MinecraftServer.getSerializationManager().serialize(component, this));
} else {
disconnectPacket = new DisconnectPacket(MinecraftServer.getSerializationManager().serialize(component));
disconnectPacket = new DisconnectPacket(MinecraftServer.getSerializationManager().serialize(component, this));
}
if (playerConnection instanceof NettyPlayerConnection) {
@ -2536,7 +2544,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
PlayerInfoPacket.AddPlayer addPlayer =
new PlayerInfoPacket.AddPlayer(getUuid(), getUsername(), getGameMode(), getLatency());
addPlayer.displayName = displayName;
addPlayer.displayName = MinecraftServer.getSerializationManager().serialize(displayName);
// Skin support
if (skin != null) {

View File

@ -1,5 +1,8 @@
package net.minestom.server.entity.damage;
import com.google.gson.stream.JsonReader;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.chat.ColoredText;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.chat.RichMessage;
@ -55,18 +58,25 @@ public class DamageType implements DataContainer {
return identifier;
}
/**
* @deprecated Use {@link #buildDeathMessage(Player)}
*/
@Deprecated
public JsonMessage buildDeathMessageJson(@NotNull Player killed) {
return JsonMessage.fromComponent(this.buildDeathMessage(killed));
}
/**
* Builds the death message linked to this damage type.
* <p>
* Used in {@link Player#kill()} to broadcast the proper message.
*
* @param killed the player who has been killed
* @return the death message, null to do not send anything.
* Can be for instance, of type {@link ColoredText} or {@link RichMessage}.
* @return the death message, null to do not send anything
*/
@Nullable
public JsonMessage buildDeathMessage(@NotNull Player killed) {
return ColoredText.of("{@death." + identifier + "," + killed.getUsername() + "}");
public Component buildDeathMessage(@NotNull Player killed) {
return Component.translatable("death." + identifier, Component.text(killed.getUsername()));
}
/**
@ -103,15 +113,23 @@ public class DamageType implements DataContainer {
return new EntityDamage(entity);
}
/**
* @deprecated Use {@link #buildDeathScreenText(Player)}
*/
@Deprecated
@Nullable
public JsonMessage buildDeathScreenTextJson(@NotNull Player killed) {
return JsonMessage.fromComponent(this.buildDeathScreenText(killed));
}
/**
* Builds the text sent to a player in his death screen.
*
* @param killed the player who has been killed
* @return the death screen text, null to do not send anything
*/
@Nullable
public JsonMessage buildDeathScreenText(@NotNull Player killed) {
return ColoredText.of("{@death." + identifier + "}");
public Component buildDeathScreenText(@NotNull Player killed) {
return Component.translatable("death." + identifier);
}
/**

View File

@ -1,5 +1,6 @@
package net.minestom.server.entity.hologram;
import net.kyori.adventure.text.Component;
import net.minestom.server.Viewable;
import net.minestom.server.chat.ColoredText;
import net.minestom.server.chat.JsonMessage;
@ -13,7 +14,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.Set;
/**
* Represents an invisible armor stand showing a {@link JsonMessage}.
* Represents an invisible armor stand showing a {@link Component}.
*/
public class Hologram implements Viewable {
@ -22,7 +23,7 @@ public class Hologram implements Viewable {
private final HologramEntity entity;
private Position position;
private JsonMessage text;
private Component text;
private boolean removed;
@ -33,14 +34,24 @@ public class Hologram implements Viewable {
* @param spawnPosition The spawn position of this hologram.
* @param text The text of this hologram.
* @param autoViewable {@code true}if the hologram should be visible automatically, otherwise {@code false}.
* @deprecated Use {@link #Hologram(Instance, Position, Component, boolean)}
*/
@Deprecated
public Hologram(Instance instance, Position spawnPosition, JsonMessage text, boolean autoViewable) {
this.entity = new HologramEntity(spawnPosition.clone().add(0, OFFSET_Y, 0));
this.entity.setInstance(instance);
this.entity.setAutoViewable(autoViewable);
this(instance, spawnPosition, text.asComponent(), autoViewable);
}
this.position = spawnPosition;
setText(text);
/**
* Constructs a new {@link Hologram} with the given parameters.
*
* @param instance The instance where the hologram should be spawned.
* @param spawnPosition The spawn position of this hologram.
* @param text The text of this hologram.
* @deprecated Use {@link #Hologram(Instance, Position, Component)}
*/
@Deprecated
public Hologram(Instance instance, Position spawnPosition, JsonMessage text) {
this(instance, spawnPosition, text, true);
}
/**
@ -50,10 +61,27 @@ public class Hologram implements Viewable {
* @param spawnPosition The spawn position of this hologram.
* @param text The text of this hologram.
*/
public Hologram(Instance instance, Position spawnPosition, JsonMessage text) {
public Hologram(Instance instance, Position spawnPosition, Component text) {
this(instance, spawnPosition, text, true);
}
/**
* Constructs a new {@link Hologram} with the given parameters.
*
* @param instance The instance where the hologram should be spawned.
* @param spawnPosition The spawn position of this hologram.
* @param text The text of this hologram.
* @param autoViewable {@code true}if the hologram should be visible automatically, otherwise {@code false}.
*/
public Hologram(Instance instance, Position spawnPosition, Component text, boolean autoViewable) {
this.entity = new HologramEntity(spawnPosition.clone().add(0, OFFSET_Y, 0));
this.entity.setInstance(instance);
this.entity.setAutoViewable(autoViewable);
this.position = spawnPosition;
setText(text);
}
/**
* Gets the position of the hologram.
*
@ -79,8 +107,19 @@ public class Hologram implements Viewable {
* Gets the hologram text.
*
* @return the hologram text
* @deprecated Use {@link #getText()}
*/
public JsonMessage getText() {
@Deprecated
public JsonMessage getTextJson() {
return JsonMessage.fromComponent(text);
}
/**
* Gets the hologram text.
*
* @return the hologram text
*/
public Component getText() {
return text;
}
@ -88,8 +127,19 @@ public class Hologram implements Viewable {
* Changes the hologram text.
*
* @param text the new hologram text
* @deprecated Use {@link #setText(Component)}
*/
@Deprecated
public void setText(JsonMessage text) {
this.setText(text.asComponent());
}
/**
* Changes the hologram text.
*
* @param text the new hologram text
*/
public void setText(Component text) {
checkRemoved();
this.text = text;
this.entity.setCustomName(text);

View File

@ -1,5 +1,6 @@
package net.minestom.server.entity.metadata;
import net.kyori.adventure.text.Component;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
@ -106,11 +107,29 @@ public class EntityMeta {
this.metadata.setIndex((byte) 1, Metadata.VarInt(value));
}
public JsonMessage getCustomName() {
/**
* @deprecated Use {@link #getCustomName()}
*/
@Deprecated
public JsonMessage getCustomNameJson() {
return JsonMessage.fromComponent(this.getCustomName());
}
/**
* @deprecated Use {@link #setCustomName(Component)}
*/
@Deprecated
public void setCustomName(JsonMessage value) {
if (value != null) {
this.setCustomName(value.asComponent());
}
}
public Component getCustomName() {
return this.metadata.getIndex((byte) 2, null);
}
public void setCustomName(JsonMessage value) {
public void setCustomName(Component value) {
this.metadata.setIndex((byte) 2, Metadata.OptChat(value));
}

View File

@ -1,5 +1,6 @@
package net.minestom.server.entity.metadata.minecart;
import net.kyori.adventure.text.Component;
import net.minestom.server.chat.ColoredText;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.entity.Entity;
@ -21,12 +22,29 @@ public class CommandBlockMinecartMeta extends AbstractMinecartMeta {
super.metadata.setIndex((byte) 13, Metadata.String(value));
}
/**
* @deprecated Use {@link #getLastOutput()}
*/
@Deprecated
@NotNull
public JsonMessage getLastOutput() {
return super.metadata.getIndex((byte) 14, ColoredText.of(""));
public JsonMessage getLastOutputJson() {
return JsonMessage.fromComponent(getLastOutput());
}
@NotNull
public Component getLastOutput() {
return super.metadata.getIndex((byte) 14, Component.empty());
}
/**
* @deprecated Use {@link #setLastOutput(Component)}
*/
@Deprecated
public void setLastOutput(@NotNull JsonMessage value) {
this.setLastOutput(value.asComponent());
}
public void setLastOutput(@NotNull Component value) {
super.metadata.setIndex((byte) 14, Metadata.Chat(value));
}

View File

@ -1,5 +1,6 @@
package net.minestom.server.event.player;
import net.kyori.adventure.text.Component;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.entity.Player;
import net.minestom.server.event.CancellableEvent;
@ -19,7 +20,7 @@ public class PlayerChatEvent extends PlayerEvent implements CancellableEvent {
private final Collection<Player> recipients;
private String message;
private Function<PlayerChatEvent, JsonMessage> chatFormat;
private Function<PlayerChatEvent, Component> chatFormat;
private boolean cancelled;
@ -33,8 +34,19 @@ public class PlayerChatEvent extends PlayerEvent implements CancellableEvent {
* Changes the chat format.
*
* @param chatFormat the custom chat format, null to use the default one
* @deprecated Use {@link #setChatFormat(Function)}
*/
public void setChatFormat(@Nullable Function<PlayerChatEvent, JsonMessage> chatFormat) {
@Deprecated
public void setChatFormatJson(@Nullable Function<PlayerChatEvent, JsonMessage> chatFormat) {
this.chatFormat = chatFormat == null ? null : chatFormat.andThen(JsonMessage::asComponent);
}
/**
* Changes the chat format.
*
* @param chatFormat the custom chat format, null to use the default one
*/
public void setChatFormat(@Nullable Function<PlayerChatEvent, Component> chatFormat) {
this.chatFormat = chatFormat;
}
@ -77,7 +89,7 @@ public class PlayerChatEvent extends PlayerEvent implements CancellableEvent {
* @return the chat format which will be used, null if this is the default one
*/
@Nullable
public Function<PlayerChatEvent, JsonMessage> getChatFormatFunction() {
public Function<PlayerChatEvent, Component> getChatFormatFunction() {
return chatFormat;
}

View File

@ -1,6 +1,7 @@
package net.minestom.server.event.player;
import net.minestom.server.chat.ColoredText;
import com.google.gson.stream.JsonReader;
import net.kyori.adventure.text.Component;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.entity.Player;
import net.minestom.server.event.PlayerEvent;
@ -12,10 +13,18 @@ import org.jetbrains.annotations.Nullable;
*/
public class PlayerDeathEvent extends PlayerEvent {
private JsonMessage deathText;
private JsonMessage chatMessage;
private Component deathText;
private Component chatMessage;
/**
* @deprecated Use {@link #PlayerDeathEvent(Player, Component, Component)}
*/
@Deprecated
public PlayerDeathEvent(@NotNull Player player, JsonMessage deathText, JsonMessage chatMessage) {
this(player, deathText.asComponent(), chatMessage.asComponent());
}
public PlayerDeathEvent(@NotNull Player player, Component deathText, Component chatMessage) {
super(player);
this.deathText = deathText;
this.chatMessage = chatMessage;
@ -25,9 +34,21 @@ public class PlayerDeathEvent extends PlayerEvent {
* Gets the text displayed in the death screen.
*
* @return the death text, can be null
* @deprecated Use {@link #getDeathText()}
*/
@Nullable
public JsonMessage getDeathText() {
@Deprecated
public JsonMessage getDeathTextJson() {
return JsonMessage.fromComponent(deathText);
}
/**
* Gets the text displayed in the death screen.
*
* @return the death text, can be null
*/
@Nullable
public Component getDeathText() {
return deathText;
}
@ -35,18 +56,41 @@ public class PlayerDeathEvent extends PlayerEvent {
* Changes the text displayed in the death screen.
*
* @param deathText the death text to display, null to remove
* @deprecated Use {@link #setDeathText(Component)}
*/
@Deprecated
public void setDeathText(@Nullable JsonMessage deathText) {
this.deathText = deathText == null ? null : deathText.asComponent();
}
/**
* Changes the text displayed in the death screen.
*
* @param deathText the death text to display, null to remove
*/
public void setDeathText(@Nullable Component deathText) {
this.deathText = deathText;
}
/**
* Gets the message sent to chat.
*
* @return the death chat message
* @deprecated Use {@link #getChatMessage()}
*/
@Deprecated
@Nullable
public JsonMessage getChatMessageJson() {
return JsonMessage.fromComponent(chatMessage);
}
/**
* Gets the message sent to chat.
*
* @return the death chat message
*/
@Nullable
public JsonMessage getChatMessage() {
public Component getChatMessage() {
return chatMessage;
}
@ -54,8 +98,19 @@ public class PlayerDeathEvent extends PlayerEvent {
* Changes the text sent in chat
*
* @param chatMessage the death message to send, null to remove
* @deprecated Use {@link #setChatMessage(Component)}
*/
@Deprecated
public void setChatMessage(@Nullable JsonMessage chatMessage) {
this.chatMessage = chatMessage == null ? null : chatMessage.asComponent();
}
/**
* Changes the text sent in chat
*
* @param chatMessage the death message to send, null to remove
*/
public void setChatMessage(@Nullable Component chatMessage) {
this.chatMessage = chatMessage;
}
}

View File

@ -1,13 +1,31 @@
package net.minestom.server.item;
import com.google.gson.JsonNull;
import com.google.gson.stream.JsonReader;
import net.kyori.adventure.text.Component;
import net.minestom.server.chat.JsonMessage;
import java.util.stream.Stream;
public class ItemDisplay {
private JsonMessage displayName;
private JsonMessage[] lore;
private Component displayName;
private Component[] lore;
/**
* @deprecated Use {@link #ItemDisplay(Component, Component[])}
*/
@Deprecated
public ItemDisplay(JsonMessage displayName, JsonMessage[] lore) {
this.displayName = displayName.asComponent();
this.lore = new Component[lore.length];
for (int i = 0; i < lore.length; i++) {
this.lore[i] = lore[i].asComponent();
}
}
public ItemDisplay(Component displayName, Component[] lore) {
this.displayName = displayName;
this.lore = lore;
}
@ -16,8 +34,34 @@ public class ItemDisplay {
* Gets the item display name.
*
* @return the item display name
* @deprecated Use {@link #getDisplayName()}
*/
public JsonMessage getDisplayName() {
@Deprecated
public JsonMessage getDisplayNameJson() {
return JsonMessage.fromComponent(displayName);
}
/**
* Gets the item lore.
*
* @return the item lore
* @deprecated Use {@link #getLore()}
*/
@Deprecated
public JsonMessage[] getLoreJson() {
JsonMessage[] loreOld = new JsonMessage[lore.length];
for (int i = 0; i < lore.length; i++) {
loreOld[i] = JsonMessage.fromComponent(lore[i]);
}
return loreOld;
}
/**
* Gets the item display name.
*
* @return the item display name
*/
public Component getDisplayName() {
return displayName;
}
@ -26,7 +70,7 @@ public class ItemDisplay {
*
* @return the item lore
*/
public JsonMessage[] getLore() {
public Component[] getLore() {
return lore;
}
}

View File

@ -2,6 +2,7 @@ package net.minestom.server.item;
import it.unimi.dsi.fastutil.objects.Object2ShortMap;
import it.unimi.dsi.fastutil.objects.Object2ShortOpenHashMap;
import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.data.Data;
@ -26,6 +27,7 @@ import org.jetbrains.annotations.Nullable;
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
import java.util.*;
import java.util.stream.Collectors;
// TODO should we cache a ByteBuf of this item for faster packet write
@ -54,9 +56,9 @@ public class ItemStack implements DataContainer, PublicCloneable<ItemStack> {
private byte amount;
private int damage;
private JsonMessage displayName;
private Component displayName;
private boolean unbreakable;
private List<JsonMessage> lore;
private List<Component> lore;
private Object2ShortMap<Enchantment> enchantmentMap;
private List<ItemAttribute> attributes;
@ -176,7 +178,7 @@ public class ItemStack implements DataContainer, PublicCloneable<ItemStack> {
return true;
}
final JsonMessage itemDisplayName = itemStack.getDisplayName();
final Component itemDisplayName = itemStack.getDisplayName();
final boolean displayNameCheck = (displayName == null && itemDisplayName == null) ||
(displayName != null && displayName.equals(itemDisplayName));
@ -309,13 +311,25 @@ public class ItemStack implements DataContainer, PublicCloneable<ItemStack> {
this.itemMeta = itemMeta;
}
/**
* Gets the item display name.
*
* @return the item display name, can be null if not present
* @deprecated Use {@link #getDisplayName()}
*/
@Deprecated
@Nullable
public JsonMessage getDisplayNameJson() {
return JsonMessage.fromComponent(displayName);
}
/**
* Gets the item display name.
*
* @return the item display name, can be null if not present
*/
@Nullable
public JsonMessage getDisplayName() {
public Component getDisplayName() {
return displayName;
}
@ -323,8 +337,19 @@ public class ItemStack implements DataContainer, PublicCloneable<ItemStack> {
* Sets the item display name.
*
* @param displayName the item display name
* @deprecated Use {@link #setDisplayName(Component)}
*/
@Deprecated
public void setDisplayName(@Nullable JsonMessage displayName) {
this.setDisplayName(displayName == null ? null : displayName.asComponent());
}
/**
* Sets the item display name.
*
* @param displayName the item display name
*/
public void setDisplayName(@Nullable Component displayName) {
this.displayName = displayName;
}
@ -337,13 +362,25 @@ public class ItemStack implements DataContainer, PublicCloneable<ItemStack> {
return displayName != null;
}
/**
* Gets the item lore.
*
* @return a modifiable list containing the item lore, can be empty if not present
* @deprecated Use {@link #getLore()}
*/
@Deprecated
@NotNull
public List<JsonMessage> getLoreJson() {
return lore.stream().map(JsonMessage::fromComponent).collect(Collectors.toList());
}
/**
* Gets the item lore.
*
* @return a modifiable list containing the item lore, can be empty if not present
*/
@NotNull
public List<JsonMessage> getLore() {
public List<Component> getLore() {
return lore;
}
@ -351,8 +388,20 @@ public class ItemStack implements DataContainer, PublicCloneable<ItemStack> {
* Sets the item lore.
*
* @param lore the item lore, can be empty to remove
* @deprecated Use {@link #setLore}
*/
public void setLore(@NotNull List<JsonMessage> lore) {
@Deprecated
public void setLoreJson(@NotNull List<JsonMessage> lore) {
this.lore = lore.stream().map(JsonMessage::asComponent).collect(Collectors.toList());
}
/**
* Sets the item lore.
*
* @param lore the item lore, can be empty to remove
*/
@NotNull
public void setLore(List<Component> lore) {
this.lore = lore;
}

View File

@ -1,6 +1,8 @@
package net.minestom.server.item.firework;
import net.kyori.adventure.text.format.TextColor;
import net.minestom.server.chat.ChatColor;
import net.minestom.server.color.Color;
import org.jetbrains.annotations.NotNull;
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
@ -11,8 +13,23 @@ public class FireworkEffect {
private final boolean flicker;
private final boolean trail;
private final FireworkEffectType type;
private final ChatColor color;
private final ChatColor fadeColor;
private final Color color;
private final Color fadeColor;
/**
* Initializes a new firework effect.
*
* @param flicker {@code true} if this explosion has the Twinkle effect (glowstone dust), otherwise {@code false}.
* @param trail {@code true} if this explosion hsa the Trail effect (diamond), otherwise {@code false}.
* @param type The shape of this firework's explosion.
* @param color The primary color of this firework effect.
* @param fadeColor The secondary color of this firework effect.
* @deprecated Use {@link #FireworkEffect(boolean, boolean, FireworkEffectType, Color, Color)}
*/
@Deprecated
public FireworkEffect(boolean flicker, boolean trail, FireworkEffectType type, ChatColor color, ChatColor fadeColor) {
this(flicker, trail, type, color.asColor(), fadeColor.asColor());
}
/**
* Initializes a new firework effect.
@ -23,7 +40,7 @@ public class FireworkEffect {
* @param color The primary color of this firework effect.
* @param fadeColor The secondary color of this firework effect.
*/
public FireworkEffect(boolean flicker, boolean trail, FireworkEffectType type, ChatColor color, ChatColor fadeColor) {
public FireworkEffect(boolean flicker, boolean trail, FireworkEffectType type, Color color, Color fadeColor) {
this.flicker = flicker;
this.trail = trail;
this.type = type;
@ -39,17 +56,17 @@ public class FireworkEffect {
*/
public static FireworkEffect fromCompound(@NotNull NBTCompound compound) {
ChatColor primaryColor = null;
ChatColor secondaryColor = null;
Color primaryColor = null;
Color secondaryColor = null;
if (compound.containsKey("Colors")) {
int[] color = compound.getIntArray("Colors");
primaryColor = ChatColor.fromRGB((byte) color[0], (byte) color[1], (byte) color[2]);
primaryColor = new Color(color[0], color[1], color[2]);
}
if (compound.containsKey("FadeColors")) {
int[] fadeColor = compound.getIntArray("FadeColors");
secondaryColor = ChatColor.fromRGB((byte) fadeColor[0], (byte) fadeColor[1], (byte) fadeColor[2]);
secondaryColor = new Color(fadeColor[0], fadeColor[1], fadeColor[2]);
}

View File

@ -1,6 +1,7 @@
package net.minestom.server.item.metadata;
import net.minestom.server.chat.ChatColor;
import net.minestom.server.color.Color;
import org.jetbrains.annotations.NotNull;
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
@ -8,25 +9,18 @@ import org.jglrxavpok.hephaistos.nbt.NBTCompound;
* Represents the item meta for leather armor parts.
*/
public class LeatherArmorMeta extends ItemMeta {
private static final int BIT_MASK = 0xFF;
private boolean modified;
private byte red;
private byte green;
private byte blue;
private Color color;
/**
* Sets the color of the leather armor piece.
*
* @param color the color of the leather armor
* @deprecated Use {@link #setColor(Color)}
*/
@Deprecated
public void setColor(ChatColor color) {
// TODO using "CHAT color" is pretty weird, maybe that the class should be renamed to "Color"
this.red = color.getRed();
this.green = color.getGreen();
this.blue = color.getBlue();
this.modified = true;
this.setColor(color.asColor());
}
/**
@ -35,21 +29,37 @@ public class LeatherArmorMeta extends ItemMeta {
* @param red The red color of the leather armor piece.
* @param green The green color of the leather armor piece.
* @param blue The blue color of the leather armor piece.
* @deprecated Use {@link #setColor(Color)}
*/
@Deprecated
public void setColor(byte red, byte green, byte blue) {
this.red = red;
this.green = green;
this.blue = blue;
this.modified = true;
this.setColor(new Color(red, green, blue));
}
/**
* Sets the color of this leather armor piece.
*
* @param color the new color
*/
public void setColor(@NotNull Color color) {
this.modified = !color.equals(this.color);
this.color = color;
}
/**
* Gets the color of this leather armor piece.
*
* @return the color
*/
public @NotNull Color getColor() {
return this.color;
}
/**
* Resets the color to the default leather one.
*/
public void reset() {
this.red = 0;
this.green = 0;
this.blue = 0;
this.color = new Color(0, 0, 0);
this.modified = false;
}
@ -57,27 +67,33 @@ public class LeatherArmorMeta extends ItemMeta {
* Gets the red component.
*
* @return the red component
* @deprecated Use {@link #getColor}
*/
@Deprecated
public int getRed() {
return BIT_MASK & red;
return this.color.getRed();
}
/**
* Gets the green component.
*
* @return the green component
* @deprecated Use {@link #getColor}
*/
@Deprecated
public int getGreen() {
return BIT_MASK & green;
return this.color.getGreen();
}
/**
* Gets the blue component.
*
* @return the blue component
* @deprecated Use {@link #getColor}
*/
@Deprecated
public int getBlue() {
return BIT_MASK & blue;
return this.color.getBlue();
}
/**
@ -105,9 +121,7 @@ public class LeatherArmorMeta extends ItemMeta {
if (!(itemMeta instanceof LeatherArmorMeta)) return false;
final LeatherArmorMeta leatherArmorMeta = (LeatherArmorMeta) itemMeta;
return leatherArmorMeta.isModified() == isModified()
&& leatherArmorMeta.getRed() == getRed()
&& leatherArmorMeta.getGreen() == getGreen()
&& leatherArmorMeta.getBlue() == getBlue();
&& leatherArmorMeta.getColor().equals(getColor());
}
/**
@ -123,10 +137,7 @@ public class LeatherArmorMeta extends ItemMeta {
// Sets the color of the leather armor piece
// This also fixes that the armor pieces do not decolorize again when you are in creative
// mode.
this.setColor(
(byte) ((color >> 16) & BIT_MASK),
(byte) ((color >> 8) & BIT_MASK),
(byte) ((color) & BIT_MASK));
this.setColor(new Color(color));
}
}
}
@ -143,9 +154,7 @@ public class LeatherArmorMeta extends ItemMeta {
} else {
displayCompound = compound.getCompound("display");
}
final int color = this.getRed() << 16 | this.getGreen() << 8 | this.getBlue();
displayCompound.setInt("color", color);
displayCompound.setInt("color", color.asRGB());
// Adds the color compound to the display compound
compound.set("display", displayCompound);
}
@ -159,9 +168,7 @@ public class LeatherArmorMeta extends ItemMeta {
public ItemMeta clone() {
LeatherArmorMeta leatherArmorMeta = (LeatherArmorMeta) super.clone();
leatherArmorMeta.modified = this.isModified();
leatherArmorMeta.red = (byte) this.getRed();
leatherArmorMeta.green = (byte) this.getGreen();
leatherArmorMeta.blue = (byte) this.getBlue();
leatherArmorMeta.color = color;
return leatherArmorMeta;
}

View File

@ -1,7 +1,10 @@
package net.minestom.server.item.metadata;
import net.kyori.adventure.text.format.TextColor;
import net.minestom.server.MinecraftServer;
import net.minestom.server.chat.ChatColor;
import net.minestom.server.color.Color;
import net.minestom.server.color.DyeColor;
import net.minestom.server.utils.clone.CloneUtils;
import net.minestom.server.utils.clone.PublicCloneable;
import org.jetbrains.annotations.NotNull;
@ -17,7 +20,7 @@ public class MapMeta extends ItemMeta {
private int mapId;
private int mapScaleDirection = 1;
private List<MapDecoration> decorations = new CopyOnWriteArrayList<>();
private ChatColor mapColor = ChatColor.NO_COLOR;
private Color mapColor = new Color(0, 0, 0);
public MapMeta() {
}
@ -84,21 +87,40 @@ public class MapMeta extends ItemMeta {
* Gets the map color.
*
* @return the map color
* @deprecated Use {@link #getMapColor()}
*/
public ChatColor getMapColor() {
return mapColor;
@Deprecated
public ChatColor getLegacyMapColor() {
return this.mapColor.asLegacyChatColor();
}
/**
* Gets the map color.
*
* @return the map color
*/
public @NotNull Color getMapColor() {
return this.mapColor;
}
/**
* Changes the map color.
* <p>
* WARNING: RGB colors are not supported.
*
* @param mapColor the new map color
* @deprecated Use {@link #setMapColor(Color)}
*/
@Deprecated
public void setMapColor(ChatColor mapColor) {
mapColor.getId(); // used to throw an error if rgb color is used
this.mapColor = mapColor;
this.setMapColor(mapColor.asColor());
}
/**
* Changes the map color.
*
* @param color the new map color
*/
public void setMapColor(@NotNull Color color) {
this.mapColor = color;
}
@Override
@ -156,8 +178,7 @@ public class MapMeta extends ItemMeta {
if (compound.containsKey("display")) {
final NBTCompound displayCompound = compound.getCompound("display");
if (displayCompound.containsKey("MapColor")) {
final int color = displayCompound.getAsInt("MapColor");
this.mapColor = ChatColor.fromId(color);
this.mapColor = new Color(displayCompound.getAsInt("MapColor"));
}
}
@ -191,7 +212,7 @@ public class MapMeta extends ItemMeta {
} else {
displayCompound = new NBTCompound();
}
displayCompound.setInt("MapColor", mapColor.getId());
displayCompound.setInt("MapColor", mapColor.asRGB());
}
}

View File

@ -1,6 +1,8 @@
package net.minestom.server.item.metadata;
import net.kyori.adventure.text.format.TextColor;
import net.minestom.server.chat.ChatColor;
import net.minestom.server.color.Color;
import net.minestom.server.potion.CustomPotionEffect;
import net.minestom.server.potion.PotionType;
import net.minestom.server.registry.Registries;
@ -29,8 +31,7 @@ public class PotionMeta extends ItemMeta {
// Not final because of #clone()
private List<CustomPotionEffect> customPotionEffects = new CopyOnWriteArrayList<>();
private boolean hasColor;
private byte red, green, blue;
private Color color;
/**
* Gets the potion type.
@ -65,19 +66,20 @@ public class PotionMeta extends ItemMeta {
* Changes the color of the potion.
*
* @param color the new color of the potion
* @deprecated Use {@link #setColor(Color)}
*/
@Deprecated
public void setColor(ChatColor color) {
// FIXME: weird usage of ChatColor, should maybe rename
this.setColor(color.asColor());
}
if (color == null) {
this.hasColor = false;
return;
}
this.red = color.getRed();
this.green = color.getGreen();
this.blue = color.getBlue();
this.hasColor = true;
/**
* Changes the color of the potion.
*
* @param color the new color of the potion
*/
public void setColor(@Nullable Color color) {
this.color = color;
}
@Override
@ -93,10 +95,7 @@ public class PotionMeta extends ItemMeta {
PotionMeta potionMeta = (PotionMeta) itemMeta;
return potionMeta.potionType == potionType &&
potionMeta.customPotionEffects.equals(customPotionEffects) &&
potionMeta.hasColor == hasColor &&
potionMeta.red == red &&
potionMeta.green == green &&
potionMeta.blue == blue;
potionMeta.color.equals(color);
}
@Override
@ -121,10 +120,7 @@ public class PotionMeta extends ItemMeta {
}
if (compound.containsKey("CustomPotionColor")) {
final int color = compound.getInt("CustomPotionColor");
this.red = (byte) ((color >> 16) & 0x000000FF);
this.green = (byte) ((color >> 8) & 0x000000FF);
this.blue = (byte) ((color) & 0x000000FF);
this.color = new Color(compound.getInt("CustomPotionColor"));
}
}
@ -151,9 +147,8 @@ public class PotionMeta extends ItemMeta {
compound.set("CustomPotionEffects", potionList);
}
if (hasColor) {
final int color = red << 16 + green << 8 + blue;
compound.setInt("CustomPotionColor", color);
if (color != null) {
compound.setInt("CustomPotionColor", color.asRGB());
}
}
@ -165,10 +160,7 @@ public class PotionMeta extends ItemMeta {
potionMeta.potionType = potionType;
potionMeta.customPotionEffects = CloneUtils.cloneCopyOnWriteArrayList(customPotionEffects);
potionMeta.hasColor = hasColor;
potionMeta.red = red;
potionMeta.green = green;
potionMeta.blue = blue;
potionMeta.color = color;
return potionMeta;
}

View File

@ -39,6 +39,19 @@ public class SoundEffectPacket implements ServerPacket {
return packet;
}
@NotNull
public static SoundEffectPacket create(Source category, Sound sound, Position position, float volume, float pitch) {
SoundEffectPacket packet = new SoundEffectPacket();
packet.soundId = sound.getId();
packet.soundCategory = category.ordinal();
// *8 converts to fixed-point representation with 3 bits for fractional part
packet.x = (int) position.getX();
packet.y = (int) position.getY();
packet.z = (int) position.getZ();
packet.volume = volume;
packet.pitch = pitch;
return packet;
}
@Override
public void write(@NotNull BinaryWriter writer) {
writer.writeVarInt(soundId);

View File

@ -94,4 +94,12 @@ public final class MathUtils {
public static double mod(final double a, final double b) {
return (a % b + b) % b;
}
public static Integer tryParse(String string) {
try {
return Integer.parseInt(string);
} catch (NumberFormatException ignored) {
return null;
}
}
}