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

View File

@ -1,5 +1,6 @@
package net.minestom.server.advancements; package net.minestom.server.advancements;
import net.kyori.adventure.text.Component;
import net.minestom.server.chat.ColoredText; import net.minestom.server.chat.ColoredText;
import net.minestom.server.chat.JsonMessage; import net.minestom.server.chat.JsonMessage;
import net.minestom.server.item.ItemStack; import net.minestom.server.item.ItemStack;
@ -15,6 +16,10 @@ import org.jetbrains.annotations.Nullable;
*/ */
public class AdvancementRoot extends Advancement { 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, public AdvancementRoot(@NotNull JsonMessage title, @NotNull JsonMessage description,
@NotNull ItemStack icon, @NotNull FrameType frameType, @NotNull ItemStack icon, @NotNull FrameType frameType,
float x, float y, float x, float y,
@ -23,6 +28,10 @@ public class AdvancementRoot extends Advancement {
setBackground(background); setBackground(background);
} }
/**
* @deprecated Use {@link #AdvancementRoot(Component, Component, Material, FrameType, float, float, String)}
*/
@Deprecated
public AdvancementRoot(@NotNull JsonMessage title, @NotNull JsonMessage description, public AdvancementRoot(@NotNull JsonMessage title, @NotNull JsonMessage description,
@NotNull Material icon, FrameType frameType, @NotNull Material icon, FrameType frameType,
float x, float y, float x, float y,
@ -31,4 +40,20 @@ public class AdvancementRoot extends Advancement {
setBackground(background); 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; package net.minestom.server.advancements.notifications;
import net.kyori.adventure.text.Component;
import net.minestom.server.advancements.FrameType; import net.minestom.server.advancements.FrameType;
import net.minestom.server.chat.JsonMessage; import net.minestom.server.chat.JsonMessage;
import net.minestom.server.item.ItemStack; import net.minestom.server.item.ItemStack;
@ -11,20 +12,46 @@ import org.jetbrains.annotations.NotNull;
*/ */
public class Notification { public class Notification {
private final JsonMessage title; private final Component title;
private final FrameType frameType; private final FrameType frameType;
private final ItemStack icon; private final ItemStack icon;
/**
* @deprecated Use {@link #Notification(Component, FrameType, ItemStack)}
*/
@Deprecated
public Notification(@NotNull JsonMessage title, @NotNull FrameType frameType, @NotNull ItemStack icon) { 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.title = title;
this.frameType = frameType; this.frameType = frameType;
this.icon = icon; this.icon = icon;
} }
public Notification(@NotNull JsonMessage title, @NotNull FrameType frameType, @NotNull Material icon) { /**
this.title = title; * Gets the title of the notification.
this.frameType = frameType; *
this.icon = new ItemStack(icon, (byte) 1); * @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 * @return the notification title
*/ */
@NotNull public Component getTitle() {
public JsonMessage getTitle() {
return title; return title;
} }

View File

@ -1,6 +1,6 @@
package net.minestom.server.advancements.notifications; 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.entity.Player;
import net.minestom.server.network.packet.server.play.AdvancementsPacket; import net.minestom.server.network.packet.server.play.AdvancementsPacket;
import net.minestom.server.network.player.PlayerConnection; import net.minestom.server.network.player.PlayerConnection;
@ -82,9 +82,9 @@ public class NotificationCenter {
// Setup display data for the advancement // Setup display data for the advancement
AdvancementsPacket.DisplayData displayData = new AdvancementsPacket.DisplayData(); 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. // 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.icon = notification.getIcon();
displayData.frameType = notification.getFrameType(); displayData.frameType = notification.getFrameType();
displayData.flags = 0x6; 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.GlobalTranslator;
import net.kyori.adventure.translation.TranslationRegistry; import net.kyori.adventure.translation.TranslationRegistry;
import net.kyori.adventure.translation.Translator; import net.kyori.adventure.translation.Translator;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Locale; import java.util.Locale;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.Function; import java.util.function.Function;
@ -123,7 +126,8 @@ public class SerializationManager {
* *
* @return the serialized string * @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); return this.serialize(component, this.defaultLocale);
} }
@ -138,8 +142,9 @@ public class SerializationManager {
* *
* @return the serialized string * @return the serialized string
*/ */
public @NotNull String serialize(@NotNull Component component, @NotNull Localizable localizable) { @Contract("null, _ -> null")
return this.serialize(component, localizable.getLocale()); 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 * @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 // apply renderers
for (Function<Component, Component> renderer : this.renderers) { for (Function<Component, Component> renderer : this.renderers) {
component = renderer.apply(component); 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.Long2LongMap;
import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap; 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.MinecraftServer;
import net.minestom.server.chat.ChatColor;
import net.minestom.server.utils.MathUtils; import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.time.UpdateOption; import net.minestom.server.utils.time.UpdateOption;
import net.minestom.server.utils.validate.Check; import net.minestom.server.utils.validate.Check;
@ -106,20 +108,25 @@ public final class BenchmarkManager {
@NotNull @NotNull
public String getCpuMonitoringMessage() { public String getCpuMonitoringMessage() {
Check.stateCondition(!enabled, "CPU monitoring is only possible when the benchmark manager is enabled."); 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()) { for (Map.Entry<String, ThreadResult> resultEntry : resultMap.entrySet()) {
final String name = resultEntry.getKey(); final String name = resultEntry.getKey();
final ThreadResult result = resultEntry.getValue(); final ThreadResult result = resultEntry.getValue();
benchmarkMessage.append(ChatColor.GRAY).append(name); benchmarkMessage.append(Component.text(name, NamedTextColor.GRAY));
benchmarkMessage.append(": "); benchmarkMessage.append(Component.text(": "));
benchmarkMessage.append(ChatColor.YELLOW.toString()).append(MathUtils.round(result.getCpuPercentage(), 2)).append("% CPU "); benchmarkMessage.append(Component.text(MathUtils.round(result.getCpuPercentage(), 2), NamedTextColor.YELLOW));
benchmarkMessage.append(ChatColor.RED.toString()).append(MathUtils.round(result.getUserPercentage(), 2)).append("% USER "); benchmarkMessage.append(Component.text("% CPU "));
benchmarkMessage.append(ChatColor.PINK.toString()).append(MathUtils.round(result.getBlockedPercentage(), 2)).append("% BLOCKED "); benchmarkMessage.append(Component.text(MathUtils.round(result.getUserPercentage(), 2), NamedTextColor.RED));
benchmarkMessage.append(ChatColor.BRIGHT_GREEN.toString()).append(MathUtils.round(result.getWaitedPercentage(), 2)).append("% WAITED "); benchmarkMessage.append(Component.text("% USER "));
benchmarkMessage.append("\n"); 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() { 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.chars.Char2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; 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 net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -273,6 +276,18 @@ public final class ChatColor {
return id; 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 @NotNull
@Override @Override
public String toString() { 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 // Minecraft specific arguments
/** /**
* @see ArgumentColor * @deprecated Use {@link #TextColor} for colors and {@link #TextDecoration} for styles.
*/ */
@Deprecated
public static ArgumentColor Color(@NotNull String id) { public static ArgumentColor Color(@NotNull String id) {
return new ArgumentColor(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 * @see ArgumentTime
*/ */

View File

@ -11,7 +11,9 @@ import org.jetbrains.annotations.NotNull;
* Represents an argument which will give you a {@link ChatColor}. * Represents an argument which will give you a {@link ChatColor}.
* <p> * <p>
* Example: red, white, reset * Example: red, white, reset
* @deprecated Use {@link ArgumentTextColor} for colors and {@link ArgumentTextDecoration} for styles.
*/ */
@Deprecated
public class ArgumentColor extends Argument<ChatColor> { public class ArgumentColor extends Argument<ChatColor> {
public static final int UNDEFINED_COLOR = -2; 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; package net.minestom.server.entity;
import com.google.common.collect.Queues; import com.google.common.collect.Queues;
import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.Viewable; import net.minestom.server.Viewable;
import net.minestom.server.chat.JsonMessage; import net.minestom.server.chat.JsonMessage;
@ -1189,13 +1190,25 @@ public class Entity implements Viewable, EventHandler, DataContainer, Permission
this.entityMeta.setPose(pose); 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. * Gets the entity custom name.
* *
* @return the custom name of the entity, null if there is not * @return the custom name of the entity, null if there is not
*/ */
@Nullable @Nullable
public JsonMessage getCustomName() { public Component getCustomName() {
return this.entityMeta.getCustomName(); return this.entityMeta.getCustomName();
} }
@ -1203,11 +1216,22 @@ public class Entity implements Viewable, EventHandler, DataContainer, Permission
* Changes the entity custom name. * Changes the entity custom name.
* *
* @param customName the custom name of the entity, null to remove it * @param customName the custom name of the entity, null to remove it
* @deprecated Use {@link #setCustomName(Component)}
*/ */
@Deprecated
public void setCustomName(@Nullable JsonMessage customName) { public void setCustomName(@Nullable JsonMessage customName) {
this.entityMeta.setCustomName(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. * Gets the custom name visible metadata field.
* *

View File

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

View File

@ -1,5 +1,7 @@
package net.minestom.server.entity; 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.chat.JsonMessage;
import net.minestom.server.item.ItemStack; import net.minestom.server.item.ItemStack;
import net.minestom.server.network.packet.server.play.EntityMetaDataPacket; 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)); return new Value<>(TYPE_STRING, value, writer -> writer.writeSizedString(value));
} }
@Deprecated
public static Value<JsonMessage> Chat(@NotNull JsonMessage value) { public static Value<JsonMessage> Chat(@NotNull JsonMessage value) {
return new Value<>(TYPE_CHAT, value, writer -> writer.writeSizedString(value.toString())); return new Value<>(TYPE_CHAT, value, writer -> writer.writeSizedString(value.toString()));
} }
@Deprecated
public static Value<JsonMessage> OptChat(@Nullable JsonMessage value) { public static Value<JsonMessage> OptChat(@Nullable JsonMessage value) {
return new Value<>(TYPE_OPTCHAT, value, writer -> { return new Value<>(TYPE_OPTCHAT, value, writer -> {
final boolean present = value != null; 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) { public static Value<ItemStack> Slot(@NotNull ItemStack value) {
return new Value<>(TYPE_SLOT, value, writer -> writer.writeItemStack(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(); protected final Set<Entity> viewableEntities = ConcurrentHashMap.newKeySet();
private int latency; private int latency;
private JsonMessage displayName; private Component displayName;
private PlayerSkin skin; private PlayerSkin skin;
private DimensionType dimensionType; private DimensionType dimensionType;
@ -475,15 +475,15 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
public void kill() { public void kill() {
if (!isDead()) { if (!isDead()) {
JsonMessage deathText; Component deathText;
JsonMessage chatMessage; Component chatMessage;
// get death screen text to the killed player // get death screen text to the killed player
{ {
if (lastDamageSource != null) { if (lastDamageSource != null) {
deathText = lastDamageSource.buildDeathScreenText(this); deathText = lastDamageSource.buildDeathScreenText(this);
} else { // may happen if killed by the server without applying damage } 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) { if (lastDamageSource != null) {
chatMessage = lastDamageSource.buildDeathMessage(this); chatMessage = lastDamageSource.buildDeathMessage(this);
} else { // may happen if killed by the server without applying damage } 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 // #buildDeathScreenText can return null, check here
if (deathText != null) { if (deathText != null) {
CombatEventPacket deathPacket = CombatEventPacket.death(this, null, deathText); CombatEventPacket deathPacket = CombatEventPacket.death(this, null, MinecraftServer.getSerializationManager().serialize(deathText, this));
playerConnection.sendPacket(deathPacket); playerConnection.sendPacket(deathPacket);
} }
// #buildDeathMessage can return null, check here // #buildDeathMessage can return null, check here
if (chatMessage != null) { 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); 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. * Sends a legacy message with the specified color char.
* *
@ -819,7 +803,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
@Override @Override
public void sendMessage(@NotNull Identity source, @NotNull Component message, @NotNull MessageType type) { 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); playerConnection.sendPacket(chatMessagePacket);
} }
@ -1023,8 +1007,8 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
@Override @Override
public void sendPlayerListHeaderAndFooter(@NotNull Component header, @NotNull Component footer) { public void sendPlayerListHeaderAndFooter(@NotNull Component header, @NotNull Component footer) {
PlayerListHeaderAndFooterPacket packet = new PlayerListHeaderAndFooterPacket(); PlayerListHeaderAndFooterPacket packet = new PlayerListHeaderAndFooterPacket();
packet.header = MinecraftServer.getSerializationManager().serialize(header); packet.header = MinecraftServer.getSerializationManager().serialize(header, this);
packet.footer = MinecraftServer.getSerializationManager().serialize(footer); packet.footer = MinecraftServer.getSerializationManager().serialize(footer, this);
playerConnection.sendPacket(packet); playerConnection.sendPacket(packet);
} }
@ -1105,7 +1089,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
@Override @Override
public void sendActionBar(@NotNull Component message) { 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); playerConnection.sendPacket(titlePacket);
} }
@ -1313,9 +1297,20 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
* Gets the player display name in the tab-list. * Gets the player display name in the tab-list.
* *
* @return the player display name, null means that {@link #getUsername()} is displayed * @return the player display name, null means that {@link #getUsername()} is displayed
* @deprecated Use {@link #getDisplayName()}
*/ */
@Nullable @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; return displayName;
} }
@ -1325,12 +1320,25 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
* Sets to null to show the player username. * Sets to null to show the player username.
* *
* @param displayName the display name, null to display the username * @param displayName the display name, null to display the username
* @deprecated Use {@link #setDisplayName(Component)}
*/ */
@Deprecated
public void setDisplayName(@Nullable JsonMessage displayName) { 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; this.displayName = displayName;
PlayerInfoPacket infoPacket = new PlayerInfoPacket(PlayerInfoPacket.Action.UPDATE_DISPLAY_NAME); 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); sendPacketToViewersAndSelf(infoPacket);
} }
@ -1909,9 +1917,9 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
// Packet type depends on the current player connection state // Packet type depends on the current player connection state
final ServerPacket disconnectPacket; final ServerPacket disconnectPacket;
if (connectionState == ConnectionState.LOGIN) { if (connectionState == ConnectionState.LOGIN) {
disconnectPacket = new LoginDisconnectPacket(MinecraftServer.getSerializationManager().serialize(component)); disconnectPacket = new LoginDisconnectPacket(MinecraftServer.getSerializationManager().serialize(component, this));
} else { } else {
disconnectPacket = new DisconnectPacket(MinecraftServer.getSerializationManager().serialize(component)); disconnectPacket = new DisconnectPacket(MinecraftServer.getSerializationManager().serialize(component, this));
} }
if (playerConnection instanceof NettyPlayerConnection) { if (playerConnection instanceof NettyPlayerConnection) {
@ -2536,7 +2544,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
PlayerInfoPacket.AddPlayer addPlayer = PlayerInfoPacket.AddPlayer addPlayer =
new PlayerInfoPacket.AddPlayer(getUuid(), getUsername(), getGameMode(), getLatency()); new PlayerInfoPacket.AddPlayer(getUuid(), getUsername(), getGameMode(), getLatency());
addPlayer.displayName = displayName; addPlayer.displayName = MinecraftServer.getSerializationManager().serialize(displayName);
// Skin support // Skin support
if (skin != null) { if (skin != null) {

View File

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

View File

@ -1,5 +1,6 @@
package net.minestom.server.entity.hologram; package net.minestom.server.entity.hologram;
import net.kyori.adventure.text.Component;
import net.minestom.server.Viewable; import net.minestom.server.Viewable;
import net.minestom.server.chat.ColoredText; import net.minestom.server.chat.ColoredText;
import net.minestom.server.chat.JsonMessage; import net.minestom.server.chat.JsonMessage;
@ -13,7 +14,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.Set; 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 { public class Hologram implements Viewable {
@ -22,7 +23,7 @@ public class Hologram implements Viewable {
private final HologramEntity entity; private final HologramEntity entity;
private Position position; private Position position;
private JsonMessage text; private Component text;
private boolean removed; private boolean removed;
@ -33,14 +34,24 @@ public class Hologram implements Viewable {
* @param spawnPosition The spawn position of this hologram. * @param spawnPosition The spawn position of this hologram.
* @param text The text of this hologram. * @param text The text of this hologram.
* @param autoViewable {@code true}if the hologram should be visible automatically, otherwise {@code false}. * @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) { public Hologram(Instance instance, Position spawnPosition, JsonMessage text, boolean autoViewable) {
this.entity = new HologramEntity(spawnPosition.clone().add(0, OFFSET_Y, 0)); this(instance, spawnPosition, text.asComponent(), autoViewable);
this.entity.setInstance(instance); }
this.entity.setAutoViewable(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 spawnPosition The spawn position of this hologram.
* @param text The text 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); 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. * Gets the position of the hologram.
* *
@ -79,8 +107,19 @@ public class Hologram implements Viewable {
* Gets the hologram text. * Gets the hologram text.
* *
* @return 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; return text;
} }
@ -88,8 +127,19 @@ public class Hologram implements Viewable {
* Changes the hologram text. * Changes the hologram text.
* *
* @param text the new hologram text * @param text the new hologram text
* @deprecated Use {@link #setText(Component)}
*/ */
@Deprecated
public void setText(JsonMessage text) { 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(); checkRemoved();
this.text = text; this.text = text;
this.entity.setCustomName(text); this.entity.setCustomName(text);

View File

@ -1,5 +1,6 @@
package net.minestom.server.entity.metadata; package net.minestom.server.entity.metadata;
import net.kyori.adventure.text.Component;
import net.minestom.server.chat.JsonMessage; import net.minestom.server.chat.JsonMessage;
import net.minestom.server.entity.Entity; import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata; import net.minestom.server.entity.Metadata;
@ -106,11 +107,29 @@ public class EntityMeta {
this.metadata.setIndex((byte) 1, Metadata.VarInt(value)); 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); 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)); this.metadata.setIndex((byte) 2, Metadata.OptChat(value));
} }

View File

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

View File

@ -1,5 +1,6 @@
package net.minestom.server.event.player; package net.minestom.server.event.player;
import net.kyori.adventure.text.Component;
import net.minestom.server.chat.JsonMessage; import net.minestom.server.chat.JsonMessage;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.event.CancellableEvent; import net.minestom.server.event.CancellableEvent;
@ -19,7 +20,7 @@ public class PlayerChatEvent extends PlayerEvent implements CancellableEvent {
private final Collection<Player> recipients; private final Collection<Player> recipients;
private String message; private String message;
private Function<PlayerChatEvent, JsonMessage> chatFormat; private Function<PlayerChatEvent, Component> chatFormat;
private boolean cancelled; private boolean cancelled;
@ -33,8 +34,19 @@ public class PlayerChatEvent extends PlayerEvent implements CancellableEvent {
* Changes the chat format. * Changes the chat format.
* *
* @param chatFormat the custom chat format, null to use the default one * @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; 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 * @return the chat format which will be used, null if this is the default one
*/ */
@Nullable @Nullable
public Function<PlayerChatEvent, JsonMessage> getChatFormatFunction() { public Function<PlayerChatEvent, Component> getChatFormatFunction() {
return chatFormat; return chatFormat;
} }

View File

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

View File

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

View File

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

View File

@ -1,7 +1,10 @@
package net.minestom.server.item.metadata; package net.minestom.server.item.metadata;
import net.kyori.adventure.text.format.TextColor;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.chat.ChatColor; 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.CloneUtils;
import net.minestom.server.utils.clone.PublicCloneable; import net.minestom.server.utils.clone.PublicCloneable;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -17,7 +20,7 @@ public class MapMeta extends ItemMeta {
private int mapId; private int mapId;
private int mapScaleDirection = 1; private int mapScaleDirection = 1;
private List<MapDecoration> decorations = new CopyOnWriteArrayList<>(); private List<MapDecoration> decorations = new CopyOnWriteArrayList<>();
private ChatColor mapColor = ChatColor.NO_COLOR; private Color mapColor = new Color(0, 0, 0);
public MapMeta() { public MapMeta() {
} }
@ -84,21 +87,40 @@ public class MapMeta extends ItemMeta {
* Gets the map color. * Gets the map color.
* *
* @return the map color * @return the map color
* @deprecated Use {@link #getMapColor()}
*/ */
public ChatColor getMapColor() { @Deprecated
return mapColor; 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. * Changes the map color.
* <p>
* WARNING: RGB colors are not supported.
* *
* @param mapColor the new map color * @param mapColor the new map color
* @deprecated Use {@link #setMapColor(Color)}
*/ */
@Deprecated
public void setMapColor(ChatColor mapColor) { public void setMapColor(ChatColor mapColor) {
mapColor.getId(); // used to throw an error if rgb color is used this.setMapColor(mapColor.asColor());
this.mapColor = mapColor; }
/**
* Changes the map color.
*
* @param color the new map color
*/
public void setMapColor(@NotNull Color color) {
this.mapColor = color;
} }
@Override @Override
@ -156,8 +178,7 @@ public class MapMeta extends ItemMeta {
if (compound.containsKey("display")) { if (compound.containsKey("display")) {
final NBTCompound displayCompound = compound.getCompound("display"); final NBTCompound displayCompound = compound.getCompound("display");
if (displayCompound.containsKey("MapColor")) { if (displayCompound.containsKey("MapColor")) {
final int color = displayCompound.getAsInt("MapColor"); this.mapColor = new Color(displayCompound.getAsInt("MapColor"));
this.mapColor = ChatColor.fromId(color);
} }
} }
@ -191,7 +212,7 @@ public class MapMeta extends ItemMeta {
} else { } else {
displayCompound = new NBTCompound(); 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; package net.minestom.server.item.metadata;
import net.kyori.adventure.text.format.TextColor;
import net.minestom.server.chat.ChatColor; import net.minestom.server.chat.ChatColor;
import net.minestom.server.color.Color;
import net.minestom.server.potion.CustomPotionEffect; import net.minestom.server.potion.CustomPotionEffect;
import net.minestom.server.potion.PotionType; import net.minestom.server.potion.PotionType;
import net.minestom.server.registry.Registries; import net.minestom.server.registry.Registries;
@ -29,8 +31,7 @@ public class PotionMeta extends ItemMeta {
// Not final because of #clone() // Not final because of #clone()
private List<CustomPotionEffect> customPotionEffects = new CopyOnWriteArrayList<>(); private List<CustomPotionEffect> customPotionEffects = new CopyOnWriteArrayList<>();
private boolean hasColor; private Color color;
private byte red, green, blue;
/** /**
* Gets the potion type. * Gets the potion type.
@ -65,19 +66,20 @@ public class PotionMeta extends ItemMeta {
* Changes the color of the potion. * Changes the color of the potion.
* *
* @param color the new color of the potion * @param color the new color of the potion
* @deprecated Use {@link #setColor(Color)}
*/ */
@Deprecated
public void setColor(ChatColor color) { public void setColor(ChatColor color) {
// FIXME: weird usage of ChatColor, should maybe rename this.setColor(color.asColor());
}
if (color == null) { /**
this.hasColor = false; * Changes the color of the potion.
return; *
} * @param color the new color of the potion
*/
this.red = color.getRed(); public void setColor(@Nullable Color color) {
this.green = color.getGreen(); this.color = color;
this.blue = color.getBlue();
this.hasColor = true;
} }
@Override @Override
@ -93,10 +95,7 @@ public class PotionMeta extends ItemMeta {
PotionMeta potionMeta = (PotionMeta) itemMeta; PotionMeta potionMeta = (PotionMeta) itemMeta;
return potionMeta.potionType == potionType && return potionMeta.potionType == potionType &&
potionMeta.customPotionEffects.equals(customPotionEffects) && potionMeta.customPotionEffects.equals(customPotionEffects) &&
potionMeta.hasColor == hasColor && potionMeta.color.equals(color);
potionMeta.red == red &&
potionMeta.green == green &&
potionMeta.blue == blue;
} }
@Override @Override
@ -121,10 +120,7 @@ public class PotionMeta extends ItemMeta {
} }
if (compound.containsKey("CustomPotionColor")) { if (compound.containsKey("CustomPotionColor")) {
final int color = compound.getInt("CustomPotionColor"); this.color = new Color(compound.getInt("CustomPotionColor"));
this.red = (byte) ((color >> 16) & 0x000000FF);
this.green = (byte) ((color >> 8) & 0x000000FF);
this.blue = (byte) ((color) & 0x000000FF);
} }
} }
@ -151,9 +147,8 @@ public class PotionMeta extends ItemMeta {
compound.set("CustomPotionEffects", potionList); compound.set("CustomPotionEffects", potionList);
} }
if (hasColor) { if (color != null) {
final int color = red << 16 + green << 8 + blue; compound.setInt("CustomPotionColor", color.asRGB());
compound.setInt("CustomPotionColor", color);
} }
} }
@ -165,10 +160,7 @@ public class PotionMeta extends ItemMeta {
potionMeta.potionType = potionType; potionMeta.potionType = potionType;
potionMeta.customPotionEffects = CloneUtils.cloneCopyOnWriteArrayList(customPotionEffects); potionMeta.customPotionEffects = CloneUtils.cloneCopyOnWriteArrayList(customPotionEffects);
potionMeta.hasColor = hasColor; potionMeta.color = color;
potionMeta.red = red;
potionMeta.green = green;
potionMeta.blue = blue;
return potionMeta; return potionMeta;
} }

View File

@ -39,6 +39,19 @@ public class SoundEffectPacket implements ServerPacket {
return packet; 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 @Override
public void write(@NotNull BinaryWriter writer) { public void write(@NotNull BinaryWriter writer) {
writer.writeVarInt(soundId); writer.writeVarInt(soundId);

View File

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