From 58fd95879a142c33fc8c371d10a3340db8ec193f Mon Sep 17 00:00:00 2001 From: mworzala Date: Tue, 12 Mar 2024 15:22:15 -0400 Subject: [PATCH] fix: correct painting metadata --- .github/workflows/close_invalid_prs.yml | 2 +- .../net/minestom/server/entity/Metadata.java | 5 + .../entity/metadata/other/PaintingMeta.java | 180 ++++++++++-------- .../server/network/NetworkBuffer.java | 11 +- .../server/network/NetworkBufferTypes.java | 10 + 5 files changed, 117 insertions(+), 91 deletions(-) diff --git a/.github/workflows/close_invalid_prs.yml b/.github/workflows/close_invalid_prs.yml index 6576bc285..44c763b6d 100644 --- a/.github/workflows/close_invalid_prs.yml +++ b/.github/workflows/close_invalid_prs.yml @@ -1,4 +1,4 @@ -# Thanks paper: https://github.com/lynxplay/paper/blob/master/.github/workflows/close_invalid_prs.yml +# Thanks paper: https://github.com/papermc/paper/blob/master/.github/workflows/close_invalid_prs.yml name: Close invalid PRs on: diff --git a/src/main/java/net/minestom/server/entity/Metadata.java b/src/main/java/net/minestom/server/entity/Metadata.java index cead98da3..a7993cb46 100644 --- a/src/main/java/net/minestom/server/entity/Metadata.java +++ b/src/main/java/net/minestom/server/entity/Metadata.java @@ -5,6 +5,7 @@ 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; +import net.minestom.server.entity.metadata.other.PaintingMeta; import net.minestom.server.item.ItemStack; import net.minestom.server.network.NetworkBuffer; import net.minestom.server.network.packet.server.play.EntityMetaDataPacket; @@ -115,6 +116,10 @@ public final class Metadata { return new MetadataImpl.EntryImpl<>(TYPE_FROG_VARIANT, value, NetworkBuffer.FROG_VARIANT); } + public static Entry PaintingVariant(@NotNull PaintingMeta.Variant value) { + return new MetadataImpl.EntryImpl<>(TYPE_PAINTINGVARIANT, value, NetworkBuffer.PAINTING_VARIANT); + } + public static Entry SnifferState(@NotNull SnifferMeta.State value) { return new MetadataImpl.EntryImpl<>(TYPE_SNIFFER_STATE, value, NetworkBuffer.SNIFFER_STATE); } diff --git a/src/main/java/net/minestom/server/entity/metadata/other/PaintingMeta.java b/src/main/java/net/minestom/server/entity/metadata/other/PaintingMeta.java index 5aefa3fea..bb9fb49a7 100644 --- a/src/main/java/net/minestom/server/entity/metadata/other/PaintingMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/other/PaintingMeta.java @@ -3,128 +3,144 @@ package net.minestom.server.entity.metadata.other; import net.minestom.server.entity.Entity; import net.minestom.server.entity.Metadata; import net.minestom.server.entity.metadata.EntityMeta; -import net.minestom.server.utils.Direction; +import net.minestom.server.entity.metadata.ObjectDataProvider; +import net.minestom.server.registry.StaticProtocolObject; +import net.minestom.server.utils.NamespaceID; import net.minestom.server.utils.validate.Check; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Locale; -public class PaintingMeta extends EntityMeta { +public class PaintingMeta extends EntityMeta implements ObjectDataProvider { public static final byte OFFSET = EntityMeta.MAX_OFFSET; - public static final byte MAX_OFFSET = OFFSET + 0; + public static final byte MAX_OFFSET = OFFSET + 1; - private Motive motive = Motive.KEBAB; - private Direction direction = Direction.SOUTH; + private Orientation orientation = null; public PaintingMeta(@NotNull Entity entity, @NotNull Metadata metadata) { super(entity, metadata); } - @NotNull - public Motive getMotive() { - return motive; + public @NotNull Variant getVariant() { + return super.metadata.getIndex(OFFSET, Variant.KEBAB); } - /** - * Sets motive of a painting. - * This is possible only before spawn packet is sent. - * - * @param motive motive of a painting. - */ - public void setMotive(@NotNull Motive motive) { - this.motive = motive; + public void setVariant(@NotNull Variant value) { + super.metadata.setIndex(OFFSET, Metadata.PaintingVariant(value)); } @NotNull - public Direction getDirection() { - return direction; + public Orientation getOrientation() { + return this.orientation; } /** - * Sets direction of a painting. + * Sets orientation of the painting. * This is possible only before spawn packet is sent. * - * @param direction direction of a painting. + * @param orientation the orientation of the painting. */ - public void setDirection(@NotNull Direction direction) { - Check.argCondition(direction == Direction.UP || direction == Direction.DOWN, "Painting can't look up or down!"); - this.direction = direction; + public void setOrientation(@NotNull Orientation orientation) { + this.orientation = orientation; } - /* - TODO: write a parser? - Currently none of existing ones support it. - */ - public enum Motive { - KEBAB(0, 0, 16, 16), - AZTEC(16, 0, 16, 16), - ALBAN(32, 0, 16, 16), - AZTEC2(48, 0, 16, 16), - BOMB(64, 0, 16, 16), - PLANT(80, 0, 16, 16), - WASTELAND(96, 0, 16, 16), - POOL(0, 32, 32, 16), - COURBET(32, 32, 32, 16), - SEA(64, 32, 32, 16), - SUNSET(96, 32, 32, 16), - CREEBET(128, 32, 32, 16), - WANDERER(0, 64, 16, 32), - GRAHAM(16, 64, 16, 32), - MATCH(0, 128, 32, 32), - BUST(32, 128, 32, 32), - STAGE(64, 128, 32, 32), - VOID(96, 128, 32, 32), - SKULL_AND_ROSES("skull_and_roses", 128, 128, 32, 32), - WITHER(160, 128, 32, 32), - FIGHTERS(0, 96, 64, 32), - POINTER(0, 192, 64, 64), - PIGSCENE(64, 192, 64, 64), - BURNING_SKULL(128, 192, 64, 64), - SKELETON(192, 64, 64, 48), - DONKEY_KONG(192, 112, 64, 48); + @Override + public int getObjectData() { + Check.stateCondition(this.orientation == null, "Painting orientation must be set before spawn"); + return this.orientation.id(); + } - private final String name; - private final int x; - private final int y; + @Override + public boolean requiresVelocityPacketAtSpawn() { + return false; + } + + public enum Orientation { + NORTH(2), + SOUTH(3), + WEST(4), + EAST(5); + + private final int id; + + Orientation(int id) { + this.id = id; + } + + public int id() { + return id; + } + } + + public enum Variant implements StaticProtocolObject { + KEBAB(16, 16), + AZTEC(16, 16), + ALBAN(16, 16), + AZTEC2(16, 16), + BOMB(16, 16), + PLANT(16, 16), + WASTELAND(16, 16), + POOL(32, 16), + COURBET(32, 16), + SEA(32, 16), + SUNSET(32, 16), + CREEBET(32, 16), + WANDERER(16, 32), + GRAHAM(16, 32), + MATCH(32, 32), + BUST(32, 32), + STAGE(32, 32), + VOID(32, 32), + SKULL_AND_ROSES(32, 32), + WITHER(32, 32), + FIGHTERS(64, 32), + POINTER(64, 64), + PIGSCENE(64, 64), + BURNING_SKULL(64, 64), + SKELETON(64, 48), + EARTH(32, 32), + WIND(32, 32), + WATER(32, 32), + FIRE(32, 32), + DONKEY_KONG(64, 48); + + private static final Variant[] VALUES = values(); + + public static @Nullable Variant fromId(int id) { + if (id < 0 || id >= VALUES.length) { + return null; + } + return VALUES[id]; + } + + private final NamespaceID namespace; private final int width; private final int height; - Motive(String name, int x, int y, int width, int height) { - this.name = name; - this.x = x; - this.y = y; + Variant(int width, int height) { + this.namespace = NamespaceID.from("minecraft", name().toLowerCase(Locale.ROOT)); this.width = width; this.height = height; } - Motive(int x, int y, int width, int height) { - this.name = "minecraft:" + name().toLowerCase(Locale.ROOT); - this.x = x; - this.y = y; - this.width = width; - this.height = height; + @Override + public int id() { + return ordinal(); } - public String getName() { - return this.name; + public int width() { + return width; } - public int getX() { - return this.x; + public int height() { + return height; } - public int getY() { - return this.y; + @Override + public @NotNull NamespaceID namespace() { + return namespace; } - - public int getWidth() { - return this.width; - } - - public int getHeight() { - return this.height; - } - } } diff --git a/src/main/java/net/minestom/server/network/NetworkBuffer.java b/src/main/java/net/minestom/server/network/NetworkBuffer.java index c470bccb9..60b1322cb 100644 --- a/src/main/java/net/minestom/server/network/NetworkBuffer.java +++ b/src/main/java/net/minestom/server/network/NetworkBuffer.java @@ -1,19 +1,12 @@ package net.minestom.server.network; -import java.util.BitSet; -import java.util.Collection; - -import java.util.EnumSet; -import java.util.List; - -import java.util.UUID; - import net.kyori.adventure.text.Component; import net.minestom.server.coordinate.Point; import net.minestom.server.entity.Entity; 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; +import net.minestom.server.entity.metadata.other.PaintingMeta; import net.minestom.server.item.ItemStack; import net.minestom.server.network.packet.server.play.data.DeathLocation; import net.minestom.server.particle.Particle; @@ -29,6 +22,7 @@ import org.jglrxavpok.hephaistos.nbt.NBTWriter; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.util.*; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; @@ -73,6 +67,7 @@ public final class NetworkBuffer { public static final Type DEATH_LOCATION = NetworkBufferTypes.DEATH_LOCATION; public static final Type CAT_VARIANT = NetworkBufferTypes.CAT_VARIANT; public static final Type FROG_VARIANT = NetworkBufferTypes.FROG_VARIANT; + public static final Type PAINTING_VARIANT = NetworkBufferTypes.PAINTING_VARIANT; public static final Type SNIFFER_STATE = NetworkBufferTypes.SNIFFER_STATE; public static final Type VECTOR3 = NetworkBufferTypes.VECTOR3; public static final Type VECTOR3D = NetworkBufferTypes.VECTOR3D; diff --git a/src/main/java/net/minestom/server/network/NetworkBufferTypes.java b/src/main/java/net/minestom/server/network/NetworkBufferTypes.java index bbaaeadaa..1c1a77578 100644 --- a/src/main/java/net/minestom/server/network/NetworkBufferTypes.java +++ b/src/main/java/net/minestom/server/network/NetworkBufferTypes.java @@ -9,6 +9,7 @@ import net.minestom.server.entity.Entity; 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; +import net.minestom.server.entity.metadata.other.PaintingMeta; import net.minestom.server.item.ItemStack; import net.minestom.server.item.Material; import net.minestom.server.network.packet.server.play.data.DeathLocation; @@ -578,6 +579,15 @@ final class NetworkBufferTypes { final int ordinal = buffer.read(VAR_INT); return FrogMeta.Variant.values()[ordinal]; }); + static final TypeImpl PAINTING_VARIANT = new TypeImpl<>(PaintingMeta.Variant.class, + (buffer, value) -> { + buffer.write(VAR_INT, value.ordinal()); + return -1; + }, + buffer -> { + final int ordinal = buffer.read(VAR_INT); + return PaintingMeta.Variant.values()[ordinal]; + }); static final TypeImpl SNIFFER_STATE = new TypeImpl<>(SnifferMeta.State.class, (buffer, value) -> { buffer.write(VAR_INT, value.ordinal());