Fix particle data codec

This commit is contained in:
2026-09-11 11:37:57 +08:00
parent 8b23fd4383
commit 8fbc2406ac
12 files changed
+211 -112

No files matched your search

+1
View File
@@ -52,3 +52,4 @@ bin/
/libmc-protocol-context/src/commonTest/resources/accessToken.txt /libmc-protocol-context/src/commonTest/resources/accessToken.txt
/libmc-protocol/src/commonTest/resources/accessToken.txt /libmc-protocol/src/commonTest/resources/accessToken.txt
/libmc-protocol/src/cinterop/generated_defs/ /libmc-protocol/src/cinterop/generated_defs/
/scritps/registries.json
@@ -19,6 +19,11 @@ public interface Decoder<out T> {
public interface PacketCodec<T> : Encoder<T>, Decoder<T> public interface PacketCodec<T> : Encoder<T>, Decoder<T>
public abstract class EmptyPacketCodec<T>(private val instance: T) : PacketCodec<T> {
override fun encode(buffer: BytesBuffer, value: T) {}
override fun decode(buffer: BytesBuffer): T = instance
}
public fun BytesBuffer.writeBuffer(source: BytesBuffer, length: Int = source.size) { public fun BytesBuffer.writeBuffer(source: BytesBuffer, length: Int = source.size) {
if (length <= 0) return if (length <= 0) return
val bytes = source.readBytes(length) val bytes = source.readBytes(length)
@@ -12,21 +12,21 @@ import cn.rtast.libmc.packet.MinecraftPacket
import cn.rtast.libmc.packet.PacketCodec import cn.rtast.libmc.packet.PacketCodec
import cn.rtast.libmc.primitives.readPrefixed import cn.rtast.libmc.primitives.readPrefixed
import cn.rtast.libmc.primitives.readVarInt import cn.rtast.libmc.primitives.readVarInt
import cn.rtast.libmc.protocol.protocol.game.item.slot.Slot import cn.rtast.libmc.protocol.protocol.game.item.slot.ItemStack
import cn.rtast.libmc.protocol.protocol.game.item.slot.readSlot import cn.rtast.libmc.protocol.protocol.game.item.slot.readItemStack
public data class ClientboundContainerSetContentPacket( public data class ClientboundContainerSetContentPacket(
val windowId: Int, val windowId: Int,
val stateId: Int, val stateId: Int,
val slotData: List<Slot>, val itemStackData: List<ItemStack>,
val carriedItem: Slot?, val carriedItem: ItemStack?,
) : MinecraftPacket { ) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundContainerSetContentPacket> { internal companion object Codec : PacketCodec<ClientboundContainerSetContentPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundContainerSetContentPacket) {} override fun encode(buffer: BytesBuffer, value: ClientboundContainerSetContentPacket) {}
override fun decode(buffer: BytesBuffer): ClientboundContainerSetContentPacket { override fun decode(buffer: BytesBuffer): ClientboundContainerSetContentPacket {
val windowId = buffer.readVarInt() val windowId = buffer.readVarInt()
val stateId = buffer.readVarInt() val stateId = buffer.readVarInt()
val slotData = buffer.readPrefixed { readSlot() } val slotData = buffer.readPrefixed { readItemStack() }
// val carriedItem = buffer.readSlot() // TODO FIX ME // val carriedItem = buffer.readSlot() // TODO FIX ME
return ClientboundContainerSetContentPacket(windowId, stateId, slotData, null) return ClientboundContainerSetContentPacket(windowId, stateId, slotData, null)
} }
@@ -11,14 +11,14 @@ import cn.rtast.libmc.network.BytesBuffer
import cn.rtast.libmc.packet.MinecraftPacket import cn.rtast.libmc.packet.MinecraftPacket
import cn.rtast.libmc.packet.PacketCodec import cn.rtast.libmc.packet.PacketCodec
import cn.rtast.libmc.primitives.readVarInt import cn.rtast.libmc.primitives.readVarInt
import cn.rtast.libmc.protocol.protocol.game.item.slot.Slot import cn.rtast.libmc.protocol.protocol.game.item.slot.ItemStack
import cn.rtast.libmc.protocol.protocol.game.item.slot.readSlot import cn.rtast.libmc.protocol.protocol.game.item.slot.readItemStack
public data class ClientboundContainerSetSlotPacket( public data class ClientboundContainerSetSlotPacket(
val windowId: Int, val windowId: Int,
val stateId: Int, val stateId: Int,
val slot: Short, val slot: Short,
val slotData: Slot, val itemStackData: ItemStack,
) : MinecraftPacket { ) : MinecraftPacket {
internal companion object Codec : PacketCodec<ClientboundContainerSetSlotPacket> { internal companion object Codec : PacketCodec<ClientboundContainerSetSlotPacket> {
override fun encode(buffer: BytesBuffer, value: ClientboundContainerSetSlotPacket) {} override fun encode(buffer: BytesBuffer, value: ClientboundContainerSetSlotPacket) {}
@@ -26,7 +26,7 @@ public data class ClientboundContainerSetSlotPacket(
val windowId = buffer.readVarInt() val windowId = buffer.readVarInt()
val stateId = buffer.readVarInt() val stateId = buffer.readVarInt()
val slot = buffer.readShort() val slot = buffer.readShort()
val slotData = buffer.readSlot() val slotData = buffer.readItemStack()
return ClientboundContainerSetSlotPacket(windowId, stateId, slot, slotData) return ClientboundContainerSetSlotPacket(windowId, stateId, slot, slotData)
} }
} }
@@ -10,14 +10,14 @@ package cn.rtast.libmc.protocol.packet.play.serverbound
import cn.rtast.libmc.network.BytesBuffer import cn.rtast.libmc.network.BytesBuffer
import cn.rtast.libmc.packet.MinecraftPacket import cn.rtast.libmc.packet.MinecraftPacket
import cn.rtast.libmc.packet.PacketCodec import cn.rtast.libmc.packet.PacketCodec
import cn.rtast.libmc.protocol.protocol.game.item.slot.Slot import cn.rtast.libmc.protocol.protocol.game.item.slot.ItemStack
import cn.rtast.libmc.protocol.protocol.game.item.slot.writeSlot import cn.rtast.libmc.protocol.protocol.game.item.slot.writeItemStack
public data class ServerboundSetCreativeModeSlotPacket(val slot: Short, val clickedItem: Slot) : MinecraftPacket { public data class ServerboundSetCreativeModeSlotPacket(val slot: Short, val clickedItem: ItemStack) : MinecraftPacket {
internal companion object Codec : PacketCodec<ServerboundSetCreativeModeSlotPacket> { internal companion object Codec : PacketCodec<ServerboundSetCreativeModeSlotPacket> {
override fun encode(buffer: BytesBuffer, value: ServerboundSetCreativeModeSlotPacket) { override fun encode(buffer: BytesBuffer, value: ServerboundSetCreativeModeSlotPacket) {
buffer.writeShort(value.slot) buffer.writeShort(value.slot)
buffer.writeSlot(value.clickedItem) buffer.writeItemStack(value.clickedItem)
} }
override fun decode(buffer: BytesBuffer): ServerboundSetCreativeModeSlotPacket = override fun decode(buffer: BytesBuffer): ServerboundSetCreativeModeSlotPacket =
@@ -25,9 +25,9 @@ import cn.rtast.libmc.protocol.protocol.game.entity.*
import cn.rtast.libmc.protocol.protocol.game.item.ItemUseAnimation import cn.rtast.libmc.protocol.protocol.game.item.ItemUseAnimation
import cn.rtast.libmc.protocol.protocol.game.item.PaintingVariantType import cn.rtast.libmc.protocol.protocol.game.item.PaintingVariantType
import cn.rtast.libmc.protocol.protocol.game.item.readPaintingVariantType import cn.rtast.libmc.protocol.protocol.game.item.readPaintingVariantType
import cn.rtast.libmc.protocol.protocol.game.item.slot.Slot import cn.rtast.libmc.protocol.protocol.game.item.slot.ItemStack
import cn.rtast.libmc.protocol.protocol.game.item.slot.readSlot import cn.rtast.libmc.protocol.protocol.game.item.slot.readItemStack
import cn.rtast.libmc.protocol.protocol.game.item.slot.writeSlot import cn.rtast.libmc.protocol.protocol.game.item.slot.writeItemStack
import cn.rtast.libmc.protocol.protocol.game.item.writePaintingVariantType import cn.rtast.libmc.protocol.protocol.game.item.writePaintingVariantType
import cn.rtast.libmc.protocol.protocol.game.potion.* import cn.rtast.libmc.protocol.protocol.game.potion.*
import cn.rtast.libmc.protocol.protocol.game.readIdentifier import cn.rtast.libmc.protocol.protocol.game.readIdentifier
@@ -335,14 +335,14 @@ public sealed interface DataComponent {
} }
} }
public data class UseRemainderComponent(val remainder: Slot) : DataComponent { public data class UseRemainderComponent(val remainder: ItemStack) : DataComponent {
internal companion object Codec : PacketCodec<UseRemainderComponent> { internal companion object Codec : PacketCodec<UseRemainderComponent> {
override fun encode(buffer: BytesBuffer, value: UseRemainderComponent) { override fun encode(buffer: BytesBuffer, value: UseRemainderComponent) {
buffer.writeSlot(value.remainder) buffer.writeItemStack(value.remainder)
} }
override fun decode(buffer: BytesBuffer): UseRemainderComponent = override fun decode(buffer: BytesBuffer): UseRemainderComponent =
UseRemainderComponent(buffer.readSlot()) UseRemainderComponent(buffer.readItemStack())
} }
} }
@@ -722,25 +722,25 @@ public sealed interface DataComponent {
} }
} }
public data class ChargedProjectilesComponent(val projectiles: List<Slot>) : DataComponent { public data class ChargedProjectilesComponent(val projectiles: List<ItemStack>) : DataComponent {
internal companion object Codec : PacketCodec<ChargedProjectilesComponent> { internal companion object Codec : PacketCodec<ChargedProjectilesComponent> {
override fun encode(buffer: BytesBuffer, value: ChargedProjectilesComponent) { override fun encode(buffer: BytesBuffer, value: ChargedProjectilesComponent) {
buffer.writePrefixed(value.projectiles) { writeSlot(it) } buffer.writePrefixed(value.projectiles) { writeItemStack(it) }
} }
override fun decode(buffer: BytesBuffer): ChargedProjectilesComponent = override fun decode(buffer: BytesBuffer): ChargedProjectilesComponent =
ChargedProjectilesComponent(buffer.readPrefixed { readSlot() }) ChargedProjectilesComponent(buffer.readPrefixed { readItemStack() })
} }
} }
public data class BundleContentsComponent(val items: List<Slot>) : DataComponent { public data class BundleContentsComponent(val items: List<ItemStack>) : DataComponent {
internal companion object Codec : PacketCodec<BundleContentsComponent> { internal companion object Codec : PacketCodec<BundleContentsComponent> {
override fun encode(buffer: BytesBuffer, value: BundleContentsComponent) { override fun encode(buffer: BytesBuffer, value: BundleContentsComponent) {
buffer.writePrefixed(value.items) { writeSlot(it) } buffer.writePrefixed(value.items) { writeItemStack(it) }
} }
override fun decode(buffer: BytesBuffer): BundleContentsComponent = override fun decode(buffer: BytesBuffer): BundleContentsComponent =
BundleContentsComponent(buffer.readPrefixed { readSlot() }) BundleContentsComponent(buffer.readPrefixed { readItemStack() })
} }
} }
@@ -1257,14 +1257,14 @@ public sealed interface DataComponent {
} }
} }
public data class ContainerComponent(val items: List<Slot>) : DataComponent { public data class ContainerComponent(val items: List<ItemStack>) : DataComponent {
internal companion object Codec : PacketCodec<ContainerComponent> { internal companion object Codec : PacketCodec<ContainerComponent> {
override fun encode(buffer: BytesBuffer, value: ContainerComponent) { override fun encode(buffer: BytesBuffer, value: ContainerComponent) {
buffer.writePrefixed(value.items) { writeSlot(it) } buffer.writePrefixed(value.items) { writeItemStack(it) }
} }
override fun decode(buffer: BytesBuffer): ContainerComponent { override fun decode(buffer: BytesBuffer): ContainerComponent {
return ContainerComponent(buffer.readPrefixed { readSlot() }) return ContainerComponent(buffer.readPrefixed { readItemStack() })
} }
} }
} }
@@ -1341,14 +1341,14 @@ public sealed interface DataComponent {
} }
} }
public data class SulfurCubeContentComponent(val content: Slot) : DataComponent { public data class SulfurCubeContentComponent(val content: ItemStack) : DataComponent {
internal companion object Codec : PacketCodec<SulfurCubeContentComponent> { internal companion object Codec : PacketCodec<SulfurCubeContentComponent> {
override fun encode(buffer: BytesBuffer, value: SulfurCubeContentComponent) { override fun encode(buffer: BytesBuffer, value: SulfurCubeContentComponent) {
buffer.writeSlot(value.content) buffer.writeItemStack(value.content)
} }
override fun decode(buffer: BytesBuffer): SulfurCubeContentComponent = override fun decode(buffer: BytesBuffer): SulfurCubeContentComponent =
SulfurCubeContentComponent(buffer.readSlot()) SulfurCubeContentComponent(buffer.readItemStack())
} }
} }
@@ -14,9 +14,7 @@ import cn.rtast.libmc.protocol.protocol.game.data.component.DataComponent
import cn.rtast.libmc.protocol.registry.readDataComponent import cn.rtast.libmc.protocol.registry.readDataComponent
import cn.rtast.libmc.protocol.registry.writeDataComponent import cn.rtast.libmc.protocol.registry.writeDataComponent
public typealias ItemStack = Slot public data class ItemStack(
public data class Slot(
val count: Int, val count: Int,
val itemId: Int?, val itemId: Int?,
val componentsToAdd: List<DataComponent>, val componentsToAdd: List<DataComponent>,
@@ -25,13 +23,13 @@ public data class Slot(
val isEmpty: Boolean get() = count <= 0 val isEmpty: Boolean get() = count <= 0
public companion object { public companion object {
public val EMPTY: Slot = Slot(0, null, emptyList(), emptyList()) public val EMPTY: ItemStack = ItemStack(0, null, emptyList(), emptyList())
} }
} }
internal fun BytesBuffer.readSlot(): Slot { internal fun BytesBuffer.readItemStack(): ItemStack {
val count = readVarInt() val count = readVarInt()
if (count <= 0) return Slot.EMPTY if (count <= 0) return ItemStack.EMPTY
val itemId = readVarInt() val itemId = readVarInt()
val addCount = readVarInt() val addCount = readVarInt()
val removeCount = readVarInt() val removeCount = readVarInt()
@@ -42,18 +40,18 @@ internal fun BytesBuffer.readSlot(): Slot {
} }
val componentsToRemove = ArrayList<Int>(removeCount) val componentsToRemove = ArrayList<Int>(removeCount)
repeat(removeCount) { componentsToRemove.add(readVarInt()) } repeat(removeCount) { componentsToRemove.add(readVarInt()) }
return Slot(count, itemId, componentsToAdd, componentsToRemove) return ItemStack(count, itemId, componentsToAdd, componentsToRemove)
} }
internal fun BytesBuffer.writeSlot(slot: Slot) { internal fun BytesBuffer.writeItemStack(itemStack: ItemStack) {
if (slot.isEmpty || slot.itemId == null) { if (itemStack.isEmpty || itemStack.itemId == null) {
writeVarInt(0) writeVarInt(0)
return return
} }
writeVarInt(slot.count) writeVarInt(itemStack.count)
writeVarInt(slot.itemId) writeVarInt(itemStack.itemId)
writeVarInt(slot.componentsToAdd.size) writeVarInt(itemStack.componentsToAdd.size)
writeVarInt(slot.componentsToRemove.size) writeVarInt(itemStack.componentsToRemove.size)
for (component in slot.componentsToAdd) writeDataComponent(component) for (component in itemStack.componentsToAdd) writeDataComponent(component)
for (typeId in slot.componentsToRemove) writeVarInt(typeId) for (typeId in itemStack.componentsToRemove) writeVarInt(typeId)
} }
@@ -13,6 +13,8 @@ import cn.rtast.libmc.protocol.protocol.game.block.BlockPos
import cn.rtast.libmc.protocol.protocol.game.block.readBlockPos import cn.rtast.libmc.protocol.protocol.game.block.readBlockPos
import cn.rtast.libmc.protocol.protocol.game.color.Color24 import cn.rtast.libmc.protocol.protocol.game.color.Color24
import cn.rtast.libmc.protocol.protocol.game.color.readColor24 import cn.rtast.libmc.protocol.protocol.game.color.readColor24
import cn.rtast.libmc.protocol.protocol.game.item.slot.ItemStack
import cn.rtast.libmc.protocol.protocol.game.item.slot.readItemStack
import cn.rtast.libmc.protocol.protocol.game.math.Vec3d import cn.rtast.libmc.protocol.protocol.game.math.Vec3d
import cn.rtast.libmc.protocol.protocol.game.math.readVec3d import cn.rtast.libmc.protocol.protocol.game.math.readVec3d
@@ -40,18 +42,7 @@ public sealed interface ParticleData {
public data class Trail(val position: Vec3d, val color: Color24, val durationTicks: Int) : ParticleData public data class Trail(val position: Vec3d, val color: Color24, val durationTicks: Int) : ParticleData
public data class Shriek(val delay: Int) : ParticleData public data class Shriek(val delay: Int) : ParticleData
public data class Item(val slot: ByteArray) : ParticleData { public data class Item(val itemStack: ItemStack) : ParticleData
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false
other as Item
return slot.contentEquals(other.slot)
}
override fun hashCode(): Int {
return slot.contentHashCode()
}
}
} }
internal fun BytesBuffer.readParticleData(type: ParticleType): ParticleData { internal fun BytesBuffer.readParticleData(type: ParticleType): ParticleData {
@@ -151,14 +142,14 @@ internal fun BytesBuffer.readParticleData(type: ParticleType): ParticleData {
ParticleType.SCRAPE, ParticleType.SCRAPE,
ParticleType.EGG_CRACK, ParticleType.EGG_CRACK,
ParticleType.DUST_PLUME, ParticleType.DUST_PLUME,
ParticleType.TRIAL_SPAWNER_DETECTED_PLAYER,
ParticleType.TRIAL_SPAWNER_DETECTED_PLAYER_OMINOUS,
ParticleType.VAULT_CONNECTION, ParticleType.VAULT_CONNECTION,
ParticleType.OMINOUS_SPAWNING, ParticleType.OMINOUS_SPAWNING,
ParticleType.RAID_OMEN, ParticleType.RAID_OMEN,
ParticleType.TRIAL_OMEN, ParticleType.TRIAL_OMEN,
ParticleType.FIREFLY, ParticleType.FIREFLY,
ParticleType.SULFUR_CUBE_GOO, ParticleType.SULFUR_CUBE_GOO,
ParticleType.TRIAL_SPAWNER_DETECTION,
ParticleType.TRIAL_SPAWNER_DETECTION_OMINOUS,
-> ParticleData.Empty -> ParticleData.Empty
ParticleType.BLOCK, ParticleType.BLOCK,
@@ -191,8 +182,7 @@ internal fun BytesBuffer.readParticleData(type: ParticleType): ParticleData {
ParticleType.INSTANT_EFFECT, ParticleType.INSTANT_EFFECT,
-> ParticleData.Effect(this.readColor24(), this.readFloat()) -> ParticleData.Effect(this.readColor24(), this.readFloat())
// slot parsed as raw bytearray ParticleType.ITEM -> ParticleData.Item(readItemStack())
ParticleType.ITEM -> ParticleData.Item(this.toByteArray())
ParticleType.VIBRATION -> { ParticleType.VIBRATION -> {
val source = when (val sourceTypeId = this.readVarInt()) { val source = when (val sourceTypeId = this.readVarInt()) {
0 -> ParticleData.Vibration.VibrationSource.Block(this.readBlockPos()) 0 -> ParticleData.Vibration.VibrationSource.Block(this.readBlockPos())
@@ -7,56 +7,135 @@
package cn.rtast.libmc.protocol.protocol.game.particle package cn.rtast.libmc.protocol.protocol.game.particle
import cn.rtast.libmc.protocol.protocol.game.Identifier public enum class ParticleType {
ANGRY_VILLAGER,
public enum class ParticleType(public val id: Int, public val key: String) { BLOCK,
ANGRY_VILLAGER(0, "angry_villager"), BLOCK(1, "block"), BLOCK_MARKER(2, "block_marker"), BLOCK_MARKER,
BUBBLE(3, "bubble"), SULFUR_BUBBLES(4, "sulfur_bubbles"), NOXIOUS_GAS(5, "noxious_gas"), BUBBLE,
NOXIOUS_GAS_CLOUD(6, "noxious_gas_cloud"), GEYSER(7, "geyser"), GEYSER_BASE(8, "geyser_base"), SULFUR_BUBBLES,
GEYSER_POOF(9, "geyser_poof"), GEYSER_PLUME(10, "geyser_plume"), CLOUD(11, "cloud"), NOXIOUS_GAS,
COPPER_FIRE_FLAME(12, "copper_fire_flame"), CRIT(13, "crit"), DAMAGE_INDICATOR(14, "damage_indicator"), NOXIOUS_GAS_CLOUD,
DRAGON_BREATH(15, "dragon_breath"), DRIPPING_LAVA(16, "dripping_lava"), FALLING_LAVA(17, "falling_lava"), GEYSER,
LANDING_LAVA(18, "landing_lava"), DRIPPING_WATER(19, "dripping_water"), FALLING_WATER(20, "falling_water"), GEYSER_BASE,
DUST(21, "dust"), DUST_COLOR_TRANSITION(22, "dust_color_transition"), EFFECT(23, "effect"), GEYSER_POOF,
ELDER_GUARDIAN(24, "elder_guardian"), ENCHANTED_HIT(25, "enchanted_hit"), ENCHANT(26, "enchant"), GEYSER_PLUME,
END_ROD(27, "end_rod"), ENTITY_EFFECT(28, "entity_effect"), EXPLOSION_EMITTER(29, "explosion_emitter"), CLOUD,
EXPLOSION(30, "explosion"), GUST(31, "gust"), SMALL_GUST(32, "small_gust"), COPPER_FIRE_FLAME,
GUST_EMITTER_LARGE(33, "gust_emitter_large"), GUST_EMITTER_SMALL(34, "gust_emitter_small"), CRIT,
SONIC_BOOM(35, "sonic_boom"), FALLING_DUST(36, "falling_dust"), FIREWORK(37, "firework"), FISHING(38, "fishing"), DAMAGE_INDICATOR,
FLAME(39, "flame"), INFESTED(40, "infested"), CHERRY_LEAVES(41, "cherry_leaves"), DRAGON_BREATH,
PALE_OAK_LEAVES(42, "pale_oak_leaves"), TINTED_LEAVES(43, "tinted_leaves"), SCULK_SOUL(44, "sculk_soul"), DRIPPING_LAVA,
SCULK_CHARGE(45, "sculk_charge"), SCULK_CHARGE_POP(46, "sculk_charge_pop"), SOUL_FIRE_FLAME(47, "soul_fire_flame"), FALLING_LAVA,
SOUL(48, "soul"), FLASH(49, "flash"), HAPPY_VILLAGER(50, "happy_villager"), COMPOSTER(51, "composter"), LANDING_LAVA,
HEART(52, "heart"), INSTANT_EFFECT(53, "instant_effect"), ITEM(54, "item"), VIBRATION(55, "vibration"), DRIPPING_WATER,
TRAIL(56, "trail"), PAUSE_MOB_GROWTH(57, "pause_mob_growth"), RESET_MOB_GROWTH(58, "reset_mob_growth"), FALLING_WATER,
ITEM_SLIME(59, "item_slime"), ITEM_COBWEB(60, "item_cobweb"), ITEM_SNOWBALL(61, "item_snowball"), DUST,
LARGE_SMOKE(62, "large_smoke"), LAVA(63, "lava"), MYCELIUM(64, "mycelium"), NOTE(65, "note"), POOF(66, "poof"), DUST_COLOR_TRANSITION,
PORTAL(67, "portal"), RAIN(68, "rain"), SMOKE(69, "smoke"), WHITE_SMOKE(70, "white_smoke"), SNEEZE(71, "sneeze"), EFFECT,
SPIT(72, "spit"), SQUID_INK(73, "squid_ink"), SWEEP_ATTACK(74, "sweep_attack"), ELDER_GUARDIAN,
TOTEM_OF_UNDYING(75, "totem_of_undying"), UNDERWATER(76, "underwater"), SPLASH(77, "splash"), WITCH(78, "witch"), ENCHANTED_HIT,
BUBBLE_POP(79, "bubble_pop"), CURRENT_DOWN(80, "current_down"), BUBBLE_COLUMN_UP(81, "bubble_column_up"), ENCHANT,
NAUTILUS(82, "nautilus"), DOLPHIN(83, "dolphin"), CAMPFIRE_COSY_SMOKE(84, "campfire_cosy_smoke"), END_ROD,
CAMPFIRE_SIGNAL_SMOKE(85, "campfire_signal_smoke"), DRIPPING_HONEY(86, "dripping_honey"), ENTITY_EFFECT,
FALLING_HONEY(87, "falling_honey"), LANDING_HONEY(88, "landing_honey"), FALLING_NECTAR(89, "falling_nectar"), EXPLOSION_EMITTER,
FALLING_SPORE_BLOSSOM(90, "falling_spore_blossom"), ASH(91, "ash"), CRIMSON_SPORE(92, "crimson_spore"), EXPLOSION,
WARPED_SPORE(93, "warped_spore"), SPORE_BLOSSOM_AIR(94, "spore_blossom_air"), GUST,
DRIPPING_OBSIDIAN_TEAR(95, "dripping_obsidian_tear"), FALLING_OBSIDIAN_TEAR(96, "falling_obsidian_tear"), SMALL_GUST,
LANDING_OBSIDIAN_TEAR(97, "landing_obsidian_tear"), REVERSE_PORTAL(98, "reverse_portal"), GUST_EMITTER_LARGE,
WHITE_ASH(99, "white_ash"), SMALL_FLAME(100, "small_flame"), SNOWFLAKE(101, "snowflake"), GUST_EMITTER_SMALL,
DRIPPING_DRIPSTONE_LAVA(102, "dripping_dripstone_lava"), FALLING_DRIPSTONE_LAVA(103, "falling_dripstone_lava"), SONIC_BOOM,
DRIPPING_DRIPSTONE_WATER(104, "dripping_dripstone_water"), FALLING_DRIPSTONE_WATER(105, "falling_dripstone_water"), FALLING_DUST,
GLOW_SQUID_INK(106, "glow_squid_ink"), GLOW(107, "glow"), WAX_ON(108, "wax_on"), WAX_OFF(109, "wax_off"), FIREWORK,
ELECTRIC_SPARK(110, "electric_spark"), SCRAPE(111, "scrape"), SHRIEK(112, "shriek"), EGG_CRACK(113, "egg_crack"), FISHING,
DUST_PLUME(114, "dust_plume"), TRIAL_SPAWNER_DETECTED_PLAYER(115, "trial_spawner_detection"), FLAME,
TRIAL_SPAWNER_DETECTED_PLAYER_OMINOUS(116, "trial_spawner_detection_ominous"), INFESTED,
VAULT_CONNECTION(117, "vault_connection"), DUST_PILLAR(118, "dust_pillar"), CHERRY_LEAVES,
OMINOUS_SPAWNING(119, "ominous_spawning"), RAID_OMEN(120, "raid_omen"), TRIAL_OMEN(121, "trial_omen"), PALE_OAK_LEAVES,
BLOCK_CRUMBLE(122, "block_crumble"), FIREFLY(123, "firefly"), SULFUR_CUBE_GOO(124, "sulfur_cube_goo"); TINTED_LEAVES,
SCULK_SOUL,
public val identifier: Identifier = Identifier.of("minecraft", key) SCULK_CHARGE,
SCULK_CHARGE_POP,
SOUL_FIRE_FLAME,
SOUL,
FLASH,
HAPPY_VILLAGER,
COMPOSTER,
HEART,
INSTANT_EFFECT,
ITEM,
VIBRATION,
TRAIL,
PAUSE_MOB_GROWTH,
RESET_MOB_GROWTH,
ITEM_SLIME,
ITEM_COBWEB,
ITEM_SNOWBALL,
LARGE_SMOKE,
LAVA,
MYCELIUM,
NOTE,
POOF,
PORTAL,
RAIN,
SMOKE,
WHITE_SMOKE,
SNEEZE,
SPIT,
SQUID_INK,
SWEEP_ATTACK,
TOTEM_OF_UNDYING,
UNDERWATER,
SPLASH,
WITCH,
BUBBLE_POP,
CURRENT_DOWN,
BUBBLE_COLUMN_UP,
NAUTILUS,
DOLPHIN,
CAMPFIRE_COSY_SMOKE,
CAMPFIRE_SIGNAL_SMOKE,
DRIPPING_HONEY,
FALLING_HONEY,
LANDING_HONEY,
FALLING_NECTAR,
FALLING_SPORE_BLOSSOM,
ASH,
CRIMSON_SPORE,
WARPED_SPORE,
SPORE_BLOSSOM_AIR,
DRIPPING_OBSIDIAN_TEAR,
FALLING_OBSIDIAN_TEAR,
LANDING_OBSIDIAN_TEAR,
REVERSE_PORTAL,
WHITE_ASH,
SMALL_FLAME,
SNOWFLAKE,
DRIPPING_DRIPSTONE_LAVA,
FALLING_DRIPSTONE_LAVA,
DRIPPING_DRIPSTONE_WATER,
FALLING_DRIPSTONE_WATER,
GLOW_SQUID_INK,
GLOW,
WAX_ON,
WAX_OFF,
ELECTRIC_SPARK,
SCRAPE,
SHRIEK,
EGG_CRACK,
DUST_PLUME,
TRIAL_SPAWNER_DETECTION,
TRIAL_SPAWNER_DETECTION_OMINOUS,
VAULT_CONNECTION,
DUST_PILLAR,
OMINOUS_SPAWNING,
RAID_OMEN,
TRIAL_OMEN,
BLOCK_CRUMBLE,
FIREFLY,
SULFUR_CUBE_GOO;
public companion object { public companion object {
private val CACHED_ID = entries private val CACHED_ID = entries
public fun fromID(id: Int): ParticleType = CACHED_ID.first { it.id == id } public fun fromID(id: Int): ParticleType = CACHED_ID.first { it.ordinal == id }
} }
} }
@@ -9,10 +9,9 @@ package client
import cn.rtast.libmc.crypto.AuthenticationProvider import cn.rtast.libmc.crypto.AuthenticationProvider
import cn.rtast.libmc.protocol.client.createMinecraftClient import cn.rtast.libmc.protocol.client.createMinecraftClient
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundContainerSetContentPacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundContainerSetSlotPacket import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundContainerSetSlotPacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundLevelParticlePacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundPlayerChatMessagePacket import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundPlayerChatMessagePacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundServerDataPacket
import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundStepTickPacket import cn.rtast.libmc.protocol.packet.play.clientbound.ClientboundStepTickPacket
import cn.rtast.libmc.protocol.protocol.session.SessionEvent import cn.rtast.libmc.protocol.protocol.session.SessionEvent
import cn.rtast.libmc.protocol.protocol.session.onEvent import cn.rtast.libmc.protocol.protocol.session.onEvent
@@ -103,6 +102,7 @@ class TestClient {
} }
cli.onPacket<ClientboundPlayerChatMessagePacket> { chatTracker.onReceivePlayerChat(it.messageSignature) } cli.onPacket<ClientboundPlayerChatMessagePacket> { chatTracker.onReceivePlayerChat(it.messageSignature) }
cli.onPacket<ClientboundContainerSetSlotPacket> { println(it) } cli.onPacket<ClientboundContainerSetSlotPacket> { println(it) }
cli.onPacket<ClientboundLevelParticlePacket> { println(it) }
// cli.on { packet, direction -> println("$direction -> $packet") } // cli.on { packet, direction -> println("$direction -> $packet") }
cli.connect() cli.connect()
+26
View File
@@ -0,0 +1,26 @@
import json
import os
path = "./registries.json"
with open(path, "r") as f:
data = json.loads(f.read())["minecraft:particle_type"]
sorted_entries = sorted(
data.get('entries', {}).items(),
key=lambda item: item[1].get('protocol_id', 0)
)
for raw_key, value in sorted_entries:
identifier = raw_key.replace('minecraft:', '', 1)
if ':' in identifier:
parts = identifier.split(':', 1)
name_upper = parts[1].upper()
formatted_name = f"{parts[0]}_{name_upper}"
else:
formatted_name = identifier.upper()
proto_id = value.get('protocol_id')
# print(f"{formatted_name}({proto_id}, \"{raw_key}\"),")
print(f"{formatted_name},")