fix: correct painting metadata

This commit is contained in:
mworzala 2024-03-12 15:22:15 -04:00
parent 7aaa85cd47
commit 58fd95879a
No known key found for this signature in database
GPG Key ID: B148F922E64797C7
5 changed files with 117 additions and 91 deletions

View File

@ -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 name: Close invalid PRs
on: on:

View File

@ -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.FrogMeta;
import net.minestom.server.entity.metadata.animal.SnifferMeta; import net.minestom.server.entity.metadata.animal.SnifferMeta;
import net.minestom.server.entity.metadata.animal.tameable.CatMeta; 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.ItemStack;
import net.minestom.server.network.NetworkBuffer; import net.minestom.server.network.NetworkBuffer;
import net.minestom.server.network.packet.server.play.EntityMetaDataPacket; 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); return new MetadataImpl.EntryImpl<>(TYPE_FROG_VARIANT, value, NetworkBuffer.FROG_VARIANT);
} }
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) { public static Entry<SnifferMeta.State> SnifferState(@NotNull SnifferMeta.State value) {
return new MetadataImpl.EntryImpl<>(TYPE_SNIFFER_STATE, value, NetworkBuffer.SNIFFER_STATE); return new MetadataImpl.EntryImpl<>(TYPE_SNIFFER_STATE, value, NetworkBuffer.SNIFFER_STATE);
} }

View File

@ -3,128 +3,144 @@ package net.minestom.server.entity.metadata.other;
import net.minestom.server.entity.Entity; import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata; import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.EntityMeta; 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 net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Locale; 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 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 Orientation orientation = null;
private Direction direction = Direction.SOUTH;
public PaintingMeta(@NotNull Entity entity, @NotNull Metadata metadata) { public PaintingMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata); super(entity, metadata);
} }
@NotNull public @NotNull Variant getVariant() {
public Motive getMotive() { return super.metadata.getIndex(OFFSET, Variant.KEBAB);
return motive;
} }
/** public void setVariant(@NotNull Variant value) {
* Sets motive of a painting. super.metadata.setIndex(OFFSET, Metadata.PaintingVariant(value));
* This is possible only before spawn packet is sent.
*
* @param motive motive of a painting.
*/
public void setMotive(@NotNull Motive motive) {
this.motive = motive;
} }
@NotNull @NotNull
public Direction getDirection() { public Orientation getOrientation() {
return direction; return this.orientation;
} }
/** /**
* Sets direction of a painting. * Sets orientation of the painting.
* This is possible only before spawn packet is sent. * 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) { public void setOrientation(@NotNull Orientation orientation) {
Check.argCondition(direction == Direction.UP || direction == Direction.DOWN, "Painting can't look up or down!"); this.orientation = orientation;
this.direction = direction;
} }
/* @Override
TODO: write a parser? public int getObjectData() {
Currently none of existing ones support it. Check.stateCondition(this.orientation == null, "Painting orientation must be set before spawn");
*/ return this.orientation.id();
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);
private final String name; @Override
private final int x; public boolean requiresVelocityPacketAtSpawn() {
private final int y; 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 width;
private final int height; private final int height;
Motive(String name, int x, int y, int width, int height) { Variant(int width, int height) {
this.name = name; this.namespace = NamespaceID.from("minecraft", name().toLowerCase(Locale.ROOT));
this.x = x;
this.y = y;
this.width = width; this.width = width;
this.height = height; this.height = height;
} }
Motive(int x, int y, int width, int height) { @Override
this.name = "minecraft:" + name().toLowerCase(Locale.ROOT); public int id() {
this.x = x; return ordinal();
this.y = y;
this.width = width;
this.height = height;
} }
public String getName() { public int width() {
return this.name; return width;
} }
public int getX() { public int height() {
return this.x; return height;
} }
public int getY() { @Override
return this.y; public @NotNull NamespaceID namespace() {
return namespace;
} }
public int getWidth() {
return this.width;
}
public int getHeight() {
return this.height;
}
} }
} }

View File

@ -1,19 +1,12 @@
package net.minestom.server.network; 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.kyori.adventure.text.Component;
import net.minestom.server.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.Entity; import net.minestom.server.entity.Entity;
import net.minestom.server.entity.metadata.animal.FrogMeta; import net.minestom.server.entity.metadata.animal.FrogMeta;
import net.minestom.server.entity.metadata.animal.SnifferMeta; import net.minestom.server.entity.metadata.animal.SnifferMeta;
import net.minestom.server.entity.metadata.animal.tameable.CatMeta; 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.ItemStack;
import net.minestom.server.network.packet.server.play.data.DeathLocation; import net.minestom.server.network.packet.server.play.data.DeathLocation;
import net.minestom.server.particle.Particle; import net.minestom.server.particle.Particle;
@ -29,6 +22,7 @@ import org.jglrxavpok.hephaistos.nbt.NBTWriter;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.*;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
@ -73,6 +67,7 @@ public final class NetworkBuffer {
public static final Type<DeathLocation> DEATH_LOCATION = NetworkBufferTypes.DEATH_LOCATION; public static final Type<DeathLocation> DEATH_LOCATION = NetworkBufferTypes.DEATH_LOCATION;
public static final Type<CatMeta.Variant> CAT_VARIANT = NetworkBufferTypes.CAT_VARIANT; public static final Type<CatMeta.Variant> CAT_VARIANT = NetworkBufferTypes.CAT_VARIANT;
public static final Type<FrogMeta.Variant> FROG_VARIANT = NetworkBufferTypes.FROG_VARIANT; public static final Type<FrogMeta.Variant> FROG_VARIANT = NetworkBufferTypes.FROG_VARIANT;
public static final Type<PaintingMeta.Variant> PAINTING_VARIANT = NetworkBufferTypes.PAINTING_VARIANT;
public static final Type<SnifferMeta.State> SNIFFER_STATE = NetworkBufferTypes.SNIFFER_STATE; public static final Type<SnifferMeta.State> SNIFFER_STATE = NetworkBufferTypes.SNIFFER_STATE;
public static final Type<Point> VECTOR3 = NetworkBufferTypes.VECTOR3; public static final Type<Point> VECTOR3 = NetworkBufferTypes.VECTOR3;
public static final Type<Point> VECTOR3D = NetworkBufferTypes.VECTOR3D; public static final Type<Point> VECTOR3D = NetworkBufferTypes.VECTOR3D;

View File

@ -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.FrogMeta;
import net.minestom.server.entity.metadata.animal.SnifferMeta; import net.minestom.server.entity.metadata.animal.SnifferMeta;
import net.minestom.server.entity.metadata.animal.tameable.CatMeta; 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.ItemStack;
import net.minestom.server.item.Material; import net.minestom.server.item.Material;
import net.minestom.server.network.packet.server.play.data.DeathLocation; import net.minestom.server.network.packet.server.play.data.DeathLocation;
@ -578,6 +579,15 @@ final class NetworkBufferTypes {
final int ordinal = buffer.read(VAR_INT); final int ordinal = buffer.read(VAR_INT);
return FrogMeta.Variant.values()[ordinal]; return FrogMeta.Variant.values()[ordinal];
}); });
static final TypeImpl<PaintingMeta.Variant> 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<SnifferMeta.State> SNIFFER_STATE = new TypeImpl<>(SnifferMeta.State.class, static final TypeImpl<SnifferMeta.State> SNIFFER_STATE = new TypeImpl<>(SnifferMeta.State.class,
(buffer, value) -> { (buffer, value) -> {
buffer.write(VAR_INT, value.ordinal()); buffer.write(VAR_INT, value.ordinal());