Minestom/src/main/java/net/minestom/server/entity/Metadata.java

267 lines
11 KiB
Java
Raw Normal View History

2021-01-30 04:44:44 +01:00
package net.minestom.server.entity;
2021-03-03 20:27:33 +01:00
import net.kyori.adventure.text.Component;
import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.metadata.animal.FrogMeta;
import net.minestom.server.entity.metadata.animal.SnifferMeta;
import net.minestom.server.entity.metadata.animal.tameable.CatMeta;
2024-03-12 20:22:15 +01:00
import net.minestom.server.entity.metadata.other.PaintingMeta;
2021-01-30 04:44:44 +01:00
import net.minestom.server.item.ItemStack;
2022-10-29 11:02:22 +02:00
import net.minestom.server.network.NetworkBuffer;
2021-01-30 04:44:44 +01:00
import net.minestom.server.network.packet.server.play.EntityMetaDataPacket;
import net.minestom.server.particle.Particle;
2021-01-30 04:44:44 +01:00
import net.minestom.server.utils.Direction;
import org.jetbrains.annotations.ApiStatus;
2021-01-30 04:44:44 +01:00
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.UnknownNullability;
import org.jglrxavpok.hephaistos.nbt.NBT;
2021-01-30 04:44:44 +01:00
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
2021-01-30 04:44:44 +01:00
public final class Metadata {
public static Entry<Byte> Byte(byte value) {
2022-10-29 11:02:22 +02:00
return new MetadataImpl.EntryImpl<>(TYPE_BYTE, value, NetworkBuffer.BYTE);
2021-01-30 04:44:44 +01:00
}
public static Entry<Integer> VarInt(int value) {
2022-10-29 11:02:22 +02:00
return new MetadataImpl.EntryImpl<>(TYPE_VARINT, value, NetworkBuffer.VAR_INT);
2021-01-30 04:44:44 +01:00
}
1.19.3 (#1851) * hollow-cube/1.19.3 Signed-off-by: mworzala <mattheworzala@gmail.com> fix sounds v2 (cherry picked from commit e6d4a2cc919d6ab5aa9402cc871a70535069d803) fix command packet (cherry picked from commit f3efd64f7bd1d0473e0899d202268f77bab35abf) fix sound effect packets (cherry picked from commit 8530b37b354129a2149aafe2820183b28766be00) remove named sound effect & fix sound effect, entity sound effect packet is still wrong (cherry picked from commit 612f6065a12c465c07816c8551b1c44f17c21159) update NamedSoundEffectPacket to 1.19.3 (cherry picked from commit 8c78d9beac96f94770f6fd0e9216452c3421bcfd) update datagen, add read method to player info update (though it seems kinda broken) (cherry picked from commit 6464a72dabc5edaf9b09ef1b8100815965bbad74) Add ChatSession Signed-off-by: TheMode <themode@outlook.fr> (cherry picked from commit 0488915fdaff4b51c4375da27be2dcf79215435d) Unnecessary line change Signed-off-by: TheMode <themode@outlook.fr> (cherry picked from commit 915836f490fb3c28b3326edcc6da1de57fec118c) Make tests compile Signed-off-by: TheMode <themode@outlook.fr> (cherry picked from commit 220217fcc1030441f1d2c3f6e96d3d4ca68331f3) Fix info update Signed-off-by: TheMode <themode@outlook.fr> (cherry picked from commit 1a606285c0ceb1252ed505acd963430a3d8cb0a7) Fix unsigned message Signed-off-by: TheMode <themode@outlook.fr> (cherry picked from commit 7ba55fdfef9f753c3ba6a1ca3d569b3c6fe4418e) 1.19.3 support (cherry picked from commit f09fdd862bd185f4f8bdff8fdfcd45945b38f4ab) * Cleanup * Fix tests * Fix tests round 2 * Cleanup round 2 * remove logback * remove chatbound * don't use magic numbers * Fix formatting * Unused imports * Fix and add update display name packet test back * Cleanup tests * Bump minestom data * Add ArgumentResource and ArgumentResourceOrTag * Fix spacing --------- Co-authored-by: themode <themode@outlook.fr> Co-authored-by: KrystilizeNevaDies <tyreece@rozycki.family> Co-authored-by: iam <iam4722202468@users.noreply.github.com>
2023-05-21 16:51:13 +02:00
public static Entry<Long> Long(long value) {
return new MetadataImpl.EntryImpl<>(TYPE_LONG, value, NetworkBuffer.VAR_LONG);
1.19.3 (#1851) * hollow-cube/1.19.3 Signed-off-by: mworzala <mattheworzala@gmail.com> fix sounds v2 (cherry picked from commit e6d4a2cc919d6ab5aa9402cc871a70535069d803) fix command packet (cherry picked from commit f3efd64f7bd1d0473e0899d202268f77bab35abf) fix sound effect packets (cherry picked from commit 8530b37b354129a2149aafe2820183b28766be00) remove named sound effect & fix sound effect, entity sound effect packet is still wrong (cherry picked from commit 612f6065a12c465c07816c8551b1c44f17c21159) update NamedSoundEffectPacket to 1.19.3 (cherry picked from commit 8c78d9beac96f94770f6fd0e9216452c3421bcfd) update datagen, add read method to player info update (though it seems kinda broken) (cherry picked from commit 6464a72dabc5edaf9b09ef1b8100815965bbad74) Add ChatSession Signed-off-by: TheMode <themode@outlook.fr> (cherry picked from commit 0488915fdaff4b51c4375da27be2dcf79215435d) Unnecessary line change Signed-off-by: TheMode <themode@outlook.fr> (cherry picked from commit 915836f490fb3c28b3326edcc6da1de57fec118c) Make tests compile Signed-off-by: TheMode <themode@outlook.fr> (cherry picked from commit 220217fcc1030441f1d2c3f6e96d3d4ca68331f3) Fix info update Signed-off-by: TheMode <themode@outlook.fr> (cherry picked from commit 1a606285c0ceb1252ed505acd963430a3d8cb0a7) Fix unsigned message Signed-off-by: TheMode <themode@outlook.fr> (cherry picked from commit 7ba55fdfef9f753c3ba6a1ca3d569b3c6fe4418e) 1.19.3 support (cherry picked from commit f09fdd862bd185f4f8bdff8fdfcd45945b38f4ab) * Cleanup * Fix tests * Fix tests round 2 * Cleanup round 2 * remove logback * remove chatbound * don't use magic numbers * Fix formatting * Unused imports * Fix and add update display name packet test back * Cleanup tests * Bump minestom data * Add ArgumentResource and ArgumentResourceOrTag * Fix spacing --------- Co-authored-by: themode <themode@outlook.fr> Co-authored-by: KrystilizeNevaDies <tyreece@rozycki.family> Co-authored-by: iam <iam4722202468@users.noreply.github.com>
2023-05-21 16:51:13 +02:00
}
public static Entry<Float> Float(float value) {
2022-10-29 11:02:22 +02:00
return new MetadataImpl.EntryImpl<>(TYPE_FLOAT, value, NetworkBuffer.FLOAT);
2021-01-30 04:44:44 +01:00
}
public static Entry<String> String(@NotNull String value) {
2022-10-29 11:02:22 +02:00
return new MetadataImpl.EntryImpl<>(TYPE_STRING, value, NetworkBuffer.STRING);
2021-01-30 04:44:44 +01:00
}
public static Entry<Component> Chat(@NotNull Component value) {
2022-10-29 11:02:22 +02:00
return new MetadataImpl.EntryImpl<>(TYPE_CHAT, value, NetworkBuffer.COMPONENT);
2021-03-03 20:27:33 +01:00
}
public static Entry<Component> OptChat(@Nullable Component value) {
2022-10-29 11:02:22 +02:00
return new MetadataImpl.EntryImpl<>(TYPE_OPTCHAT, value, NetworkBuffer.OPT_CHAT);
2021-03-03 20:27:33 +01:00
}
public static Entry<ItemStack> Slot(@NotNull ItemStack value) {
2022-10-29 11:02:22 +02:00
return new MetadataImpl.EntryImpl<>(TYPE_SLOT, value, NetworkBuffer.ITEM);
2021-01-30 04:44:44 +01:00
}
public static Entry<Boolean> Boolean(boolean value) {
2022-10-29 11:02:22 +02:00
return new MetadataImpl.EntryImpl<>(TYPE_BOOLEAN, value, NetworkBuffer.BOOLEAN);
2021-01-30 04:44:44 +01:00
}
public static Entry<Point> Rotation(@NotNull Point value) {
2022-10-29 11:02:22 +02:00
return new MetadataImpl.EntryImpl<>(TYPE_ROTATION, value, NetworkBuffer.ROTATION);
2021-01-30 04:44:44 +01:00
}
public static Entry<Point> Position(@NotNull Point value) {
2022-10-29 11:02:22 +02:00
return new MetadataImpl.EntryImpl<>(TYPE_POSITION, value, NetworkBuffer.BLOCK_POSITION);
2021-01-30 04:44:44 +01:00
}
public static Entry<Point> OptPosition(@Nullable Point value) {
2022-10-29 11:02:22 +02:00
return new MetadataImpl.EntryImpl<>(TYPE_OPTPOSITION, value, NetworkBuffer.OPT_BLOCK_POSITION);
2021-01-30 04:44:44 +01:00
}
public static Entry<Direction> Direction(@NotNull Direction value) {
2022-10-29 11:02:22 +02:00
return new MetadataImpl.EntryImpl<>(TYPE_DIRECTION, value, NetworkBuffer.DIRECTION);
2021-01-30 04:44:44 +01:00
}
public static Entry<UUID> OptUUID(@Nullable UUID value) {
2022-10-29 11:02:22 +02:00
return new MetadataImpl.EntryImpl<>(TYPE_OPTUUID, value, NetworkBuffer.OPT_UUID);
}
public static Entry<Integer> BlockState(@Nullable Integer value) {
return new MetadataImpl.EntryImpl<>(TYPE_BLOCKSTATE, value, NetworkBuffer.BLOCK_STATE);
}
public static Entry<Integer> OptBlockState(@Nullable Integer value) {
return new MetadataImpl.EntryImpl<>(TYPE_OPTBLOCKSTATE, value, NetworkBuffer.OPT_BLOCK_STATE);
}
public static Entry<NBT> NBT(@NotNull NBT nbt) {
2022-10-29 11:02:22 +02:00
return new MetadataImpl.EntryImpl<>(TYPE_NBT, nbt, NetworkBuffer.NBT);
2021-01-30 04:44:44 +01:00
}
public static Entry<int[]> VillagerData(int villagerType,
2021-02-02 21:03:25 +01:00
int villagerProfession,
int level) {
return new MetadataImpl.EntryImpl<>(TYPE_VILLAGERDATA, new int[]{villagerType, villagerProfession, level},
2022-10-29 11:02:22 +02:00
NetworkBuffer.VILLAGER_DATA);
}
public static Entry<Integer> OptVarInt(@Nullable Integer value) {
2022-10-29 11:02:22 +02:00
return new MetadataImpl.EntryImpl<>(TYPE_OPTVARINT, value, NetworkBuffer.OPT_VAR_INT);
}
public static Entry<Entity.Pose> Pose(@NotNull Entity.Pose value) {
2022-10-29 11:02:22 +02:00
return new MetadataImpl.EntryImpl<>(TYPE_POSE, value, NetworkBuffer.POSE);
2021-01-30 04:44:44 +01:00
}
public static Entry<CatMeta.Variant> CatVariant(@NotNull CatMeta.Variant value) {
return new MetadataImpl.EntryImpl<>(TYPE_CAT_VARIANT, value, NetworkBuffer.CAT_VARIANT);
}
public static Entry<FrogMeta.Variant> FrogVariant(@NotNull FrogMeta.Variant value) {
return new MetadataImpl.EntryImpl<>(TYPE_FROG_VARIANT, value, NetworkBuffer.FROG_VARIANT);
}
2024-03-12 20:22:15 +01:00
public static Entry<PaintingMeta.Variant> PaintingVariant(@NotNull PaintingMeta.Variant value) {
return new MetadataImpl.EntryImpl<>(TYPE_PAINTINGVARIANT, value, NetworkBuffer.PAINTING_VARIANT);
}
public static Entry<SnifferMeta.State> SnifferState(@NotNull SnifferMeta.State value) {
return new MetadataImpl.EntryImpl<>(TYPE_SNIFFER_STATE, value, NetworkBuffer.SNIFFER_STATE);
}
public static Entry<Point> Vector3(@NotNull Point value) {
return new MetadataImpl.EntryImpl<>(TYPE_VECTOR3, value, NetworkBuffer.VECTOR3);
}
public static Entry<float[]> Quaternion(float @NotNull[] value) {
return new MetadataImpl.EntryImpl<>(TYPE_QUATERNION, value, NetworkBuffer.QUATERNION);
}
public static Entry<Particle> Particle(@NotNull Particle particle) {
return new MetadataImpl.EntryImpl<>(TYPE_PARTICLE, particle, NetworkBuffer.PARTICLE);
}
2021-01-30 04:44:44 +01:00
public static final byte TYPE_BYTE = 0;
public static final byte TYPE_VARINT = 1;
1.19.3 (#1851) * hollow-cube/1.19.3 Signed-off-by: mworzala <mattheworzala@gmail.com> fix sounds v2 (cherry picked from commit e6d4a2cc919d6ab5aa9402cc871a70535069d803) fix command packet (cherry picked from commit f3efd64f7bd1d0473e0899d202268f77bab35abf) fix sound effect packets (cherry picked from commit 8530b37b354129a2149aafe2820183b28766be00) remove named sound effect & fix sound effect, entity sound effect packet is still wrong (cherry picked from commit 612f6065a12c465c07816c8551b1c44f17c21159) update NamedSoundEffectPacket to 1.19.3 (cherry picked from commit 8c78d9beac96f94770f6fd0e9216452c3421bcfd) update datagen, add read method to player info update (though it seems kinda broken) (cherry picked from commit 6464a72dabc5edaf9b09ef1b8100815965bbad74) Add ChatSession Signed-off-by: TheMode <themode@outlook.fr> (cherry picked from commit 0488915fdaff4b51c4375da27be2dcf79215435d) Unnecessary line change Signed-off-by: TheMode <themode@outlook.fr> (cherry picked from commit 915836f490fb3c28b3326edcc6da1de57fec118c) Make tests compile Signed-off-by: TheMode <themode@outlook.fr> (cherry picked from commit 220217fcc1030441f1d2c3f6e96d3d4ca68331f3) Fix info update Signed-off-by: TheMode <themode@outlook.fr> (cherry picked from commit 1a606285c0ceb1252ed505acd963430a3d8cb0a7) Fix unsigned message Signed-off-by: TheMode <themode@outlook.fr> (cherry picked from commit 7ba55fdfef9f753c3ba6a1ca3d569b3c6fe4418e) 1.19.3 support (cherry picked from commit f09fdd862bd185f4f8bdff8fdfcd45945b38f4ab) * Cleanup * Fix tests * Fix tests round 2 * Cleanup round 2 * remove logback * remove chatbound * don't use magic numbers * Fix formatting * Unused imports * Fix and add update display name packet test back * Cleanup tests * Bump minestom data * Add ArgumentResource and ArgumentResourceOrTag * Fix spacing --------- Co-authored-by: themode <themode@outlook.fr> Co-authored-by: KrystilizeNevaDies <tyreece@rozycki.family> Co-authored-by: iam <iam4722202468@users.noreply.github.com>
2023-05-21 16:51:13 +02:00
public static final byte TYPE_LONG = 2;
public static final byte TYPE_FLOAT = 3;
public static final byte TYPE_STRING = 4;
public static final byte TYPE_CHAT = 5;
public static final byte TYPE_OPTCHAT = 6;
public static final byte TYPE_SLOT = 7;
public static final byte TYPE_BOOLEAN = 8;
public static final byte TYPE_ROTATION = 9;
public static final byte TYPE_POSITION = 10;
public static final byte TYPE_OPTPOSITION = 11;
public static final byte TYPE_DIRECTION = 12;
public static final byte TYPE_OPTUUID = 13;
public static final byte TYPE_BLOCKSTATE = 14;
public static final byte TYPE_OPTBLOCKSTATE = 15;
public static final byte TYPE_NBT = 16;
public static final byte TYPE_PARTICLE = 17;
public static final byte TYPE_VILLAGERDATA = 18;
public static final byte TYPE_OPTVARINT = 19;
public static final byte TYPE_POSE = 20;
public static final byte TYPE_CAT_VARIANT = 21;
public static final byte TYPE_FROG_VARIANT = 22;
public static final byte TYPE_OPTGLOBALPOS = 23;
public static final byte TYPE_PAINTINGVARIANT = 24;
public static final byte TYPE_SNIFFER_STATE = 25;
public static final byte TYPE_VECTOR3 = 26;
public static final byte TYPE_QUATERNION = 27;
2021-01-30 04:44:44 +01:00
// Impl Note: Adding an entry here requires that a default value entry is added in MetadataImpl.EMPTY_VALUES
private static final VarHandle NOTIFIED_CHANGES;
static {
try {
NOTIFIED_CHANGES = MethodHandles.lookup().findVarHandle(Metadata.class, "notifyAboutChanges", boolean.class);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
2021-01-30 04:44:44 +01:00
private final Entity entity;
private volatile Entry<?>[] entries = new Entry<?>[0];
private volatile Map<Integer, Entry<?>> entryMap = null;
2021-02-24 11:28:23 +01:00
@SuppressWarnings("FieldMayBeFinal")
2021-02-24 11:28:23 +01:00
private volatile boolean notifyAboutChanges = true;
private final Map<Integer, Entry<?>> notNotifiedChanges = new HashMap<>();
2021-01-30 04:44:44 +01:00
public Metadata(@Nullable Entity entity) {
this.entity = entity;
}
2021-02-24 11:28:23 +01:00
@SuppressWarnings("unchecked")
public <T> T getIndex(int index, @Nullable T defaultValue) {
final Entry<?>[] entries = this.entries;
if (index < 0 || index >= entries.length) return defaultValue;
final Entry<?> entry = entries[index];
return entry != null ? (T) entry.value() : defaultValue;
2021-01-30 04:44:44 +01:00
}
public void setIndex(int index, @NotNull Entry<?> entry) {
Entry<?>[] entries = this.entries;
// Resize array if necessary
if (index >= entries.length) {
final int newLength = Math.max(entries.length * 2, index + 1);
this.entries = entries = Arrays.copyOf(entries, newLength);
}
entries[index] = entry;
2022-08-30 21:37:25 +02:00
this.entryMap = null;
2021-01-30 04:44:44 +01:00
// Send metadata packet to update viewers and self
final Entity entity = this.entity;
if (entity != null && entity.isActive()) {
2021-02-24 11:28:23 +01:00
if (!this.notifyAboutChanges) {
synchronized (this.notNotifiedChanges) {
this.notNotifiedChanges.put(index, entry);
2021-02-24 11:28:23 +01:00
}
} else {
entity.sendPacketToViewersAndSelf(new EntityMetaDataPacket(entity.getEntityId(), Map.of(index, entry)));
2021-02-24 11:28:23 +01:00
}
2021-01-30 04:44:44 +01:00
}
}
2021-02-24 11:28:23 +01:00
public void setNotifyAboutChanges(boolean notifyAboutChanges) {
if (!NOTIFIED_CHANGES.compareAndSet(this, !notifyAboutChanges, notifyAboutChanges))
return;
if (!notifyAboutChanges) {
// Ask future metadata changes to be cached
2021-02-24 11:28:23 +01:00
return;
}
final Entity entity = this.entity;
if (entity == null || !entity.isActive()) return;
Map<Integer, Entry<?>> entries;
2021-02-24 11:28:23 +01:00
synchronized (this.notNotifiedChanges) {
Map<Integer, Entry<?>> awaitingChanges = this.notNotifiedChanges;
if (awaitingChanges.isEmpty()) return;
entries = Map.copyOf(awaitingChanges);
awaitingChanges.clear();
2021-02-24 11:28:23 +01:00
}
entity.sendPacketToViewersAndSelf(new EntityMetaDataPacket(entity.getEntityId(), entries));
2021-02-24 11:28:23 +01:00
}
public @NotNull Map<Integer, Entry<?>> getEntries() {
Map<Integer, Entry<?>> map = entryMap;
if (map == null) {
map = new HashMap<>();
final Entry<?>[] entries = this.entries;
for (int i = 0; i < entries.length; i++) {
final Entry<?> entry = entries[i];
if (entry != null) map.put(i, entry);
}
this.entryMap = Map.copyOf(map);
}
return map;
2021-01-30 04:44:44 +01:00
}
2022-10-29 11:02:22 +02:00
public sealed interface Entry<T> extends NetworkBuffer.Writer
permits MetadataImpl.EntryImpl {
int type();
@UnknownNullability T value();
@ApiStatus.Internal
2022-10-29 11:02:22 +02:00
static @NotNull Entry<?> read(int type, @NotNull NetworkBuffer reader) {
return MetadataImpl.EntryImpl.read(type, reader);
2021-01-30 04:44:44 +01:00
}
}
}