Skip to content

Commit

Permalink
Merge pull request #956 from booky10/fix/particle-data-decoding-1.20.4
Browse files Browse the repository at this point in the history
Fix particle data decoding and encoding for <1.20.5
  • Loading branch information
retrooper committed Aug 20, 2024
2 parents af1691e + bdc96a8 commit 97fee0c
Show file tree
Hide file tree
Showing 15 changed files with 284 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,14 @@ public static void write(PacketWrapper<?> wrapper, ParticleBlockStateData data)
}

public static ParticleBlockStateData decode(NBTCompound compound, ClientVersion version) {
WrappedBlockState state = WrappedBlockState.decode(compound.getTagOrThrow("block_state"), version);
String key = version.isNewerThanOrEquals(ClientVersion.V_1_20_5) ? "block_state" : "value";
WrappedBlockState state = WrappedBlockState.decode(compound.getTagOrThrow(key), version);
return new ParticleBlockStateData(state);
}

public static void encode(ParticleBlockStateData data, ClientVersion version, NBTCompound compound) {
compound.setTag("block_state", WrappedBlockState.encode(data.blockState, version));
String key = version.isNewerThanOrEquals(ClientVersion.V_1_20_5) ? "block_state" : "value";
compound.setTag(key, WrappedBlockState.encode(data.blockState, version));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,29 @@ public static void write(PacketWrapper<?> wrapper, ParticleColorData data) {

public static ParticleColorData decode(NBTCompound compound, ClientVersion version) {
int argb;
NBT colorTag = compound.getTagOrThrow("color");
if (colorTag instanceof NBTNumber) {
argb = ((NBTNumber) colorTag).getAsInt();
if (version.isNewerThanOrEquals(ClientVersion.V_1_20_5)) {
NBT colorTag = compound.getTagOrThrow("color");
if (colorTag instanceof NBTNumber) {
argb = ((NBTNumber) colorTag).getAsInt();
} else {
float[] color = decodeColor(colorTag);
assert color.length == 4; // required by vanilla protocol
argb = (floor(color[0] * 255f) << 24)
| (floor(color[1] * 255f) << 16)
| (floor(color[2] * 255f) << 8)
| floor(color[3] * 255f);
}
} else {
float[] color = decodeColor(colorTag);
assert color.length == 4; // required by vanilla protocol
argb = (floor(color[0] * 255f) << 24)
| (floor(color[1] * 255f) << 16)
| (floor(color[2] * 255f) << 8)
| floor(color[3] * 255f);
// no data to decode for <1.20.5
argb = 0xFFFFFFFF;
}
return new ParticleColorData(argb);
}

public static void encode(ParticleColorData data, ClientVersion version, NBTCompound compound) {
compound.setTag("color", new NBTInt(data.color));
if (version.isNewerThanOrEquals(ClientVersion.V_1_20_5)) {
compound.setTag("color", new NBTInt(data.color));
}
}

public int getColor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,15 +156,31 @@ public static void write(PacketWrapper<?> wrapper, ParticleDustColorTransitionDa
}

public static ParticleDustColorTransitionData decode(NBTCompound compound, ClientVersion version) {
float[] fromColor = decodeColor(compound.getTagOrThrow("from_color"));
float[] toColor = decodeColor(compound.getTagOrThrow("to_color"));
String fromColorKey = "from_color";
String toColorKey = "to_color";
if (version.isOlderThan(ClientVersion.V_1_20_5)) {
compound = compound.getCompoundTagOrThrow("value");
fromColorKey = "fromColor";
toColorKey = "toColor";
}
float[] fromColor = decodeColor(compound.getTagOrThrow(fromColorKey));
float[] toColor = decodeColor(compound.getTagOrThrow(toColorKey));
float scale = compound.getNumberTagOrThrow("scale").getAsFloat();
return new ParticleDustColorTransitionData(scale, fromColor, toColor);
}

public static void encode(ParticleDustColorTransitionData data, ClientVersion version, NBTCompound compound) {
compound.setTag("from_color", encodeColor(null, data.startRed, data.startGreen, data.startBlue));
compound.setTag("to_color", encodeColor(null, data.endRed, data.endGreen, data.endBlue));
String fromColorKey = "from_color";
String toColorKey = "to_color";
if (version.isOlderThan(ClientVersion.V_1_20_5)) {
NBTCompound innerCompound = new NBTCompound();
compound.setTag("value", innerCompound);
compound = innerCompound;
fromColorKey = "fromColor";
toColorKey = "toColor";
}
compound.setTag(fromColorKey, encodeColor(null, data.startRed, data.startGreen, data.startBlue));
compound.setTag(toColorKey, encodeColor(null, data.endRed, data.endGreen, data.endBlue));
compound.setTag("scale", new NBTFloat(data.scale));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,21 @@ public static NBT encodeColor(@Nullable Float alpha, float red, float green, flo
}

public static ParticleDustData decode(NBTCompound compound, ClientVersion version) {
if (version.isOlderThan(ClientVersion.V_1_20_5)) {
compound = compound.getCompoundTagOrThrow("value");
}
NBT colorNBT = compound.getTagOrNull("color");
float[] color = decodeColor(colorNBT);
float scale = compound.getNumberTagOrThrow("scale").getAsFloat();
return new ParticleDustData(scale, color);
}

public static void encode(ParticleDustData data, ClientVersion version, NBTCompound compound) {
if (version.isOlderThan(ClientVersion.V_1_20_5)) {
NBTCompound innerCompound = new NBTCompound();
compound.setTag("value", innerCompound);
compound = innerCompound;
}
compound.setTag("color", encodeColor(null, data.red, data.green, data.blue));
compound.setTag("scale", new NBTFloat(data.scale));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,14 @@ public static void write(PacketWrapper<?> wrapper, ParticleItemStackData data) {
}

public static ParticleItemStackData decode(NBTCompound compound, ClientVersion version) {
ItemStack stack = ItemStack.decode(compound.getTagOrThrow("item"), version);
String key = version.isNewerThanOrEquals(ClientVersion.V_1_20_5) ? "item" : "value";
ItemStack stack = ItemStack.decode(compound.getTagOrThrow(key), version);
return new ParticleItemStackData(stack);
}

public static void encode(ParticleItemStackData data, ClientVersion version, NBTCompound compound) {
compound.setTag("item", ItemStack.encodeForParticle(data.itemStack, version));
String key = version.isNewerThanOrEquals(ClientVersion.V_1_20_5) ? "item" : "value";
compound.setTag(key, ItemStack.encodeForParticle(data.itemStack, version));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,19 @@ public static void write(PacketWrapper<?> wrapper, ParticleSculkChargeData data)
}

public static ParticleSculkChargeData decode(NBTCompound compound, ClientVersion version) {
if (version.isOlderThan(ClientVersion.V_1_20_5)) {
compound = compound.getCompoundTagOrThrow("value");
}
float roll = compound.getNumberTagOrThrow("roll").getAsFloat();
return new ParticleSculkChargeData(roll);
}

public static void encode(ParticleSculkChargeData data, ClientVersion version, NBTCompound compound) {
if (version.isOlderThan(ClientVersion.V_1_20_5)) {
NBTCompound innerCompound = new NBTCompound();
compound.setTag("value", innerCompound);
compound = innerCompound;
}
compound.setTag("roll", new NBTFloat(data.roll));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,19 @@ public static void write(PacketWrapper<?> wrapper, ParticleShriekData data) {
}

public static ParticleShriekData decode(NBTCompound compound, ClientVersion version) {
if (version.isOlderThan(ClientVersion.V_1_20_5)) {
compound = compound.getCompoundTagOrThrow("value");
}
int delay = compound.getNumberTagOrThrow("delay").getAsInt();
return new ParticleShriekData(delay);
}

public static void encode(ParticleShriekData data, ClientVersion version, NBTCompound compound) {
if (version.isOlderThan(ClientVersion.V_1_20_5)) {
NBTCompound innerCompound = new NBTCompound();
compound.setTag("value", innerCompound);
compound = innerCompound;
}
compound.setTag("delay", new NBTInt(data.delay));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTInt;
import com.github.retrooper.packetevents.protocol.nbt.NBTIntArray;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.world.positionsource.PositionSource;
import com.github.retrooper.packetevents.protocol.world.positionsource.PositionSourceType;
Expand Down Expand Up @@ -154,11 +156,31 @@ public static void write(PacketWrapper<?> wrapper, ParticleVibrationData data) {
}

public static ParticleVibrationData decode(NBTCompound compound, ClientVersion version) {
throw new UnsupportedOperationException(); // FIXME
if (version.isOlderThan(ClientVersion.V_1_20_5)) {
compound = compound.getCompoundTagOrThrow("value");
}
Vector3i origin = version.isNewerThanOrEquals(ClientVersion.V_1_19) ? null :
new Vector3i(compound.getTagOfTypeOrThrow("origin", NBTIntArray.class).getValue());
PositionSource destination = PositionSource.decode(compound.getCompoundTagOrThrow("destination"), version);
int arrivalInTicks = compound.getNumberTagOrThrow("arrival_in_ticks").getAsInt();
return new ParticleVibrationData(origin, destination, arrivalInTicks);
}

public static void encode(ParticleVibrationData data, ClientVersion version, NBTCompound compound) {
throw new UnsupportedOperationException(); // FIXME
if (version.isOlderThan(ClientVersion.V_1_20_5)) {
NBTCompound innerCompound = new NBTCompound();
compound.setTag("value", innerCompound);
compound = innerCompound;
}
if (version.isOlderThan(ClientVersion.V_1_19)) {
Vector3i startPos = data.getStartingPosition();
if (startPos != null) {
compound.setTag("origin", new NBTIntArray(
new int[]{startPos.x, startPos.y, startPos.z}));
}
}
compound.setTag("destination", PositionSource.encode(data.source, version));
compound.setTag("arrival_in_ticks", new NBTInt(data.ticks));
}

@ApiStatus.Obsolete
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@

package com.github.retrooper.packetevents.protocol.world.positionsource;

import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;

public abstract class PositionSource {

protected final PositionSourceType<?> type;
Expand All @@ -26,6 +31,28 @@ public PositionSource(PositionSourceType<?> type) {
this.type = type;
}

public static PositionSource decode(NBT nbt, ClientVersion version) {
NBTCompound compound = (NBTCompound) nbt;
String typeId = compound.getStringTagValueOrThrow("type");
PositionSourceType<?> sourceType = PositionSourceTypes.getByName(typeId);
if (sourceType == null) {
throw new IllegalStateException("Can't find position source type with id " + typeId);
}
return sourceType.decode(compound, version);
}

@SuppressWarnings("unchecked") // should not cause issues if used correctly
public static NBT encode(PositionSource source, ClientVersion version) {
return encode(source, (PositionSourceType<? super PositionSource>) source.getType(), version);
}

public static <T extends PositionSource> NBT encode(T source, PositionSourceType<T> type, ClientVersion version) {
NBTCompound compound = new NBTCompound();
compound.setTag("type", new NBTString(type.getName().toString()));
type.encode(source, version, compound);
return compound;
}

public PositionSourceType<?> getType() {
return this.type;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@
package com.github.retrooper.packetevents.protocol.world.positionsource;

import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;

public interface PositionSourceType<T extends PositionSource> extends MappedEntity {

T read(PacketWrapper<?> wrapper);

void write(PacketWrapper<?> wrapper, T source);

T decode(NBTCompound compound, ClientVersion version);

void encode(T source, ClientVersion version, NBTCompound compound);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package com.github.retrooper.packetevents.protocol.world.positionsource;

import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.world.positionsource.builtin.BlockPositionSource;
import com.github.retrooper.packetevents.protocol.world.positionsource.builtin.EntityPositionSource;
Expand All @@ -26,6 +27,10 @@
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Reader;
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Writer;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

import java.util.HashMap;
import java.util.Map;
Expand All @@ -36,8 +41,11 @@ public class PositionSourceTypes {
private static final Map<Byte, Map<Integer, PositionSourceType<?>>> POS_SOURCE_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("world/world_position_source_mappings");

@ApiStatus.Internal
public static <T extends PositionSource> PositionSourceType<T> define(
String key, PacketWrapper.Reader<T> reader, PacketWrapper.Writer<T> writer
String key,
Reader<T> reader, Writer<T> writer,
Decoder<T> decoder, Encoder<T> encoder
) {
TypesBuilderData data = TYPES_BUILDER.define(key);
PositionSourceType<T> sourceType = new PositionSourceType<T>() {
Expand All @@ -51,6 +59,16 @@ public void write(PacketWrapper<?> wrapper, T source) {
writer.accept(wrapper, source);
}

@Override
public T decode(NBTCompound compound, ClientVersion version) {
return decoder.decode(compound, version);
}

@Override
public void encode(T source, ClientVersion version, NBTCompound compound) {
encoder.encode(source, version, compound);
}

@Override
public ResourceLocation getName() {
return data.getName();
Expand All @@ -74,6 +92,7 @@ public boolean equals(Object obj) {
}

// with minecraft:key
@Nullable
public static PositionSourceType<?> getByName(String name) {
return POS_SOURCE_MAP.get(name);
}
Expand All @@ -85,11 +104,25 @@ public static PositionSourceType<?> getById(ClientVersion version, int id) {
}

public static final PositionSourceType<BlockPositionSource> BLOCK = define("block",
BlockPositionSource::read, BlockPositionSource::write);
BlockPositionSource::read, BlockPositionSource::write,
BlockPositionSource::decodeSource, BlockPositionSource::encodeSource);
public static final PositionSourceType<EntityPositionSource> ENTITY = define("entity",
EntityPositionSource::read, EntityPositionSource::write);
EntityPositionSource::read, EntityPositionSource::write,
EntityPositionSource::decodeSource, EntityPositionSource::encodeSource);

static {
TYPES_BUILDER.unloadFileMappings();
}

@FunctionalInterface
public interface Decoder<T> {

T decode(NBTCompound compound, ClientVersion version);
}

@FunctionalInterface
public interface Encoder<T> {

void encode(T value, ClientVersion version, NBTCompound compound);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

package com.github.retrooper.packetevents.protocol.world.positionsource.builtin;

import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTIntArray;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.world.positionsource.PositionSource;
import com.github.retrooper.packetevents.protocol.world.positionsource.PositionSourceTypes;
import com.github.retrooper.packetevents.util.Vector3i;
Expand All @@ -40,6 +43,15 @@ public static void write(PacketWrapper<?> wrapper, BlockPositionSource source) {
wrapper.writeBlockPosition(source.pos);
}

public static BlockPositionSource decodeSource(NBTCompound compound, ClientVersion version) {
NBTIntArray arr = compound.getTagOfTypeOrThrow("pos", NBTIntArray.class);
return new BlockPositionSource(new Vector3i(arr.getValue()));
}

public static void encodeSource(BlockPositionSource source, ClientVersion version, NBTCompound compound) {
compound.setTag("pos", new NBTIntArray(new int[]{source.pos.x, source.pos.y, source.pos.z}));
}

public Vector3i getPos() {
return this.pos;
}
Expand Down
Loading

0 comments on commit 97fee0c

Please sign in to comment.