Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@

public class Color implements RGBLike {

public static final Color WHITE = new Color(0xFFFFFFFF);

protected static final int BIT_MASK = 0xFF;

protected final int red, green, blue;
Expand Down Expand Up @@ -75,6 +77,11 @@ public static void writeShort(PacketWrapper<?> wrapper, Color color) {
wrapper.writeByte(color.blue);
}

public static Color decode(NBT nbt, PacketWrapper<?> wrapper) {
return decode(nbt, wrapper.getServerVersion().toClientVersion());
}

@Deprecated
public static Color decode(NBT nbt, ClientVersion version) {
if (nbt instanceof NBTNumber) {
return new Color(((NBTNumber) nbt).getAsInt());
Expand All @@ -86,6 +93,11 @@ public static Color decode(NBT nbt, ClientVersion version) {
return new Color(red, green, blue);
}

public static NBT encode(PacketWrapper<?> wrapper, Color color) {
return encode(color, wrapper.getServerVersion().toClientVersion());
}

@Deprecated
public static NBT encode(Color color, ClientVersion version) {
if (version.isNewerThanOrEquals(ClientVersion.V_1_21_2)) {
return new NBTInt(color.asRGB());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,9 @@ public T getData() {
public void setData(T data) {
this.data = data;
}

@Override
public String toString() {
return "Particle[" + this.type.getName() + ", " + this.data + ']';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.github.retrooper.packetevents.protocol.particle.data;

import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTFloat;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;

/**
* @versions 1.21.9+
*/
@NullMarked
public class ParticlePowerData extends ParticleData {

private float power;

public ParticlePowerData(float power) {
this.power = power;
}

public static ParticlePowerData read(PacketWrapper<?> wrapper) {
float power = wrapper.getServerVersion().isOlderThan(ServerVersion.V_1_21_9) ? 1f : wrapper.readFloat();
return new ParticlePowerData(power);
}

public static void write(PacketWrapper<?> wrapper, ParticlePowerData data) {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_9)) {
wrapper.writeFloat(data.power);
}
}

@ApiStatus.Internal
public static ParticlePowerData decode(NBTCompound tag, ClientVersion version) {
float power = tag.getNumberTagValueOrDefault("power", 1f).floatValue();
return new ParticlePowerData(power);
}

@ApiStatus.Internal
public static void encode(ParticlePowerData data, ClientVersion version, NBTCompound tag) {
if (version.isNewerThanOrEquals(ClientVersion.V_1_21_9) && data.power != 1f) {
tag.setTag("power", new NBTFloat(data.power));
}
}

@Override
public boolean isEmpty() {
return false;
}

public float getPower() {
return this.power;
}

public void setPower(float power) {
this.power = power;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.github.retrooper.packetevents.protocol.particle.data;

import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.color.Color;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTFloat;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;

/**
* @version 1.21.9+
*/
@NullMarked
public class ParticleSpellData extends ParticleData {

private Color color;
private float power;

public ParticleSpellData(Color color, float power) {
this.color = color;
this.power = power;
}

public static ParticleSpellData read(PacketWrapper<?> wrapper) {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_9)) {
Color color = Color.read(wrapper);
float power = wrapper.readFloat();
return new ParticleSpellData(color, power);
}
return new ParticleSpellData(Color.WHITE, 1f);
}

public static void write(PacketWrapper<?> wrapper, ParticleSpellData data) {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_9)) {
Color.write(wrapper, data.color);
wrapper.writeFloat(data.power);
}
}

@ApiStatus.Internal
public static ParticleSpellData decode(NBTCompound compound, ClientVersion version) {
Color color = compound.getOr("color", Color::decode, Color.WHITE, null);
float power = compound.getNumberTagValueOrDefault("power", 1f).floatValue();
return new ParticleSpellData(color, power);
}

@ApiStatus.Internal
public static void encode(ParticleSpellData data, ClientVersion version, NBTCompound compound) {
if (version.isNewerThanOrEquals(ClientVersion.V_1_21_9)) {
if (!Color.WHITE.equals(data.color)) {
compound.setTag("color", Color.encode(data.color, version));
}
if (data.power != 1f) {
compound.setTag("power", new NBTFloat(data.power));
}
}
}

@Override
public boolean isEmpty() {
return false;
}

public Color getColor() {
return this.color;
}

public void setColor(Color color) {
this.color = color;
}

public float getPower() {
return this.power;
}

public void setPower(float power) {
this.power = power;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,18 @@

package com.github.retrooper.packetevents.protocol.particle.type;

import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleBlockStateData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleColorData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleDustColorTransitionData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleDustData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleItemStackData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticlePowerData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleSculkChargeData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleShriekData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleSpellData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleTrailData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleVibrationData;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
Expand Down Expand Up @@ -102,7 +105,9 @@ public static ParticleType<?> getById(ClientVersion version, int id) {
public static final ParticleType<ParticleData> CLOUD = define("cloud");
public static final ParticleType<ParticleData> CRIT = define("crit");
public static final ParticleType<ParticleData> DAMAGE_INDICATOR = define("damage_indicator");
public static final ParticleType<ParticleData> DRAGON_BREATH = define("dragon_breath");
public static final ParticleType<ParticlePowerData> DRAGON_BREATH = define("dragon_breath",
ParticlePowerData::read, ParticlePowerData::write,
ParticlePowerData::decode, ParticlePowerData::encode);
public static final ParticleType<ParticleData> DRIPPING_LAVA = define("dripping_lava");
public static final ParticleType<ParticleData> FALLING_LAVA = define("falling_lava");
public static final ParticleType<ParticleData> LANDING_LAVA = define("landing_lava");
Expand All @@ -114,7 +119,9 @@ public static ParticleType<?> getById(ClientVersion version, int id) {
public static final ParticleType<ParticleDustColorTransitionData> DUST_COLOR_TRANSITION = define("dust_color_transition",
ParticleDustColorTransitionData::read, ParticleDustColorTransitionData::write,
ParticleDustColorTransitionData::decode, ParticleDustColorTransitionData::encode);
public static final ParticleType<ParticleData> EFFECT = define("effect");
public static final ParticleType<ParticleSpellData> EFFECT = define("effect",
ParticleSpellData::read, ParticleSpellData::write,
ParticleSpellData::decode, ParticleSpellData::encode);
public static final ParticleType<ParticleData> ELDER_GUARDIAN = define("elder_guardian");
public static final ParticleType<ParticleData> ENCHANTED_HIT = define("enchanted_hit");
public static final ParticleType<ParticleData> ENCHANT = define("enchant");
Expand All @@ -138,11 +145,33 @@ public static ParticleType<?> getById(ClientVersion version, int id) {
public static final ParticleType<ParticleData> SCULK_CHARGE_POP = define("sculk_charge_pop");
public static final ParticleType<ParticleData> SOUL_FIRE_FLAME = define("soul_fire_flame");
public static final ParticleType<ParticleData> SOUL = define("soul");
public static final ParticleType<ParticleData> FLASH = define("flash");
// TODO this is horrible
public static final ParticleType<ParticleColorData> FLASH = define("flash",
wrapper -> {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_9)) {
return ParticleColorData.read(wrapper);
}
return new ParticleColorData(0);
}, (wrapper, data) -> {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_9)) {
ParticleColorData.write(wrapper, data);
}
}, (compound, version) -> {
if (version.isNewerThanOrEquals(ClientVersion.V_1_21_9)) {
return ParticleColorData.decode(compound, version);
}
return new ParticleColorData(0);
}, (data, version, compound) -> {
if (version.isNewerThanOrEquals(ClientVersion.V_1_21_9)) {
ParticleColorData.encode(data, version, compound);
}
});
public static final ParticleType<ParticleData> HAPPY_VILLAGER = define("happy_villager");
public static final ParticleType<ParticleData> COMPOSTER = define("composter");
public static final ParticleType<ParticleData> HEART = define("heart");
public static final ParticleType<ParticleData> INSTANT_EFFECT = define("instant_effect");
public static final ParticleType<ParticleSpellData> INSTANT_EFFECT = define("instant_effect",
ParticleSpellData::read, ParticleSpellData::write,
ParticleSpellData::decode, ParticleSpellData::encode);
public static final ParticleType<ParticleItemStackData> ITEM = define("item",
ParticleItemStackData::read, ParticleItemStackData::write,
ParticleItemStackData::decode, ParticleItemStackData::encode);
Expand Down