Merge branch 'master' into new-block-api

# Conflicts:
#	build.gradle
This commit is contained in:
TheMode 2021-06-17 13:58:01 +02:00
commit de22a76e9f
96 changed files with 606 additions and 2337 deletions

View File

@ -39,9 +39,6 @@ allprojects {
maven {
url "https://repo.velocitypowered.com/snapshots/"
}
maven {
url "https://repo.minestom.net/repository/maven-public/"
}
}
javadoc {
options {
@ -174,9 +171,6 @@ dependencies {
}
}
// This is the data Minestom uses. from https://github.com/Minestom/MinestomDataGenerator
api "net.minestom:minestom-data-full:${rootProject.properties.get("mcVersion")}"
api "com.github.Minestom:DependencyGetter:v1.0.1"
// Adventure, for user-interface

View File

@ -13,6 +13,10 @@ application {
mainClass.set("net.minestom.codegen.Generators")
}
repositories {
maven { url "https://repo.minestom.net/repository/maven-public/" }
}
dependencies {
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'org.jetbrains:annotations:20.1.0'

View File

@ -5,4 +5,4 @@ asmVersion=9.0
mixinVersion=0.8.1
hephaistosVersion=v1.1.8
kotlinVersion=1.5.0
adventureVersion=4.7.0
adventureVersion=4.8.1

View File

@ -1,9 +1,11 @@
package net.minestom.demo.largeframebuffers;
import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer;
import net.minestom.server.chat.ColoredText;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.type.decoration.EntityItemFrame;
import net.minestom.server.entity.metadata.other.ItemFrameMeta;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.InstanceManager;
import net.minestom.server.item.ItemStack;
@ -66,15 +68,26 @@ public class Demo {
}
private static void createFrame(Instance instance, int id, int x, int y, int z) {
EntityItemFrame itemFrame = new EntityItemFrame(new Position(x, y, z), EntityItemFrame.ItemFrameOrientation.NORTH);
itemFrame.getPosition().setYaw(180f);
Entity itemFrame = new Entity(EntityType.ITEM_FRAME);
ItemFrameMeta itemFrameMeta = (ItemFrameMeta) itemFrame.getEntityMeta();
itemFrameMeta.setNotifyAboutChanges(false);
itemFrameMeta.setOrientation(ItemFrameMeta.Orientation.NORTH);
ItemStack map = ItemStack.builder(Material.FILLED_MAP)
.meta(new MapMeta.Builder().mapId(id).build())
.build();
itemFrame.setItemStack(map);
itemFrame.setInstance(instance);
itemFrame.setCustomNameVisible(true);
itemFrame.setCustomName(ColoredText.of("MapID: " + id));
itemFrameMeta.setItem(map);
itemFrameMeta.setCustomNameVisible(true);
itemFrameMeta.setCustomName(Component.text("MapID: " + id));
itemFrameMeta.setNotifyAboutChanges(true);
itemFrame.setInstance(instance, new Position(x, y, z));
itemFrame.getPosition().setYaw(180f);
}
private static void setupMaps(Instance instance, int mapIDStart, int zCoordinate) {

View File

@ -3,6 +3,7 @@ package net.minestom.server.adventure;
import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.sound.SoundStop;
import net.kyori.adventure.text.format.NamedTextColor;
@ -14,6 +15,7 @@ import net.minestom.server.network.packet.server.play.SoundEffectPacket;
import net.minestom.server.network.packet.server.play.StopSoundPacket;
import net.minestom.server.registry.Registries;
import net.minestom.server.sound.SoundEvent;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
@ -44,6 +46,7 @@ public class AdventurePacketConvertor {
/**
* Gets the int value of a boss bar overlay.
*
* @param overlay the overlay
* @return the value
*/
@ -53,6 +56,7 @@ public class AdventurePacketConvertor {
/**
* Gets the byte value of a collection of boss bar flags.
*
* @param flags the flags
* @return the value
*/
@ -66,6 +70,7 @@ public class AdventurePacketConvertor {
/**
* Gets the int value of a boss bar color.
*
* @param color the color
* @return the value
*/
@ -75,6 +80,7 @@ public class AdventurePacketConvertor {
/**
* Gets the int value of a sound source.
*
* @param source the source
* @return the value
*/
@ -84,6 +90,7 @@ public class AdventurePacketConvertor {
/**
* Gets the int value from a named text color.
*
* @param color the color
* @return the int value
*/
@ -93,17 +100,18 @@ public class AdventurePacketConvertor {
/**
* Creates a sound packet from a sound and a location.
*
* @param sound the sound
* @param x the x coordinate
* @param y the y coordinate
* @param z the z coordinate
* @return the sound packet
*/
public static ServerPacket createSoundPacket(@NotNull Sound sound, double x, double y, double z) {
SoundEvent minestomSound = Registries.getSoundEvent(sound.name());
public static @NotNull ServerPacket createSoundPacket(@NotNull Sound sound, double x, double y, double z) {
final SoundEvent minestomSound = Registries.getSoundEvent(sound.name());
if (minestomSound == null) {
NamedSoundEffectPacket packet = new NamedSoundEffectPacket();
final NamedSoundEffectPacket packet = new NamedSoundEffectPacket();
packet.soundName = sound.name().asString();
packet.soundSource = sound.source();
packet.x = (int) x;
@ -113,7 +121,7 @@ public class AdventurePacketConvertor {
packet.pitch = sound.pitch();
return packet;
} else {
SoundEffectPacket packet = new SoundEffectPacket();
final SoundEffectPacket packet = new SoundEffectPacket();
packet.soundId = minestomSound.getId();
packet.soundSource = sound.source();
packet.x = (int) x;
@ -126,29 +134,60 @@ public class AdventurePacketConvertor {
}
/**
* Creates an entity sound packet from an Adventure sound.
* Creates a sound effect packet from a sound and an emitter.
*
* @param sound the sound
* @param entity the entity the sound is coming from
* @return the packet
* @param emitter the emitter, must be an {@link Entity}
* @return the sound packet
*/
public static ServerPacket createEntitySoundPacket(@NotNull Sound sound, @NotNull Entity entity) {
SoundEvent soundEvent = Registries.getSoundEvent(sound.name());
public static @NotNull ServerPacket createSoundPacket(@NotNull Sound sound, Sound.@NotNull Emitter emitter) {
if (emitter == Sound.Emitter.self())
throw new IllegalArgumentException("you must replace instances of Emitter.self() before calling this method");
if (!(emitter instanceof Entity))
throw new IllegalArgumentException("you can only call this method with entities");
if (soundEvent == null) {
throw new IllegalArgumentException("Sound must be a valid sound event.");
} else {
EntitySoundEffectPacket packet = new EntitySoundEffectPacket();
packet.soundId = soundEvent.getId();
final Entity entity = (Entity) emitter;
final SoundEvent minestomSound = Registries.getSoundEvent(sound.name());
if (minestomSound != null) {
final EntitySoundEffectPacket packet = new EntitySoundEffectPacket();
packet.soundId = minestomSound.getId();
packet.soundSource = sound.source();
packet.entityId = entity.getEntityId();
packet.volume = sound.volume();
packet.pitch = sound.pitch();
return packet;
} else {
final Position pos = entity.getPosition();
final NamedSoundEffectPacket packet = new NamedSoundEffectPacket();
packet.soundName = sound.name().asString();
packet.soundSource = sound.source();
packet.x = (int) pos.getX();
packet.y = (int) pos.getY();
packet.z = (int) pos.getX();
packet.volume = sound.volume();
packet.pitch = sound.pitch();
return packet;
}
}
/**
* Creates an entity sound packet from an Adventure sound.
*
* @param sound the sound
* @param entity the entity the sound is coming from
* @return the packet
* @deprecated Use {@link #createSoundPacket(Sound, Sound.Emitter)}
*/
@Deprecated(forRemoval = true)
public static ServerPacket createEntitySoundPacket(@NotNull Sound sound, @NotNull Entity entity) {
return createSoundPacket(sound, entity);
}
/**
* Creates a sound stop packet from a sound stop.
*
* @param stop the sound stop
* @return the sound stop packet
*/
@ -156,14 +195,16 @@ public class AdventurePacketConvertor {
StopSoundPacket packet = new StopSoundPacket();
packet.flags = 0x0;
if (stop.source() != null) {
final Sound.Source source = stop.source();
if (source != null) {
packet.flags |= 0x1;
packet.source = AdventurePacketConvertor.getSoundSourceValue(stop.source());
packet.source = AdventurePacketConvertor.getSoundSourceValue(source);
}
if (stop.sound() != null) {
final Key sound = stop.sound();
if (sound != null) {
packet.flags |= 0x2;
packet.sound = stop.sound().asString();
packet.sound = sound.asString();
}
return packet;

View File

@ -6,6 +6,7 @@ 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 net.minestom.server.utils.ComponentUtils;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
@ -13,6 +14,8 @@ import java.util.Locale;
import java.util.Objects;
import java.util.function.Function;
import org.jetbrains.annotations.Nullable;
/**
* Manager class for handling Adventure serialization. By default AdventureSerializer will simply
* serialize components to Strings using {@link GsonComponentSerializer}. However, AdventureSerializer
@ -25,17 +28,19 @@ import java.util.function.Function;
* of specific players, or other elements which implement {@link Localizable}. To add your
* own translations, use {@link GlobalTranslator#addSource(Translator)} with a
* {@link TranslationRegistry} or your own implementation of {@link Translator}.
*
* @deprecated Use {@link MinestomAdventure}
*/
@Deprecated(forRemoval = true)
public class AdventureSerializer {
/**
* If components should be automatically translated in outgoing packets.
* @deprecated Use {@link MinestomAdventure#AUTOMATIC_COMPONENT_TRANSLATION}
*/
public static final boolean AUTOMATIC_COMPONENT_TRANSLATION = false;
protected static final Localizable NULL_LOCALIZABLE = () -> null;
@Deprecated(forRemoval = true)
public static final boolean AUTOMATIC_COMPONENT_TRANSLATION = MinestomAdventure.AUTOMATIC_COMPONENT_TRANSLATION;
private static Function<Component, String> serializer = component -> GsonComponentSerializer.gson().serialize(component);
private static Locale defaultLocale = Locale.US;
private AdventureSerializer() {}
@ -43,7 +48,9 @@ public class AdventureSerializer {
* Gets the root serializer that is used to convert components into strings.
*
* @return the serializer
* @deprecated The serializer is no longer in use, use the adventure-provided serializers
*/
@Deprecated(forRemoval = true)
public static @NotNull Function<Component, String> getSerializer() {
return AdventureSerializer.serializer;
}
@ -52,7 +59,9 @@ public class AdventureSerializer {
* Sets the root serializer that is used to convert components into strings.
*
* @param serializer the serializer
* @deprecated The serializer is no longer in use
*/
@Deprecated
public static void setSerializer(@NotNull Function<Component, String> serializer) {
AdventureSerializer.serializer = serializer;
}
@ -63,9 +72,11 @@ public class AdventureSerializer {
* does not have a locale.
*
* @return the default locale
* @deprecated Use {@link MinestomAdventure#getDefaultLocale()}
*/
@Deprecated(forRemoval = true)
public static @NotNull Locale getDefaultLocale() {
return defaultLocale;
return MinestomAdventure.getDefaultLocale();
}
/**
@ -73,10 +84,12 @@ public class AdventureSerializer {
* {@link #translate(Component, Localizable)} is called with a localizable that
* does not have a locale.
*
* @param defaultLocale the new default locale
* @param defaultLocale the new default locale, or {@code null} to return to the default
* @deprecated Use {@link MinestomAdventure#setDefaultLocale(Locale)}}
*/
public static void setDefaultLocale(@NotNull Locale defaultLocale) {
AdventureSerializer.defaultLocale = defaultLocale;
@Deprecated(forRemoval = true)
public static void setDefaultLocale(@Nullable Locale defaultLocale) {
MinestomAdventure.setDefaultLocale(defaultLocale);
}
/**
@ -84,7 +97,9 @@ public class AdventureSerializer {
* {@link GlobalTranslator#get()}.
*
* @return the global translator
* @deprecated Use {@link GlobalTranslator#get()}
*/
@Deprecated(forRemoval = true)
public static @NotNull GlobalTranslator getTranslator() {
return GlobalTranslator.get();
}
@ -97,7 +112,9 @@ public class AdventureSerializer {
* @param localizable the localizable
*
* @return the prepared component
* @deprecated Use {@link GlobalTranslator#translate(String, Locale)}
*/
@Deprecated(forRemoval = true)
public static @NotNull Component translate(@NotNull Component component, @NotNull Localizable localizable) {
return GlobalTranslator.renderer().render(component, Objects.requireNonNullElse(localizable.getLocale(), AdventureSerializer.getDefaultLocale()));
}
@ -110,7 +127,9 @@ public class AdventureSerializer {
* @param locale the locale
*
* @return the prepared component
* @deprecated Use {@link GlobalTranslator#translate(String, Locale)}
*/
@Deprecated(forRemoval = true)
public static @NotNull Component translate(@NotNull Component component, @NotNull Locale locale) {
return GlobalTranslator.renderer().render(component, locale);
}
@ -121,7 +140,9 @@ public class AdventureSerializer {
* @param component the component
*
* @return the serialized string
* @deprecated Use the Adventure serializers directly
*/
@Deprecated(forRemoval = true)
public static @NotNull String serialize(@NotNull Component component) {
return AdventureSerializer.serializer.apply(component);
}
@ -133,7 +154,9 @@ public class AdventureSerializer {
* @param localizable the localisable
*
* @return the string
* @deprecated Use {@link GlobalTranslator#translate(String, Locale)} and the Adventure serializers
*/
@Deprecated(forRemoval = true)
public static String translateAndSerialize(@NotNull Component component, @NotNull Localizable localizable) {
return AdventureSerializer.translateAndSerialize(component, Objects.requireNonNullElse(localizable.getLocale(), AdventureSerializer.getDefaultLocale()));
}
@ -145,7 +168,9 @@ public class AdventureSerializer {
* @param locale the locale
*
* @return the string
* @deprecated Use {@link GlobalTranslator#translate(String, Locale)} and the Adventure serializers
*/
@Deprecated(forRemoval = true)
public static String translateAndSerialize(@NotNull Component component, @NotNull Locale locale) {
return AdventureSerializer.serialize(AdventureSerializer.translate(component, locale));
}
@ -157,9 +182,11 @@ public class AdventureSerializer {
* @param component the component
* @return {@code true} if the component can be translated server-side,
* {@code false} otherwise
* @deprecated Use {@link ComponentUtils#isTranslatable(Component)}
*/
@Deprecated(forRemoval = true)
public static boolean isTranslatable(@NotNull Component component) {
return !component.equals(AdventureSerializer.translate(component, AdventureSerializer.getDefaultLocale()));
return ComponentUtils.isTranslatable(component);
}
/**
@ -167,14 +194,10 @@ public class AdventureSerializer {
* @param components the components
* @return {@code true} if any of the components can be translated server-side,
* {@code false} otherwise
* @deprecated Use {@link ComponentUtils#areAnyTranslatable(Collection)}
*/
@Deprecated(forRemoval = true)
public static boolean areAnyTranslatable(@NotNull Collection<Component> components) {
for (Component component : components) {
if (AdventureSerializer.isTranslatable(component)) {
return true;
}
}
return false;
return ComponentUtils.areAnyTranslatable(components);
}
}

View File

@ -16,7 +16,7 @@ public interface Localizable {
* @return the empty localizable
*/
static @NotNull Localizable empty() {
return AdventureSerializer.NULL_LOCALIZABLE;
return MinestomAdventure.NULL_LOCALIZABLE;
}
/**

View File

@ -0,0 +1,55 @@
package net.minestom.server.adventure;
import java.io.StringReader;
import net.kyori.adventure.util.Codec;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Locale;
import java.util.Objects;
import org.jglrxavpok.hephaistos.nbt.NBT;
import org.jglrxavpok.hephaistos.nbt.NBTException;
import org.jglrxavpok.hephaistos.nbt.SNBTParser;
/**
* Adventure related constants, etc.
*/
public final class MinestomAdventure {
/**
* A codec to convert between strings and NBT.
*/
public static final Codec<NBT, String, NBTException, RuntimeException> NBT_CODEC
= Codec.of(encoded -> new SNBTParser(new StringReader(encoded)).parse(), NBT::toSNBT);
/**
* If components should be automatically translated in outgoing packets.
*/
public static final boolean AUTOMATIC_COMPONENT_TRANSLATION = false;
static final Localizable NULL_LOCALIZABLE = () -> null;
private static Locale defaultLocale = Locale.getDefault();
private MinestomAdventure() {
}
/**
* Gets the default locale used to translate components when no overriding locale has been provided.
*
* @return the default locale
*/
public static @NotNull Locale getDefaultLocale() {
return defaultLocale;
}
/**
* Sets the default locale used to translate components when no overriding locale has been provided.
*
* @param defaultLocale the new default, or {@code null} to return to {@link Locale#getDefault()}
*/
public static void setDefaultLocale(@Nullable Locale defaultLocale) {
MinestomAdventure.defaultLocale = Objects.requireNonNullElseGet(defaultLocale, Locale::getDefault);
}
}

View File

@ -90,11 +90,25 @@ public interface PacketGroupingAudience extends ForwardingAudience {
PacketUtils.sendGroupedPacket(this.getPlayers(), AdventurePacketConvertor.createSoundPacket(sound, x, y, z));
}
@Override
default void playSound(@NotNull Sound sound, Sound.@NotNull Emitter emitter) {
if (emitter != Sound.Emitter.self()) {
PacketUtils.sendGroupedPacket(this.getPlayers(), AdventurePacketConvertor.createSoundPacket(sound, emitter));
} else {
// if we're playing on self, we need to delegate to each audience member
for (Audience audience : this.audiences()) {
audience.playSound(sound, emitter);
}
}
}
@Override
default void stopSound(@NotNull SoundStop stop) {
PacketUtils.sendGroupedPacket(this.getPlayers(), AdventurePacketConvertor.createSoundStopPacket(stop));
}
@Override
default @NotNull Iterable<? extends Audience> audiences() {
return this.getPlayers();

View File

@ -0,0 +1,22 @@
package net.minestom.server.adventure.provider;
import net.kyori.adventure.text.TranslatableComponent;
import net.kyori.adventure.text.flattener.ComponentFlattener;
import net.kyori.adventure.translation.GlobalTranslator;
import net.minestom.server.adventure.MinestomAdventure;
final class MinestomFlattenerProvider {
static final ComponentFlattener INSTANCE;
static {
final ComponentFlattener.Builder builder = ComponentFlattener.basic().toBuilder();
// handle server-side translations if needed
builder.complexMapper(TranslatableComponent.class, ((component, consumer) -> {
if (MinestomAdventure.AUTOMATIC_COMPONENT_TRANSLATION) {
consumer.accept(GlobalTranslator.render(component, MinestomAdventure.getDefaultLocale()));
}
}));
INSTANCE = builder.build();
}
}

View File

@ -0,0 +1,29 @@
package net.minestom.server.adventure.provider;
import java.util.function.Consumer;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("UnstableApiUsage") // we are permitted to provide this
public final class MinestomGsonComponentSerializerProvider implements GsonComponentSerializer.Provider {
@Override
public @NotNull GsonComponentSerializer gson() {
return GsonComponentSerializer.builder()
.legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.INSTANCE)
.build();
}
@Override
public @NotNull GsonComponentSerializer gsonLegacy() {
return GsonComponentSerializer.builder()
.legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.INSTANCE)
.downsampleColors()
.build();
}
@Override
public @NotNull Consumer<GsonComponentSerializer.Builder> builder() {
return builder -> {}; // we don't need to touch the builder here
}
}

View File

@ -0,0 +1,31 @@
package net.minestom.server.adventure.provider;
import java.util.function.Consumer;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("UnstableApiUsage") // we are permitted to provide this
public final class MinestomLegacyComponentSerializerProvider implements LegacyComponentSerializer.Provider {
@Override
public @NotNull LegacyComponentSerializer legacyAmpersand() {
return LegacyComponentSerializer.builder()
.character(LegacyComponentSerializer.AMPERSAND_CHAR)
.flattener(MinestomFlattenerProvider.INSTANCE)
.build();
}
@Override
public @NotNull LegacyComponentSerializer legacySection() {
return LegacyComponentSerializer.builder()
.character(LegacyComponentSerializer.SECTION_CHAR)
.flattener(MinestomFlattenerProvider.INSTANCE)
.build();
}
@Override
public @NotNull Consumer<LegacyComponentSerializer.Builder> legacy() {
// we will provide our flattener to allow for custom translations/etc
return builder -> builder.flattener(MinestomFlattenerProvider.INSTANCE);
}
}

View File

@ -0,0 +1,22 @@
package net.minestom.server.adventure.provider;
import java.util.function.Consumer;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("UnstableApiUsage") // we are permitted to provide this
public final class MinestomPlainTextComponentSerializerProvider implements PlainTextComponentSerializer.Provider {
@Override
public @NotNull PlainTextComponentSerializer plainTextSimple() {
return PlainTextComponentSerializer.builder()
.flattener(MinestomFlattenerProvider.INSTANCE)
.build();
}
@Override
public @NotNull Consumer<PlainTextComponentSerializer.Builder> plainText() {
// we will provide our flattener to allow for custom translations/etc
return builder -> builder.flattener(MinestomFlattenerProvider.INSTANCE);
}
}

View File

@ -0,0 +1,101 @@
package net.minestom.server.adventure.provider;
import java.util.UUID;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.nbt.api.BinaryTagHolder;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.serializer.gson.LegacyHoverEventSerializer;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import net.kyori.adventure.util.Codec;
import net.minestom.server.adventure.MinestomAdventure;
import org.jetbrains.annotations.NotNull;
import org.jglrxavpok.hephaistos.nbt.NBT;
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
import org.jglrxavpok.hephaistos.nbt.NBTException;
import java.io.IOException;
import java.util.Objects;
final class NBTLegacyHoverEventSerializer implements LegacyHoverEventSerializer {
static final NBTLegacyHoverEventSerializer INSTANCE = new NBTLegacyHoverEventSerializer();
private static final String ITEM_TYPE = "id", ITEM_COUNT = "Count", ITEM_TAG = "tag";
private static final String ENTITY_TYPE = "type", ENTITY_NAME = "name", ENTITY_ID = "id";
private NBTLegacyHoverEventSerializer() {
}
@Override
public HoverEvent.@NotNull ShowItem deserializeShowItem(@NotNull Component input) throws IOException {
final String raw = PlainTextComponentSerializer.plainText().serialize(input);
try {
// attempt the parse
final NBT nbt = MinestomAdventure.NBT_CODEC.decode(raw);
if (!(nbt instanceof NBTCompound)) throw new IOException("contents were not a compound");
final NBTCompound contents = (NBTCompound) nbt, tag = contents.getCompound(ITEM_TAG);
// create the event
return HoverEvent.ShowItem.of(
Key.key(Objects.requireNonNullElse(contents.getString(ITEM_TYPE), "")),
Objects.requireNonNullElse(contents.getByte(ITEM_COUNT), (byte) 1),
tag == null ? null : BinaryTagHolder.encode(tag, MinestomAdventure.NBT_CODEC)
);
} catch (final NBTException e) {
throw new IOException(e);
}
}
@Override
public HoverEvent.@NotNull ShowEntity deserializeShowEntity(@NotNull Component input, Codec.Decoder<Component, String, ? extends RuntimeException> componentDecoder) throws IOException {
final String raw = PlainTextComponentSerializer.plainText().serialize(input);
try {
final NBT nbt = MinestomAdventure.NBT_CODEC.decode(raw);
if (!(nbt instanceof NBTCompound)) throw new IOException("contents were not a compound");
final NBTCompound contents = (NBTCompound) nbt;
return HoverEvent.ShowEntity.of(
Key.key(Objects.requireNonNullElse(contents.getString(ENTITY_TYPE), "")),
UUID.fromString(Objects.requireNonNullElse(contents.getString(ENTITY_ID), "")),
componentDecoder.decode(Objects.requireNonNullElse(contents.getString(ENTITY_NAME), ""))
);
} catch (NBTException e) {
throw new IOException(e);
}
}
@Override
public @NotNull Component serializeShowItem(HoverEvent.@NotNull ShowItem input) throws IOException {
final NBTCompound tag = new NBTCompound();
tag.setString(ITEM_TYPE, input.item().asString());
tag.setByte(ITEM_COUNT, (byte) input.count());
final BinaryTagHolder nbt = input.nbt();
if (nbt != null) {
try {
tag.set(ITEM_TAG, nbt.get(MinestomAdventure.NBT_CODEC));
} catch (NBTException e) {
throw new IOException(e);
}
}
return Component.text(MinestomAdventure.NBT_CODEC.encode(tag));
}
@Override
public @NotNull Component serializeShowEntity(HoverEvent.@NotNull ShowEntity input, Codec.Encoder<Component, String, ? extends RuntimeException> componentEncoder) throws IOException {
final NBTCompound tag = new NBTCompound();
tag.setString(ENTITY_ID, input.id().toString());
tag.setString(ENTITY_TYPE, input.type().asString());
final Component name = input.name();
if (name != null) {
tag.setString(ENTITY_NAME, componentEncoder.encode(name));
}
return Component.text(MinestomAdventure.NBT_CODEC.encode(tag));
}
}

View File

@ -1,20 +0,0 @@
package net.minestom.server.bossbar;
/**
* Represents the displayed color of a {@link BossBar}.
* @deprecated Use {@link net.kyori.adventure.bossbar.BossBar.Color}
*/
@Deprecated
public enum BarColor {
PINK,
BLUE,
RED,
GREEN,
YELLOW,
PURPLE,
WHITE;
public net.kyori.adventure.bossbar.BossBar.Color asAdventureColor() {
return net.kyori.adventure.bossbar.BossBar.Color.valueOf(this.name());
}
}

View File

@ -1,19 +0,0 @@
package net.minestom.server.bossbar;
/**
* Used to define the number of segments on a {@link BossBar}.
*
* @deprecated Use {@link net.kyori.adventure.bossbar.BossBar.Overlay}
*/
@Deprecated
public enum BarDivision {
SOLID,
SEGMENT_6,
SEGMENT_10,
SEGMENT_12,
SEGMENT_20;
public net.kyori.adventure.bossbar.BossBar.Overlay asAdventureOverlay() {
return net.kyori.adventure.bossbar.BossBar.Overlay.values()[this.ordinal()];
}
}

View File

@ -1,300 +0,0 @@
package net.minestom.server.bossbar;
import net.minestom.server.Viewable;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.entity.Player;
import net.minestom.server.network.packet.server.play.BossBarPacket;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* Represents a boss bar which is displayed on the top of the client screen (max amount of boss bar defined by {@link #MAX_BOSSBAR}).
* <p>
* To use it, create a new instance using the constructor
* and add the {@link Player} you want using {@link #addViewer(Player)} and remove them using {@link #removeViewer(Player)}.
* <p>
* You can retrieve all the boss bars of a {@link Player} with {@link #getBossBars(Player)}.
*
* @deprecated Use {@link net.kyori.adventure.bossbar.BossBar}
*/
@Deprecated
public class BossBar implements Viewable {
private static final int MAX_BOSSBAR = 7;
private static final Map<UUID, Set<BossBar>> PLAYER_BOSSBAR_MAP = new HashMap<>();
private final UUID uuid = UUID.randomUUID();
private final Set<Player> viewers = new CopyOnWriteArraySet<>();
private final Set<Player> unmodifiableViewers = Collections.unmodifiableSet(viewers);
private JsonMessage title;
private float progress;
private BarColor color;
private BarDivision division;
private byte flags;
/**
* Creates a new {@link BossBar}.
*
* @param title the boss bar title
* @param color the boss bar color
* @param division the boss bar division
*/
public BossBar(@NotNull JsonMessage title, @NotNull BarColor color, @NotNull BarDivision division) {
this.title = title;
this.color = color;
this.division = division;
}
/**
* Gets all the visible boss bars of a {@link Player}.
*
* @param player the player to check the boss bars
* @return all the visible boss bars of the player, null if not any
*/
@Nullable
public static Set<BossBar> getBossBars(@NotNull Player player) {
return PLAYER_BOSSBAR_MAP.getOrDefault(player.getUuid(), null);
}
@Override
public synchronized boolean addViewer(@NotNull Player player) {
// Check already viewer
if (isViewer(player)) {
return false;
}
// Check max boss bar count
final Set<BossBar> playerBossBars = getBossBars(player);
if (playerBossBars != null && playerBossBars.size() >= MAX_BOSSBAR) {
return false;
}
addToPlayer(player);
return viewers.add(player);
}
@Override
public synchronized boolean removeViewer(@NotNull Player player) {
// Check not viewer
final boolean result = this.viewers.remove(player);
if (result) {
removeToPlayer(player);
}
// Remove from the map
removePlayer(player);
return result;
}
@NotNull
@Override
public Set<Player> getViewers() {
return unmodifiableViewers;
}
/**
* Gets the bossbar title.
*
* @return the current title of the bossbar
*/
@NotNull
public JsonMessage getTitle() {
return title;
}
/**
* Changes the bossbar title.
*
* @param title the new title of the bossbar
*/
public void setTitle(@NotNull JsonMessage title) {
this.title = title;
updateTitle();
}
/**
* Gets the bossbar progress.
*
* @return the current progress of the bossbar
*/
public float getProgress() {
return progress;
}
/**
* Changes the bossbar progress.
*
* @param progress the new progress bar percentage
* @throws IllegalArgumentException if {@code progress} is not between 0 and 1
*/
public void setProgress(float progress) {
Check.argCondition(!MathUtils.isBetween(progress, 0, 1),
"BossBar progress percentage should be between 0 and 1");
this.progress = progress;
updateProgress();
}
/**
* Gets the bossbar color.
*
* @return the current bossbar color
*/
@NotNull
public BarColor getColor() {
return color;
}
/**
* Changes the bossbar color.
*
* @param color the new color of the bossbar
*/
public void setColor(@NotNull BarColor color) {
this.color = color;
updateStyle();
}
/**
* Gets the bossbar division.
*
* @return the current bossbar division
*/
@NotNull
public BarDivision getDivision() {
return division;
}
/**
* Changes the bossbar division.
*
* @param division the new bossbar division count
*/
public void setDivision(@NotNull BarDivision division) {
this.division = division;
updateStyle();
}
/**
* Gets the bossbar flags.
*
* @return the flags
*/
public byte getFlags() {
return flags;
}
/**
* Sets the bossbar flags.
*
* @param flags the bossbar flags
* @see <a href="https://wiki.vg/Protocol#Boss_Bar">Boss bar packet</a>
*/
public void setFlags(byte flags) {
this.flags = flags;
}
/**
* Deletes the boss bar and remove all of its viewers.
*/
public void delete() {
BossBarPacket bossBarPacket = new BossBarPacket();
bossBarPacket.uuid = uuid;
bossBarPacket.action = BossBarPacket.Action.REMOVE;
sendPacketToViewers(bossBarPacket);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BossBar bossBar = (BossBar) o;
return Objects.equals(uuid, bossBar.uuid);
}
@Override
public int hashCode() {
return Objects.hash(uuid);
}
/**
* Removes the player from the bossbar map.
*
* @param player the player to remove from the map
*/
private void removePlayer(@NotNull Player player) {
final UUID uuid = player.getUuid();
if (!PLAYER_BOSSBAR_MAP.containsKey(uuid)) {
return;
}
Set<BossBar> bossBars = PLAYER_BOSSBAR_MAP.get(uuid);
bossBars.remove(this);
if (bossBars.isEmpty()) {
PLAYER_BOSSBAR_MAP.remove(uuid);
}
}
/**
* Sends a {@link BossBarPacket} to create the bossbar.
* <p>
* Also add the bossbar to the player viewing list.
*
* @param player the player to create the bossbar to
*/
private void addToPlayer(@NotNull Player player) {
// Add to the map
Set<BossBar> bossBars = PLAYER_BOSSBAR_MAP.computeIfAbsent(player.getUuid(), p -> new HashSet<>());
bossBars.add(this);
BossBarPacket bossBarPacket = new BossBarPacket();
bossBarPacket.uuid = uuid;
bossBarPacket.action = BossBarPacket.Action.ADD;
bossBarPacket.title = title.asComponent();
bossBarPacket.health = progress;
bossBarPacket.color = color.asAdventureColor();
bossBarPacket.overlay = division.asAdventureOverlay();
bossBarPacket.flags = flags;
player.getPlayerConnection().sendPacket(bossBarPacket);
}
/**
* Sends a {@link BossBarPacket} to remove the bossbar.
*
* @param player the player to remove the bossbar to
*/
private void removeToPlayer(@NotNull Player player) {
if (!player.isRemoved()) {
BossBarPacket bossBarPacket = new BossBarPacket();
bossBarPacket.uuid = uuid;
bossBarPacket.action = BossBarPacket.Action.REMOVE;
player.getPlayerConnection().sendPacket(bossBarPacket);
}
}
private void updateTitle() {
BossBarPacket bossBarPacket = new BossBarPacket();
bossBarPacket.uuid = uuid;
bossBarPacket.action = BossBarPacket.Action.UPDATE_TITLE;
bossBarPacket.title = title.asComponent();
sendPacketToViewers(bossBarPacket);
}
private void updateProgress() {
BossBarPacket bossBarPacket = new BossBarPacket();
bossBarPacket.uuid = uuid;
bossBarPacket.action = BossBarPacket.Action.UPDATE_HEALTH;
bossBarPacket.health = progress;
sendPacketToViewers(bossBarPacket);
}
private void updateStyle() {
BossBarPacket bossBarPacket = new BossBarPacket();
bossBarPacket.uuid = uuid;
bossBarPacket.action = BossBarPacket.Action.UPDATE_STYLE;
bossBarPacket.color = color.asAdventureColor();
sendPacketToViewers(bossBarPacket);
}
}

View File

@ -4,8 +4,10 @@ import com.google.common.annotations.Beta;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.arguments.*;
import net.minestom.server.command.builder.arguments.minecraft.SuggestionType;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.arguments.ArgumentLiteral;
import net.minestom.server.command.builder.arguments.ArgumentType;
import net.minestom.server.command.builder.arguments.ArgumentWord;
import net.minestom.server.command.builder.condition.CommandCondition;
import net.minestom.server.utils.StringUtils;
import org.jetbrains.annotations.NotNull;
@ -285,19 +287,6 @@ public class Command {
return syntaxes;
}
/**
* Allows for tab auto completion, this is called everytime the player press a key in the chat
* when in a dynamic argument ({@link ArgumentDynamicWord} (when {@link SuggestionType#ASK_SERVER} is used)
* and {@link ArgumentDynamicStringArray}).
*
* @param sender the command sender
* @param text the whole player's text
* @return the array containing all the suggestion for the current arg (split SPACE), can be null
*/
public @Nullable String[] onDynamicWrite(@NotNull CommandSender sender, @NotNull String text) {
return null;
}
/**
* Called when a {@link CommandSender} executes this command before any syntax callback.
* <p>

View File

@ -226,7 +226,6 @@ public abstract class Argument<T> {
* @param suggestionCallback The suggestion callback to set.
* @return 'this' for chaining
*/
@Beta
public Argument<T> setSuggestionCallback(@NotNull SuggestionCallback suggestionCallback) {
this.suggestionCallback = suggestionCallback;
return this;

View File

@ -1,72 +0,0 @@
package net.minestom.server.command.builder.arguments;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.NodeMaker;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.command.builder.suggestion.SuggestionCallback;
import net.minestom.server.network.packet.server.play.DeclareCommandsPacket;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.callback.validator.StringArrayValidator;
import net.minestom.server.utils.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Same as {@link ArgumentStringArray} with the exception
* that this argument can trigger {@link net.minestom.server.command.builder.Command#onDynamicWrite(CommandSender, String)}.
*
* @deprecated Use {@link Argument#setSuggestionCallback(SuggestionCallback)} with any argument type you want
*/
@Deprecated
public class ArgumentDynamicStringArray extends Argument<String[]> {
public static final int RESTRICTION_ERROR = 1;
private StringArrayValidator dynamicRestriction;
public ArgumentDynamicStringArray(String id) {
super(id, true, true);
}
@NotNull
@Override
public String[] parse(@NotNull String input) throws ArgumentSyntaxException {
final String[] value = input.split(StringUtils.SPACE);
// true if 'value' is valid based on the dynamic restriction
final boolean restrictionCheck = dynamicRestriction == null || dynamicRestriction.isValid(value);
if (!restrictionCheck) {
throw new ArgumentSyntaxException("Argument does not respect the dynamic restriction", input, RESTRICTION_ERROR);
}
return value;
}
@Override
public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) {
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(this, executable, false, true);
argumentNode.parser = "brigadier:string";
argumentNode.properties = BinaryWriter.makeArray(packetWriter -> {
packetWriter.writeVarInt(2); // Greedy phrase
});
argumentNode.suggestionsType = "minecraft:ask_server";
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
/**
* Sets the dynamic restriction of this dynamic argument.
* <p>
* Will be called once the argument condition is checked.
*
* @param dynamicRestriction the dynamic restriction, can be null to disable
* @return 'this' for chaining
*/
public ArgumentDynamicStringArray fromRestrictions(@Nullable StringArrayValidator dynamicRestriction) {
this.dynamicRestriction = dynamicRestriction;
return this;
}
}

View File

@ -1,93 +0,0 @@
package net.minestom.server.command.builder.arguments;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.NodeMaker;
import net.minestom.server.command.builder.arguments.minecraft.SuggestionType;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.command.builder.suggestion.SuggestionCallback;
import net.minestom.server.network.packet.server.play.DeclareCommandsPacket;
import net.minestom.server.utils.StringUtils;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.callback.validator.StringValidator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Same as {@link ArgumentWord} with the exception
* that this argument can trigger {@link net.minestom.server.command.builder.Command#onDynamicWrite(CommandSender, String)}
* when the suggestion type is {@link SuggestionType#ASK_SERVER}, or any other suggestions available in the enum.
*
* @deprecated Use {@link Argument#setSuggestionCallback(SuggestionCallback)} with any argument type you want
*/
@Deprecated
public class ArgumentDynamicWord extends Argument<String> {
public static final int SPACE_ERROR = 1;
public static final int RESTRICTION_ERROR = 2;
private final SuggestionType suggestionType;
private StringValidator dynamicRestriction;
public ArgumentDynamicWord(@NotNull String id, @NotNull SuggestionType suggestionType) {
super(id);
this.suggestionType = suggestionType;
}
@NotNull
@Override
public String parse(@NotNull String input) throws ArgumentSyntaxException {
if (input.contains(StringUtils.SPACE))
throw new ArgumentSyntaxException("Word cannot contain space characters", input, SPACE_ERROR);
// true if 'value' is valid based on the dynamic restriction
final boolean restrictionCheck = dynamicRestriction == null || dynamicRestriction.isValid(input);
if (!restrictionCheck) {
throw new ArgumentSyntaxException("Word does not respect the dynamic restriction", input, RESTRICTION_ERROR);
}
return input;
}
@Override
public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) {
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(this, executable, false, true);
final SuggestionType suggestionType = this.getSuggestionType();
argumentNode.parser = "brigadier:string";
argumentNode.properties = BinaryWriter.makeArray(packetWriter -> {
packetWriter.writeVarInt(0); // Single word
});
argumentNode.suggestionsType = suggestionType.getIdentifier();
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
/**
* Gets the suggestion type of this argument.
* <p>
* Suggestions are only suggestion, this means that the end value could not be the expected one.
*
* @return this argument suggestion type
*/
@NotNull
public SuggestionType getSuggestionType() {
return suggestionType;
}
/**
* Sets the dynamic restriction of this dynamic argument.
* <p>
* Will be called once the argument condition is checked.
*
* @param dynamicRestriction the dynamic restriction, can be null to disable
* @return 'this' for chaining
*/
@NotNull
public ArgumentDynamicWord fromRestrictions(@Nullable StringValidator dynamicRestriction) {
this.dynamicRestriction = dynamicRestriction;
return this;
}
}

View File

@ -270,31 +270,4 @@ public class ArgumentType {
public static ArgumentEntity Entities(@NotNull String id) {
return new ArgumentEntity(id);
}
/**
* @see ArgumentDynamicWord
* @deprecated will be replaced soon
*/
@Deprecated
public static ArgumentDynamicWord DynamicWord(@NotNull String id, @NotNull SuggestionType suggestionType) {
return new ArgumentDynamicWord(id, suggestionType);
}
/**
* @see ArgumentDynamicWord
* @deprecated will be replaced soon
*/
@Deprecated
public static ArgumentDynamicWord DynamicWord(@NotNull String id) {
return DynamicWord(id, SuggestionType.ASK_SERVER);
}
/**
* @see ArgumentDynamicStringArray
* @deprecated will be replaced soon
*/
@Deprecated
public static ArgumentDynamicStringArray DynamicStringArray(@NotNull String id) {
return new ArgumentDynamicStringArray(id);
}
}

View File

@ -2,6 +2,7 @@ package net.minestom.server.entity;
import com.google.common.annotations.Beta;
import com.google.common.collect.Queues;
import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.event.HoverEvent.ShowEntity;
@ -65,7 +66,7 @@ import java.util.function.UnaryOperator;
* <p>
* To create your own entity you probably want to extends {@link LivingEntity} or {@link EntityCreature} instead.
*/
public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, DataContainer, PermissionHandler, HoverEventSource<ShowEntity> {
public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, DataContainer, PermissionHandler, HoverEventSource<ShowEntity>, Sound.Emitter {
private static final Map<Integer, Entity> ENTITY_BY_ID = new ConcurrentHashMap<>();
private static final Map<UUID, Entity> ENTITY_BY_UUID = new ConcurrentHashMap<>();

View File

@ -1,4 +1,4 @@
package net.minestom.server.entity.type.projectile;
package net.minestom.server.entity;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityType;

View File

@ -1,5 +1,6 @@
package net.minestom.server.entity;
import net.minestom.server.entity.metadata.item.ItemEntityMeta;
import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.entity.EntityItemMergeEvent;
import net.minestom.server.instance.Chunk;
@ -18,7 +19,7 @@ import java.util.Set;
/**
* Represents an item on the ground.
*/
public class ItemEntity extends ObjectEntity {
public class ItemEntity extends Entity {
/**
* Used to slow down the merge check delay
@ -42,6 +43,7 @@ public class ItemEntity extends ObjectEntity {
public ItemEntity(@NotNull ItemStack itemStack, @NotNull Position spawnPosition) {
super(EntityType.ITEM, spawnPosition);
setItemStack(itemStack);
setGravity(0.02f, 0.04f, 1.96f);
setBoundingBox(0.25f, 0.25f, 0.25f);
}
@ -129,8 +131,8 @@ public class ItemEntity extends ObjectEntity {
}
@Override
public int getObjectData() {
return 1;
public @NotNull ItemEntityMeta getEntityMeta() {
return (ItemEntityMeta) super.getEntityMeta();
}
/**
@ -150,7 +152,7 @@ public class ItemEntity extends ObjectEntity {
*/
public void setItemStack(@NotNull ItemStack itemStack) {
this.itemStack = itemStack;
this.metadata.setIndex((byte) 7, Metadata.Slot(itemStack));
getEntityMeta().setItem(itemStack);
}
/**

View File

@ -1,6 +1,7 @@
package net.minestom.server.entity;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.minestom.server.MinecraftServer;
import net.minestom.server.chat.ColoredText;
import net.minestom.server.chat.JsonMessage;

View File

@ -1,36 +0,0 @@
package net.minestom.server.entity;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.EntityMeta} that inherits
* {@link net.minestom.server.entity.metadata.ObjectDataProvider} instead.
*/
@Deprecated
public abstract class ObjectEntity extends Entity {
public ObjectEntity(@NotNull EntityType entityType, @NotNull Position spawnPosition) {
super(entityType, spawnPosition);
setGravity(0.02f, 0.04f, 1.96f);
}
/**
* Gets the data of this object entity.
*
* @return an object data
* @see <a href="https://wiki.vg/Object_Data">here</a>
*/
public abstract int getObjectData();
@Override
public void update(long time) {
}
@Override
public void spawn() {
}
}

View File

@ -6,6 +6,7 @@ import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.identity.Identified;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.inventory.Book;
import net.kyori.adventure.pointer.Pointers;
import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.sound.SoundStop;
import net.kyori.adventure.text.Component;
@ -29,6 +30,7 @@ import net.minestom.server.command.CommandSender;
import net.minestom.server.effects.Effects;
import net.minestom.server.entity.damage.DamageType;
import net.minestom.server.entity.fakeplayer.FakePlayer;
import net.minestom.server.entity.metadata.PlayerMeta;
import net.minestom.server.entity.vehicle.PlayerVehicleInformation;
import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.inventory.InventoryOpenEvent;
@ -179,6 +181,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
// Adventure
private Identity identity;
private final Pointers pointers;
public Player(@NotNull UUID uuid, @NotNull String username, @NotNull PlayerConnection playerConnection) {
super(EntityType.PLAYER, uuid);
@ -207,6 +210,11 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
playerConnectionInit();
this.identity = Identity.identity(uuid);
this.pointers = Pointers.builder()
.withDynamic(Identity.UUID, this::getUuid)
.withDynamic(Identity.NAME, this::getUsername)
.withDynamic(Identity.DISPLAY_NAME, this::getDisplayName)
.build();
}
/**
@ -510,16 +518,6 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
if (getOpenInventory() != null)
getOpenInventory().removeViewer(this);
// Boss bars cache
{
Set<net.minestom.server.bossbar.BossBar> bossBars = net.minestom.server.bossbar.BossBar.getBossBars(this);
if (bossBars != null) {
for (net.minestom.server.bossbar.BossBar bossBar : bossBars) {
bossBar.removeViewer(this);
}
}
}
MinecraftServer.getBossBarManager().removeAllBossBars(this);
// Advancement tabs cache
@ -833,7 +831,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
@Override
public void playSound(@NotNull Sound sound) {
playerConnection.sendPacket(AdventurePacketConvertor.createEntitySoundPacket(sound, this));
this.playSound(sound, this.position.getX(), this.position.getY(), this.position.getZ());
}
@Override
@ -841,6 +839,19 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
playerConnection.sendPacket(AdventurePacketConvertor.createSoundPacket(sound, x, y, z));
}
@Override
public void playSound(@NotNull Sound sound, Sound.@NotNull Emitter emitter) {
final ServerPacket packet;
if (emitter == Sound.Emitter.self()) {
packet = AdventurePacketConvertor.createSoundPacket(sound, this);
} else {
packet = AdventurePacketConvertor.createSoundPacket(sound, emitter);
}
playerConnection.sendPacket(packet);
}
@Override
public void stopSound(@NotNull SoundStop stop) {
playerConnection.sendPacket(AdventurePacketConvertor.createSoundStopPacket(stop));
@ -1037,13 +1048,18 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
sendUpdateHealthPacket();
}
@Override
public @NotNull PlayerMeta getEntityMeta() {
return (PlayerMeta) super.getEntityMeta();
}
/**
* Gets the player additional hearts.
*
* @return the player additional hearts
*/
public float getAdditionalHearts() {
return metadata.getIndex((byte) 14, 0f);
return getEntityMeta().getAdditionalHearts();
}
/**
@ -1052,7 +1068,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
* @param additionalHearts the count of additional hearts
*/
public void setAdditionalHearts(float additionalHearts) {
this.metadata.setIndex((byte) 14, Metadata.Float(additionalHearts));
getEntityMeta().setAdditionalHearts(additionalHearts);
}
/**
@ -2504,6 +2520,11 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
return this.identity;
}
@Override
public @NotNull Pointers pointers() {
return this.pointers;
}
@Override
public void setUuid(@NotNull UUID uuid) {
super.setUuid(uuid);

View File

@ -5,7 +5,7 @@ import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.ai.GoalSelector;
import net.minestom.server.entity.pathfinding.Navigator;
import net.minestom.server.entity.type.projectile.EntityProjectile;
import net.minestom.server.entity.EntityProjectile;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.time.Cooldown;
import net.minestom.server.utils.time.TimeUnit;

View File

@ -5,7 +5,7 @@ import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.ai.GoalSelector;
import net.minestom.server.entity.pathfinding.Navigator;
import net.minestom.server.entity.type.projectile.EntityProjectile;
import net.minestom.server.entity.EntityProjectile;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.time.Cooldown;
import net.minestom.server.utils.time.TimeUnit;

View File

@ -3,8 +3,10 @@ package net.minestom.server.entity.hologram;
import net.kyori.adventure.text.Component;
import net.minestom.server.Viewable;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.type.decoration.EntityArmorStand;
import net.minestom.server.entity.metadata.other.ArmorStandMeta;
import net.minestom.server.instance.Instance;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.validate.Check;
@ -19,7 +21,7 @@ public class Hologram implements Viewable {
private static final float OFFSET_Y = -0.9875f;
private final HologramEntity entity;
private final Entity entity;
private Position position;
private Component text;
@ -73,8 +75,21 @@ public class Hologram implements Viewable {
* @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 = new Entity(EntityType.ARMOR_STAND);
ArmorStandMeta armorStandMeta = (ArmorStandMeta) entity.getEntityMeta();
armorStandMeta.setNotifyAboutChanges(false);
armorStandMeta.setSmall(true);
armorStandMeta.setHasNoGravity(true);
armorStandMeta.setCustomName(Component.empty());
armorStandMeta.setCustomNameVisible(true);
armorStandMeta.setInvisible(true);
armorStandMeta.setNotifyAboutChanges(true);
this.entity.setInstance(instance, spawnPosition.clone().add(0, OFFSET_Y, 0));
this.entity.setAutoViewable(autoViewable);
this.position = spawnPosition;
@ -166,7 +181,7 @@ public class Hologram implements Viewable {
*
* @return the hologram entity
*/
public HologramEntity getEntity() {
public Entity getEntity() {
return entity;
}
@ -201,24 +216,4 @@ public class Hologram implements Viewable {
private void checkRemoved() {
Check.stateCondition(isRemoved(), "You cannot interact with a removed Hologram");
}
public static class HologramEntity extends EntityArmorStand {
/**
* Constructs a new {@link HologramEntity} with the given {@code spawnPosition}.
*
* @param spawnPosition The spawn position of this hologram entity.
*/
public HologramEntity(Position spawnPosition) {
super(spawnPosition);
setSmall(true);
setNoGravity(true);
setCustomName(Component.empty());
setCustomNameVisible(true);
setInvisible(true);
}
}
}

View File

@ -1,9 +0,0 @@
package net.minestom.server.entity.type;
public interface Ageable {
boolean isBaby();
void setBaby(boolean value);
}

View File

@ -1,35 +0,0 @@
package net.minestom.server.entity.type;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.instance.Instance;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class AgeableCreature extends EntityCreature implements Ageable {
protected AgeableCreature(@NotNull EntityType entityType, @NotNull Position spawnPosition) {
super(entityType, spawnPosition);
}
protected AgeableCreature(@NotNull EntityType entityType, @NotNull Position spawnPosition, @Nullable Instance instance) {
super(entityType, spawnPosition, instance);
}
@Override
public boolean isBaby() {
return this.metadata.getIndex((byte) 15, false);
}
@Override
public void setBaby(boolean value) {
this.metadata.setIndex((byte) 15, Metadata.Boolean(value));
}
@Override
public double getEyeHeight() {
return isBaby() ? super.getEyeHeight() / 2 : super.getEyeHeight();
}
}

View File

@ -1,4 +0,0 @@
package net.minestom.server.entity.type;
public interface Animal extends Ageable {
}

View File

@ -1,4 +0,0 @@
package net.minestom.server.entity.type;
public interface Constructable {
}

View File

@ -1,4 +0,0 @@
package net.minestom.server.entity.type;
public interface Monster {
}

View File

@ -1,4 +0,0 @@
package net.minestom.server.entity.type;
public interface TameableAnimal extends Animal {
}

View File

@ -1,71 +0,0 @@
package net.minestom.server.entity.type;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.instance.Instance;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
public class TameableAnimalCreature extends AgeableCreature implements TameableAnimal {
private final static byte SITTING_BIT = 0x1;
private final static byte TAMED_BIT = 0x4;
protected TameableAnimalCreature(@NotNull EntityType entityType, @NotNull Position spawnPosition) {
super(entityType, spawnPosition);
}
protected TameableAnimalCreature(@NotNull EntityType entityType, @NotNull Position spawnPosition, @Nullable Instance instance) {
super(entityType, spawnPosition, instance);
}
public boolean isSitting() {
return (getMask() & SITTING_BIT) != 0;
}
public void setSitting(boolean value) {
modifyMask(SITTING_BIT, value);
}
public boolean isTamed() {
return (getMask() & TAMED_BIT) != 0;
}
public void setTamed(boolean value) {
modifyMask(TAMED_BIT, value);
}
public UUID getOwner() {
return this.metadata.getIndex((byte) 17, null);
}
public void setOwner(UUID value) {
this.metadata.setIndex((byte) 17, Metadata.OptUUID(value));
}
private byte getMask() {
return this.metadata.getIndex((byte) 16, (byte) 0);
}
private void setMask(byte mask) {
this.metadata.setIndex((byte) 16, Metadata.Byte(mask));
}
private void modifyMask(byte bit, boolean value) {
byte mask = getMask();
boolean isPresent = (mask & bit) == bit;
if (isPresent == value) {
return;
}
if (value) {
mask |= bit;
} else {
mask &= ~bit;
}
setMask(mask);
}
}

View File

@ -1,4 +0,0 @@
package net.minestom.server.entity.type;
public interface Vehicle {
}

View File

@ -1,17 +0,0 @@
package net.minestom.server.entity.type.animal;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.type.AgeableCreature;
import net.minestom.server.entity.type.Animal;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.animal.BeeMeta} instead.
*/
@Deprecated
public class EntityBee extends AgeableCreature implements Animal {
public EntityBee(Position spawnPosition) {
super(EntityType.BEE, spawnPosition);
setBoundingBox(0.7f, 0.6f, 0.7f);
}
}

View File

@ -1,74 +0,0 @@
package net.minestom.server.entity.type.animal;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.type.TameableAnimalCreature;
import net.minestom.server.instance.Instance;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.animal.tameable.CatMeta} instead.
*/
@Deprecated
public class EntityCat extends TameableAnimalCreature {
public EntityCat(@NotNull Position spawnPosition) {
super(EntityType.CAT, spawnPosition);
setBoundingBox(.6D, .7D, .6D);
}
public EntityCat(@NotNull Position spawnPosition, @Nullable Instance instance) {
super(EntityType.CAT, spawnPosition, instance);
setBoundingBox(.6D, .7D, .6D);
}
public Color getColor() {
return Color.VALUES[this.metadata.getIndex((byte) 18, 1)];
}
public void setColor(Color value) {
this.metadata.setIndex((byte) 18, Metadata.VarInt(value.ordinal()));
}
public boolean isLying() {
return this.metadata.getIndex((byte) 19, false);
}
public void setLying(boolean value) {
this.metadata.setIndex((byte) 19, Metadata.Boolean(value));
}
public boolean isRelaxed() {
return this.metadata.getIndex((byte) 20, false);
}
public void setRelaxed(boolean value) {
this.metadata.setIndex((byte) 20, Metadata.Boolean(value));
}
public int getCollarColor() {
return this.metadata.getIndex((byte) 21, 14);
}
public void setCollarColor(int value) {
this.metadata.setIndex((byte) 21, Metadata.VarInt(value));
}
public enum Color {
TABBY,
BLACK,
RED,
SIAMESE,
BRITISH_SHORTHAIR,
CALICO,
PERSIAN,
RAGDOLL,
WHITE,
JELLIE,
ALL_BLACK;
private final static Color[] VALUES = values();
}
}

View File

@ -1,17 +0,0 @@
package net.minestom.server.entity.type.animal;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.type.AgeableCreature;
import net.minestom.server.entity.type.Animal;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.animal.ChickenMeta} instead.
*/
@Deprecated
public class EntityChicken extends AgeableCreature implements Animal {
public EntityChicken(Position spawnPosition) {
super(EntityType.CHICKEN, spawnPosition);
setBoundingBox(0.4f, 0.7f, 0.4f);
}
}

View File

@ -1,17 +0,0 @@
package net.minestom.server.entity.type.animal;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.type.AgeableCreature;
import net.minestom.server.entity.type.Animal;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.animal.CowMeta} instead.
*/
@Deprecated
public class EntityCow extends AgeableCreature implements Animal {
public EntityCow(Position spawnPosition) {
super(EntityType.COW, spawnPosition);
setBoundingBox(0.9f, 1.4f, 0.9f);
}
}

View File

@ -1,17 +0,0 @@
package net.minestom.server.entity.type.animal;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.type.AgeableCreature;
import net.minestom.server.entity.type.Animal;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.water.DolphinMeta} instead.
*/
@Deprecated
public class EntityDolphin extends AgeableCreature implements Animal {
public EntityDolphin(Position spawnPosition) {
super(EntityType.DOLPHIN, spawnPosition);
setBoundingBox(0.9f, 0.6f, 0.9f);
}
}

View File

@ -1,17 +0,0 @@
package net.minestom.server.entity.type.animal;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.type.AgeableCreature;
import net.minestom.server.entity.type.Animal;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.animal.FoxMeta} instead.
*/
@Deprecated
public class EntityFox extends AgeableCreature implements Animal {
public EntityFox(Position spawnPosition) {
super(EntityType.FOX, spawnPosition);
setBoundingBox(0.6f, 0.7f, 0.6f);
}
}

View File

@ -1,26 +0,0 @@
package net.minestom.server.entity.type.animal;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.instance.Instance;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.animal.LlamaMeta} instead.
*/
@Deprecated
public class EntityLlama extends EntityCreature {
public EntityLlama(@NotNull Position spawnPosition) {
super(EntityType.LLAMA, spawnPosition);
setBoundingBox(.9D, 1.87D, .9D);
}
public EntityLlama(@NotNull Position spawnPosition, @Nullable Instance instance) {
super(EntityType.LLAMA, spawnPosition, instance);
setBoundingBox(.9D, 1.87D, .9D);
}
}

View File

@ -1,54 +0,0 @@
package net.minestom.server.entity.type.animal;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.type.AgeableCreature;
import net.minestom.server.entity.type.Animal;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.animal.MooshroomMeta} instead.
*/
@Deprecated
public class EntityMooshroom extends AgeableCreature implements Animal {
public EntityMooshroom(Position spawnPosition) {
super(EntityType.MOOSHROOM, spawnPosition);
setBoundingBox(0.9f, 1.4f, 0.9f);
}
public MooshroomType getMooshroomType() {
final String identifier = metadata.getIndex((byte) 16, "red");
return MooshroomType.fromIdentifier(identifier);
}
public void setMooshroomType(@NotNull MooshroomType mooshroomType) {
this.metadata.setIndex((byte) 16, Metadata.String(mooshroomType.getIdentifier()));
}
public enum MooshroomType {
RED("red"),
BROWN("brown");
private final String identifier;
MooshroomType(String identifier) {
this.identifier = identifier;
}
@NotNull
private String getIdentifier() {
return identifier;
}
public static MooshroomType fromIdentifier(String identifier) {
if (identifier.equals("red")) {
return RED;
} else if (identifier.equals("brown")) {
return BROWN;
}
throw new IllegalArgumentException("Weird thing happened");
}
}
}

View File

@ -1,17 +0,0 @@
package net.minestom.server.entity.type.animal;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.type.AgeableCreature;
import net.minestom.server.entity.type.Animal;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.animal.OcelotMeta} instead.
*/
@Deprecated
public class EntityOcelot extends AgeableCreature implements Animal {
public EntityOcelot(Position spawnPosition) {
super(EntityType.OCELOT, spawnPosition);
setBoundingBox(0.6f, 0.7f, 0.6f);
}
}

View File

@ -1,17 +0,0 @@
package net.minestom.server.entity.type.animal;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.type.AgeableCreature;
import net.minestom.server.entity.type.Animal;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.animal.PandaMeta} instead.
*/
@Deprecated
public class EntityPanda extends AgeableCreature implements Animal {
public EntityPanda(Position spawnPosition) {
super(EntityType.PANDA, spawnPosition);
setBoundingBox(1.3f, 1.25f, 1.3f);
}
}

View File

@ -1,37 +0,0 @@
package net.minestom.server.entity.type.animal;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.type.AgeableCreature;
import net.minestom.server.entity.type.Animal;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.animal.PigMeta} instead.
*/
@Deprecated
public class EntityPig extends AgeableCreature implements Animal {
public EntityPig(Position spawnPosition) {
super(EntityType.PIG, spawnPosition);
setBoundingBox(0.9f, 0.9f, 0.9f);
}
/**
* Gets if the pig has a saddle.
*
* @return true if the pig has a saddle, false otherwise
*/
public boolean hasSaddle() {
return metadata.getIndex((byte) 16, false);
}
/**
* Sets a saddle to the pig.
*
* @param saddle true to add a saddle, false to remove it
*/
public void setSaddle(boolean saddle) {
this.metadata.setIndex((byte) 16, Metadata.Boolean(saddle));
}
}

View File

@ -1,27 +0,0 @@
package net.minestom.server.entity.type.animal;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.type.AgeableCreature;
import net.minestom.server.entity.type.Animal;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.animal.PolarBearMeta} instead.
*/
@Deprecated
public class EntityPolarBear extends AgeableCreature implements Animal {
public EntityPolarBear(Position spawnPosition) {
super(EntityType.POLAR_BEAR, spawnPosition);
setBoundingBox(1.3f, 1.4f, 1.3f);
}
public boolean isStandingUp() {
return metadata.getIndex((byte) 16, false);
}
public void setStandingUp(boolean standingUp) {
this.metadata.setIndex((byte) 16, Metadata.Boolean(standingUp));
}
}

View File

@ -1,27 +0,0 @@
package net.minestom.server.entity.type.animal;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.type.AgeableCreature;
import net.minestom.server.entity.type.Animal;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.animal.RabbitMeta} instead.
*/
@Deprecated
public class EntityRabbit extends AgeableCreature implements Animal {
public EntityRabbit(Position spawnPosition) {
super(EntityType.RABBIT, spawnPosition);
setBoundingBox(0.4f, 0.5f, 0.4f);
}
public int getType() {
return metadata.getIndex((byte) 16, 0);
}
public void setType(int type) {
this.metadata.setIndex((byte) 16, Metadata.VarInt(type));
}
}

View File

@ -1,244 +0,0 @@
package net.minestom.server.entity.type.decoration;
import net.minestom.server.entity.*;
import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.item.EntityEquipEvent;
import net.minestom.server.inventory.EquipmentHandler;
import net.minestom.server.item.ItemStack;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.Vector;
import net.minestom.server.utils.binary.BitmaskUtil;
import org.jetbrains.annotations.NotNull;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.other.ArmorStandMeta} instead.
*/
@Deprecated
public class EntityArmorStand extends ObjectEntity implements EquipmentHandler {
// Equipments
private ItemStack mainHandItem;
private ItemStack offHandItem;
private ItemStack helmet;
private ItemStack chestplate;
private ItemStack leggings;
private ItemStack boots;
public EntityArmorStand(Position spawnPosition) {
super(EntityType.ARMOR_STAND, spawnPosition);
// Refresh BoundingBox
setSmall(false);
setHeadRotation(new Vector(0, 0, 0));
setBodyRotation(new Vector(0, 0, 0));
setLeftArmRotation(new Vector(-10f, 0, -10f));
setRightArmRotation(new Vector(-15f, 0, -10f));
setLeftLegRotation(new Vector(-1f, 0, -1f));
setRightLegRotation(new Vector(1, 0, 1));
this.mainHandItem = ItemStack.AIR;
this.offHandItem = ItemStack.AIR;
this.helmet = ItemStack.AIR;
this.chestplate = ItemStack.AIR;
this.leggings = ItemStack.AIR;
this.boots = ItemStack.AIR;
}
@Override
protected boolean addViewer0(@NotNull Player player) {
if (!super.addViewer0(player)) {
return false;
}
player.getPlayerConnection().sendPacket(getEquipmentsPacket());
return true;
}
@Override
public int getObjectData() {
return 0;
}
@NotNull
@Override
public ItemStack getItemInMainHand() {
return mainHandItem;
}
@Override
public void setItemInMainHand(@NotNull ItemStack itemStack) {
this.mainHandItem = getEquipmentItem(itemStack, EquipmentSlot.MAIN_HAND);
syncEquipment(EquipmentSlot.MAIN_HAND);
}
@NotNull
@Override
public ItemStack getItemInOffHand() {
return offHandItem;
}
@Override
public void setItemInOffHand(@NotNull ItemStack itemStack) {
this.offHandItem = getEquipmentItem(itemStack, EquipmentSlot.OFF_HAND);
syncEquipment(EquipmentSlot.OFF_HAND);
}
@NotNull
@Override
public ItemStack getHelmet() {
return helmet;
}
@Override
public void setHelmet(@NotNull ItemStack itemStack) {
this.helmet = getEquipmentItem(itemStack, EquipmentSlot.HELMET);
syncEquipment(EquipmentSlot.HELMET);
}
@NotNull
@Override
public ItemStack getChestplate() {
return chestplate;
}
@Override
public void setChestplate(@NotNull ItemStack itemStack) {
this.chestplate = getEquipmentItem(itemStack, EquipmentSlot.CHESTPLATE);
syncEquipment(EquipmentSlot.CHESTPLATE);
}
@NotNull
@Override
public ItemStack getLeggings() {
return leggings;
}
@Override
public void setLeggings(@NotNull ItemStack itemStack) {
this.leggings = getEquipmentItem(itemStack, EquipmentSlot.LEGGINGS);
syncEquipment(EquipmentSlot.LEGGINGS);
}
@NotNull
@Override
public ItemStack getBoots() {
return boots;
}
@Override
public void setBoots(@NotNull ItemStack itemStack) {
this.boots = getEquipmentItem(itemStack, EquipmentSlot.BOOTS);
syncEquipment(EquipmentSlot.BOOTS);
}
public boolean isSmall() {
return (getStateMeta() & 0x01) != 0;
}
public void setSmall(boolean small) {
final byte state = BitmaskUtil.changeBit(getStateMeta(), (byte) 0x01, (byte) (small ? 1 : 0), (byte) 0);
this.metadata.setIndex((byte) 14, Metadata.Byte(state));
if (small) {
setBoundingBox(0.25f, 0.9875f, 0.25f);
} else {
setBoundingBox(0.5f, 1.975f, 0.5f);
}
}
public boolean hasArms() {
return (getStateMeta() & 0x04) != 0;
}
public void setHasArms(boolean hasArms) {
final byte state = BitmaskUtil.changeBit(getStateMeta(), (byte) 0x08, (byte) (hasArms ? 1 : 0), (byte) 2);
this.metadata.setIndex((byte) 14, Metadata.Byte(state));
}
public boolean hasNoBasePlate() {
return (getStateMeta() & 0x08) != 0;
}
public void setNoBasePlate(boolean noBasePlate) {
final byte state = BitmaskUtil.changeBit(getStateMeta(), (byte) 0x10, (byte) (noBasePlate ? 1 : 0), (byte) 3);
this.metadata.setIndex((byte) 14, Metadata.Byte(state));
}
public boolean hasMarker() {
return (getStateMeta() & 0x10) != 0;
}
public void setMarker(boolean setMarker) {
final byte state = BitmaskUtil.changeBit(getStateMeta(), (byte) 0x20, (byte) (setMarker ? 1 : 0), (byte) 4);
this.metadata.setIndex((byte) 14, Metadata.Byte(state));
}
@NotNull
public Vector getHeadRotation() {
return metadata.getIndex((byte) 15, new Vector(0, 0, 0));
}
public void setHeadRotation(@NotNull Vector headRotation) {
this.metadata.setIndex((byte) 15, Metadata.Rotation(headRotation));
}
@NotNull
public Vector getBodyRotation() {
return metadata.getIndex((byte) 16, new Vector(0, 0, 0));
}
public void setBodyRotation(@NotNull Vector bodyRotation) {
this.metadata.setIndex((byte) 16, Metadata.Rotation(bodyRotation));
}
@NotNull
public Vector getLeftArmRotation() {
return metadata.getIndex((byte) 17, new Vector(-10, 0, -10));
}
public void setLeftArmRotation(@NotNull Vector leftArmRotation) {
this.metadata.setIndex((byte) 17, Metadata.Rotation(leftArmRotation));
}
@NotNull
public Vector getRightArmRotation() {
return metadata.getIndex((byte) 18, new Vector(-15, 0, 10));
}
public void setRightArmRotation(@NotNull Vector rightArmRotation) {
this.metadata.setIndex((byte) 18, Metadata.Rotation(rightArmRotation));
}
@NotNull
public Vector getLeftLegRotation() {
return metadata.getIndex((byte) 19, new Vector(-1, 0, -1));
}
public void setLeftLegRotation(@NotNull Vector leftLegRotation) {
this.metadata.setIndex((byte) 19, Metadata.Rotation(leftLegRotation));
}
@NotNull
public Vector getRightLegRotation() {
return metadata.getIndex((byte) 20, new Vector(1, 0, 1));
}
public void setRightLegRotation(@NotNull Vector rightLegRotation) {
this.metadata.setIndex((byte) 20, Metadata.Rotation(rightLegRotation));
}
private byte getStateMeta() {
return metadata.getIndex((byte) 14, (byte) 0);
}
// Equipments
private ItemStack getEquipmentItem(@NotNull ItemStack itemStack, @NotNull EquipmentSlot slot) {
EntityEquipEvent entityEquipEvent = new EntityEquipEvent(this, itemStack, slot);
EventDispatcher.call(entityEquipEvent);
return entityEquipEvent.getEquippedItem();
}
}

View File

@ -1,80 +0,0 @@
package net.minestom.server.entity.type.decoration;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.ObjectEntity;
import net.minestom.server.item.ItemStack;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.Rotation;
import org.jetbrains.annotations.NotNull;
// FIXME: https://wiki.vg/Object_Data#Item_Frame_.28id_71.29
// "You have to set both Orientation and Yaw/Pitch accordingly, otherwise it will not work."
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.other.ItemFrameMeta} instead.
*/
@Deprecated
public class EntityItemFrame extends ObjectEntity {
private final ItemFrameOrientation orientation;
public EntityItemFrame(@NotNull Position spawnPosition, @NotNull ItemFrameOrientation orientation) {
super(EntityType.ITEM_FRAME, spawnPosition);
this.orientation = orientation;
setNoGravity(true);
setGravity(0f, 0f, 0f);
}
@Override
public int getObjectData() {
return orientation.ordinal();
}
/**
* Gets the item stack in the frame.
*
* @return the item stack in the frame
*/
@NotNull
public ItemStack getItemStack() {
return metadata.getIndex((byte) 7, ItemStack.AIR);
}
/**
* Changes the item stack in the frame.
*
* @param itemStack the new item stack in the frame
*/
public void setItemStack(@NotNull ItemStack itemStack) {
this.metadata.setIndex((byte) 7, Metadata.Slot(itemStack));
}
/**
* Gets the item rotation.
*
* @return the item rotation
*/
@NotNull
public Rotation getRotation() {
final int ordinal = metadata.getIndex((byte) 8, 0);
return Rotation.values()[ordinal];
}
/**
* Changes the item rotation.
*
* @param rotation the new item rotation
*/
public void setRotation(@NotNull Rotation rotation) {
this.metadata.setIndex((byte) 8, Metadata.VarInt(rotation.ordinal()));
}
/**
* Represents the orientation of the frame.
*/
public enum ItemFrameOrientation {
DOWN, UP, NORTH, SOUTH, WEST, EAST
}
}

View File

@ -1,25 +0,0 @@
package net.minestom.server.entity.type.monster;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.type.Monster;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.monster.BlazeMeta} instead.
*/
@Deprecated
public class EntityBlaze extends EntityCreature implements Monster {
public EntityBlaze(Position spawnPosition) {
super(EntityType.BLAZE, spawnPosition);
setBoundingBox(0.6f, 1.8f, 0.6f);
}
@Override
public void setOnFire(boolean fire) {
super.setOnFire(fire);
this.metadata.setIndex((byte) 15, Metadata.Byte((byte) (fire ? 1 : 0)));
}
}

View File

@ -1,17 +0,0 @@
package net.minestom.server.entity.type.monster;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.type.Monster;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.monster.SpiderMeta} instead.
*/
@Deprecated
public class EntityCaveSpider extends EntityCreature implements Monster {
public EntityCaveSpider(Position spawnPosition) {
super(EntityType.CAVE_SPIDER, spawnPosition);
setBoundingBox(0.7f, 0.5f, 0.7f);
}
}

View File

@ -1,70 +0,0 @@
package net.minestom.server.entity.type.monster;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.type.Monster;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.monster.CreeperMeta} instead.
*/
@Deprecated
public class EntityCreeper extends EntityCreature implements Monster {
public EntityCreeper(Position spawnPosition) {
super(EntityType.CREEPER, spawnPosition);
setBoundingBox(0.6f, 1.7f, 0.6f);
}
@NotNull
public CreeperState getCreeperState() {
final int state = metadata.getIndex((byte) 15, -1);
return CreeperState.fromState(state);
}
public void setCreeperState(@NotNull CreeperState creeperState) {
this.metadata.setIndex((byte) 15, Metadata.VarInt(creeperState.getState()));
}
public boolean isCharged() {
return metadata.getIndex((byte) 16, false);
}
public void setCharged(boolean charged) {
this.metadata.setIndex((byte) 16, Metadata.Boolean(charged));
}
public boolean isIgnited() {
return metadata.getIndex((byte) 17, false);
}
public void setIgnited(boolean ignited) {
this.metadata.setIndex((byte) 17, Metadata.Boolean(ignited));
}
public enum CreeperState {
IDLE(-1),
FUSE(1);
private final int state;
CreeperState(int state) {
this.state = state;
}
private int getState() {
return state;
}
private static CreeperState fromState(int state) {
if (state == -1) {
return IDLE;
} else if (state == 1) {
return FUSE;
}
throw new IllegalArgumentException("Weird thing happened");
}
}
}

View File

@ -1,18 +0,0 @@
package net.minestom.server.entity.type.monster;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.metadata.monster.EndermiteMeta;
import net.minestom.server.entity.type.Monster;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link EndermiteMeta} instead.
*/
@Deprecated
public class EntityEndermite extends EntityCreature implements Monster {
public EntityEndermite(Position spawnPosition) {
super(EntityType.ENDERMITE, spawnPosition);
setBoundingBox(0.4f, 0.3f, 0.4f);
}
}

View File

@ -1,27 +0,0 @@
package net.minestom.server.entity.type.monster;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.type.Monster;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.flying.GhastMeta} instead.
*/
@Deprecated
public class EntityGhast extends EntityCreature implements Monster {
public EntityGhast(Position spawnPosition) {
super(EntityType.GHAST, spawnPosition);
setBoundingBox(4, 4, 4);
}
public boolean isAttacking() {
return metadata.getIndex((byte) 15, false);
}
public void setAttacking(boolean attacking) {
this.metadata.setIndex((byte) 15, Metadata.Boolean(attacking));
}
}

View File

@ -1,17 +0,0 @@
package net.minestom.server.entity.type.monster;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.type.Monster;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.monster.GiantMeta} instead.
*/
@Deprecated
public class EntityGiant extends EntityCreature implements Monster {
public EntityGiant(Position spawnPosition) {
super(EntityType.GIANT, spawnPosition);
setBoundingBox(3.6f, 10.8f, 3.6f);
}
}

View File

@ -1,55 +0,0 @@
package net.minestom.server.entity.type.monster;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.type.Monster;
import net.minestom.server.instance.Instance;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.monster.GuardianMeta} instead.
*/
@Deprecated
public class EntityGuardian extends EntityCreature implements Monster {
private Entity target;
public EntityGuardian(@NotNull Position spawnPosition) {
super(EntityType.GUARDIAN, spawnPosition);
setBoundingBox(0.85f, 0.85f, 0.85f);
}
public EntityGuardian(@NotNull Position spawnPosition, @Nullable Instance instance) {
super(EntityType.GUARDIAN, spawnPosition, instance);
setBoundingBox(0.85f, 0.85f, 0.85f);
}
EntityGuardian(@NotNull EntityType entityType, @NotNull Position spawnPosition) {
super(entityType, spawnPosition);
}
EntityGuardian(@NotNull EntityType entityType, @NotNull Position spawnPosition, @Nullable Instance instance) {
super(entityType, spawnPosition, instance);
}
public boolean isRetractingSpikes() {
return metadata.getIndex((byte) 15, false);
}
public void setRetractingSpikes(boolean retractingSpikes) {
this.metadata.setIndex((byte) 15, Metadata.Boolean(retractingSpikes));
}
public Entity getTarget() {
return target;
}
public void setTarget(@NotNull Entity target) {
this.target = target;
this.metadata.setIndex((byte) 16, Metadata.VarInt(target.getEntityId()));
}
}

View File

@ -1,27 +0,0 @@
package net.minestom.server.entity.type.monster;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.type.Monster;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.flying.PhantomMeta} instead.
*/
@Deprecated
public class EntityPhantom extends EntityCreature implements Monster {
public EntityPhantom(Position spawnPosition) {
super(EntityType.PHANTOM, spawnPosition);
setBoundingBox(0.9f, 0.5f, 0.9f); // TODO change based on size
}
public int getSize() {
return metadata.getIndex((byte) 17, 0);
}
public void setSize(int size) {
this.metadata.setIndex((byte) 15, Metadata.VarInt(size));
}
}

View File

@ -1,17 +0,0 @@
package net.minestom.server.entity.type.monster;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.type.Monster;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.monster.SilverfishMeta} instead.
*/
@Deprecated
public class EntitySilverfish extends EntityCreature implements Monster {
public EntitySilverfish(Position spawnPosition) {
super(EntityType.SILVERFISH, spawnPosition);
setBoundingBox(0.4f, 0.3f, 0.4f);
}
}

View File

@ -1,34 +0,0 @@
package net.minestom.server.entity.type.monster;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.type.Monster;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.other.SlimeMeta} instead.
*/
@Deprecated
public class EntitySlime extends EntityCreature implements Monster {
public EntitySlime(@NotNull Position spawnPosition) {
this(EntityType.SLIME, spawnPosition);
}
EntitySlime(@NotNull EntityType type, @NotNull Position spawnPosition) {
super(type, spawnPosition);
setSize(1);
}
public int getSize() {
return metadata.getIndex((byte) 15, 1);
}
public void setSize(int size) {
final float boxSize = 0.51000005f * size;
setBoundingBox(boxSize, boxSize, boxSize);
this.metadata.setIndex((byte) 15, Metadata.VarInt(size));
}
}

View File

@ -1,37 +0,0 @@
package net.minestom.server.entity.type.monster;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.type.Monster;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.monster.SpiderMeta} instead.
*/
@Deprecated
public class EntitySpider extends EntityCreature implements Monster {
public EntitySpider(Position spawnPosition) {
super(EntityType.SPIDER, spawnPosition);
setBoundingBox(1.4f, 0.9f, 1.4f);
}
/**
* Gets if the spider is climbing.
*
* @return true if the spider is climbing, false otherwise
*/
public boolean isClimbing() {
return metadata.getIndex((byte) 15, false);
}
/**
* Makes the spider climbs.
*
* @param climbing true to make the spider climbs, false otherwise
*/
public void setClimbing(boolean climbing) {
this.metadata.setIndex((byte) 15, Metadata.Boolean(climbing));
}
}

View File

@ -1,27 +0,0 @@
package net.minestom.server.entity.type.monster;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.type.Monster;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.monster.raider.WitchMeta} instead.
*/
@Deprecated
public class EntityWitch extends EntityCreature implements Monster {
public EntityWitch(Position spawnPosition) {
super(EntityType.WITCH, spawnPosition);
setBoundingBox(0.6f, 1.95f, 0.6f);
}
public boolean isDrinkingPotion() {
return metadata.getIndex((byte) 16, false);
}
public void setDrinkingPotion(boolean drinkingPotion) {
this.metadata.setIndex((byte) 16, Metadata.Boolean(drinkingPotion));
}
}

View File

@ -1,45 +0,0 @@
package net.minestom.server.entity.type.monster;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.type.Monster;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.monster.zombie.ZombieMeta} instead.
*/
@Deprecated
public class EntityZombie extends EntityCreature implements Monster {
public EntityZombie(@NotNull Position spawnPosition) {
this(EntityType.ZOMBIE, spawnPosition);
}
EntityZombie(@NotNull EntityType entityType, @NotNull Position spawnPosition) {
super(entityType, spawnPosition);
setBoundingBox(0.6f, 1.95f, 0.6f);
}
public boolean isBaby() {
return metadata.getIndex((byte) 15, false);
}
public void setBaby(boolean baby) {
this.metadata.setIndex((byte) 15, Metadata.Boolean(baby));
}
public boolean isBecomingDrowned() {
return metadata.getIndex((byte) 17, false);
}
public void setBecomingDrowned(boolean becomingDrowned) {
this.metadata.setIndex((byte) 17, Metadata.Boolean(becomingDrowned));
}
@Override
public double getEyeHeight() {
return isBaby() ? 0.93 : 1.74;
}
}

View File

@ -1,17 +0,0 @@
package net.minestom.server.entity.type.monster;
import net.minestom.server.entity.EntityType;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.monster.zombie.ZombifiedPiglinMeta} instead.
*/
@Deprecated
public class EntityZombifiedPiglin extends EntityZombie {
public EntityZombifiedPiglin(@NotNull Position spawnPosition) {
super(EntityType.ZOMBIFIED_PIGLIN, spawnPosition);
}
}

View File

@ -1,123 +0,0 @@
package net.minestom.server.entity.type.other;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.ObjectEntity;
import net.minestom.server.particle.Particle;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.binary.BinaryWriter;
import java.util.function.Consumer;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.other.AreaEffectCloudMeta} instead.
*/
@Deprecated
public class EntityAreaEffectCloud extends ObjectEntity {
public Consumer<BinaryWriter> particleDataConsumer;
private float radius;
private int color;
private boolean ignoreRadius;
private Particle particleType;
public EntityAreaEffectCloud(Position spawnPosition) {
super(EntityType.AREA_EFFECT_CLOUD, spawnPosition);
setRadius(0.5f);
setColor(0);
setIgnoreRadius(false);
setParticle(Particle.EFFECT);
setParticleDataConsumer(packetWriter -> {
});
}
/*@NotNull
@Override
public Consumer<BinaryWriter> getMetadataConsumer() {
return packet -> {
super.getMetadataConsumer().accept(packet);
fillMetadataIndex(packet, 7);
fillMetadataIndex(packet, 8);
fillMetadataIndex(packet, 9);
fillMetadataIndex(packet, 10);
};
}*/
/*@Override
protected void fillMetadataIndex(@NotNull BinaryWriter packet, int index) {
super.fillMetadataIndex(packet, index);
if (index == 7) {
packet.writeByte((byte) 7);
packet.writeByte(METADATA_FLOAT);
packet.writeFloat(radius);
} else if (index == 8) {
packet.writeByte((byte) 8);
packet.writeByte(METADATA_VARINT);
packet.writeVarInt(color);
} else if (index == 9) {
packet.writeByte((byte) 9);
packet.writeByte(METADATA_BOOLEAN);
packet.writeBoolean(ignoreRadius);
} else if (index == 10) {
packet.writeByte((byte) 10);
packet.writeByte(METADATA_PARTICLE);
packet.writeVarInt(particle.getId());
particleDataConsumer.accept(packet);
}
}*/
@Override
public int getObjectData() {
return 0;
}
public float getRadius() {
return radius;
}
public void setRadius(float radius) {
this.radius = radius;
setBoundingBox(2 * radius, 0.5f, 2 * radius);
//sendMetadataIndex(7);
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
//sendMetadataIndex(8);
}
public boolean isIgnoreRadius() {
return ignoreRadius;
}
public void setIgnoreRadius(boolean ignoreRadius) {
this.ignoreRadius = ignoreRadius;
//sendMetadataIndex(9);
}
public Particle getParticle() {
return particleType;
}
public void setParticle(Particle particleType) {
this.particleType = particleType;
//sendMetadataIndex(10);
}
public Consumer<BinaryWriter> getParticleDataConsumer() {
return particleDataConsumer;
}
/**
* Used to add data to the particle
*
* @param particleDataConsumer the particle data consumer
* @see <a href="https://wiki.vg/Data_types#Particle">Particle data</a>
*/
public void setParticleDataConsumer(Consumer<BinaryWriter> particleDataConsumer) {
this.particleDataConsumer = particleDataConsumer;
}
}

View File

@ -1,44 +0,0 @@
package net.minestom.server.entity.type.other;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.ObjectEntity;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.other.EndCrystalMeta} instead.
*/
@Deprecated
public class EntityEndCrystal extends ObjectEntity {
public EntityEndCrystal(@NotNull Position spawnPosition) {
super(EntityType.END_CRYSTAL, spawnPosition);
setBoundingBox(2f, 2f, 2f);
}
@Nullable
public BlockPosition getBeamTarget() {
return metadata.getIndex((byte) 7, null);
}
public void setBeamTarget(@Nullable BlockPosition beamTarget) {
this.metadata.setIndex((byte) 7, Metadata.OptPosition(beamTarget));
}
public boolean showBottom() {
return metadata.getIndex((byte) 8, true);
}
public void setShowBottom(boolean showBottom) {
this.metadata.setIndex((byte) 8, Metadata.Boolean(showBottom));
}
@Override
public int getObjectData() {
return 0;
}
}

View File

@ -1,27 +0,0 @@
package net.minestom.server.entity.type.other;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.type.Constructable;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.golem.IronGolemMeta} instead.
*/
@Deprecated
public class EntityIronGolem extends EntityCreature implements Constructable {
public EntityIronGolem(Position spawnPosition) {
super(EntityType.IRON_GOLEM, spawnPosition);
setBoundingBox(1.4f, 2.7f, 1.4f);
}
public boolean isPlayerCreated() {
return metadata.getIndex((byte) 15, 0) == 0x01;
}
public void setPlayerCreated(boolean playerCreated) {
this.metadata.setIndex((byte) 15, Metadata.Byte((byte) (playerCreated ? 0x01 : 0x00)));
}
}

View File

@ -1,27 +0,0 @@
package net.minestom.server.entity.type.other;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.type.Constructable;
import net.minestom.server.utils.Position;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.golem.SnowGolemMeta} instead.
*/
@Deprecated
public class EntitySnowman extends EntityCreature implements Constructable {
public EntitySnowman(Position spawnPosition) {
super(EntityType.SNOW_GOLEM, spawnPosition);
setBoundingBox(0.7f, 1.9f, 0.7f);
}
public boolean hasPumpkinHat() {
return metadata.getIndex((byte) 15, (byte) 0x00) == 0x10;
}
public void setPumpkinHat(boolean pumpkinHat) {
this.metadata.setIndex((byte) 15, Metadata.Byte((byte) (pumpkinHat ? 0x10 : 0x00)));
}
}

View File

@ -1,43 +0,0 @@
package net.minestom.server.entity.type.projectile;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.item.EyeOfEnderMeta} instead.
*/
@Deprecated
public class EntityEyeOfEnder extends Entity {
public EntityEyeOfEnder(@Nullable Entity shooter, @NotNull Position spawnPosition) {
super(EntityType.EYE_OF_ENDER, spawnPosition);
}
/**
* Gets the eye of ender item.
*
* @return the item
*/
public ItemStack getItemStack() {
return metadata.getIndex((byte) 7, ItemStack.AIR);
}
/**
* Changes the eye of ender item.
* <p>
* Can be null to make it like {@link Material#ENDER_EYE}.
*
* @param itemStack the new item stack
*/
public void setItemStack(ItemStack itemStack) {
this.metadata.setIndex((byte) 7, Metadata.Slot(itemStack));
}
}

View File

@ -1,31 +0,0 @@
package net.minestom.server.entity.type.projectile;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.item.ItemStack;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.item.ThrownPotionMeta} instead.
*/
@Deprecated
public class EntityPotion extends Entity {
public EntityPotion(@Nullable Entity shooter, @NotNull Position spawnPosition, @NotNull ItemStack potion) {
super(EntityType.POTION, spawnPosition);
setBoundingBox(0.25f, 0.25f, 0.25f);
setPotion(potion);
}
@NotNull
public ItemStack getPotion() {
return metadata.getIndex((byte) 7, ItemStack.AIR);
}
public void setPotion(@NotNull ItemStack potion) {
this.metadata.setIndex((byte) 7, Metadata.Slot(potion));
}
}

View File

@ -1,57 +0,0 @@
package net.minestom.server.entity.type.vehicle;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.ObjectEntity;
import net.minestom.server.entity.type.Vehicle;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.other.BoatMeta} instead.
*/
@Deprecated
public class EntityBoat extends ObjectEntity implements Vehicle {
public EntityBoat(Position spawnPosition) {
super(EntityType.BOAT, spawnPosition);
setBoundingBox(1.375f, 0.5625f, 1.375f);
}
@Override
public int getObjectData() {
return 0;
}
/**
* Gets the boat type.
*
* @return the boat type
*/
@NotNull
public BoatType getBoatType() {
final int ordinal = metadata.getIndex((byte) 10, 0);
return BoatType.values()[ordinal];
}
/**
* Changes the boat type.
*
* @param boatType the new boat type
*/
public void setBoatType(@NotNull BoatType boatType) {
this.metadata.setIndex((byte) 10, Metadata.VarInt(boatType.ordinal()));
}
public void refreshPaddle(boolean left, boolean right) {
this.metadata.setIndex((byte) 11, Metadata.Boolean(left));
this.metadata.setIndex((byte) 12, Metadata.Boolean(right));
}
public enum BoatType {
OAK, SPRUCE, BIRCH, JUNGLE, ACACIA, DARK_OAK
}
}

View File

@ -1,13 +1,14 @@
package net.minestom.server.event.entity;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityProjectile;
import net.minestom.server.event.trait.CancellableEvent;
import net.minestom.server.event.trait.EntityEvent;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
/**
* Called with {@link net.minestom.server.entity.type.projectile.EntityProjectile#shoot(Position, double, double)}
* Called with {@link EntityProjectile#shoot(Position, double, double)}
*/
public class EntityShootEvent implements EntityEvent, CancellableEvent {

View File

@ -1,6 +1,8 @@
package net.minestom.server.instance;
import com.google.common.collect.Queues;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.pointer.Pointers;
import net.minestom.server.MinecraftServer;
import net.minestom.server.Tickable;
import net.minestom.server.UpdateManager;
@ -109,6 +111,9 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ev
// Pathfinder
private final PFInstanceSpace instanceSpace = new PFInstanceSpace(this);
// Adventure
private final Pointers pointers;
/**
* Creates a new instance.
*
@ -124,6 +129,10 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ev
this.worldBorder = new WorldBorder(this);
this.eventNode = EventNode.value("instance-" + uniqueId, EventFilter.INSTANCE, this::equals);
this.pointers = Pointers.builder()
.withDynamic(Identity.UUID, this::getUniqueId)
.build();
}
/**
@ -919,4 +928,9 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ev
public PFInstanceSpace getInstanceSpace() {
return instanceSpace;
}
@Override
public @NotNull Pointers pointers() {
return this.pointers;
}
}

View File

@ -68,7 +68,7 @@ public abstract class ItemMetaBuilder implements TagWritable {
this.displayName = displayName;
handleCompound("display", nbtCompound -> {
if (displayName != null) {
final String name = AdventureSerializer.serialize(displayName);
final String name = GsonComponentSerializer.gson().serialize(displayName);
nbtCompound.setString("Name", name);
} else {
nbtCompound.removeTag("Name");

View File

@ -71,7 +71,7 @@ public class WritableBookMeta extends ItemMeta implements ItemMetaBuilder.Provid
handleCollection(pages, "pages", nbt, () -> {
NBTList<NBTString> list = new NBTList<>(NBTTypes.TAG_String);
for (Component page : pages) {
list.add(new NBTString(AdventureSerializer.serialize(page)));
list.add(new NBTString(GsonComponentSerializer.gson().serialize(page)));
}
return list;
});

View File

@ -117,7 +117,7 @@ public class WrittenBookMeta extends ItemMeta implements ItemMetaBuilder.Provide
handleCollection(pages, "pages", nbt, () -> {
NBTList<NBTString> list = new NBTList<>(NBTTypes.TAG_String);
for (Component page : pages) {
list.add(new NBTString(AdventureSerializer.serialize(page)));
list.add(new NBTString(GsonComponentSerializer.gson().serialize(page)));
}
return list;
});

View File

@ -2,7 +2,7 @@ package net.minestom.server.listener;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.type.vehicle.EntityBoat;
import net.minestom.server.entity.metadata.other.BoatMeta;
import net.minestom.server.network.packet.client.play.ClientSteerBoatPacket;
import net.minestom.server.network.packet.client.play.ClientSteerVehiclePacket;
import net.minestom.server.network.packet.client.play.ClientVehicleMovePacket;
@ -40,11 +40,12 @@ public class PlayerVehicleListener {
public static void boatSteerListener(ClientSteerBoatPacket packet, Player player) {
final Entity vehicle = player.getVehicle();
if (!(vehicle instanceof EntityBoat))
if (!(vehicle.getEntityMeta() instanceof BoatMeta))
return;
EntityBoat boat = (EntityBoat) vehicle;
boat.refreshPaddle(packet.leftPaddleTurning, packet.rightPaddleTurning);
BoatMeta boat = (BoatMeta) vehicle.getEntityMeta();
boat.setLeftPaddleTurning(packet.leftPaddleTurning);
boat.setRightPaddleTurning(packet.rightPaddleTurning);
}
}

View File

@ -38,13 +38,15 @@ public class MapDataPacket implements ComponentHoldingServerPacket {
writer.writeBoolean(locked);
writer.writeBoolean(trackingPosition);
if (icons != null && icons.length > 0) {
writer.writeVarInt(icons.length);
for (Icon icon : icons) {
icon.write(writer);
if (trackingPosition) {
if (icons != null && icons.length > 0) {
writer.writeVarInt(icons.length);
for (Icon icon : icons) {
icon.write(writer);
}
} else {
writer.writeVarInt(0);
}
} else {
writer.writeVarInt(0);
}
writer.writeByte((byte) columns);

View File

@ -4,8 +4,13 @@ import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.socket.SocketChannel;
import java.util.Objects;
import net.kyori.adventure.translation.GlobalTranslator;
import net.minestom.server.MinecraftServer;
import net.minestom.server.adventure.AdventureSerializer;
import net.minestom.server.adventure.MinestomAdventure;
import net.minestom.server.entity.PlayerSkin;
import net.minestom.server.extras.mojangAuth.Decrypter;
import net.minestom.server.extras.mojangAuth.Encrypter;
@ -149,8 +154,9 @@ public class NettyPlayerConnection extends PlayerConnection {
} else if (message instanceof ServerPacket) {
ServerPacket serverPacket = (ServerPacket) message;
if ((AdventureSerializer.AUTOMATIC_COMPONENT_TRANSLATION && !skipTranslating) && getPlayer() != null && serverPacket instanceof ComponentHoldingServerPacket) {
serverPacket = ((ComponentHoldingServerPacket) serverPacket).copyWithOperator(component -> AdventureSerializer.translate(component, getPlayer()));
if ((MinestomAdventure.AUTOMATIC_COMPONENT_TRANSLATION && !skipTranslating) && getPlayer() != null && serverPacket instanceof ComponentHoldingServerPacket) {
serverPacket = ((ComponentHoldingServerPacket) serverPacket).copyWithOperator(component ->
GlobalTranslator.render(component, Objects.requireNonNullElseGet(getPlayer().getLocale(), MinestomAdventure::getDefaultLocale)));
}
synchronized (tickBufferLock) {

View File

@ -1,6 +1,8 @@
package net.minestom.server.scoreboard;
import com.google.common.collect.MapMaker;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.pointer.Pointers;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.MinecraftServer;
@ -73,6 +75,9 @@ public class Team implements PacketGroupingAudience {
private final Set<Player> playerMembers = Collections.newSetFromMap(new MapMaker().weakKeys().makeMap());
private boolean isPlayerMembersUpToDate;
// Adventure
private final Pointers pointers;
/**
* Default constructor to creates a team.
*
@ -91,6 +96,11 @@ public class Team implements PacketGroupingAudience {
this.suffix = Component.empty();
this.members = new CopyOnWriteArraySet<>();
this.pointers = Pointers.builder()
.withDynamic(Identity.NAME, this::getTeamName)
.withDynamic(Identity.DISPLAY_NAME, this::getTeamDisplayName)
.build();
}
/**
@ -587,4 +597,9 @@ public class Team implements PacketGroupingAudience {
return this.playerMembers;
}
@Override
public @NotNull Pointers pointers() {
return this.pointers;
}
}

View File

@ -1,14 +1,13 @@
package net.minestom.server.sound;
import net.kyori.adventure.sound.Sound;
import org.jetbrains.annotations.NotNull;
import static net.kyori.adventure.sound.Sound.*;
/**
* @deprecated Use {@link Source}
* @deprecated Use {@link Sound.Source}
*/
@Deprecated
public enum SoundCategory {
public enum SoundCategory implements Sound.Source.Provider {
MASTER,
MUSIC,
RECORDS,
@ -24,8 +23,15 @@ public enum SoundCategory {
* Gets the Adventure source representing this sound category.
*
* @return the source
* @deprecated Use {@link #soundSource()}
*/
public @NotNull Source asSource() {
return Source.values()[this.ordinal()];
@Deprecated
public @NotNull Sound.Source asSource() {
return this.soundSource();
}
@Override
public @NotNull Sound.Source soundSource() {
return Sound.Source.values()[this.ordinal()];
}
}

View File

@ -133,15 +133,17 @@ public abstract class ThreadProvider {
if (!ChunkUtils.isLoaded(chunk))
return;
chunk.tick(time);
chunkEntry.entities.forEach(entity -> {
final boolean hasQueue = lock.hasQueuedThreads();
if (hasQueue) {
lock.unlock();
// #acquire callbacks should be called here
lock.lock();
final var entities = chunkEntry.entities;
if (!entities.isEmpty()) {
for (Entity entity : entities) {
if (lock.hasQueuedThreads()) {
lock.unlock();
// #acquire callbacks should be called here
lock.lock();
}
entity.tick(time);
}
entity.tick(time);
});
}
});
Acquirable.refreshEntries(Collections.emptySet());
lock.unlock();

View File

@ -0,0 +1,41 @@
package net.minestom.server.utils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.translation.GlobalTranslator;
import net.minestom.server.adventure.MinestomAdventure;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
/**
* {@link Component} utilities.
*/
public final class ComponentUtils {
/**
* Checks if a component can be translated server-side. This is done by running the
* component through the translator and seeing if the translated component is equal
* to the non translated component.
*
* @param component the component
* @return {@code true} if the component can be translated server-side, {@code false} otherwise
*/
public static boolean isTranslatable(@NotNull Component component) {
return !component.equals(GlobalTranslator.render(component, MinestomAdventure.getDefaultLocale()));
}
/**
* Checks if any of a series of components are translatable server-side.
*
* @param components the components
* @return {@code true} if any of the components can be translated server-side, {@code false} otherwise
*/
public static boolean areAnyTranslatable(@NotNull Collection<Component> components) {
for (Component component : components) {
if (isTranslatable(component)) {
return true;
}
}
return false;
}
}

View File

@ -5,6 +5,7 @@ import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.util.Codec;
import net.minestom.server.MinecraftServer;
import net.minestom.server.adventure.MinestomAdventure;
import net.minestom.server.attribute.Attribute;
import net.minestom.server.attribute.AttributeOperation;
import net.minestom.server.instance.block.Block;
@ -34,9 +35,11 @@ public final class NBTUtils {
/**
* An Adventure codec to convert between NBT and SNBT.
*
* @deprecated Use {@link MinestomAdventure#NBT_CODEC}
*/
public static final Codec<NBT, String, NBTException, RuntimeException> SNBT_CODEC
= Codec.of(encoded -> new SNBTParser(new StringReader(encoded)).parse(), NBT::toSNBT);
@Deprecated(forRemoval = true)
public static final Codec<NBT, String, NBTException, RuntimeException> SNBT_CODEC = MinestomAdventure.NBT_CODEC;
private NBTUtils() {
@ -54,7 +57,7 @@ public final class NBTUtils {
return null;
}
return BinaryTagHolder.encode(tag, SNBT_CODEC);
return BinaryTagHolder.encode(tag, MinestomAdventure.NBT_CODEC);
}
/**

View File

@ -103,11 +103,10 @@ public class NamespaceID implements CharSequence, Key {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
NamespaceID that = (NamespaceID) o;
return Objects.equals(domain, that.domain) &&
Objects.equals(path, that.path);
if(this == o) return true;
if(!(o instanceof Key)) return false;
final Key that = (Key) o;
return Objects.equals(this.domain, that.namespace()) && Objects.equals(this.path, that.value());
}
@Override

View File

@ -7,6 +7,7 @@ import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.audience.ForwardingAudience;
import net.minestom.server.MinecraftServer;
import net.minestom.server.adventure.AdventureSerializer;
import net.minestom.server.adventure.MinestomAdventure;
import net.minestom.server.adventure.audience.PacketGroupingAudience;
import net.minestom.server.entity.Player;
import net.minestom.server.listener.manager.PacketListenerManager;
@ -84,8 +85,8 @@ public final class PacketUtils {
// work out if the packet needs to be sent individually due to server-side translating
boolean needsTranslating = false;
if (AdventureSerializer.AUTOMATIC_COMPONENT_TRANSLATION && packet instanceof ComponentHoldingServerPacket) {
needsTranslating = AdventureSerializer.areAnyTranslatable(((ComponentHoldingServerPacket) packet).components());
if (MinestomAdventure.AUTOMATIC_COMPONENT_TRANSLATION && packet instanceof ComponentHoldingServerPacket) {
needsTranslating = ComponentUtils.areAnyTranslatable(((ComponentHoldingServerPacket) packet).components());
}
if (MinecraftServer.hasGroupedPacket() && !needsTranslating) {

View File

@ -4,6 +4,7 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.minestom.server.MinecraftServer;
import net.minestom.server.adventure.AdventureSerializer;
import net.minestom.server.chat.JsonMessage;
@ -71,7 +72,7 @@ public class BinaryWriter extends OutputStream {
* @param component the component
*/
public void writeComponent(@NotNull Component component) {
this.writeSizedString(AdventureSerializer.serialize(component));
this.writeSizedString(GsonComponentSerializer.gson().serialize(component));
}
/**

View File

@ -0,0 +1 @@
net.minestom.server.adventure.provider.MinestomGsonComponentSerializerProvider

View File

@ -0,0 +1 @@
net.minestom.server.adventure.provider.MinestomLegacyComponentSerializerProvider

View File

@ -0,0 +1 @@
net.minestom.server.adventure.provider.MinestomPlainTextComponentSerializerProvider

View File

@ -10,8 +10,6 @@ import net.minestom.server.command.builder.arguments.ArgumentType;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.extensions.Extension;
import net.minestom.server.extensions.ExtensionManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@ -78,10 +76,4 @@ public class ReloadExtensionCommand extends Command {
private void gameModeCallback(CommandSender sender, ArgumentSyntaxException argumentSyntaxException) {
sender.sendMessage(Component.text("'" + argumentSyntaxException.getInput() + "' is not a valid extension name!"));
}
@Nullable
@Override
public String[] onDynamicWrite(@NotNull CommandSender sender, @NotNull String text) {
return extensionsName;
}
}

View File

@ -10,7 +10,7 @@ import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.metadata.arrow.ArrowMeta;
import net.minestom.server.entity.type.projectile.EntityProjectile;
import net.minestom.server.entity.EntityProjectile;
import java.util.concurrent.ThreadLocalRandom;