feat(plugin-api): add java/bedrock abstraction

This commit is contained in:
Alexander Medvedev 2026-05-16 09:56:18 +02:00
parent 5aafff35e8
commit 966fbec3d3
138 changed files with 3613 additions and 1126 deletions

14
Cargo.lock generated
View File

@ -488,7 +488,7 @@ version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34"
dependencies = [
"windows-sys 0.61.2",
"windows-sys 0.52.0",
]
[[package]]
@ -1189,7 +1189,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys 0.61.2",
"windows-sys 0.52.0",
]
[[package]]
@ -2284,7 +2284,7 @@ version = "0.50.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
dependencies = [
"windows-sys 0.61.2",
"windows-sys 0.59.0",
]
[[package]]
@ -3318,7 +3318,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys 0.12.1",
"windows-sys 0.61.2",
"windows-sys 0.52.0",
]
[[package]]
@ -3646,7 +3646,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
dependencies = [
"libc",
"windows-sys 0.61.2",
"windows-sys 0.60.2",
]
[[package]]
@ -3789,7 +3789,7 @@ dependencies = [
"getrandom 0.4.2",
"once_cell",
"rustix 1.1.4",
"windows-sys 0.61.2",
"windows-sys 0.52.0",
]
[[package]]
@ -4938,7 +4938,7 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
"windows-sys 0.61.2",
"windows-sys 0.52.0",
]
[[package]]

View File

@ -183,7 +183,7 @@ wasmtime = "44.0"
wasmtime-wasi = { version = "44.0", default-features = false, features = ["p2"] }
wasmtime-wasi-http = "44.0"
# needed for interacting with wasmtime-wasi-http - keep in sync
hyper = { version = "^1.7", features = ["full"] }
hyper = { version = "^1.9", features = ["full"] }
wit-bindgen = "0.57"
postcard = { version = "1.1", features = ["alloc"] }

View File

@ -3,23 +3,23 @@ use std::{collections::BTreeMap, fs};
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use crate::version::MinecraftVersion;
use crate::version::JavaMinecraftVersion;
/// Generates the `TokenStream` for the `MetaDataType` struct with per-version ID fields and constants.
pub fn build() -> TokenStream {
let assets = [
(MinecraftVersion::V_1_21, "1_21_meta_data_type.json"),
(MinecraftVersion::V_1_21_2, "1_21_2_meta_data_type.json"),
(MinecraftVersion::V_1_21_4, "1_21_4_meta_data_type.json"),
(MinecraftVersion::V_1_21_5, "1_21_5_meta_data_type.json"),
(MinecraftVersion::V_1_21_6, "1_21_6_meta_data_type.json"),
(MinecraftVersion::V_1_21_7, "1_21_7_meta_data_type.json"),
(MinecraftVersion::V_1_21_9, "1_21_9_meta_data_type.json"),
(MinecraftVersion::V_1_21_11, "1_21_11_meta_data_type.json"),
(MinecraftVersion::V_26_1, "26_1_meta_data_type.json"),
(JavaMinecraftVersion::V_1_21, "1_21_meta_data_type.json"),
(JavaMinecraftVersion::V_1_21_2, "1_21_2_meta_data_type.json"),
(JavaMinecraftVersion::V_1_21_4, "1_21_4_meta_data_type.json"),
(JavaMinecraftVersion::V_1_21_5, "1_21_5_meta_data_type.json"),
(JavaMinecraftVersion::V_1_21_6, "1_21_6_meta_data_type.json"),
(JavaMinecraftVersion::V_1_21_7, "1_21_7_meta_data_type.json"),
(JavaMinecraftVersion::V_1_21_9, "1_21_9_meta_data_type.json"),
(JavaMinecraftVersion::V_1_21_11, "1_21_11_meta_data_type.json"),
(JavaMinecraftVersion::V_26_1, "26_1_meta_data_type.json"),
];
let mut handlers_map: BTreeMap<String, BTreeMap<MinecraftVersion, i32>> = BTreeMap::new();
let mut handlers_map: BTreeMap<String, BTreeMap<JavaMinecraftVersion, i32>> = BTreeMap::new();
for &(ver, file) in &assets {
let path = format!("../assets/meta_data_type/{file}");
@ -70,7 +70,7 @@ pub fn build() -> TokenStream {
impl MetaDataType {
#variants
pub const fn id(&self, version: pumpkin_util::version::MinecraftVersion) -> i32 {
pub const fn id(&self, version: pumpkin_util::version::JavaMinecraftVersion) -> i32 {
match version {
#to_id_arms
_ => -1i32,

View File

@ -3,10 +3,10 @@ use quote::{format_ident, quote};
use serde::Deserialize;
use std::{collections::BTreeMap, fs};
use crate::version::MinecraftVersion;
use crate::version::JavaMinecraftVersion;
/// The newest protocol version used as the fallback for unknown versions in `PacketId::to_id`.
const LATEST_VERSION: MinecraftVersion = MinecraftVersion::V_26_1;
const LATEST_VERSION: JavaMinecraftVersion = JavaMinecraftVersion::V_26_1;
/// Raw deserialization shape for a single versioned packet mapping file.
#[derive(Deserialize)]
@ -24,19 +24,19 @@ pub struct Packets {
/// all `serverbound`/`clientbound` packet ID constants.
pub(crate) fn build() -> TokenStream {
let assets = [
(MinecraftVersion::V_1_20_5, "1_20_5_packets.json"),
(MinecraftVersion::V_1_21, "1_21_packets.json"),
(MinecraftVersion::V_1_21_2, "1_21_2_packets.json"),
(MinecraftVersion::V_1_21_4, "1_21_4_packets.json"),
(MinecraftVersion::V_1_21_5, "1_21_5_packets.json"),
(MinecraftVersion::V_1_21_6, "1_21_6_packets.json"),
(MinecraftVersion::V_1_21_7, "1_21_7_packets.json"),
(MinecraftVersion::V_1_21_9, "1_21_9_packets.json"),
(MinecraftVersion::V_1_21_11, "1_21_11_packets.json"),
(MinecraftVersion::V_26_1, "26_1_packets.json"),
(JavaMinecraftVersion::V_1_20_5, "1_20_5_packets.json"),
(JavaMinecraftVersion::V_1_21, "1_21_packets.json"),
(JavaMinecraftVersion::V_1_21_2, "1_21_2_packets.json"),
(JavaMinecraftVersion::V_1_21_4, "1_21_4_packets.json"),
(JavaMinecraftVersion::V_1_21_5, "1_21_5_packets.json"),
(JavaMinecraftVersion::V_1_21_6, "1_21_6_packets.json"),
(JavaMinecraftVersion::V_1_21_7, "1_21_7_packets.json"),
(JavaMinecraftVersion::V_1_21_9, "1_21_9_packets.json"),
(JavaMinecraftVersion::V_1_21_11, "1_21_11_packets.json"),
(JavaMinecraftVersion::V_26_1, "26_1_packets.json"),
];
// Parse available packet files into a BTreeMap keyed by MinecraftVersion
// Parse available packet files into a BTreeMap keyed by JavaMinecraftVersion
let mut versions = BTreeMap::new();
for (ver, file) in assets {
let path = format!("../assets/packet/{file}");
@ -55,10 +55,10 @@ pub(crate) fn build() -> TokenStream {
let clientbound_consts = generate_mapped_consts(&versions, false);
quote!(
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
pub const CURRENT_MC_VERSION: MinecraftVersion = #LATEST_VERSION;
pub const LOWEST_SUPPORTED_MC_VERSION: MinecraftVersion = MinecraftVersion::V_1_20_5;
pub const CURRENT_MC_VERSION: JavaMinecraftVersion = #LATEST_VERSION;
pub const LOWEST_SUPPORTED_MC_VERSION: JavaMinecraftVersion = JavaMinecraftVersion::V_1_20_5;
#packet_id_struct
@ -74,7 +74,7 @@ pub(crate) fn build() -> TokenStream {
}
/// Generate the `PacketId` struct and impls (including `to_id`) dynamically based on available versions.
fn generate_struct<T>(versions: &BTreeMap<MinecraftVersion, T>) -> TokenStream {
fn generate_struct<T>(versions: &BTreeMap<JavaMinecraftVersion, T>) -> TokenStream {
// Build struct fields
let mut struct_fields = TokenStream::new();
for ver in versions.keys() {
@ -104,7 +104,7 @@ fn generate_struct<T>(versions: &BTreeMap<MinecraftVersion, T>) -> TokenStream {
impl PacketId {
/// Converts the requested protocol version into the corresponding packet ID.
/// Returns -1 if the packet does not exist in that version.
pub fn to_id(&self, version: MinecraftVersion) -> i32 {
pub fn to_id(&self, version: JavaMinecraftVersion) -> i32 {
match version {
#match_arms
_ => self.#latest_field_ident,
@ -129,10 +129,10 @@ fn generate_struct<T>(versions: &BTreeMap<MinecraftVersion, T>) -> TokenStream {
/// Generates `PacketId` constants for all packets in either the serverbound or clientbound direction.
///
/// # Arguments
/// - `versions` – Map from `MinecraftVersion` to parsed `Packets` data.
/// - `versions` – Map from `JavaMinecraftVersion` to parsed `Packets` data.
/// - `is_serverbound` – When `true`, emits serverbound constants; otherwise emits clientbound constants.
fn generate_mapped_consts(
versions: &BTreeMap<MinecraftVersion, Packets>,
versions: &BTreeMap<JavaMinecraftVersion, Packets>,
is_serverbound: bool,
) -> TokenStream {
let mut conv_packets = BTreeMap::<_, BTreeMap<_, _>>::new();

View File

@ -4,28 +4,28 @@ use quote::{format_ident, quote};
use serde_json::Value;
use std::fs;
use crate::version::MinecraftVersion;
use crate::version::JavaMinecraftVersion;
/// The newest protocol version whose registry data is used as the fallback for unknown versions.
const LATEST_VERSION: MinecraftVersion = MinecraftVersion::V_26_1;
const LATEST_VERSION: JavaMinecraftVersion = JavaMinecraftVersion::V_26_1;
/// Generates the `TokenStream` for the `Registry` and `StaticRegistry` structs, version-keyed
/// static registry data, and the `Registry::get_synced` method.
pub(crate) fn build() -> TokenStream {
let assets = [
(MinecraftVersion::V_1_20_5, "1_21_synced_registries.json"),
(MinecraftVersion::V_1_21, "1_21_synced_registries.json"),
(MinecraftVersion::V_1_21_2, "1_21_2_synced_registries.json"),
(MinecraftVersion::V_1_21_4, "1_21_4_synced_registries.json"),
(MinecraftVersion::V_1_21_5, "1_21_5_synced_registries.json"),
(MinecraftVersion::V_1_21_6, "1_21_6_synced_registries.json"),
(MinecraftVersion::V_1_21_7, "1_21_7_synced_registries.json"),
(MinecraftVersion::V_1_21_9, "1_21_9_synced_registries.json"),
(JavaMinecraftVersion::V_1_20_5, "1_21_synced_registries.json"),
(JavaMinecraftVersion::V_1_21, "1_21_synced_registries.json"),
(JavaMinecraftVersion::V_1_21_2, "1_21_2_synced_registries.json"),
(JavaMinecraftVersion::V_1_21_4, "1_21_4_synced_registries.json"),
(JavaMinecraftVersion::V_1_21_5, "1_21_5_synced_registries.json"),
(JavaMinecraftVersion::V_1_21_6, "1_21_6_synced_registries.json"),
(JavaMinecraftVersion::V_1_21_7, "1_21_7_synced_registries.json"),
(JavaMinecraftVersion::V_1_21_9, "1_21_9_synced_registries.json"),
(
MinecraftVersion::V_1_21_11,
JavaMinecraftVersion::V_1_21_11,
"1_21_11_synced_registries.json",
),
(MinecraftVersion::V_26_1, "26_1_synced_registries.json"),
(JavaMinecraftVersion::V_26_1, "26_1_synced_registries.json"),
];
let process_version = |path: &str| -> TokenStream {
@ -100,7 +100,7 @@ pub(crate) fn build() -> TokenStream {
quote! {
use pumpkin_util::resource_location::ResourceLocation;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
pub struct StaticRegistryEntry {
pub name: &'static str,
@ -125,7 +125,7 @@ pub(crate) fn build() -> TokenStream {
#static_values
impl Registry {
pub fn get_synced(version: MinecraftVersion) -> Vec<Self> {
pub fn get_synced(version: JavaMinecraftVersion) -> Vec<Self> {
let static_regs = match version {
#match_arms
_ => #latest_registry,

View File

@ -2,59 +2,59 @@ use proc_macro2::{Literal, TokenStream};
use quote::{format_ident, quote};
use crate::remap::{MappingNode, ParsedMappings, Remapper};
use crate::version::MinecraftVersion;
use crate::version::JavaMinecraftVersion;
/// Generates the `TokenStream` for per-version block-state remap tables and the
/// `remap_block_state_for_version` function.
pub fn build() -> TokenStream {
let node_1_20_5 = MappingNode {
version: MinecraftVersion::V_1_20_5,
version: JavaMinecraftVersion::V_1_20_5,
value: "../assets/viaversion/data/mappings-1.20.5to1.21.nbt",
child: None,
};
let node_1_21 = MappingNode {
version: MinecraftVersion::V_1_21,
version: JavaMinecraftVersion::V_1_21,
value: "../assets/viaversion/data/mappings-1.21to1.21.2.nbt",
child: Some(&node_1_20_5),
};
let node_1_21_2 = MappingNode {
version: MinecraftVersion::V_1_21_2,
version: JavaMinecraftVersion::V_1_21_2,
value: "../assets/viaversion/data/mappings-1.21.2to1.21.4.nbt",
child: Some(&node_1_21),
};
let node_1_21_4 = MappingNode {
version: MinecraftVersion::V_1_21_4,
version: JavaMinecraftVersion::V_1_21_4,
value: "../assets/viaversion/data/mappings-1.21.4to1.21.5.nbt",
child: Some(&node_1_21_2),
};
let node_1_21_5 = MappingNode {
version: MinecraftVersion::V_1_21_5,
version: JavaMinecraftVersion::V_1_21_5,
value: "../assets/viaversion/data/mappings-1.21.5to1.21.6.nbt",
child: Some(&node_1_21_4),
};
let node_1_21_6 = MappingNode {
version: MinecraftVersion::V_1_21_6,
version: JavaMinecraftVersion::V_1_21_6,
value: "../assets/viaversion/data/mappings-1.21.6to1.21.7.nbt",
child: Some(&node_1_21_5),
};
let node_1_21_7 = MappingNode {
version: MinecraftVersion::V_1_21_7,
version: JavaMinecraftVersion::V_1_21_7,
value: "../assets/viaversion/data/mappings-1.21.7to1.21.9.nbt",
child: Some(&node_1_21_6),
};
let node_1_21_9 = MappingNode {
version: MinecraftVersion::V_1_21_9,
version: JavaMinecraftVersion::V_1_21_9,
value: "../assets/viaversion/data/mappings-1.21.9to1.21.11.nbt",
child: Some(&node_1_21_7),
};
let node_1_21_11 = MappingNode {
version: MinecraftVersion::V_1_21_11,
version: JavaMinecraftVersion::V_1_21_11,
value: "../assets/viaversion/data/mappings-1.21.11to26.1.nbt",
child: Some(&node_1_21_9),
};
let remapper: Remapper<_, Option<Vec<u16>>> = Remapper {
version: MinecraftVersion::V_26_1,
version: JavaMinecraftVersion::V_26_1,
remapper: |first, second| match (first, second) {
(Some(first), Some(second)) => Some(
first
@ -108,7 +108,7 @@ pub fn build() -> TokenStream {
#static_values
#[must_use]
pub fn remap_block_state_for_version(state_id: u16, version: pumpkin_util::version::MinecraftVersion) -> u16 {
pub fn remap_block_state_for_version(state_id: u16, version: pumpkin_util::version::JavaMinecraftVersion) -> u16 {
match version {
#match_arms
_ => state_id,

View File

@ -2,54 +2,54 @@ use proc_macro2::{Literal, TokenStream};
use quote::{format_ident, quote};
use crate::remap::{MappingNode, ParsedMappings, Remapper};
use crate::version::MinecraftVersion;
use crate::version::JavaMinecraftVersion;
/// Generates the `TokenStream` for per-version entity ID remap tables and the
/// `remap_entity_id_for_version` function.
pub fn build() -> TokenStream {
let node_1_20_5 = MappingNode {
version: MinecraftVersion::V_1_20_5,
version: JavaMinecraftVersion::V_1_20_5,
value: "../assets/viaversion/data/mappings-1.20.5to1.21.nbt",
child: None,
};
let node_1_21 = MappingNode {
version: MinecraftVersion::V_1_21,
version: JavaMinecraftVersion::V_1_21,
value: "../assets/viaversion/data/mappings-1.21to1.21.2.nbt",
child: Some(&node_1_20_5),
};
let node_1_21_2 = MappingNode {
version: MinecraftVersion::V_1_21_2,
version: JavaMinecraftVersion::V_1_21_2,
value: "../assets/viaversion/data/mappings-1.21.2to1.21.4.nbt",
child: Some(&node_1_21),
};
let node_1_21_4 = MappingNode {
version: MinecraftVersion::V_1_21_4,
version: JavaMinecraftVersion::V_1_21_4,
value: "../assets/viaversion/data/mappings-1.21.4to1.21.5.nbt",
child: Some(&node_1_21_2),
};
let node_1_21_5 = MappingNode {
version: MinecraftVersion::V_1_21_5,
version: JavaMinecraftVersion::V_1_21_5,
value: "../assets/viaversion/data/mappings-1.21.5to1.21.6.nbt",
child: Some(&node_1_21_4),
};
let node_1_21_6 = MappingNode {
version: MinecraftVersion::V_1_21_6,
version: JavaMinecraftVersion::V_1_21_6,
value: "../assets/viaversion/data/mappings-1.21.6to1.21.7.nbt",
child: Some(&node_1_21_5),
};
let node_1_21_7 = MappingNode {
version: MinecraftVersion::V_1_21_7,
version: JavaMinecraftVersion::V_1_21_7,
value: "../assets/viaversion/data/mappings-1.21.7to1.21.9.nbt",
child: Some(&node_1_21_6),
};
let node_1_21_9 = MappingNode {
version: MinecraftVersion::V_1_21_9,
version: JavaMinecraftVersion::V_1_21_9,
value: "../assets/viaversion/data/mappings-1.21.9to1.21.11.nbt",
child: Some(&node_1_21_7),
};
let remapper: Remapper<_, Option<Vec<u16>>> = Remapper {
version: MinecraftVersion::V_26_1,
version: JavaMinecraftVersion::V_26_1,
remapper: |first, second| match (first, second) {
(Some(first), Some(second)) => Some(
first
@ -103,7 +103,7 @@ pub fn build() -> TokenStream {
#static_values
#[must_use]
pub fn remap_entity_id_for_version(entity_id: u16, version: pumpkin_util::version::MinecraftVersion) -> u16 {
pub fn remap_entity_id_for_version(entity_id: u16, version: pumpkin_util::version::JavaMinecraftVersion) -> u16 {
match version {
#match_arms
_ => entity_id,

View File

@ -2,7 +2,7 @@ use proc_macro2::{Literal, TokenStream};
use quote::{format_ident, quote};
use crate::remap::{MappingNode, ParsedMappings, Remapper};
use crate::version::MinecraftVersion;
use crate::version::JavaMinecraftVersion;
/// Computes the inverse of an item ID mapping table, mapping new IDs back to old IDs.
///
@ -24,52 +24,52 @@ fn reverse_mapping(mapping: &[u16], mapped_size: usize) -> Vec<u16> {
/// `remap_item_id_for_version`/`remap_item_id_from_version` functions.
pub fn build() -> TokenStream {
let node_1_20_5 = MappingNode {
version: MinecraftVersion::V_1_20_5,
version: JavaMinecraftVersion::V_1_20_5,
value: "../assets/viaversion/data/mappings-1.20.5to1.21.nbt",
child: None,
};
let node_1_21 = MappingNode {
version: MinecraftVersion::V_1_21,
version: JavaMinecraftVersion::V_1_21,
value: "../assets/viaversion/data/mappings-1.21to1.21.2.nbt",
child: Some(&node_1_20_5),
};
let node_1_21_2 = MappingNode {
version: MinecraftVersion::V_1_21_2,
version: JavaMinecraftVersion::V_1_21_2,
value: "../assets/viaversion/data/mappings-1.21.2to1.21.4.nbt",
child: Some(&node_1_21),
};
let node_1_21_4 = MappingNode {
version: MinecraftVersion::V_1_21_4,
version: JavaMinecraftVersion::V_1_21_4,
value: "../assets/viaversion/data/mappings-1.21.4to1.21.5.nbt",
child: Some(&node_1_21_2),
};
let node_1_21_5 = MappingNode {
version: MinecraftVersion::V_1_21_5,
version: JavaMinecraftVersion::V_1_21_5,
value: "../assets/viaversion/data/mappings-1.21.5to1.21.6.nbt",
child: Some(&node_1_21_4),
};
let node_1_21_6 = MappingNode {
version: MinecraftVersion::V_1_21_6,
version: JavaMinecraftVersion::V_1_21_6,
value: "../assets/viaversion/data/mappings-1.21.6to1.21.7.nbt",
child: Some(&node_1_21_5),
};
let node_1_21_7 = MappingNode {
version: MinecraftVersion::V_1_21_7,
version: JavaMinecraftVersion::V_1_21_7,
value: "../assets/viaversion/data/mappings-1.21.7to1.21.9.nbt",
child: Some(&node_1_21_6),
};
let node_1_21_9 = MappingNode {
version: MinecraftVersion::V_1_21_9,
version: JavaMinecraftVersion::V_1_21_9,
value: "../assets/viaversion/data/mappings-1.21.9to1.21.11.nbt",
child: Some(&node_1_21_7),
};
let node_1_21_11 = MappingNode {
version: MinecraftVersion::V_1_21_11,
version: JavaMinecraftVersion::V_1_21_11,
value: "../assets/viaversion/data/mappings-1.21.11to26.1.nbt",
child: Some(&node_1_21_9),
};
let remapper: Remapper<_, Option<Vec<u16>>> = Remapper {
version: MinecraftVersion::V_26_1,
version: JavaMinecraftVersion::V_26_1,
remapper: |first, second| match (first, second) {
(Some(first), Some(second)) => Some(
first
@ -144,12 +144,12 @@ pub fn build() -> TokenStream {
}
quote! {
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
#static_values
#[must_use]
pub fn remap_item_id_for_version(item_id: u16, version: MinecraftVersion) -> u16 {
pub fn remap_item_id_for_version(item_id: u16, version: JavaMinecraftVersion) -> u16 {
match version {
#match_arms_id_for_ver
_ => item_id,
@ -157,7 +157,7 @@ pub fn build() -> TokenStream {
}
#[must_use]
pub fn remap_item_id_from_version(item_id: u16, version: MinecraftVersion) -> u16 {
pub fn remap_item_id_from_version(item_id: u16, version: JavaMinecraftVersion) -> u16 {
match version {
#match_arms_id_from_ver
_ => item_id,

View File

@ -1,7 +1,7 @@
use proc_macro2::TokenStream;
use pumpkin_nbt::compound::NbtCompound;
use crate::version::MinecraftVersion;
use crate::version::JavaMinecraftVersion;
mod block_state;
mod entity_id;
@ -23,7 +23,7 @@ pub fn build() -> Vec<(fn() -> TokenStream, &'static str)> {
/// between consecutive Minecraft versions.
pub struct MappingNode<'a, P> {
/// The Minecraft version this node represents.
pub version: MinecraftVersion,
pub version: JavaMinecraftVersion,
/// The path to (or data of) the ViaVersion NBT mapping file for this version hop.
pub value: P,
/// The previous version node in the chain, or `None` if this is the oldest supported version.
@ -34,7 +34,7 @@ pub struct MappingNode<'a, P> {
/// into per-version translation tables.
pub struct Remapper<P, R> {
/// The target (latest) version that all older mappings are translated toward.
pub version: MinecraftVersion,
pub version: JavaMinecraftVersion,
/// Combines the current-version mapping with a child mapping into a composed mapping.
pub remapper: fn(&R, &R) -> R,
/// Converts the raw path/data `P` stored in a [`MappingNode`] into the mapping type `R`.
@ -45,9 +45,9 @@ impl<P, R> Remapper<P, R> {
/// Recursively processes the [`MappingNode`] chain and returns a list of `(version, mapping)` pairs.
///
/// # Returns
/// A `Vec` where each entry contains a [`MinecraftVersion`] and its composed mapping relative
/// A `Vec` where each entry contains a [`JavaMinecraftVersion`] and its composed mapping relative
/// to `self.version`.
pub fn process(&self, mappings: &MappingNode<'_, P>) -> Vec<(MinecraftVersion, R)> {
pub fn process(&self, mappings: &MappingNode<'_, P>) -> Vec<(JavaMinecraftVersion, R)> {
let current_mapping = (self.serializer)(&mappings.value);
let mut remap = if let Some(child) = mappings.child {
let mut res = self.process(child);

View File

@ -2,58 +2,58 @@ use proc_macro2::{Literal, TokenStream};
use quote::{format_ident, quote};
use crate::remap::{MappingNode, ParsedMappings, Remapper};
use crate::version::MinecraftVersion;
use crate::version::JavaMinecraftVersion;
/// Generates the `TokenStream` for per-version sound ID remap tables and the
/// `remap_sound_id_for_version` function.
pub fn build() -> TokenStream {
let node_1_20_5 = MappingNode {
version: MinecraftVersion::V_1_20_5,
version: JavaMinecraftVersion::V_1_20_5,
value: "../assets/viaversion/data/mappings-1.20.5to1.21.nbt",
child: None,
};
let node_1_21 = MappingNode {
version: MinecraftVersion::V_1_21,
version: JavaMinecraftVersion::V_1_21,
value: "../assets/viaversion/data/mappings-1.21to1.21.2.nbt",
child: Some(&node_1_20_5),
};
let node_1_21_2 = MappingNode {
version: MinecraftVersion::V_1_21_2,
version: JavaMinecraftVersion::V_1_21_2,
value: "../assets/viaversion/data/mappings-1.21.2to1.21.4.nbt",
child: Some(&node_1_21),
};
let node_1_21_4 = MappingNode {
version: MinecraftVersion::V_1_21_4,
version: JavaMinecraftVersion::V_1_21_4,
value: "../assets/viaversion/data/mappings-1.21.4to1.21.5.nbt",
child: Some(&node_1_21_2),
};
let node_1_21_5 = MappingNode {
version: MinecraftVersion::V_1_21_5,
version: JavaMinecraftVersion::V_1_21_5,
value: "../assets/viaversion/data/mappings-1.21.5to1.21.6.nbt",
child: Some(&node_1_21_4),
};
let node_1_21_6 = MappingNode {
version: MinecraftVersion::V_1_21_6,
version: JavaMinecraftVersion::V_1_21_6,
value: "../assets/viaversion/data/mappings-1.21.6to1.21.7.nbt",
child: Some(&node_1_21_5),
};
let node_1_21_7 = MappingNode {
version: MinecraftVersion::V_1_21_7,
version: JavaMinecraftVersion::V_1_21_7,
value: "../assets/viaversion/data/mappings-1.21.7to1.21.9.nbt",
child: Some(&node_1_21_6),
};
let node_1_21_9 = MappingNode {
version: MinecraftVersion::V_1_21_9,
version: JavaMinecraftVersion::V_1_21_9,
value: "../assets/viaversion/data/mappings-1.21.9to1.21.11.nbt",
child: Some(&node_1_21_7),
};
let node_1_21_11 = MappingNode {
version: MinecraftVersion::V_1_21_11,
version: JavaMinecraftVersion::V_1_21_11,
value: "../assets/viaversion/data/mappings-1.21.11to26.1.nbt",
child: Some(&node_1_21_9),
};
let remapper: Remapper<_, Option<Vec<u16>>> = Remapper {
version: MinecraftVersion::V_26_1,
version: JavaMinecraftVersion::V_26_1,
remapper: |first, second| match (first, second) {
(Some(first), Some(second)) => Some(
first
@ -102,12 +102,12 @@ pub fn build() -> TokenStream {
}
quote! {
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
#static_values
#[must_use]
pub fn remap_sound_id_for_version(sound_id: u16, version: MinecraftVersion) -> u16 {
pub fn remap_sound_id_for_version(sound_id: u16, version: JavaMinecraftVersion) -> u16 {
match version {
#match_arms
_ => sound_id,

View File

@ -8,7 +8,7 @@ use crate::enchantments::Enchantment;
use crate::entity_type::EntityType;
use crate::fluid::Fluid;
use crate::item::Item;
use crate::{biome::Biome, version::MinecraftVersion};
use crate::{biome::Biome, version::JavaMinecraftVersion};
use heck::ToPascalCase;
use proc_macro2::TokenStream;
use quote::{ToTokens, format_ident, quote};
@ -66,7 +66,7 @@ impl ToTokens for EnumCreator {
}
/// The newest protocol version whose tag data is served as the latest-version fallback.
const LATEST_VERSION: MinecraftVersion = MinecraftVersion::V_26_1;
const LATEST_VERSION: JavaMinecraftVersion = JavaMinecraftVersion::V_26_1;
/// Generates the `TokenStream` for the `Tag` type, `RegistryKey` enum, all per-version tag
/// modules, and the `Taggable` trait with its lookup helpers.
@ -75,17 +75,17 @@ pub(crate) fn build() -> TokenStream {
// Watch specific tag versions
let assets = [
(MinecraftVersion::V_1_20_5, "1_21_2_tags.json"),
(JavaMinecraftVersion::V_1_20_5, "1_21_2_tags.json"),
// TODO: upload 1_21_tags.json
(MinecraftVersion::V_1_21, "1_21_2_tags.json"),
(MinecraftVersion::V_1_21_2, "1_21_2_tags.json"),
(MinecraftVersion::V_1_21_4, "1_21_4_tags.json"),
(MinecraftVersion::V_1_21_5, "1_21_5_tags.json"),
(MinecraftVersion::V_1_21_6, "1_21_6_tags.json"),
(MinecraftVersion::V_1_21_7, "1_21_7_tags.json"),
(MinecraftVersion::V_1_21_9, "1_21_9_tags.json"),
(MinecraftVersion::V_1_21_11, "1_21_11_tags.json"),
(MinecraftVersion::V_26_1, "26_1_tags.json"),
(JavaMinecraftVersion::V_1_21, "1_21_2_tags.json"),
(JavaMinecraftVersion::V_1_21_2, "1_21_2_tags.json"),
(JavaMinecraftVersion::V_1_21_4, "1_21_4_tags.json"),
(JavaMinecraftVersion::V_1_21_5, "1_21_5_tags.json"),
(JavaMinecraftVersion::V_1_21_6, "1_21_6_tags.json"),
(JavaMinecraftVersion::V_1_21_7, "1_21_7_tags.json"),
(JavaMinecraftVersion::V_1_21_9, "1_21_9_tags.json"),
(JavaMinecraftVersion::V_1_21_11, "1_21_11_tags.json"),
(JavaMinecraftVersion::V_26_1, "26_1_tags.json"),
];
// --- Load Global Assets ---
@ -245,7 +245,7 @@ pub(crate) fn build() -> TokenStream {
.to_token_stream();
quote! {
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
pub type Tag = (&'static [&'static str], &'static [u16]);
@ -265,7 +265,7 @@ pub(crate) fn build() -> TokenStream {
get_latest_map(tag_category).and_then(|m| m.get(tag)).map(|t| t.1)
}
pub fn get_registry_key_tags(version: MinecraftVersion, tag_category: RegistryKey) -> Option<&'static phf::Map<&'static str, &'static Tag>> {
pub fn get_registry_key_tags(version: JavaMinecraftVersion, tag_category: RegistryKey) -> Option<&'static phf::Map<&'static str, &'static Tag>> {
match version {
#(#match_get_map),*,
_ => get_latest_map(tag_category)

View File

@ -2,23 +2,23 @@ use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use std::{collections::BTreeMap, fs};
use crate::version::MinecraftVersion;
use crate::version::JavaMinecraftVersion;
/// The newest protocol version used as the fallback for unknown versions in `TrackedId::get`.
const LATEST_VERSION: MinecraftVersion = MinecraftVersion::V_26_1;
const LATEST_VERSION: JavaMinecraftVersion = JavaMinecraftVersion::V_26_1;
/// Generates the `TokenStream` for `TrackedId`, `TrackedData`, and all per-entity tracking constants.
pub(crate) fn build() -> TokenStream {
let assets = [
(MinecraftVersion::V_1_21, "1_21_tracked_data.json"),
(MinecraftVersion::V_1_21_2, "1_21_2_tracked_data.json"),
(MinecraftVersion::V_1_21_4, "1_21_4_tracked_data.json"),
(MinecraftVersion::V_1_21_5, "1_21_5_tracked_data.json"),
(MinecraftVersion::V_1_21_6, "1_21_6_tracked_data.json"),
(MinecraftVersion::V_1_21_7, "1_21_7_tracked_data.json"),
(MinecraftVersion::V_1_21_9, "1_21_9_tracked_data.json"),
(MinecraftVersion::V_1_21_11, "1_21_11_tracked_data.json"),
(MinecraftVersion::V_26_1, "26_1_tracked_data.json"),
(JavaMinecraftVersion::V_1_21, "1_21_tracked_data.json"),
(JavaMinecraftVersion::V_1_21_2, "1_21_2_tracked_data.json"),
(JavaMinecraftVersion::V_1_21_4, "1_21_4_tracked_data.json"),
(JavaMinecraftVersion::V_1_21_5, "1_21_5_tracked_data.json"),
(JavaMinecraftVersion::V_1_21_6, "1_21_6_tracked_data.json"),
(JavaMinecraftVersion::V_1_21_7, "1_21_7_tracked_data.json"),
(JavaMinecraftVersion::V_1_21_9, "1_21_9_tracked_data.json"),
(JavaMinecraftVersion::V_1_21_11, "1_21_11_tracked_data.json"),
(JavaMinecraftVersion::V_26_1, "26_1_tracked_data.json"),
];
let mut versions = BTreeMap::new();
@ -37,7 +37,7 @@ pub(crate) fn build() -> TokenStream {
let constants = generate_consts(&versions);
quote! {
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
#tracked_data_struct
@ -50,7 +50,7 @@ pub(crate) fn build() -> TokenStream {
}
/// Generates the `TrackedId` struct definition with one `u8` field per supported version.
fn generate_struct<T>(versions: &BTreeMap<MinecraftVersion, T>) -> TokenStream {
fn generate_struct<T>(versions: &BTreeMap<JavaMinecraftVersion, T>) -> TokenStream {
// Build struct fields
let mut struct_fields = TokenStream::new();
for ver in versions.keys() {
@ -77,7 +77,7 @@ fn generate_struct<T>(versions: &BTreeMap<MinecraftVersion, T>) -> TokenStream {
}
impl TrackedId {
pub fn get(&self, version: &MinecraftVersion) -> u8 {
pub fn get(&self, version: &JavaMinecraftVersion) -> u8 {
match version {
#match_arms
_ => self.#latest_field_ident,
@ -94,7 +94,7 @@ fn generate_struct<T>(versions: &BTreeMap<MinecraftVersion, T>) -> TokenStream {
}
/// Generates `TrackedId` constants for every tracked data key present in the latest version.
fn generate_consts(versions: &BTreeMap<MinecraftVersion, BTreeMap<String, u8>>) -> TokenStream {
fn generate_consts(versions: &BTreeMap<JavaMinecraftVersion, BTreeMap<String, u8>>) -> TokenStream {
let mut constants = TokenStream::new();
let mut generated_names = std::collections::HashSet::new();

View File

@ -2,11 +2,11 @@ use quote::{ToTokens, format_ident, quote};
use syn::Ident;
/// Represents a specific version of the Minecraft Java Edition protocol.
/// from pumpkin_util::version::MinecraftVersion
/// from pumpkin_util::version::JavaMinecraftVersion
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[allow(non_camel_case_types)]
#[allow(dead_code)]
pub enum MinecraftVersion {
pub enum JavaMinecraftVersion {
/// 1.7.2: The Update That Changed The World
V_1_7_2,
V_1_7_6,
@ -76,11 +76,11 @@ pub enum MinecraftVersion {
V_26_1,
}
impl MinecraftVersion {
impl JavaMinecraftVersion {
/// Converts this version to a snake_case `Ident` suitable for use as a struct field name.
///
/// # Returns
/// A `syn::Ident` like `v1_21_4` for `MinecraftVersion::V_1_21_4`.
/// A `syn::Ident` like `v1_21_4` for `JavaMinecraftVersion::V_1_21_4`.
pub fn to_field_ident(self) -> Ident {
match self {
Self::V_1_7_2 => format_ident!("v1_7_2"),
@ -137,60 +137,60 @@ impl MinecraftVersion {
}
}
impl ToTokens for MinecraftVersion {
/// Emits a fully-qualified `pumpkin_util::version::MinecraftVersion::V_x_y_z` token stream.
impl ToTokens for JavaMinecraftVersion {
/// Emits a fully-qualified `pumpkin_util::version::JavaMinecraftVersion::V_x_y_z` token stream.
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
tokens.extend(match self {
Self::V_1_7_2 => quote! { pumpkin_util::version::MinecraftVersion::V_1_7_2 },
Self::V_1_7_6 => quote! { pumpkin_util::version::MinecraftVersion::V_1_7_6 },
Self::V_1_8 => quote! { pumpkin_util::version::MinecraftVersion::V_1_8 },
Self::V_1_9 => quote! { pumpkin_util::version::MinecraftVersion::V_1_9 },
Self::V_1_9_1 => quote! { pumpkin_util::version::MinecraftVersion::V_1_9_1 },
Self::V_1_9_2 => quote! { pumpkin_util::version::MinecraftVersion::V_1_9_2 },
Self::V_1_9_3 => quote! { pumpkin_util::version::MinecraftVersion::V_1_9_3 },
Self::V_1_10 => quote! { pumpkin_util::version::MinecraftVersion::V_1_10 },
Self::V_1_11 => quote! { pumpkin_util::version::MinecraftVersion::V_1_11 },
Self::V_1_11_1 => quote! { pumpkin_util::version::MinecraftVersion::V_1_11_1 },
Self::V_1_12 => quote! { pumpkin_util::version::MinecraftVersion::V_1_12 },
Self::V_1_12_1 => quote! { pumpkin_util::version::MinecraftVersion::V_1_12_1 },
Self::V_1_12_2 => quote! { pumpkin_util::version::MinecraftVersion::V_1_12_2 },
Self::V_1_13 => quote! { pumpkin_util::version::MinecraftVersion::V_1_13 },
Self::V_1_13_1 => quote! { pumpkin_util::version::MinecraftVersion::V_1_13_1 },
Self::V_1_13_2 => quote! { pumpkin_util::version::MinecraftVersion::V_1_13_2 },
Self::V_1_14 => quote! { pumpkin_util::version::MinecraftVersion::V_1_14 },
Self::V_1_14_1 => quote! { pumpkin_util::version::MinecraftVersion::V_1_14_1 },
Self::V_1_14_2 => quote! { pumpkin_util::version::MinecraftVersion::V_1_14_2 },
Self::V_1_14_3 => quote! { pumpkin_util::version::MinecraftVersion::V_1_14_3 },
Self::V_1_14_4 => quote! { pumpkin_util::version::MinecraftVersion::V_1_14_4 },
Self::V_1_15 => quote! { pumpkin_util::version::MinecraftVersion::V_1_15 },
Self::V_1_15_1 => quote! { pumpkin_util::version::MinecraftVersion::V_1_15_1 },
Self::V_1_15_2 => quote! { pumpkin_util::version::MinecraftVersion::V_1_15_2 },
Self::V_1_16 => quote! { pumpkin_util::version::MinecraftVersion::V_1_16 },
Self::V_1_16_1 => quote! { pumpkin_util::version::MinecraftVersion::V_1_16_1 },
Self::V_1_16_2 => quote! { pumpkin_util::version::MinecraftVersion::V_1_16_2 },
Self::V_1_16_3 => quote! { pumpkin_util::version::MinecraftVersion::V_1_16_3 },
Self::V_1_16_4 => quote! { pumpkin_util::version::MinecraftVersion::V_1_16_4 },
Self::V_1_17 => quote! { pumpkin_util::version::MinecraftVersion::V_1_17 },
Self::V_1_17_1 => quote! { pumpkin_util::version::MinecraftVersion::V_1_17_1 },
Self::V_1_18 => quote! { pumpkin_util::version::MinecraftVersion::V_1_18 },
Self::V_1_18_2 => quote! { pumpkin_util::version::MinecraftVersion::V_1_18_2 },
Self::V_1_19 => quote! { pumpkin_util::version::MinecraftVersion::V_1_19 },
Self::V_1_19_1 => quote! { pumpkin_util::version::MinecraftVersion::V_1_19_1 },
Self::V_1_19_3 => quote! { pumpkin_util::version::MinecraftVersion::V_1_19_3 },
Self::V_1_19_4 => quote! { pumpkin_util::version::MinecraftVersion::V_1_19_4 },
Self::V_1_20 => quote! { pumpkin_util::version::MinecraftVersion::V_1_20 },
Self::V_1_20_2 => quote! { pumpkin_util::version::MinecraftVersion::V_1_20_2 },
Self::V_1_20_3 => quote! { pumpkin_util::version::MinecraftVersion::V_1_20_3 },
Self::V_1_20_5 => quote! { pumpkin_util::version::MinecraftVersion::V_1_20_5 },
Self::V_1_21 => quote! { pumpkin_util::version::MinecraftVersion::V_1_21 },
Self::V_1_21_2 => quote! { pumpkin_util::version::MinecraftVersion::V_1_21_2 },
Self::V_1_21_4 => quote! { pumpkin_util::version::MinecraftVersion::V_1_21_4 },
Self::V_1_21_5 => quote! { pumpkin_util::version::MinecraftVersion::V_1_21_5 },
Self::V_1_21_6 => quote! { pumpkin_util::version::MinecraftVersion::V_1_21_6 },
Self::V_1_21_7 => quote! { pumpkin_util::version::MinecraftVersion::V_1_21_7 },
Self::V_1_21_9 => quote! { pumpkin_util::version::MinecraftVersion::V_1_21_9 },
Self::V_1_21_11 => quote! { pumpkin_util::version::MinecraftVersion::V_1_21_11 },
Self::V_26_1 => quote! { pumpkin_util::version::MinecraftVersion::V_26_1 },
Self::V_1_7_2 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_7_2 },
Self::V_1_7_6 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_7_6 },
Self::V_1_8 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_8 },
Self::V_1_9 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_9 },
Self::V_1_9_1 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_9_1 },
Self::V_1_9_2 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_9_2 },
Self::V_1_9_3 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_9_3 },
Self::V_1_10 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_10 },
Self::V_1_11 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_11 },
Self::V_1_11_1 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_11_1 },
Self::V_1_12 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_12 },
Self::V_1_12_1 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_12_1 },
Self::V_1_12_2 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_12_2 },
Self::V_1_13 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_13 },
Self::V_1_13_1 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_13_1 },
Self::V_1_13_2 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_13_2 },
Self::V_1_14 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_14 },
Self::V_1_14_1 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_14_1 },
Self::V_1_14_2 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_14_2 },
Self::V_1_14_3 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_14_3 },
Self::V_1_14_4 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_14_4 },
Self::V_1_15 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_15 },
Self::V_1_15_1 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_15_1 },
Self::V_1_15_2 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_15_2 },
Self::V_1_16 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_16 },
Self::V_1_16_1 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_16_1 },
Self::V_1_16_2 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_16_2 },
Self::V_1_16_3 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_16_3 },
Self::V_1_16_4 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_16_4 },
Self::V_1_17 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_17 },
Self::V_1_17_1 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_17_1 },
Self::V_1_18 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_18 },
Self::V_1_18_2 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_18_2 },
Self::V_1_19 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_19 },
Self::V_1_19_1 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_19_1 },
Self::V_1_19_3 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_19_3 },
Self::V_1_19_4 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_19_4 },
Self::V_1_20 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_20 },
Self::V_1_20_2 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_20_2 },
Self::V_1_20_3 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_20_3 },
Self::V_1_20_5 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_20_5 },
Self::V_1_21 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_21 },
Self::V_1_21_2 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_21_2 },
Self::V_1_21_4 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_21_4 },
Self::V_1_21_5 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_21_5 },
Self::V_1_21_6 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_21_6 },
Self::V_1_21_7 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_21_7 },
Self::V_1_21_9 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_21_9 },
Self::V_1_21_11 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_1_21_11 },
Self::V_26_1 => quote! { pumpkin_util::version::JavaMinecraftVersion::V_26_1 },
});
}
}

View File

@ -11,10 +11,10 @@ pub fn build_java_mapping() -> String {
output.push_str("#![allow(unused_variables)]\n");
output.push_str("use crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::java_packets::ClientboundPacket;\n");
output.push_str("use pumpkin_protocol::codec::var_int::VarInt;\n");
output.push_str("use pumpkin_util::version::MinecraftVersion;\n");
output.push_str("use pumpkin_util::version::JavaMinecraftVersion;\n");
output.push_str("use bytes::Bytes;\n\n");
output.push_str("#[must_use]\n");
output.push_str("pub fn serialize_java_packet(packet: &ClientboundPacket, version: MinecraftVersion) -> Option<Bytes> {\n");
output.push_str("pub fn serialize_java_packet(packet: &ClientboundPacket, version: JavaMinecraftVersion) -> Option<Bytes> {\n");
output.push_str(" match packet {\n");
process_packets(
@ -123,7 +123,7 @@ fn parse_packet_file(
for field in fields.named {
let mut field_name = field.ident.as_ref().unwrap().to_string();
let wit_field = field_name.to_snake_case();
let (type_ident, is_ref) = get_type_info(&field.ty);
let (type_ident, is_ref, is_slice) = get_type_info(&field.ty);
if field_name == "type" {
field_name = "r#type".to_string();
@ -158,12 +158,21 @@ fn parse_packet_file(
field_inits.push_str(&format!(" {}: pumpkin_util::math::vector3::Vector3::new(data.{}.0 as _, data.{}.1 as _, data.{}.2 as _),\n", field_name, wit_field, wit_field, wit_field));
},
"Uuid" => {
prep_code.push_str(&format!(" let uuid_{} = uuid::Uuid::parse_str(&data.{}).unwrap();\n", wit_field, wit_field));
if is_slice {
prep_code.push_str(&format!(" let vec_{} = data.{}.iter().map(|u| uuid::Uuid::from_u64_pair(u.high, u.low)).collect::<Vec<_>>();\n", wit_field, wit_field));
if is_ref {
field_inits.push_str(&format!(" {}: &vec_{},\n", field_name, wit_field));
} else {
field_inits.push_str(&format!(" {}: vec_{},\n", field_name, wit_field));
}
} else {
prep_code.push_str(&format!(" let uuid_{} = uuid::Uuid::from_u64_pair(data.{}.high, data.{}.low);\n", wit_field, wit_field, wit_field));
if is_ref {
field_inits.push_str(&format!(" {}: &uuid_{},\n", field_name, wit_field));
} else {
field_inits.push_str(&format!(" {}: uuid_{},\n", field_name, wit_field));
}
}
},
"i32" | "u32" | "i64" | "u64" | "bool" | "f32" | "f64" | "u8" | "i8" | "u16" | "i16" => {
field_inits.push_str(&format!(" {}: data.{}.try_into().unwrap(),\n", field_name, wit_field));
@ -203,10 +212,17 @@ fn parse_packet_file(
}
}
fn get_type_info(ty: &syn::Type) -> (String, bool) {
fn get_type_info(ty: &syn::Type) -> (String, bool, bool) {
match ty {
syn::Type::Path(tp) => (tp.path.segments.last().unwrap().ident.to_string(), false),
syn::Type::Reference(tr) => (get_type_info(&tr.elem).0, true),
_ => (String::new(), false),
syn::Type::Path(tp) => (tp.path.segments.last().unwrap().ident.to_string(), false, false),
syn::Type::Reference(tr) => {
let (name, _, is_slice) = get_type_info(&tr.elem);
(name, true, is_slice)
}
syn::Type::Slice(ts) => {
let (name, _, _) = get_type_info(&ts.elem);
(name, false, true)
}
_ => (String::new(), false, false),
}
}

View File

@ -7,7 +7,8 @@ pub fn map_type(ty: &Type) -> WitType {
let last_segment = path.segments.last().unwrap();
let ident_str = last_segment.ident.to_string();
match ident_str.as_str() {
"String" | "Uuid" | "TextComponent" => WitType::String,
"String" | "TextComponent" => WitType::String,
"Uuid" => WitType::Named("uuid".into()),
"i32" | "VarInt" | "u32" | "VarUInt" | "usize" => WitType::S32,
"i64" | "u64" => WitType::S64,
"bool" => WitType::Bool,
@ -16,33 +17,47 @@ pub fn map_type(ty: &Type) -> WitType {
"u8" | "i8" => WitType::U8,
"u16" | "i16" => WitType::S32,
"Option" => {
if let syn::PathArguments::AngleBracketed(args) = &last_segment.arguments
&& let Some(syn::GenericArgument::Type(inner_ty)) = args.args.first()
{
if let syn::PathArguments::AngleBracketed(args) = &last_segment.arguments {
if let Some(syn::GenericArgument::Type(inner_ty)) = args.args.first() {
return WitType::option(map_type(inner_ty));
}
}
WitType::String
}
"Vec" | "Box" => {
if let syn::PathArguments::AngleBracketed(args) = &last_segment.arguments
&& let Some(syn::GenericArgument::Type(inner_ty)) = args.args.first()
if let syn::PathArguments::AngleBracketed(args) = &last_segment.arguments {
if let Some(syn::GenericArgument::Type(inner_ty)) = args.args.first() {
// Check if the inner type is u8
if let Type::Path(tp) = inner_ty
&& tp.path.segments.last().unwrap().ident == "u8"
{
return WitType::list(WitType::U8);
}
return WitType::list(map_type(inner_ty));
}
}
WitType::String
}
"Vector3" | "BlockPos" => {
// Map to tuple or common record
// For now, let's use a tuple of floats for Vector3 and ints for BlockPos
if ident_str == "Vector3" {
WitType::tuple(vec![WitType::F64, WitType::F64, WitType::F64])
} else {
WitType::tuple(vec![WitType::S32, WitType::S32, WitType::S32])
}
}
_ => WitType::String, // Fallback
_ => WitType::String,
}
}
_ => WitType::String, // Fallback
Type::Reference(tr) => map_type(&tr.elem),
Type::Slice(ts) => {
if let Type::Path(tp) = &*ts.elem
&& tp.path.segments.last().unwrap().ident == "u8"
{
WitType::list(WitType::U8)
} else {
WitType::list(map_type(&ts.elem))
}
}
_ => WitType::String,
}
}

View File

@ -504838,7 +504838,7 @@ impl BlockProperties for OakFenceGateLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -504949,7 +504949,7 @@ impl BlockProperties for CakeLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -505058,7 +505058,7 @@ impl BlockProperties for JukeboxLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -505171,7 +505171,7 @@ impl BlockProperties for PointedDripstoneLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -505344,7 +505344,7 @@ impl BlockProperties for ResinBrickSlabLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -505520,7 +505520,7 @@ impl BlockProperties for DriedGhastLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -505665,7 +505665,7 @@ impl BlockProperties for RedstoneWireLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -505814,7 +505814,7 @@ impl BlockProperties for StickyPistonLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -505951,7 +505951,7 @@ impl BlockProperties for ChiseledBookshelfLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -506112,7 +506112,7 @@ impl BlockProperties for PoweredRailLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -506244,7 +506244,7 @@ impl BlockProperties for WhiteBedLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -506357,7 +506357,7 @@ impl BlockProperties for ChorusFlowerLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -506464,7 +506464,7 @@ impl BlockProperties for CactusLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -506628,7 +506628,7 @@ impl BlockProperties for FireLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -506779,7 +506779,7 @@ impl BlockProperties for HopperLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -506925,7 +506925,7 @@ impl BlockProperties for OakDoorLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -507063,7 +507063,7 @@ impl BlockProperties for PistonHeadLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -507167,7 +507167,7 @@ impl BlockProperties for MovingPistonLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -507279,7 +507279,7 @@ impl BlockProperties for CreakingHeartLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -507409,7 +507409,7 @@ impl BlockProperties for PaleMossCarpetLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -507524,7 +507524,7 @@ impl BlockProperties for ScaffoldingLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -507663,7 +507663,7 @@ impl BlockProperties for VaultLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -507770,7 +507770,7 @@ impl BlockProperties for TrialSpawnerLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -507881,7 +507881,7 @@ impl BlockProperties for SculkShriekerLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -508005,7 +508005,7 @@ impl BlockProperties for RepeaterLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -508119,7 +508119,7 @@ impl BlockProperties for RespawnAnchorLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -508261,7 +508261,7 @@ impl BlockProperties for AcaciaShelfLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -508440,7 +508440,7 @@ impl BlockProperties for ResinBrickWallLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -508588,7 +508588,7 @@ impl BlockProperties for BrewingStandLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -508692,7 +508692,7 @@ impl BlockProperties for SnowLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -508822,7 +508822,7 @@ impl BlockProperties for NoteBlockLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -508985,7 +508985,7 @@ impl BlockProperties for DispenserLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -509094,7 +509094,7 @@ impl BlockProperties for CrafterLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -509272,7 +509272,7 @@ impl BlockProperties for OakStairsLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -509432,7 +509432,7 @@ impl BlockProperties for FarmlandLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -509543,7 +509543,7 @@ impl BlockProperties for SuspiciousSandLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -509662,7 +509662,7 @@ impl BlockProperties for BambooLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -509799,7 +509799,7 @@ impl BlockProperties for StonePressurePlateLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -509919,7 +509919,7 @@ impl BlockProperties for ComparatorLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -510023,7 +510023,7 @@ impl BlockProperties for CopperBulbLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -510163,7 +510163,7 @@ impl BlockProperties for TripwireLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -510319,7 +510319,7 @@ impl BlockProperties for OakTrapdoorLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -510460,7 +510460,7 @@ impl BlockProperties for LecternLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -510571,7 +510571,7 @@ impl BlockProperties for TripwireHookLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -510685,7 +510685,7 @@ impl BlockProperties for BellLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -510792,7 +510792,7 @@ impl BlockProperties for SkeletonWallSkullLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -510921,7 +510921,7 @@ impl BlockProperties for LeverLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -511052,7 +511052,7 @@ impl BlockProperties for LightningRodLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -511162,7 +511162,7 @@ impl BlockProperties for SkeletonSkullLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -511308,7 +511308,7 @@ impl BlockProperties for ObserverLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -511401,7 +511401,7 @@ impl BlockProperties for ComposterLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -511514,7 +511514,7 @@ impl BlockProperties for CaveVinesPlantLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -511608,7 +511608,7 @@ impl BlockProperties for CaveVinesLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -511762,7 +511762,7 @@ impl BlockProperties for TntLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -511887,7 +511887,7 @@ impl BlockProperties for BrownMushroomBlockLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -512032,7 +512032,7 @@ impl BlockProperties for GlowLichenLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -512168,7 +512168,7 @@ impl BlockProperties for VineLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -512276,7 +512276,7 @@ impl BlockProperties for EndPortalFrameLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -512392,7 +512392,7 @@ impl BlockProperties for RedstoneOreLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -512526,7 +512526,7 @@ impl BlockProperties for CampfireLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -512638,7 +512638,7 @@ impl BlockProperties for FurnaceLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -512766,7 +512766,7 @@ impl BlockProperties for CandleLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -512900,7 +512900,7 @@ impl BlockProperties for PaleHangingMossLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -512988,7 +512988,7 @@ impl BlockProperties for BubbleColumnLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -513147,7 +513147,7 @@ impl BlockProperties for OakFenceLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -513299,7 +513299,7 @@ impl BlockProperties for BarrelLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -513392,7 +513392,7 @@ impl BlockProperties for SculkCatalystLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -513480,7 +513480,7 @@ impl BlockProperties for GrassBlockLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -513568,7 +513568,7 @@ impl BlockProperties for StructureBlockLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -513684,7 +513684,7 @@ impl BlockProperties for ChestLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -513820,7 +513820,7 @@ impl BlockProperties for CalibratedSculkSensorLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -513982,7 +513982,7 @@ impl BlockProperties for SculkSensorLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -514142,7 +514142,7 @@ impl BlockProperties for OakLeavesLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -514269,7 +514269,7 @@ impl BlockProperties for SnifferEggLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -514379,7 +514379,7 @@ impl BlockProperties for TurtleEggLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -514534,7 +514534,7 @@ impl BlockProperties for OakHangingSignLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -514693,7 +514693,7 @@ impl BlockProperties for DaylightDetectorLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -514827,7 +514827,7 @@ impl BlockProperties for WaterCauldronLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -514951,7 +514951,7 @@ impl BlockProperties for MangrovePropaguleLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -515092,7 +515092,7 @@ impl BlockProperties for LanternLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -515191,7 +515191,7 @@ impl BlockProperties for NetherPortalLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -515282,7 +515282,7 @@ impl BlockProperties for OakSaplingLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -515406,7 +515406,7 @@ impl BlockProperties for CopperGolemStatueLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -515509,7 +515509,7 @@ impl BlockProperties for WheatLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -515666,7 +515666,7 @@ impl BlockProperties for WallTorchLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -515809,7 +515809,7 @@ impl BlockProperties for BeeNestLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -515939,7 +515939,7 @@ impl BlockProperties for DecoratedPotLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -516085,7 +516085,7 @@ impl BlockProperties for LadderLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -516236,7 +516236,7 @@ impl BlockProperties for BigDripleafLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -516350,7 +516350,7 @@ impl BlockProperties for SmallDripleafLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -516457,7 +516457,7 @@ impl BlockProperties for GrindstoneLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -516559,7 +516559,7 @@ impl BlockProperties for PinkPetalsLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -516678,7 +516678,7 @@ impl BlockProperties for LeafLitterLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -516797,7 +516797,7 @@ impl BlockProperties for CocoaLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -516914,7 +516914,7 @@ impl BlockProperties for RailLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -517019,7 +517019,7 @@ impl BlockProperties for SeaPickleLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -517167,7 +517167,7 @@ impl BlockProperties for MangroveRootsLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -517316,7 +517316,7 @@ impl BlockProperties for OakSignLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -517476,7 +517476,7 @@ impl BlockProperties for AmethystClusterLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -517581,7 +517581,7 @@ impl BlockProperties for LightLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -517730,7 +517730,7 @@ impl BlockProperties for IronChainLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -517838,7 +517838,7 @@ impl BlockProperties for CommandBlockLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -517937,7 +517937,7 @@ impl BlockProperties for TallSeagrassLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -518037,7 +518037,7 @@ impl BlockProperties for PitcherCropLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -518167,7 +518167,7 @@ impl BlockProperties for WhiteBannerLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -518332,7 +518332,7 @@ impl BlockProperties for EndRodLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -518440,7 +518440,7 @@ impl BlockProperties for WaterLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -518567,7 +518567,7 @@ impl BlockProperties for KelpLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -518714,7 +518714,7 @@ impl BlockProperties for LightWeightedPressurePlateLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -518841,7 +518841,7 @@ impl BlockProperties for TestBlockLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -518929,7 +518929,7 @@ impl BlockProperties for TorchflowerCropLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -519028,7 +519028,7 @@ impl BlockProperties for NetherWartLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -519191,7 +519191,7 @@ impl BlockProperties for PaleOakWoodLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}
@ -519339,7 +519339,7 @@ impl BlockProperties for JigsawLikeProperties {
Self::from_index(state_id - min_id)
} else {
#[cfg(debug_assertions)]
panic!("State ID {} does not exist for {}", state_id, block.name);
panic!("State ID {} does not exist for {}", state_id, &block.name);
#[cfg(not(debug_assertions))]
Self::from_index(0)
}

View File

@ -19134,45 +19134,61 @@ pub static BLOCK_STATE_REMAP_V_26_1_TO_V_1_21_11: &[u16] = &[
#[must_use]
pub fn remap_block_state_for_version(
state_id: u16,
version: pumpkin_util::version::MinecraftVersion,
version: pumpkin_util::version::JavaMinecraftVersion,
) -> u16 {
match version {
pumpkin_util::version::MinecraftVersion::V_1_20_5 => BLOCK_STATE_REMAP_V_26_1_TO_V_1_20_5
pumpkin_util::version::JavaMinecraftVersion::V_1_20_5 => {
BLOCK_STATE_REMAP_V_26_1_TO_V_1_20_5
.get(usize::from(state_id))
.copied()
.unwrap_or(0)
}
pumpkin_util::version::JavaMinecraftVersion::V_1_21 => BLOCK_STATE_REMAP_V_26_1_TO_V_1_21
.get(usize::from(state_id))
.copied()
.unwrap_or(0),
pumpkin_util::version::MinecraftVersion::V_1_21 => BLOCK_STATE_REMAP_V_26_1_TO_V_1_21
pumpkin_util::version::JavaMinecraftVersion::V_1_21_2 => {
BLOCK_STATE_REMAP_V_26_1_TO_V_1_21_2
.get(usize::from(state_id))
.copied()
.unwrap_or(0),
pumpkin_util::version::MinecraftVersion::V_1_21_2 => BLOCK_STATE_REMAP_V_26_1_TO_V_1_21_2
.unwrap_or(0)
}
pumpkin_util::version::JavaMinecraftVersion::V_1_21_4 => {
BLOCK_STATE_REMAP_V_26_1_TO_V_1_21_4
.get(usize::from(state_id))
.copied()
.unwrap_or(0),
pumpkin_util::version::MinecraftVersion::V_1_21_4 => BLOCK_STATE_REMAP_V_26_1_TO_V_1_21_4
.unwrap_or(0)
}
pumpkin_util::version::JavaMinecraftVersion::V_1_21_5 => {
BLOCK_STATE_REMAP_V_26_1_TO_V_1_21_5
.get(usize::from(state_id))
.copied()
.unwrap_or(0),
pumpkin_util::version::MinecraftVersion::V_1_21_5 => BLOCK_STATE_REMAP_V_26_1_TO_V_1_21_5
.unwrap_or(0)
}
pumpkin_util::version::JavaMinecraftVersion::V_1_21_6 => {
BLOCK_STATE_REMAP_V_26_1_TO_V_1_21_6
.get(usize::from(state_id))
.copied()
.unwrap_or(0),
pumpkin_util::version::MinecraftVersion::V_1_21_6 => BLOCK_STATE_REMAP_V_26_1_TO_V_1_21_6
.unwrap_or(0)
}
pumpkin_util::version::JavaMinecraftVersion::V_1_21_7 => {
BLOCK_STATE_REMAP_V_26_1_TO_V_1_21_7
.get(usize::from(state_id))
.copied()
.unwrap_or(0),
pumpkin_util::version::MinecraftVersion::V_1_21_7 => BLOCK_STATE_REMAP_V_26_1_TO_V_1_21_7
.unwrap_or(0)
}
pumpkin_util::version::JavaMinecraftVersion::V_1_21_9 => {
BLOCK_STATE_REMAP_V_26_1_TO_V_1_21_9
.get(usize::from(state_id))
.copied()
.unwrap_or(0),
pumpkin_util::version::MinecraftVersion::V_1_21_9 => BLOCK_STATE_REMAP_V_26_1_TO_V_1_21_9
.unwrap_or(0)
}
pumpkin_util::version::JavaMinecraftVersion::V_1_21_11 => {
BLOCK_STATE_REMAP_V_26_1_TO_V_1_21_11
.get(usize::from(state_id))
.copied()
.unwrap_or(0),
pumpkin_util::version::MinecraftVersion::V_1_21_11 => BLOCK_STATE_REMAP_V_26_1_TO_V_1_21_11
.get(usize::from(state_id))
.copied()
.unwrap_or(0),
.unwrap_or(0)
}
_ => state_id,
}
}

View File

@ -62,8 +62,8 @@ pub struct CarverConfig {
pub replaceable: crate::tag::Tag,
pub additional: CarverAdditionalConfig,
}
use super::*;
pub const CANYON: CarverConfig = CarverConfig {
use super::*;
pub const CANYON: CarverConfig = CarverConfig {
probability: 0.01f32,
y: HeightProvider::Uniform(UniformHeightProvider {
min_inclusive: YOffset::Absolute(Absolute { absolute: 10i16 }),
@ -91,8 +91,8 @@ pub struct CarverConfig {
vertical_radius_center_factor: 0f32,
},
}),
};
pub const CAVE: CarverConfig = CarverConfig {
};
pub const CAVE: CarverConfig = CarverConfig {
probability: 0.15f32,
y: HeightProvider::Uniform(UniformHeightProvider {
min_inclusive: YOffset::AboveBottom(AboveBottom { above_bottom: 8i8 }),
@ -114,8 +114,8 @@ pub struct CarverConfig {
UniformFloatProvider::new(-1f32, -0.4f32),
)),
}),
};
pub const CAVE_EXTRA_UNDERGROUND: CarverConfig = CarverConfig {
};
pub const CAVE_EXTRA_UNDERGROUND: CarverConfig = CarverConfig {
probability: 0.07f32,
y: HeightProvider::Uniform(UniformHeightProvider {
min_inclusive: YOffset::AboveBottom(AboveBottom { above_bottom: 8i8 }),
@ -137,8 +137,8 @@ pub struct CarverConfig {
UniformFloatProvider::new(-1f32, -0.4f32),
)),
}),
};
pub const NETHER_CAVE: CarverConfig = CarverConfig {
};
pub const NETHER_CAVE: CarverConfig = CarverConfig {
probability: 0.2f32,
y: HeightProvider::Uniform(UniformHeightProvider {
min_inclusive: YOffset::Absolute(Absolute { absolute: 0i16 }),
@ -152,4 +152,4 @@ pub struct CarverConfig {
vertical_radius_multiplier: FloatProvider::Constant(1f32),
floor_level: FloatProvider::Constant(-0.7f32),
}),
};
};

View File

@ -80,38 +80,38 @@ pub static ENTITY_ID_REMAP_V_26_1_TO_V_1_21_9: &[u16] = &[
#[must_use]
pub fn remap_entity_id_for_version(
entity_id: u16,
version: pumpkin_util::version::MinecraftVersion,
version: pumpkin_util::version::JavaMinecraftVersion,
) -> u16 {
match version {
pumpkin_util::version::MinecraftVersion::V_1_20_5 => ENTITY_ID_REMAP_V_26_1_TO_V_1_20_5
pumpkin_util::version::JavaMinecraftVersion::V_1_20_5 => ENTITY_ID_REMAP_V_26_1_TO_V_1_20_5
.get(usize::from(entity_id))
.copied()
.unwrap_or(0),
pumpkin_util::version::MinecraftVersion::V_1_21 => ENTITY_ID_REMAP_V_26_1_TO_V_1_21
pumpkin_util::version::JavaMinecraftVersion::V_1_21 => ENTITY_ID_REMAP_V_26_1_TO_V_1_21
.get(usize::from(entity_id))
.copied()
.unwrap_or(0),
pumpkin_util::version::MinecraftVersion::V_1_21_2 => ENTITY_ID_REMAP_V_26_1_TO_V_1_21_2
pumpkin_util::version::JavaMinecraftVersion::V_1_21_2 => ENTITY_ID_REMAP_V_26_1_TO_V_1_21_2
.get(usize::from(entity_id))
.copied()
.unwrap_or(0),
pumpkin_util::version::MinecraftVersion::V_1_21_4 => ENTITY_ID_REMAP_V_26_1_TO_V_1_21_4
pumpkin_util::version::JavaMinecraftVersion::V_1_21_4 => ENTITY_ID_REMAP_V_26_1_TO_V_1_21_4
.get(usize::from(entity_id))
.copied()
.unwrap_or(0),
pumpkin_util::version::MinecraftVersion::V_1_21_5 => ENTITY_ID_REMAP_V_26_1_TO_V_1_21_5
pumpkin_util::version::JavaMinecraftVersion::V_1_21_5 => ENTITY_ID_REMAP_V_26_1_TO_V_1_21_5
.get(usize::from(entity_id))
.copied()
.unwrap_or(0),
pumpkin_util::version::MinecraftVersion::V_1_21_6 => ENTITY_ID_REMAP_V_26_1_TO_V_1_21_6
pumpkin_util::version::JavaMinecraftVersion::V_1_21_6 => ENTITY_ID_REMAP_V_26_1_TO_V_1_21_6
.get(usize::from(entity_id))
.copied()
.unwrap_or(0),
pumpkin_util::version::MinecraftVersion::V_1_21_7 => ENTITY_ID_REMAP_V_26_1_TO_V_1_21_7
pumpkin_util::version::JavaMinecraftVersion::V_1_21_7 => ENTITY_ID_REMAP_V_26_1_TO_V_1_21_7
.get(usize::from(entity_id))
.copied()
.unwrap_or(0),
pumpkin_util::version::MinecraftVersion::V_1_21_9 => ENTITY_ID_REMAP_V_26_1_TO_V_1_21_9
pumpkin_util::version::JavaMinecraftVersion::V_1_21_9 => ENTITY_ID_REMAP_V_26_1_TO_V_1_21_9
.get(usize::from(entity_id))
.copied()
.unwrap_or(0),

View File

@ -907,7 +907,7 @@ impl FluidProperties for WaterLikeFluidProperties {
if !["water", "lava"].contains(&fluid.name) {
panic!(
"{} is not a valid fluid for {}",
fluid.name, "WaterLikeFluidProperties"
&fluid.name, "WaterLikeFluidProperties"
);
}
let prop_index = self.to_index();
@ -921,7 +921,7 @@ impl FluidProperties for WaterLikeFluidProperties {
if !["water", "lava"].contains(&fluid.name) {
panic!(
"{} is not a valid fluid for {}",
fluid.name, "WaterLikeFluidProperties"
&fluid.name, "WaterLikeFluidProperties"
);
}
for (idx, state) in fluid.states.iter().enumerate() {
@ -935,7 +935,7 @@ impl FluidProperties for WaterLikeFluidProperties {
if !["water", "lava"].contains(&fluid.name) {
panic!(
"{} is not a valid fluid for {}",
fluid.name, "WaterLikeFluidProperties"
&fluid.name, "WaterLikeFluidProperties"
);
}
Self::from_state_id(fluid.default_state_index, fluid)
@ -947,7 +947,7 @@ impl FluidProperties for WaterLikeFluidProperties {
if !["water", "lava"].contains(&fluid.name) {
panic!(
"{} is not a valid fluid for {}",
fluid.name, "WaterLikeFluidProperties"
&fluid.name, "WaterLikeFluidProperties"
);
}
let mut fluid_props = Self::default(fluid);
@ -995,7 +995,7 @@ impl FluidProperties for FlowingWaterLikeFluidProperties {
if !["flowing_water", "flowing_lava"].contains(&fluid.name) {
panic!(
"{} is not a valid fluid for {}",
fluid.name, "FlowingWaterLikeFluidProperties"
&fluid.name, "FlowingWaterLikeFluidProperties"
);
}
let prop_index = self.to_index();
@ -1009,7 +1009,7 @@ impl FluidProperties for FlowingWaterLikeFluidProperties {
if !["flowing_water", "flowing_lava"].contains(&fluid.name) {
panic!(
"{} is not a valid fluid for {}",
fluid.name, "FlowingWaterLikeFluidProperties"
&fluid.name, "FlowingWaterLikeFluidProperties"
);
}
for (idx, state) in fluid.states.iter().enumerate() {
@ -1023,7 +1023,7 @@ impl FluidProperties for FlowingWaterLikeFluidProperties {
if !["flowing_water", "flowing_lava"].contains(&fluid.name) {
panic!(
"{} is not a valid fluid for {}",
fluid.name, "FlowingWaterLikeFluidProperties"
&fluid.name, "FlowingWaterLikeFluidProperties"
);
}
Self::from_state_id(fluid.default_state_index, fluid)
@ -1038,7 +1038,7 @@ impl FluidProperties for FlowingWaterLikeFluidProperties {
if !["flowing_water", "flowing_lava"].contains(&fluid.name) {
panic!(
"{} is not a valid fluid for {}",
fluid.name, "FlowingWaterLikeFluidProperties"
&fluid.name, "FlowingWaterLikeFluidProperties"
);
}
let mut fluid_props = Self::default(fluid);

View File

@ -1,5 +1,5 @@
/* This file is generated. Do not edit manually. */
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
const ITEM_ID_REMAP_V_26_1_TO_V_1_20_5: &[u16] = &[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 43, 44, 45, 46, 47, 48,
@ -1518,41 +1518,41 @@ const ITEM_ID_REMAP_V_1_21_11_TO_V_26_1: &[u16] = &[
1505, 0,
];
#[must_use]
pub fn remap_item_id_for_version(item_id: u16, version: MinecraftVersion) -> u16 {
pub fn remap_item_id_for_version(item_id: u16, version: JavaMinecraftVersion) -> u16 {
match version {
pumpkin_util::version::MinecraftVersion::V_1_20_5 => ITEM_ID_REMAP_V_26_1_TO_V_1_20_5
pumpkin_util::version::JavaMinecraftVersion::V_1_20_5 => ITEM_ID_REMAP_V_26_1_TO_V_1_20_5
.get(usize::from(item_id))
.copied()
.unwrap_or(item_id),
pumpkin_util::version::MinecraftVersion::V_1_21 => ITEM_ID_REMAP_V_26_1_TO_V_1_21
pumpkin_util::version::JavaMinecraftVersion::V_1_21 => ITEM_ID_REMAP_V_26_1_TO_V_1_21
.get(usize::from(item_id))
.copied()
.unwrap_or(item_id),
pumpkin_util::version::MinecraftVersion::V_1_21_2 => ITEM_ID_REMAP_V_26_1_TO_V_1_21_2
pumpkin_util::version::JavaMinecraftVersion::V_1_21_2 => ITEM_ID_REMAP_V_26_1_TO_V_1_21_2
.get(usize::from(item_id))
.copied()
.unwrap_or(item_id),
pumpkin_util::version::MinecraftVersion::V_1_21_4 => ITEM_ID_REMAP_V_26_1_TO_V_1_21_4
pumpkin_util::version::JavaMinecraftVersion::V_1_21_4 => ITEM_ID_REMAP_V_26_1_TO_V_1_21_4
.get(usize::from(item_id))
.copied()
.unwrap_or(item_id),
pumpkin_util::version::MinecraftVersion::V_1_21_5 => ITEM_ID_REMAP_V_26_1_TO_V_1_21_5
pumpkin_util::version::JavaMinecraftVersion::V_1_21_5 => ITEM_ID_REMAP_V_26_1_TO_V_1_21_5
.get(usize::from(item_id))
.copied()
.unwrap_or(item_id),
pumpkin_util::version::MinecraftVersion::V_1_21_6 => ITEM_ID_REMAP_V_26_1_TO_V_1_21_6
pumpkin_util::version::JavaMinecraftVersion::V_1_21_6 => ITEM_ID_REMAP_V_26_1_TO_V_1_21_6
.get(usize::from(item_id))
.copied()
.unwrap_or(item_id),
pumpkin_util::version::MinecraftVersion::V_1_21_7 => ITEM_ID_REMAP_V_26_1_TO_V_1_21_7
pumpkin_util::version::JavaMinecraftVersion::V_1_21_7 => ITEM_ID_REMAP_V_26_1_TO_V_1_21_7
.get(usize::from(item_id))
.copied()
.unwrap_or(item_id),
pumpkin_util::version::MinecraftVersion::V_1_21_9 => ITEM_ID_REMAP_V_26_1_TO_V_1_21_9
pumpkin_util::version::JavaMinecraftVersion::V_1_21_9 => ITEM_ID_REMAP_V_26_1_TO_V_1_21_9
.get(usize::from(item_id))
.copied()
.unwrap_or(item_id),
pumpkin_util::version::MinecraftVersion::V_1_21_11 => ITEM_ID_REMAP_V_26_1_TO_V_1_21_11
pumpkin_util::version::JavaMinecraftVersion::V_1_21_11 => ITEM_ID_REMAP_V_26_1_TO_V_1_21_11
.get(usize::from(item_id))
.copied()
.unwrap_or(item_id),
@ -1560,41 +1560,41 @@ pub fn remap_item_id_for_version(item_id: u16, version: MinecraftVersion) -> u16
}
}
#[must_use]
pub fn remap_item_id_from_version(item_id: u16, version: MinecraftVersion) -> u16 {
pub fn remap_item_id_from_version(item_id: u16, version: JavaMinecraftVersion) -> u16 {
match version {
pumpkin_util::version::MinecraftVersion::V_1_20_5 => ITEM_ID_REMAP_V_1_20_5_TO_V_26_1
pumpkin_util::version::JavaMinecraftVersion::V_1_20_5 => ITEM_ID_REMAP_V_1_20_5_TO_V_26_1
.get(usize::from(item_id))
.copied()
.unwrap_or(item_id),
pumpkin_util::version::MinecraftVersion::V_1_21 => ITEM_ID_REMAP_V_1_21_TO_V_26_1
pumpkin_util::version::JavaMinecraftVersion::V_1_21 => ITEM_ID_REMAP_V_1_21_TO_V_26_1
.get(usize::from(item_id))
.copied()
.unwrap_or(item_id),
pumpkin_util::version::MinecraftVersion::V_1_21_2 => ITEM_ID_REMAP_V_1_21_2_TO_V_26_1
pumpkin_util::version::JavaMinecraftVersion::V_1_21_2 => ITEM_ID_REMAP_V_1_21_2_TO_V_26_1
.get(usize::from(item_id))
.copied()
.unwrap_or(item_id),
pumpkin_util::version::MinecraftVersion::V_1_21_4 => ITEM_ID_REMAP_V_1_21_4_TO_V_26_1
pumpkin_util::version::JavaMinecraftVersion::V_1_21_4 => ITEM_ID_REMAP_V_1_21_4_TO_V_26_1
.get(usize::from(item_id))
.copied()
.unwrap_or(item_id),
pumpkin_util::version::MinecraftVersion::V_1_21_5 => ITEM_ID_REMAP_V_1_21_5_TO_V_26_1
pumpkin_util::version::JavaMinecraftVersion::V_1_21_5 => ITEM_ID_REMAP_V_1_21_5_TO_V_26_1
.get(usize::from(item_id))
.copied()
.unwrap_or(item_id),
pumpkin_util::version::MinecraftVersion::V_1_21_6 => ITEM_ID_REMAP_V_1_21_6_TO_V_26_1
pumpkin_util::version::JavaMinecraftVersion::V_1_21_6 => ITEM_ID_REMAP_V_1_21_6_TO_V_26_1
.get(usize::from(item_id))
.copied()
.unwrap_or(item_id),
pumpkin_util::version::MinecraftVersion::V_1_21_7 => ITEM_ID_REMAP_V_1_21_7_TO_V_26_1
pumpkin_util::version::JavaMinecraftVersion::V_1_21_7 => ITEM_ID_REMAP_V_1_21_7_TO_V_26_1
.get(usize::from(item_id))
.copied()
.unwrap_or(item_id),
pumpkin_util::version::MinecraftVersion::V_1_21_9 => ITEM_ID_REMAP_V_1_21_9_TO_V_26_1
pumpkin_util::version::JavaMinecraftVersion::V_1_21_9 => ITEM_ID_REMAP_V_1_21_9_TO_V_26_1
.get(usize::from(item_id))
.copied()
.unwrap_or(item_id),
pumpkin_util::version::MinecraftVersion::V_1_21_11 => ITEM_ID_REMAP_V_1_21_11_TO_V_26_1
pumpkin_util::version::JavaMinecraftVersion::V_1_21_11 => ITEM_ID_REMAP_V_1_21_11_TO_V_26_1
.get(usize::from(item_id))
.copied()
.unwrap_or(item_id),

View File

@ -661,17 +661,17 @@ impl MetaDataType {
v1_21_11: 28i32,
v26_1: 32i32,
};
pub const fn id(&self, version: pumpkin_util::version::MinecraftVersion) -> i32 {
pub const fn id(&self, version: pumpkin_util::version::JavaMinecraftVersion) -> i32 {
match version {
pumpkin_util::version::MinecraftVersion::V_1_21 => self.v1_21,
pumpkin_util::version::MinecraftVersion::V_1_21_2 => self.v1_21_2,
pumpkin_util::version::MinecraftVersion::V_1_21_4 => self.v1_21_4,
pumpkin_util::version::MinecraftVersion::V_1_21_5 => self.v1_21_5,
pumpkin_util::version::MinecraftVersion::V_1_21_6 => self.v1_21_6,
pumpkin_util::version::MinecraftVersion::V_1_21_7 => self.v1_21_7,
pumpkin_util::version::MinecraftVersion::V_1_21_9 => self.v1_21_9,
pumpkin_util::version::MinecraftVersion::V_1_21_11 => self.v1_21_11,
pumpkin_util::version::MinecraftVersion::V_26_1 => self.v26_1,
pumpkin_util::version::JavaMinecraftVersion::V_1_21 => self.v1_21,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_2 => self.v1_21_2,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_4 => self.v1_21_4,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_5 => self.v1_21_5,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_6 => self.v1_21_6,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_7 => self.v1_21_7,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_9 => self.v1_21_9,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_11 => self.v1_21_11,
pumpkin_util::version::JavaMinecraftVersion::V_26_1 => self.v26_1,
_ => -1i32,
}
}

View File

@ -1,7 +1,8 @@
/* This file is generated. Do not edit manually. */
use pumpkin_util::version::MinecraftVersion;
pub const CURRENT_MC_VERSION: MinecraftVersion = pumpkin_util::version::MinecraftVersion::V_26_1;
pub const LOWEST_SUPPORTED_MC_VERSION: MinecraftVersion = MinecraftVersion::V_1_20_5;
use pumpkin_util::version::JavaMinecraftVersion;
pub const CURRENT_MC_VERSION: JavaMinecraftVersion =
pumpkin_util::version::JavaMinecraftVersion::V_26_1;
pub const LOWEST_SUPPORTED_MC_VERSION: JavaMinecraftVersion = JavaMinecraftVersion::V_1_20_5;
#[derive(Clone, Copy, Debug)]
pub struct PacketId {
pub v1_20_5: i32,
@ -18,18 +19,18 @@ pub struct PacketId {
impl PacketId {
#[doc = r" Converts the requested protocol version into the corresponding packet ID."]
#[doc = r" Returns -1 if the packet does not exist in that version."]
pub fn to_id(&self, version: MinecraftVersion) -> i32 {
pub fn to_id(&self, version: JavaMinecraftVersion) -> i32 {
match version {
pumpkin_util::version::MinecraftVersion::V_1_20_5 => self.v1_20_5,
pumpkin_util::version::MinecraftVersion::V_1_21 => self.v1_21,
pumpkin_util::version::MinecraftVersion::V_1_21_2 => self.v1_21_2,
pumpkin_util::version::MinecraftVersion::V_1_21_4 => self.v1_21_4,
pumpkin_util::version::MinecraftVersion::V_1_21_5 => self.v1_21_5,
pumpkin_util::version::MinecraftVersion::V_1_21_6 => self.v1_21_6,
pumpkin_util::version::MinecraftVersion::V_1_21_7 => self.v1_21_7,
pumpkin_util::version::MinecraftVersion::V_1_21_9 => self.v1_21_9,
pumpkin_util::version::MinecraftVersion::V_1_21_11 => self.v1_21_11,
pumpkin_util::version::MinecraftVersion::V_26_1 => self.v26_1,
pumpkin_util::version::JavaMinecraftVersion::V_1_20_5 => self.v1_20_5,
pumpkin_util::version::JavaMinecraftVersion::V_1_21 => self.v1_21,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_2 => self.v1_21_2,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_4 => self.v1_21_4,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_5 => self.v1_21_5,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_6 => self.v1_21_6,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_7 => self.v1_21_7,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_9 => self.v1_21_9,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_11 => self.v1_21_11,
pumpkin_util::version::JavaMinecraftVersion::V_26_1 => self.v26_1,
_ => self.v26_1,
}
}

View File

@ -2016,10 +2016,10 @@ fn build_placed_features() -> std::collections::HashMap<String, PlacedFeature> {
offset: OffsetBlocksBlockPredicate { offset: None },
state: {
let mut props = std::collections::HashMap::new();
props.insert("age".to_string(), "0".to_string());
props.insert("hanging".to_string(), "false".to_string());
props.insert("stage".to_string(), "0".to_string());
props.insert("waterlogged".to_string(), "false".to_string());
props.insert("stage".to_string(), "0".to_string());
props.insert("hanging".to_string(), "false".to_string());
props.insert("age".to_string(), "0".to_string());
BlockStateCodec {
name: &pumpkin_data::Block::MANGROVE_PROPAGULE,
properties: Some(props),
@ -6186,10 +6186,10 @@ fn build_placed_features() -> std::collections::HashMap<String, PlacedFeature> {
offset: OffsetBlocksBlockPredicate { offset: None },
state: {
let mut props = std::collections::HashMap::new();
props.insert("age".to_string(), "0".to_string());
props.insert("hanging".to_string(), "false".to_string());
props.insert("stage".to_string(), "0".to_string());
props.insert("waterlogged".to_string(), "false".to_string());
props.insert("stage".to_string(), "0".to_string());
props.insert("hanging".to_string(), "false".to_string());
props.insert("age".to_string(), "0".to_string());
BlockStateCodec {
name: &pumpkin_data::Block::MANGROVE_PROPAGULE,
properties: Some(props),

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/* This file is generated. Do not edit manually. */
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
const SOUND_ID_REMAP_V_26_1_TO_V_1_20_5: &[u16] = &[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
@ -984,44 +984,46 @@ const SOUND_ID_REMAP_V_26_1_TO_V_1_21_11: &[u16] = &[
1830, 1831, 1832, 1833, 1834, 1835, 1836, 1837,
];
#[must_use]
pub fn remap_sound_id_for_version(sound_id: u16, version: MinecraftVersion) -> u16 {
pub fn remap_sound_id_for_version(sound_id: u16, version: JavaMinecraftVersion) -> u16 {
match version {
pumpkin_util::version::MinecraftVersion::V_1_20_5 => SOUND_ID_REMAP_V_26_1_TO_V_1_20_5
pumpkin_util::version::JavaMinecraftVersion::V_1_20_5 => SOUND_ID_REMAP_V_26_1_TO_V_1_20_5
.get(usize::from(sound_id))
.copied()
.unwrap_or(sound_id),
pumpkin_util::version::MinecraftVersion::V_1_21 => SOUND_ID_REMAP_V_26_1_TO_V_1_21
pumpkin_util::version::JavaMinecraftVersion::V_1_21 => SOUND_ID_REMAP_V_26_1_TO_V_1_21
.get(usize::from(sound_id))
.copied()
.unwrap_or(sound_id),
pumpkin_util::version::MinecraftVersion::V_1_21_2 => SOUND_ID_REMAP_V_26_1_TO_V_1_21_2
pumpkin_util::version::JavaMinecraftVersion::V_1_21_2 => SOUND_ID_REMAP_V_26_1_TO_V_1_21_2
.get(usize::from(sound_id))
.copied()
.unwrap_or(sound_id),
pumpkin_util::version::MinecraftVersion::V_1_21_4 => SOUND_ID_REMAP_V_26_1_TO_V_1_21_4
pumpkin_util::version::JavaMinecraftVersion::V_1_21_4 => SOUND_ID_REMAP_V_26_1_TO_V_1_21_4
.get(usize::from(sound_id))
.copied()
.unwrap_or(sound_id),
pumpkin_util::version::MinecraftVersion::V_1_21_5 => SOUND_ID_REMAP_V_26_1_TO_V_1_21_5
pumpkin_util::version::JavaMinecraftVersion::V_1_21_5 => SOUND_ID_REMAP_V_26_1_TO_V_1_21_5
.get(usize::from(sound_id))
.copied()
.unwrap_or(sound_id),
pumpkin_util::version::MinecraftVersion::V_1_21_6 => SOUND_ID_REMAP_V_26_1_TO_V_1_21_6
pumpkin_util::version::JavaMinecraftVersion::V_1_21_6 => SOUND_ID_REMAP_V_26_1_TO_V_1_21_6
.get(usize::from(sound_id))
.copied()
.unwrap_or(sound_id),
pumpkin_util::version::MinecraftVersion::V_1_21_7 => SOUND_ID_REMAP_V_26_1_TO_V_1_21_7
pumpkin_util::version::JavaMinecraftVersion::V_1_21_7 => SOUND_ID_REMAP_V_26_1_TO_V_1_21_7
.get(usize::from(sound_id))
.copied()
.unwrap_or(sound_id),
pumpkin_util::version::MinecraftVersion::V_1_21_9 => SOUND_ID_REMAP_V_26_1_TO_V_1_21_9
pumpkin_util::version::JavaMinecraftVersion::V_1_21_9 => SOUND_ID_REMAP_V_26_1_TO_V_1_21_9
.get(usize::from(sound_id))
.copied()
.unwrap_or(sound_id),
pumpkin_util::version::MinecraftVersion::V_1_21_11 => SOUND_ID_REMAP_V_26_1_TO_V_1_21_11
pumpkin_util::version::JavaMinecraftVersion::V_1_21_11 => {
SOUND_ID_REMAP_V_26_1_TO_V_1_21_11
.get(usize::from(sound_id))
.copied()
.unwrap_or(sound_id),
.unwrap_or(sound_id)
}
_ => sound_id,
}
}

View File

@ -1,5 +1,5 @@
/* This file is generated. Do not edit manually. */
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
pub type Tag = (&'static [&'static str], &'static [u16]);
#[derive(Eq, PartialEq, Hash, Debug, Clone, Copy)]
pub enum RegistryKey {
@ -134561,20 +134561,36 @@ pub fn get_tag_ids(tag_category: RegistryKey, tag: &str) -> Option<&'static [u16
.map(|t| t.1)
}
pub fn get_registry_key_tags(
version: MinecraftVersion,
version: JavaMinecraftVersion,
tag_category: RegistryKey,
) -> Option<&'static phf::Map<&'static str, &'static Tag>> {
match version {
pumpkin_util::version::MinecraftVersion::V_1_20_5 => tags_v1_20_5::get_map(tag_category),
pumpkin_util::version::MinecraftVersion::V_1_21 => tags_v1_21::get_map(tag_category),
pumpkin_util::version::MinecraftVersion::V_1_21_2 => tags_v1_21_2::get_map(tag_category),
pumpkin_util::version::MinecraftVersion::V_1_21_4 => tags_v1_21_4::get_map(tag_category),
pumpkin_util::version::MinecraftVersion::V_1_21_5 => tags_v1_21_5::get_map(tag_category),
pumpkin_util::version::MinecraftVersion::V_1_21_6 => tags_v1_21_6::get_map(tag_category),
pumpkin_util::version::MinecraftVersion::V_1_21_7 => tags_v1_21_7::get_map(tag_category),
pumpkin_util::version::MinecraftVersion::V_1_21_9 => tags_v1_21_9::get_map(tag_category),
pumpkin_util::version::MinecraftVersion::V_1_21_11 => tags_v1_21_11::get_map(tag_category),
pumpkin_util::version::MinecraftVersion::V_26_1 => get_latest_map(tag_category),
pumpkin_util::version::JavaMinecraftVersion::V_1_20_5 => {
tags_v1_20_5::get_map(tag_category)
}
pumpkin_util::version::JavaMinecraftVersion::V_1_21 => tags_v1_21::get_map(tag_category),
pumpkin_util::version::JavaMinecraftVersion::V_1_21_2 => {
tags_v1_21_2::get_map(tag_category)
}
pumpkin_util::version::JavaMinecraftVersion::V_1_21_4 => {
tags_v1_21_4::get_map(tag_category)
}
pumpkin_util::version::JavaMinecraftVersion::V_1_21_5 => {
tags_v1_21_5::get_map(tag_category)
}
pumpkin_util::version::JavaMinecraftVersion::V_1_21_6 => {
tags_v1_21_6::get_map(tag_category)
}
pumpkin_util::version::JavaMinecraftVersion::V_1_21_7 => {
tags_v1_21_7::get_map(tag_category)
}
pumpkin_util::version::JavaMinecraftVersion::V_1_21_9 => {
tags_v1_21_9::get_map(tag_category)
}
pumpkin_util::version::JavaMinecraftVersion::V_1_21_11 => {
tags_v1_21_11::get_map(tag_category)
}
pumpkin_util::version::JavaMinecraftVersion::V_26_1 => get_latest_map(tag_category),
_ => get_latest_map(tag_category),
}
}

View File

@ -1,5 +1,5 @@
/* This file is generated. Do not edit manually. */
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
pub struct TrackedId {
pub v1_21: u8,
pub v1_21_2: u8,
@ -12,17 +12,17 @@ pub struct TrackedId {
pub v26_1: u8,
}
impl TrackedId {
pub fn get(&self, version: &MinecraftVersion) -> u8 {
pub fn get(&self, version: &JavaMinecraftVersion) -> u8 {
match version {
pumpkin_util::version::MinecraftVersion::V_1_21 => self.v1_21,
pumpkin_util::version::MinecraftVersion::V_1_21_2 => self.v1_21_2,
pumpkin_util::version::MinecraftVersion::V_1_21_4 => self.v1_21_4,
pumpkin_util::version::MinecraftVersion::V_1_21_5 => self.v1_21_5,
pumpkin_util::version::MinecraftVersion::V_1_21_6 => self.v1_21_6,
pumpkin_util::version::MinecraftVersion::V_1_21_7 => self.v1_21_7,
pumpkin_util::version::MinecraftVersion::V_1_21_9 => self.v1_21_9,
pumpkin_util::version::MinecraftVersion::V_1_21_11 => self.v1_21_11,
pumpkin_util::version::MinecraftVersion::V_26_1 => self.v26_1,
pumpkin_util::version::JavaMinecraftVersion::V_1_21 => self.v1_21,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_2 => self.v1_21_2,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_4 => self.v1_21_4,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_5 => self.v1_21_5,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_6 => self.v1_21_6,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_7 => self.v1_21_7,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_9 => self.v1_21_9,
pumpkin_util::version::JavaMinecraftVersion::V_1_21_11 => self.v1_21_11,
pumpkin_util::version::JavaMinecraftVersion::V_26_1 => self.v26_1,
_ => self.v26_1,
}
}

View File

@ -211,7 +211,7 @@ pub fn java_packet(args: TokenStream, item: TokenStream) -> TokenStream {
impl #impl_generics crate::packet::MultiVersionJavaPacket for #name #ty_generics #where_clause {
#[must_use]
#[inline]
fn to_id(version: pumpkin_util::version::MinecraftVersion) -> i32 {
fn to_id(version: pumpkin_util::version::JavaMinecraftVersion) -> i32 {
#packet_id_expr.to_id(version)
}
}

View File

@ -0,0 +1,22 @@
use crate::wit::pumpkin::plugin::event::{CustomClickActionEventData, Event, EventType};
use super::super::FromIntoEvent;
/// An event that occurs when a player clicks a custom dialog button.
pub struct CustomClickActionEvent;
impl FromIntoEvent for CustomClickActionEvent {
const EVENT_TYPE: EventType = EventType::CustomClickActionEvent;
type Data = CustomClickActionEventData;
fn data_from_event(event: Event) -> Self::Data {
match event {
Event::CustomClickActionEvent(data) => data,
_ => panic!("unexpected event"),
}
}
fn data_into_event(data: Self::Data) -> Event {
Event::CustomClickActionEvent(data)
}
}

View File

@ -1,5 +1,6 @@
pub mod bedrock_form_response;
pub mod changed_main_hand;
pub mod custom_click_action;
pub mod egg_throw;
pub mod exp_change;
pub mod fish;

View File

@ -1,8 +1,7 @@
use crate::player::Player;
use crate::text::TextComponent;
use crate::wit::pumpkin::plugin::forms::{
self as wit_forms, CustomForm, CustomFormElement, Form, FormImage, ImageType, ModalForm,
SimpleForm, SimpleFormButton,
CustomForm, CustomFormElement, Form, FormImage, ImageType, ModalForm, SimpleForm,
SimpleFormButton,
};
pub struct SimpleFormBuilder {
@ -160,10 +159,6 @@ impl CustomFormBuilder {
}
}
pub fn send_form(player: Player, form: Form) -> u32 {
wit_forms::send_form(player, form)
}
pub fn url_image(url: impl Into<String>) -> FormImage {
FormImage {
type_: ImageType::Url,

View File

@ -1,6 +1,7 @@
package pumpkin:plugin@0.1.0;
interface bedrock-packets {
use uuid.{uuid};
record s-animate {
action: string,
runtime-entity-id: string,
@ -12,7 +13,7 @@ interface bedrock-packets {
record s-command-request {
command: string,
command-type: string,
command-uuid: string,
command-uuid: uuid,
request-id: string,
player-actor-unique-id: s64,
is-internal-source: bool,
@ -37,6 +38,10 @@ interface bedrock-packets {
jwt: list<u8>,
raw-token: list<u8>,
}
record s-modal-form-response {
form-id: s32,
form-data: option<string>,
}
record s-player-action {
runtime-id: s32,
action: string,
@ -146,8 +151,8 @@ interface bedrock-packets {
tick: string,
}
record creative-content {
groups: string,
entries: string,
groups: list<string>,
entries: list<string>,
}
record c-disconnect-player {
reason: s32,
@ -178,6 +183,10 @@ interface bedrock-packets {
position: tuple<f64, f64, f64>,
data: s32,
}
record c-modal-form-request {
form-id: s32,
form-data: string,
}
record c-move-player {
player-runtime-id: string,
position: tuple<f64, f64, f64>,
@ -253,7 +262,7 @@ interface bedrock-packets {
has-addon-packs: bool,
has-scripts: bool,
is-vibrant-visuals-force-disabled: bool,
world-template-id: string,
world-template-id: uuid,
world-template-version: string,
resource-packs: list<string>,
}
@ -311,7 +320,7 @@ interface bedrock-packets {
compound-len: s32,
compound-end: u8,
block-registry-checksum: s64,
world-template-id: string,
world-template-id: uuid,
enable-clientside-generation: bool,
blocknetwork-ids-are-hashed: bool,
server-auth-sounds: bool,
@ -337,6 +346,7 @@ interface bedrock-packets {
s-interaction(s-interaction),
s-loading-screen(s-loading-screen),
s-login(s-login),
s-modal-form-response(s-modal-form-response),
s-player-action(s-player-action),
s-player-auth-input(s-player-auth-input),
s-connected-ping(s-connected-ping),
@ -364,6 +374,7 @@ interface bedrock-packets {
c-inventory-content(c-inventory-content),
c-level-chunk(c-level-chunk),
c-level-event(c-level-event),
c-modal-form-request(c-modal-form-request),
c-move-player(c-move-player),
c-network-chunk-publisher-update(c-network-chunk-publisher-update),
c-network-settings(c-network-settings),

View File

@ -2,6 +2,7 @@ interface boss-bar {
use text.{text-component};
use player.{player};
/// Represents the color of a boss bar.
enum boss-bar-color {
pink,

View File

@ -1,17 +1,165 @@
interface command {
use %world.{%world};
use entity.{entity};
use %world.{%world, entity};
use player.{player};
use block-entity.{command-block-entity};
use common.{position, block-position, locale};
use common.{position, block-position, locale, item-stack, game-mode};
use server.{server, difficulty};
use text.{text-component};
enum gamemode {
survival,
creative,
adventure,
spectator,
variant command-error {
invalid-consumption(option<string>),
invalid-requirement,
permission-denied,
command-failed(text-component),
}
resource command-node {
literal: static func(name: string) -> command-node;
argument: static func(name: string, %type: argument-type) -> command-node;
then: func(node: command-node);
execute-with-handler-id: func(handler-id: u32);
require-with-handler-id: func(handler-id: u32);
}
variant argument-type {
%bool,
float(tuple<option<f32>, option<f32>>),
double(tuple<option<f64>, option<f64>>),
integer(tuple<option<s32>, option<s32>>),
long(tuple<option<s64>, option<s64>>),
%string(string-type),
entities,
entity,
players,
game-profile,
block-pos,
column-pos,
position3d,
position2d,
block-state,
block-predicate,
item,
item-predicate,
color,
component,
style,
message,
nbt-compound-tag,
nbt-tag,
nbt-path,
objective,
objective-criteria,
operation,
particle,
angle,
rotation,
scoreboard-slot,
score-holder(bool),
swizzle,
team,
item-slot,
resource-location,
mob-effect,
function,
entity-anchor,
int-range,
float-range,
dimension,
gamemode,
difficulty,
time(option<s32>),
%resource(string),
resource-or-tag(string),
resource-or-tag-key(string),
resource-key(string),
template-mirror,
template-rotation,
uuid,
}
record entity-argument {
single: bool,
players-only: bool,
}
variant command-sender-type {
rcon,
console,
player(player),
command-block(tuple<command-block-entity, %world>),
dummy,
}
enum permission-level {
zero,
one,
two,
three,
four,
}
resource command-sender {
get-command-sender-type: func() -> command-sender-type;
get-name: func() -> string;
send-message: func(text: text-component);
send-system-message: func(text: text-component);
send-error: func(text: text-component);
set-success-count: func(count: s32);
is-player: func() -> bool;
is-console: func() -> bool;
as-player: func() -> option<player>;
permission-level: func() -> permission-level;
has-permission-level: func(level: permission-level) -> bool;
has-permission: func(server: borrow<server>, node: string) -> bool;
position: func() -> option<position>;
%world: func() -> option<%world>;
get-locale: func() -> locale;
should-receive-feedback: func() -> bool;
should-broadcast-console-to-ops: func() -> bool;
should-track-output: func() -> bool;
}
enum string-type {
single-word,
quotable,
greedy,
}
enum suggestion-type {
ask-server,
all-recipes,
available-sounds,
available-biomes,
summonable-entities,
}
variant arg {
simple(string),
msg(string),
%bool(bool),
item(string),
item-predicate(string),
resource-location(string),
block(string),
block-predicate(string),
time(s32),
num(result<number, not-in-bounds>),
block-pos(tuple<s32, s32, s32>),
pos3d(tuple<f64, f64, f64>),
pos2d(tuple<f64, f64>),
rotation(tuple<f32, bool, f32, bool>),
gamemode(game-mode),
difficulty(difficulty),
players(list<player>),
particle(string),
text-component(text-component),
bossbar-color(bossbar-color),
bossbar-style(bossbar-style),
sound-category(sound-category),
damage-type(string),
effect(string),
enchantment(string),
entity-anchor(entity-anchor),
}
enum bossbar-color {
@ -43,12 +191,11 @@ interface command {
players,
ambient,
voice,
ui,
}
enum entity-anchor {
feet,
eyes,
feet,
}
variant number {
@ -63,124 +210,10 @@ interface command {
upper-bound(tuple<number, number>),
}
variant arg {
entities(list<entity>),
entity(entity),
players(list<player>),
block-pos(block-position),
pos3d(position),
pos2d(tuple<f64, f64>),
rotation(tuple<f32, bool, f32, bool>),
game-mode(gamemode),
difficulty(difficulty),
item(string),
item-predicate(string),
resource-location(string),
block(string),
block-predicate(string),
bossbar-color(bossbar-color),
bossbar-style(bossbar-style),
particle(string),
msg(string),
text-component(text-component),
time(s32),
num(result<number, not-in-bounds>),
%bool(bool),
simple(string),
sound-category(sound-category),
damage-type(string),
effect(string),
enchantment(string),
entity-anchor(entity-anchor),
}
resource consumed-args {
get-value: func(key: string) -> arg;
}
variant command-sender-type {
rcon,
console,
player(player),
command-block(tuple<command-block-entity, %world>),
dummy,
}
enum permission-level {
zero,
one,
two,
three,
four,
}
resource command-sender {
get-command-sender-type: func() -> command-sender-type;
send-message: func(text: text-component);
set-success-count: func(count: s32);
is-player: func() -> bool;
is-console: func() -> bool;
as-player: func() -> option<player>;
permission-level: func() -> permission-level;
has-permission-level: func(level: permission-level) -> bool;
has-permission: func(server: borrow<server>, node: string) -> bool;
position: func() -> option<position>;
%world: func() -> option<%world>;
get-locale: func() -> locale;
should-receive-feedback: func() -> bool;
should-broadcast-console-to-ops: func() -> bool;
should-track-output: func() -> bool;
}
enum string-type {
single-word,
quotable,
greedy,
}
variant argument-type {
%bool,
float(tuple<option<f32>, option<f32>>),
double(tuple<option<f64>, option<f64>>),
integer(tuple<option<s32>, option<s32>>),
long(tuple<option<s64>, option<s64>>),
%string(string-type),
entities,
entity,
%players,
game-profile,
block-pos,
position3d,
position2d,
block-state,
block-predicate,
item,
item-predicate,
component,
rotation,
%resource-location,
entity-anchor,
gamemode,
difficulty,
time(s32),
%resource(string),
}
variant command-error {
invalid-consumption(option<string>),
invalid-requirement,
permission-denied,
command-failed(text-component),
}
resource command-node {
literal: static func(name: string) -> command-node;
argument: static func(name: string, arg-type: argument-type) -> command-node;
then: func(node: command-node);
execute-with-handler-id: func(handler-id: u32);
require-with-handler-id: func(handler-id: u32);
}
resource command {
/// First name is primary, rest are aliases
constructor(names: list<string>, description: string);

View File

@ -1,3 +1 @@
interface entity {
use %world.{entity};
}
interface entity { use %world.{entity, raycast-result, block-direction}; }

View File

@ -5,6 +5,7 @@ interface event {
use %world.{%world};
use java-packets.{serverbound-packet as java-serverbound-packet, clientbound-packet as java-clientbound-packet};
use bedrock-packets.{serverbound-packet as bedrock-serverbound-packet, clientbound-packet as bedrock-clientbound-packet};
use uuid.{uuid};
variant serverbound-packet {
java(java-serverbound-packet),
@ -127,9 +128,9 @@ interface event {
record player-fish-event-data {
player: player,
caught-uuid: option<string>,
caught-uuid: option<uuid>,
caught-type: string,
hook-uuid: string,
hook-uuid: uuid,
state: player-fish-state,
hand: hand,
exp-to-drop: s32,
@ -138,7 +139,7 @@ interface event {
record player-egg-throw-event-data {
player: player,
egg-uuid: string,
egg-uuid: uuid,
hatching: bool,
num-hatches: u8,
hatching-type: string,
@ -265,6 +266,12 @@ interface event {
response-data: option<string>,
}
record custom-click-action-event-data {
player: player,
id: string,
payload: option<list<u8>>,
}
record server-command-event-data {
command: string,
cancelled: bool
@ -329,6 +336,7 @@ interface event {
block-grow-event,
block-place-event,
bedrock-form-response-event,
custom-click-action-event,
server-command-event,
spawn-change-event,
server-broadcast-event,
@ -367,6 +375,7 @@ interface event {
block-grow-event(block-grow-event-data),
block-place-event(block-place-event-data),
bedrock-form-response-event(bedrock-form-response-event-data),
custom-click-action-event(custom-click-action-event-data),
server-command-event(server-command-event-data),
spawn-change-event(spawn-change-event-data),
server-broadcast-event(server-broadcast-event-data),

View File

@ -1,5 +1,4 @@
interface forms {
use player.{player};
use text.{text-component};
enum image-type {
@ -49,6 +48,4 @@ interface forms {
modal(modal-form),
custom(custom-form),
}
send-form: func(player: player, form: form) -> u32;
}

View File

@ -0,0 +1,155 @@
/// Provides types and utilities for displaying rich dialogs to Java Edition players.
/// These dialogs support various layouts, body elements (text and items),
/// and interactive inputs (checkboxes, text fields, sliders).
interface java-dialogs {
use text.{text-component};
use common.{item-stack};
/// Represents the layout and button configuration of a dialog.
enum dialog-type {
/// A simple dialog with a single "OK" button.
notice,
/// A dialog with "Yes" and "No" buttons.
confirmation,
/// A scrollable list of custom buttons.
multi-action,
/// A list of buttons that open other registered dialogs.
dialog-list,
/// A dedicated menu for displaying server-related links.
server-links,
}
/// Represents an element in the main content area of a dialog.
variant dialog-body {
/// A simple text message.
plain-message(text-component),
/// A visual item display.
item(item-stack),
}
/// Represents an interactive input control in a dialog.
variant dialog-input {
/// A checkbox for true/false states.
%bool(dialog-input-bool),
/// A simple string input field.
%text(dialog-input-text),
/// A slider for numerical input within a range.
number-range(dialog-input-number-range),
/// A multiple-choice selection button.
single-option(dialog-input-single-option),
}
/// A checkbox input control.
record dialog-input-bool {
label: text-component,
default-value: bool,
}
/// A text field input control.
record dialog-input-text {
label: text-component,
placeholder: text-component,
default-value: string,
}
/// A numerical range slider input control.
record dialog-input-number-range {
label: text-component,
min-value: f32,
max-value: f32,
initial-value: f32,
step: f32,
label-format: option<string>,
}
/// A multiple-choice selection input control.
record dialog-input-single-option {
label: text-component,
options: list<text-component>,
initial-index: u32,
}
/// Defines what happens after a dialog is closed.
enum after-action {
/// Returns the player to the previous screen (e.g., keeping an inventory open).
peek,
/// Closes all open screens.
pop,
}
/// Represents a clickable button in a dialog.
record action-button {
text: text-component,
tooltip: option<text-component>,
width: option<u32>,
action: action,
}
/// Represents an action triggered by a button click.
variant action {
/// Opens an external URL.
open-url(string),
/// Triggers a custom server-side callback with an ID and optional payload.
custom-click(custom-click-action),
}
/// Represents a custom server-side action.
record custom-click-action {
/// A unique identifier for the action (sent back to the server).
id: string,
/// Optional binary data to send with the action.
payload: option<list<u8>>,
}
/// Represents a link displayed in a Java Edition dialog.
record link {
/// The label to display for the link.
label: link-label,
/// The URL the link points to.
url: string,
}
/// The label for a link, which can be a built-in type or custom text.
variant link-label {
/// A built-in link type with a predefined icon/label.
built-in(link-type),
/// A custom text component label.
custom(text-component),
}
/// Built-in link types recognized by the Java Edition client.
enum link-type {
bug-report,
community-guidelines,
support,
status,
feedback,
community,
website,
forums,
news,
announcements,
}
/// Represents a dialog shown to a Java Edition player.
record dialog {
/// The main title of the dialog.
title: text-component,
/// The layout type of the dialog.
%type: dialog-type,
/// A list of body elements to display in the main area.
body: list<dialog-body>,
/// A list of interactive input controls.
inputs: list<dialog-input>,
/// A list of clickable buttons (for multi-action and other types).
buttons: list<action-button>,
/// A list of links (primarily for server-links type).
links: list<link>,
/// What to do after the dialog is closed.
after-action: option<after-action>,
/// Whether the player can exit the dialog using the Esc key.
can-close-with-escape: bool,
/// The text shown on buttons that link to/open this dialog.
external-title: option<text-component>,
}
}

View File

@ -1,6 +1,8 @@
package pumpkin:plugin@0.1.0;
interface java-packets {
use uuid.{uuid};
record s-attack {
entity-id: s32,
}
@ -63,9 +65,13 @@ interface java-packets {
key: string,
payload: option<list<string>>,
}
record s-custom-click-action {
action-id: string,
payload: option<list<string>>,
}
record s-custom-payload {
channel: string,
data: list<string>,
data: list<u8>,
}
record s-interact {
entity-id: s32,
@ -229,7 +235,7 @@ interface java-packets {
state-id: s32,
}
record c-boss-event {
uuid: string,
uuid: uuid,
action: string,
}
record c-center-chunk {
@ -268,7 +274,7 @@ interface java-packets {
}
record c-custom-payload {
channel: string,
data: string,
data: list<u8>,
}
record c-damage-event {
entity-id: s32,
@ -423,7 +429,7 @@ interface java-packets {
max-speed: f32,
particle-count: s32,
particle-id: s32,
data: string,
data: list<u8>,
}
record c-ping-response {
payload: s64,
@ -461,7 +467,7 @@ interface java-packets {
relatives: list<string>,
}
record c-remove-player-info {
players: string,
players: list<uuid>,
}
record c-player-spawn-position {
dimension-name: string,
@ -483,7 +489,7 @@ interface java-packets {
smoker-filtering: bool,
}
record c-remove-entities {
entity-ids: string,
entity-ids: list<s32>,
}
record c-remove-mob-effect {
entity-id: s32,
@ -563,7 +569,7 @@ interface java-packets {
}
record c-set-passengers {
entity-id: s32,
passengers: string,
passengers: list<s32>,
}
record c-set-player-inventory {
slot: s32,
@ -587,6 +593,9 @@ interface java-packets {
stay-ticks: s32,
fade-out-ticks: s32,
}
record c-play-show-dialog {
dialog: string,
}
record c-sound-effect {
sound-event: string,
sound-category: s32,
@ -597,7 +606,7 @@ interface java-packets {
}
record c-spawn-entity {
entity-id: s32,
entity-uuid: string,
entity-uuid: uuid,
r-type: s32,
position: tuple<f64, f64, f64>,
velocity: string,
@ -718,6 +727,7 @@ interface java-packets {
s-confirm-teleport(s-confirm-teleport),
s-container-button-click(s-container-button-click),
s-cookie-response(s-cookie-response),
s-custom-click-action(s-custom-click-action),
s-custom-payload(s-custom-payload),
s-interact(s-interact),
s-keep-alive(s-keep-alive),
@ -763,6 +773,7 @@ interface java-packets {
c-chunk-batch-end(c-chunk-batch-end),
c-chunk-batch-start,
c-chunk-data,
c-play-clear-dialog,
c-clear-title(c-clear-title),
c-close-container(c-close-container),
c-combat-death(c-combat-death),
@ -828,6 +839,7 @@ interface java-packets {
c-update-time(c-update-time),
c-title-text(c-title-text),
c-title-animation(c-title-animation),
c-play-show-dialog(c-play-show-dialog),
c-sound-effect(c-sound-effect),
c-spawn-entity(c-spawn-entity),
c-stop-sound(c-stop-sound),

View File

@ -1,13 +1,15 @@
/// Represents a player connected to the Minecraft server.
interface player {
use common.{hand, item-stack, position, game-mode};
use %world.{%world};
use entity.{entity};
use %world.{%world, entity};
use permission.{permission-level};
use text.{text-component};
use gui.{gui};
use forms.{form};
use java-dialogs.{dialog};
use java-packets.{clientbound-packet as java-packet};
use bedrock-packets.{clientbound-packet as bedrock-packet};
use uuid.{uuid};
/// Various abilities a player can have.
record player-abilities {
@ -35,7 +37,7 @@ interface player {
signature: option<string>,
}
/// Flags representing visible skin parts.
/// Represents which skin parts are visible.
flags skin-parts {
cape,
jacket,
@ -46,12 +48,502 @@ interface player {
hat,
}
/// Represents the various abilities a Bedrock Edition player can have.
enum bedrock-ability {
/// Whether the player can build.
build,
/// Whether the player can mine blocks.
mine,
/// Whether the player can use doors and switches.
doors-and-switches,
/// Whether the player can open containers.
open-containers,
/// Whether the player can attack other players.
attack-players,
/// Whether the player can attack mobs.
attack-mobs,
/// Whether the player can use operator commands.
operator-commands,
/// Whether the player can teleport.
teleport,
/// Whether the player is invulnerable.
invulnerable,
/// Whether the player is currently flying.
flying,
/// Whether the player is allowed to fly.
may-fly,
/// Whether the player has instant build (creative).
instabuild,
/// Whether the player can use lightning-related abilities.
lightning,
/// The speed at which the player flies.
fly-speed,
/// The speed at which the player walks.
walk-speed,
/// Whether the player is muted.
muted,
/// Whether the player is a world builder.
world-builder,
/// Whether the player has no-clip enabled.
no-clip,
/// Whether the player is a privileged builder.
privileged-builder,
/// The speed at which the player flies vertically.
vertical-fly-speed,
}
/// Represents the various status flags a Bedrock Edition entity can have.
/// These flags control client-side rendering and behavior.
enum bedrock-status-flag {
/// Whether the entity is currently on fire.
on-fire,
/// Whether the entity is sneaking.
sneaking,
/// Whether the entity is riding another entity.
riding,
/// Whether the entity is sprinting.
sprinting,
/// Whether the entity is using an item (e.g., eating, blocking).
using-item,
/// Whether the entity is invisible.
invisible,
/// Whether the entity is tempted by an item.
tempted,
/// Whether the entity is in love (breeding).
in-love,
/// Whether the entity is saddled.
saddled,
/// Whether the entity is powered (e.g., charged creeper).
powered,
/// Whether the entity is ignited.
ignited,
/// Whether the entity is a baby.
baby,
/// Whether the entity is currently converting to another type.
converting,
/// Whether the entity is in a critical state.
critical,
/// Whether to show the entity's name tag.
show-name,
/// Whether to always show the entity's name tag.
always-show-name,
/// Whether the entity has no AI.
no-ai,
/// Whether the entity is silent.
silent,
/// Whether the entity is climbing a wall.
wall-climbing,
/// Whether the entity is climbing.
climb,
/// Whether the entity is swimming.
swim,
/// Whether the entity is flying.
fly,
/// Whether the entity is walking.
walk,
/// Whether the entity is resting.
resting,
/// Whether the entity is sitting.
sitting,
/// Whether the entity is angry.
angry,
/// Whether the entity is interested.
interested,
/// Whether the entity is charged.
charged,
/// Whether the entity is tamed.
tamed,
/// Whether the entity is orphaned.
orphaned,
/// Whether the entity is leashed.
leashed,
/// Whether the entity is sheared.
sheared,
/// Whether the entity is gliding (elytra).
gliding,
/// Whether the entity is an elder (e.g., elder guardian).
elder,
/// Whether the entity is moving.
moving,
/// Whether the entity is breathing.
breathing,
/// Whether the entity has a chest (e.g., donkey).
chested,
/// Whether the entity is stackable.
stackable,
/// Whether to show the bottom of the entity.
show-bottom,
/// Whether the entity is standing.
standing,
/// Whether the entity is shaking.
shaking,
/// Whether the entity is idling.
idling,
/// Whether the entity is casting (e.g., evoker).
casting,
/// Whether the entity is charging an attack.
charging,
/// Whether the entity is controlled by a keyboard.
keyboard-controlled,
/// Whether the entity is performing a power jump.
power-jump,
/// Whether the entity is dashing.
dash,
/// Whether the entity is lingering.
lingering,
/// Whether the entity has collision.
has-collision,
/// Whether the entity has gravity.
has-gravity,
/// Whether the entity is immune to fire.
fire-immune,
/// Whether the entity is dancing.
dancing,
/// Whether the entity is enchanted.
enchanted,
/// Whether a trident will return to the entity.
return-trident,
/// Whether the container is private.
container-private,
/// Whether the entity is transforming.
transforming,
/// Whether the entity damages nearby mobs.
damage-nearby-mobs,
/// Whether the entity is swimming.
swimming,
/// Whether the entity has been bribed.
bribed,
/// Whether the entity is pregnant.
pregnant,
/// Whether the entity is laying an egg.
laying-egg,
/// Whether a passenger can pick up the entity.
passenger-can-pick,
/// Whether the entity is transitioning to sitting.
transition-sitting,
/// Whether the entity is eating.
eating,
/// Whether the entity is laying down.
laying-down,
/// Whether the entity is sneezing.
sneezing,
/// Whether the entity is trusting.
trusting,
/// Whether the entity is rolling.
rolling,
/// Whether the entity is scared.
scared,
/// Whether the entity is in scaffolding.
in-scaffolding,
/// Whether the entity is over scaffolding.
over-scaffolding,
/// Whether the entity is descending through a block.
descend-through-block,
/// Whether the entity is blocking.
blocking,
/// Whether the entity is transitioning to blocking.
transition-blocking,
/// Whether the entity is blocked using a shield.
blocked-using-shield,
/// Whether the entity is blocked using a damaged shield.
blocked-using-damaged-shield,
/// Whether the entity is sleeping.
sleeping,
/// Whether the entity wants to wake up.
wants-to-wake,
/// Whether the entity shows interest in trading.
trade-interest,
/// Whether the entity can break doors.
door-breaker,
/// Whether the entity is breaking an obstruction.
breaking-obstruction,
/// Whether the entity can open doors.
door-opener,
/// Whether the entity is a captain (raid).
captain,
/// Whether the entity is stunned.
stunned,
/// Whether the entity is roaring.
roaring,
/// Whether the entity has a delayed attack.
delayed-attack,
/// Whether the entity is avoiding mobs.
avoiding-mobs,
/// Whether the entity is avoiding a block.
avoiding-block,
/// Whether the entity is facing a target for a ranged attack.
facing-target-to-range-attack,
/// Whether the entity is hidden when invisible.
hidden-when-invisible,
/// Whether the entity is in a UI.
in-ui,
/// Whether the entity is stalking.
stalking,
/// Whether the entity is emoting.
emoting,
/// Whether the entity is celebrating.
celebrating,
/// Whether the entity is admiring (piglin).
admiring,
/// Whether the entity is celebrating a special event.
celebrating-special,
/// Whether the entity is out of control.
out-of-control,
/// Whether the entity is performing a ram attack.
ram-attack,
/// Whether the entity is playing dead.
playing-dead,
/// Whether the entity is in an ascending block.
in-ascending-block,
/// Whether the entity is over a descending block.
over-descending-block,
/// Whether the entity is croaking (frog).
croaking,
/// Whether the entity is digesting a mob.
digest-mob,
/// Whether the entity has a jump goal.
jump-goal,
/// Whether the entity is emerging.
emerging,
/// Whether the entity is sniffing.
sniffing,
/// Whether the entity is digging.
digging,
/// Whether the entity is performing a sonic boom.
sonic-boom,
/// Whether the entity has a dash timeout.
has-dash-timeout,
/// Whether the entity is pushed towards the closest space.
push-towards-closest-space,
/// Whether the entity is scenting.
scenting,
/// Whether the entity is rising.
rising,
/// Whether the entity is feeling happy.
feeling-happy,
/// Whether the entity is searching.
searching,
/// Whether the entity is crawling.
crawling,
/// Whether the entity's body rotation is blocked.
body-rotation-blocked,
/// Whether the entity is rendered when invisible.
render-when-invisible,
/// Whether the entity's body rotation is axis-aligned.
body-rotation-axis-aligned,
/// Whether the entity is collidable.
collidable,
/// Whether the entity is air-controlled via WASD.
wasd-air-controlled,
/// Whether only the server can authorize a dismount.
does-server-auth-only-dismount,
/// Whether the body rotation always follows the head.
body-rotation-always-follows-head,
/// Whether the entity can use vertical movement actions.
can-use-vertical-movement-action,
/// Whether rotation is locked to the vehicle.
rotation-locked-to-vehicle,
}
/// Represents a specific version of the Minecraft Java Edition protocol.
enum java-minecraft-version {
v-1-7-2,
v-1-7-6,
v-1-8,
v-1-9,
v-1-9-1,
v-1-9-2,
v-1-9-3,
v-1-10,
v-1-11,
v-1-11-1,
v-1-12,
v-1-12-1,
v-1-12-2,
v-1-13,
v-1-13-1,
v-1-13-2,
v-1-14,
v-1-14-1,
v-1-14-2,
v-1-14-3,
v-1-14-4,
v-1-15,
v-1-15-1,
v-1-15-2,
v-1-16,
v-1-16-1,
v-1-16-2,
v-1-16-3,
v-1-16-4,
v-1-17,
v-1-17-1,
v-1-18,
v-1-18-2,
v-1-19,
v-1-19-1,
v-1-19-3,
v-1-19-4,
v-1-20,
v-1-20-2,
v-1-20-3,
v-1-20-5,
v-1-21,
v-1-21-2,
v-1-21-4,
v-1-21-5,
v-1-21-6,
v-1-21-7,
v-1-21-9,
v-1-21-11,
v-26-1,
unknown,
}
/// Represents a specific version of the Minecraft Bedrock Edition protocol.
enum bedrock-minecraft-version {
v-1-21,
v-1-26-20,
unknown,
}
/// Represents settings for a Java Edition player.
record java-player-settings {
/// The player's preferred language (e.g., \"en_us\").
locale: string,
/// The maximum distance at which chunks are rendered.
view-distance: u8,
/// The player's chat visibility settings.
chat-mode: chat-mode,
/// Whether chat colors are enabled.
chat-colors: bool,
/// The player's skin configuration options.
skin-parts: skin-parts,
/// The player's dominant hand (left or right).
main-hand: hand,
/// Whether text filtering is enabled.
text-filtering: bool,
/// Whether the player wants to appear in the server list.
server-listing: bool,
}
/// The chat visibility settings for a player.
enum chat-mode {
/// Chat is fully enabled.
enabled,
/// Only system messages and commands are shown.
commands-only,
/// Chat is completely hidden.
hidden,
}
/// Represents the operating system of a Bedrock Edition client.
enum bedrock-device-os {
android,
ios,
osx,
amazon,
gear-vr,
holo-lens,
windows-10,
win-32,
dedicated,
tv-os,
playstation,
nintendo,
xbox,
windows-phone,
linux,
/// Fallback for unrecognized operating systems.
unknown,
}
/// Represents the input mode used by a Bedrock Edition client.
enum bedrock-input-mode {
/// Unknown input mode.
unknown,
/// Mouse and keyboard.
mouse,
/// Touch screen.
touch,
/// Game controller.
game-pad,
/// Motion-based controller.
motion-controller,
}
/// Represents the UI profile used by a Bedrock Edition client.
enum bedrock-ui-profile {
/// Classic desktop UI.
classic,
/// Pocket/Mobile optimized UI.
pocket,
/// Unknown UI profile.
unknown,
}
/// Represents the graphics mode used by a Bedrock Edition client.
enum bedrock-graphics-mode {
simple,
fancy,
ray-traced,
unknown,
}
/// Represents settings and client data for a Bedrock Edition player.
record bedrock-player-settings {
/// The client's specific game version string.
game-version: string,
/// The operating system of the client device.
device-os: bedrock-device-os,
/// A unique identifier for the client device.
device-id: string,
/// The model name of the client device.
device-model: string,
/// The player's preferred language code (e.g., \"en_US\").
language-code: string,
/// The input mode currently used by the player.
current-input-mode: bedrock-input-mode,
/// The default input mode for the client device.
default-input-mode: bedrock-input-mode,
/// The UI layout profile used by the client.
ui-profile: bedrock-ui-profile,
/// The current GUI scale setting.
gui-scale: s32,
/// Whether the player is in Editor mode.
is-editor-mode: bool,
/// The maximum view distance the client supports.
max-view-distance: s32,
/// The memory tier of the client device (indicates performance level).
memory-tier: s32,
/// The graphics mode used by the client.
graphics-mode: bedrock-graphics-mode,
/// The player's unique PlayFab identifier.
playfab-id: string,
/// A random 64-bit ID generated by the client.
client-random-id: s64,
/// Platform-specific offline identifier.
platform-offline-id: string,
/// Platform-specific online identifier.
platform-online-id: string,
/// The unique ID of the player's current skin.
skin-id: string,
/// The model arm size (e.g., \"wide\" or \"slim\").
arm-size: string,
/// Whether the player is using a Character Creator (Persona) skin.
is-persona-skin: bool,
/// Whether the skin is a premium (paid) skin.
is-premium-skin: bool,
/// Whether the skin is from a trusted source.
is-trusted-skin: bool,
}
/// A handle to a player on the server.
resource player {
/// Returns the player as an entity.
as-entity: func () -> entity;
/// Returns the player's unique UUID as a string.
get-id: func () -> string;
get-id: func () -> uuid;
/// Returns the player's username.
get-name: func () -> string;
@ -69,7 +561,7 @@ interface player {
get-gamemode: func () -> game-mode;
/// Changes the player's game mode. Returns true if successful.
set-gamemode: func (mode: game-mode) -> bool;
/// Returns the player's locale (e.g., "en_us").
/// Returns the player's locale (e.g., \"en_us\").
get-locale: func () -> string;
/// Returns the player's current ping in milliseconds.
get-ping: func () -> u32;
@ -140,6 +632,9 @@ interface player {
/// Bans the player's IP address with an optional reason.
ban-ip: func (reason: option<text-component>);
/// Transfers the player to another server.
transfer: func (host: string, port: u16);
// Inventory
/// Returns the index of the currently selected hotbar slot (0-8).
@ -213,16 +708,83 @@ interface player {
/// Note: this only updates the fields, it doesn't reload the skin.
set-skin: func(skin: player-skin);
/// Returns the currently visible skin parts.
/// Returns which skin parts are visible.
get-skin-parts: func() -> skin-parts;
/// Sets which skin parts are visible.
set-skin-parts: func(parts: skin-parts);
/// Returns a Java-specific player handle, if the player is connected via Java Edition.
///
/// This allows access to Java-exclusive features like sending specific packets
/// or retrieving the client brand.
as-java: func() -> option<java-player>;
/// Returns a Bedrock-specific player handle, if the player is connected via Bedrock Edition.
///
/// This allows access to Bedrock-exclusive features like custom forms
/// or detailed device information.
as-bedrock: func() -> option<bedrock-player>;
}
/// A handle to a player connected via the Java Edition.
resource java-player {
/// Returns the Minecraft Java Edition version of the player.
get-version: func() -> java-minecraft-version;
/// Returns the brand of the player's client (e.g., \"vanilla\", \"fabric\").
get-brand: func() -> string;
/// Returns the server address the player used to connect.
get-server-address: func() -> string;
/// Returns the player's configuration settings.
get-settings: func() -> java-player-settings;
/// Sends a Java-specific clientbound packet to the player.
send-java-packet: func(packet: java-packet);
/// Sends a Bedrock-specific clientbound packet to the player.
send-bedrock-packet: func(packet: bedrock-packet);
send-packet: func(packet: java-packet);
/// Sends a custom payload packet (plugin message) to the player.
send-custom-payload: func(channel: string, data: list<u8>);
/// Shows a dialog to the player.
show-dialog: func(dialog: dialog);
/// Clears any currently shown dialog for the player.
clear-dialog: func();
}
/// A handle to a player connected via the Bedrock Edition.
resource bedrock-player {
/// Returns the Minecraft Bedrock Edition version of the player.
get-version: func() -> bedrock-minecraft-version;
/// Returns the player's configuration settings.
get-settings: func() -> bedrock-player-settings;
/// Returns whether a specific Bedrock-only ability is enabled for the player.
get-ability: func(ability: bedrock-ability) -> bool;
/// Sets whether a specific Bedrock-only ability is enabled for the player.
set-ability: func(ability: bedrock-ability, value: bool);
/// Returns whether a specific Bedrock-only status flag is enabled for the player.
///
/// Status flags control things like whether the player is on fire, sneaking,
/// sprinting, or has specific visual effects.
get-status-flag: func(flag: bedrock-status-flag) -> bool;
/// Sets whether a specific Bedrock-only status flag is enabled for the player.
///
/// This can be used to manually trigger client-side visual states.
set-status-flag: func(flag: bedrock-status-flag, value: bool);
/// Sends a Bedrock-specific clientbound packet to the player.
send-packet: func(packet: bedrock-packet);
/// Opens a Bedrock custom form for the player.
open-form: func(form: form) -> u32;
}
/// Returns a list of all players in a specific world.
get-world-players: func(world-ref: %world) -> list<player>;
}

View File

@ -37,6 +37,8 @@ world plugin {
import boss-bar;
/// Provides Bedrock custom forms.
import forms;
/// Provides Java Edition dialogs.
import java-dialogs;
// --- Plugin-provided exports ---

View File

@ -3,6 +3,7 @@ interface server {
use common.{game-mode};
use %world.{%world};
use text.{text-component};
use uuid.{uuid};
/// Represents the difficulty setting of a Minecraft server.
enum difficulty {
@ -64,7 +65,7 @@ interface server {
get-player-by-name: func(name: string) -> option<player>;
/// Searches for a player by their UUID string.
get-player-by-uuid: func(id: string) -> option<player>;
get-player-by-uuid: func(id: uuid) -> option<player>;
/// Returns a list of all worlds on this server.
get-all-worlds: func() -> list<%world>;

View File

@ -0,0 +1,16 @@
interface uuid {
/// A 128-bit UUID represented as two 64-bit integers.
record uuid {
high: u64,
low: u64,
}
/// Generates a new random v4 UUID.
generate: func() -> uuid;
/// Parses a UUID from a string. Returns none if the string is not a valid UUID.
parse: func(s: string) -> option<uuid>;
/// Converts a UUID to its standard string representation.
to-string: func(id: uuid) -> string;
}

View File

@ -5,6 +5,7 @@ interface %world {
use particles.{particle};
use sounds.{sound};
use entity-types.{entity-type};
use uuid.{uuid};
/// Defines how a block reacts when pushed by a piston.
enum piston-behavior {
@ -106,7 +107,7 @@ interface %world {
resource entity {
get-id: func() -> u32;
get-uuid: func() -> string;
get-uuid: func() -> uuid;
get-type: func() -> entity-type;
get-position: func() -> position;
@ -203,7 +204,7 @@ interface %world {
/// Returns the total age of the world in ticks.
get-world-age: func() -> u64;
/// Returns the dimension type (e.g., "minecraft:overworld").
/// Returns the dimension type (e.g., \"minecraft:overworld\").
get-dimension: func() -> string;
/// Gets the highest non-air block Y coordinate at the specified X and Z.

View File

@ -23,11 +23,11 @@ use pumpkin_protocol::java::{
status::SStatusPingRequest,
},
};
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use std::io::Cursor;
use tokio::runtime::Runtime;
const TARGET_VERSION: MinecraftVersion = MinecraftVersion::V_26_1;
const TARGET_VERSION: JavaMinecraftVersion = JavaMinecraftVersion::V_26_1;
// ---------------------------------------------------------------------------
// Helper: run every known ServerPacket::read against the same payload.

View File

@ -7,11 +7,11 @@ use pumpkin_protocol::ServerPacket;
use pumpkin_protocol::java::client::play::CPlayerPosition;
use pumpkin_protocol::packet::MultiVersionJavaPacket;
use pumpkin_protocol::ClientPacket;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use std::io::Cursor;
use tokio::runtime::Runtime;
const TARGET_VERSION: MinecraftVersion = MinecraftVersion::V_1_21_4;
const TARGET_VERSION: JavaMinecraftVersion = JavaMinecraftVersion::V_1_21_4;
fuzz_target!(|data: &[u8]| {
if data.len() < 20 {

View File

@ -5,7 +5,7 @@ use pumpkin_data::data_component::DataComponent;
use pumpkin_data::item::Item;
use pumpkin_data::item_id_remap::{remap_item_id_for_version, remap_item_id_from_version};
use pumpkin_data::item_stack::ItemStack;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use serde::ser::SerializeStruct;
use serde::{
Deserialize, Serialize, Serializer,
@ -162,7 +162,7 @@ impl ItemStackSerializer<'_> {
pub fn write_with_version(
&self,
write: impl std::io::Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let remapped_item_id = remap_item_id_for_version(self.0.item.id, *version);
let mut network_serializer = serializer::Serializer::new(write);
@ -175,7 +175,7 @@ impl ItemStackSerializer<'_> {
}
#[must_use]
pub fn to_stack_for_version(self, version: &MinecraftVersion) -> ItemStack {
pub fn to_stack_for_version(self, version: &JavaMinecraftVersion) -> ItemStack {
let mut stack = self.0.into_owned();
if stack.is_empty() {
return stack;

View File

@ -1,4 +1,5 @@
mod add_resource_pack;
mod clear_dialog;
mod config_disconnect;
mod cookie_request;
mod finish_config;
@ -6,11 +7,13 @@ mod known_packs;
mod plugin_message;
mod registry_data;
mod server_links;
mod show_dialog;
mod store_cookie;
mod transfer;
mod update_tags;
pub use add_resource_pack::*;
pub use clear_dialog::*;
pub use config_disconnect::*;
pub use cookie_request::*;
pub use finish_config::*;
@ -18,6 +21,7 @@ pub use known_packs::*;
pub use plugin_message::*;
pub use registry_data::*;
pub use server_links::*;
pub use show_dialog::*;
pub use store_cookie::*;
pub use transfer::*;
pub use update_tags::*;

View File

@ -2,7 +2,7 @@ use std::io::Write;
use pumpkin_data::packet::clientbound::CONFIG_CUSTOM_PAYLOAD;
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use crate::{
ClientPacket,
@ -26,7 +26,7 @@ impl ClientPacket for CPluginMessage<'_> {
fn write_packet_data(
&self,
write: impl Write,
_version: &MinecraftVersion,
_version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;

View File

@ -7,7 +7,7 @@ use crate::{
};
use pumpkin_data::packet::clientbound::CONFIG_REGISTRY_DATA;
use pumpkin_macros::java_packet;
use pumpkin_util::{resource_location::ResourceLocation, version::MinecraftVersion};
use pumpkin_util::{resource_location::ResourceLocation, version::JavaMinecraftVersion};
#[java_packet(CONFIG_REGISTRY_DATA)]
pub struct CRegistryData<'a> {
@ -41,7 +41,7 @@ impl ClientPacket for CRegistryData<'_> {
fn write_packet_data(
&self,
write: impl Write,
_version: &MinecraftVersion,
_version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;

View File

@ -8,7 +8,7 @@ use pumpkin_data::{
tag::{RegistryKey, get_registry_key_tags},
};
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
#[java_packet(CONFIG_UPDATE_TAGS)]
pub struct CUpdateTags<'a> {
@ -26,7 +26,7 @@ impl ClientPacket for CUpdateTags<'_> {
fn write_packet_data(
&self,
mut write: impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
write.write_list(self.tags, |p, registry_key| {
p.write_string(&format!("minecraft:{}", registry_key.identifier_string()))?;

View File

@ -0,0 +1,96 @@
use pumpkin_util::text::TextComponent;
use serde::Serialize;
#[derive(Serialize)]
pub struct DialogNBT<'a>(pub &'a Dialog);
#[derive(Serialize)]
pub struct Dialog {
pub r#type: String,
pub title: TextComponent,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub body: Vec<DialogBody>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub inputs: Vec<DialogInput>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub buttons: Vec<ActionButton>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub links: Vec<DialogLink>,
#[serde(skip_serializing_if = "Option::is_none")]
pub exit_action: Option<DialogAction>,
#[serde(skip_serializing_if = "Option::is_none")]
pub after_action: Option<String>,
pub can_close_with_escape: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub external_title: Option<TextComponent>,
}
#[derive(Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum DialogBody {
#[serde(rename = "minecraft:plain_message")]
PlainMessage { contents: TextComponent },
#[serde(rename = "minecraft:item")]
Item { item: i32 }, // TODO: ItemStack serialization to NBT
}
#[derive(Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum DialogInput {
#[serde(rename = "minecraft:boolean")]
Boolean {
label: TextComponent,
default_value: bool,
},
#[serde(rename = "minecraft:text")]
Text {
label: TextComponent,
placeholder: TextComponent,
default_value: String,
},
#[serde(rename = "minecraft:number_range")]
NumberRange {
label: TextComponent,
min: f32,
max: f32,
initial: f32,
step: f32,
#[serde(skip_serializing_if = "Option::is_none")]
label_format: Option<String>,
},
#[serde(rename = "minecraft:single_option")]
SingleOption {
label: TextComponent,
options: Vec<TextComponent>,
initial_index: u32,
},
}
#[derive(Serialize)]
pub struct ActionButton {
pub text: TextComponent,
#[serde(skip_serializing_if = "Option::is_none")]
pub tooltip: Option<TextComponent>,
#[serde(skip_serializing_if = "Option::is_none")]
pub width: Option<u32>,
pub action: DialogAction,
}
#[derive(Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum DialogAction {
#[serde(rename = "minecraft:open_url")]
OpenUrl { url: String },
#[serde(rename = "minecraft:custom")]
Custom {
id: String,
#[serde(skip_serializing_if = "Option::is_none")]
payload: Option<Vec<u8>>,
},
}
#[derive(Serialize)]
pub struct DialogLink {
pub label: crate::Label,
pub url: String,
}

View File

@ -1,5 +1,5 @@
use pumpkin_data::packet::clientbound::{LOGIN_GAME_PROFILE, LOGIN_LOGIN_FINISHED};
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use serde::Serialize;
use crate::{ClientPacket, Property, packet::MultiVersionJavaPacket, ser::NetworkWriteExt};
@ -38,9 +38,9 @@ impl<'a> CLoginSuccess<'a> {
}
impl MultiVersionJavaPacket for CLoginSuccess<'_> {
fn to_id(version: MinecraftVersion) -> i32 {
fn to_id(version: JavaMinecraftVersion) -> i32 {
// TODO: this is hacky :c
if version == MinecraftVersion::V_1_21 {
if version == JavaMinecraftVersion::V_1_21 {
LOGIN_GAME_PROFILE.to_id(version)
} else {
LOGIN_LOGIN_FINISHED.to_id(version)
@ -52,7 +52,7 @@ impl ClientPacket for CLoginSuccess<'_> {
fn write_packet_data(
&self,
mut write: impl std::io::Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), crate::ser::WritingError> {
write.write_uuid(self.uuid)?;
write.write_string(self.username)?;
@ -60,7 +60,7 @@ impl ClientPacket for CLoginSuccess<'_> {
let mut serializer = crate::ser::serializer::Serializer::new(write);
property.serialize(&mut serializer)
})?;
if version < &MinecraftVersion::V_1_21_2 {
if version < &JavaMinecraftVersion::V_1_21_2 {
write.write_bool(self.strict_error_handling)?;
}
Ok(())

View File

@ -2,7 +2,7 @@ use std::io::Write;
use pumpkin_data::packet::clientbound::LOGIN_CUSTOM_QUERY;
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use crate::{
ClientPacket, VarInt,
@ -40,7 +40,7 @@ impl ClientPacket for CLoginPluginRequest<'_> {
fn write_packet_data(
&self,
write: impl Write,
_version: &MinecraftVersion,
_version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;

View File

@ -2,6 +2,7 @@
// Server -> Client
//
pub mod config;
pub mod dialog;
pub mod login;
pub mod play;
pub mod status;

View File

@ -2,7 +2,7 @@ use std::io::Write;
use pumpkin_data::packet::clientbound::PLAY_BLOCK_ENTITY_DATA;
use pumpkin_macros::java_packet;
use pumpkin_util::{math::position::BlockPos, version::MinecraftVersion};
use pumpkin_util::{math::position::BlockPos, version::JavaMinecraftVersion};
use crate::{
ClientPacket, VarInt,
@ -38,7 +38,7 @@ impl ClientPacket for CBlockEntityData {
fn write_packet_data(
&self,
write: impl Write,
_version: &MinecraftVersion,
_version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;

View File

@ -1,7 +1,7 @@
use pumpkin_data::block_state_remap::remap_block_state_for_version;
use pumpkin_data::packet::clientbound::PLAY_BLOCK_UPDATE;
use pumpkin_util::math::position::BlockPos;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use pumpkin_macros::java_packet;
use std::io::Write;
@ -34,7 +34,7 @@ impl ClientPacket for CBlockUpdate {
fn write_packet_data(
&self,
write: impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;
write.write_block_pos(&self.location)?;

View File

@ -5,7 +5,7 @@ use crate::ser::NetworkWriteExt;
use crate::{ClientPacket, WritingError};
use pumpkin_data::packet::clientbound::PLAY_BOSS_EVENT;
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
/// Updates the "Boss Bar" displayed at the top of the player's screen.
///
@ -30,7 +30,7 @@ impl ClientPacket for CBossEvent<'_> {
fn write_packet_data(
&self,
write: impl Write,
_version: &MinecraftVersion,
_version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;

View File

@ -6,7 +6,7 @@ use pumpkin_data::packet::CURRENT_MC_VERSION;
use pumpkin_data::packet::clientbound::PLAY_LEVEL_CHUNK_WITH_LIGHT;
use pumpkin_macros::java_packet;
use pumpkin_util::math::position::get_local_cord;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use pumpkin_world::chunk::format::LightContainer;
use pumpkin_world::chunk::{ChunkData, palette::NetworkPalette};
use std::io::Write;
@ -24,7 +24,7 @@ impl ClientPacket for CChunkData<'_> {
fn write_packet_data(
&self,
mut write: impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
// Chunk X
write.write_i32_be(self.0.x)?;
@ -36,7 +36,7 @@ impl ClientPacket for CChunkData<'_> {
.heightmap
.lock()
.map_err(|_| WritingError::Message("heightmap lock poisoned".into()))?;
if version <= &MinecraftVersion::V_1_21_4 {
if version <= &JavaMinecraftVersion::V_1_21_4 {
pumpkin_nbt::serializer::to_bytes_unnamed(&*heightmaps, &mut write)
.map_err(|err| WritingError::Serde(err.to_string()))?;
} else {
@ -77,7 +77,7 @@ impl ClientPacket for CChunkData<'_> {
for (block_palette, biome_palette) in block_sections.iter().zip(biome_sections.iter()) {
let non_empty_block_count = block_palette.non_air_block_count() as i16;
blocks_and_biomes_buf.write_i16_be(non_empty_block_count)?;
if version >= &MinecraftVersion::V_26_1 {
if version >= &JavaMinecraftVersion::V_26_1 {
// New in 26.1, fluid count
let liquid_count = block_palette.liquid_block_count() as i16;
blocks_and_biomes_buf.write_i16_be(liquid_count)?;
@ -137,7 +137,7 @@ impl ClientPacket for CChunkData<'_> {
NetworkPalette::Direct => {}
}
if version <= &MinecraftVersion::V_1_21_4 {
if version <= &JavaMinecraftVersion::V_1_21_4 {
blocks_and_biomes_buf
.write_list(&block_network.packed_data, |buf, &packed| {
buf.write_i64_be(packed)
@ -171,7 +171,7 @@ impl ClientPacket for CChunkData<'_> {
NetworkPalette::Direct => {}
}
if version <= &MinecraftVersion::V_1_21_4 {
if version <= &JavaMinecraftVersion::V_1_21_4 {
blocks_and_biomes_buf
.write_list(&biome_network.packed_data, |buf, &packed| {
buf.write_i64_be(packed)

View File

@ -0,0 +1,20 @@
use pumpkin_data::packet::clientbound::PLAY_CLEAR_DIALOG;
use pumpkin_macros::java_packet;
use serde::Serialize;
#[derive(Serialize)]
#[java_packet(PLAY_CLEAR_DIALOG)]
pub struct CPlayClearDialog;
impl CPlayClearDialog {
#[must_use]
pub const fn new() -> Self {
Self {}
}
}
impl Default for CPlayClearDialog {
fn default() -> Self {
Self::new()
}
}

View File

@ -2,7 +2,7 @@ use std::io::Write;
use pumpkin_data::packet::clientbound::PLAY_COMMANDS;
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use crate::{ClientPacket, VarInt, WritingError, ser::NetworkWriteExt};
@ -35,7 +35,7 @@ impl ClientPacket for CCommands<'_> {
fn write_packet_data(
&self,
write: impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;
write.write_list(&self.nodes, |bytebuf, node: &ProtoNode| {
@ -78,7 +78,7 @@ impl ProtoNode<'_> {
pub fn write_to(
&self,
write: &mut impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
// flags
let mut redirect_target_on_flag = 0i32;
@ -245,13 +245,13 @@ impl ArgumentType<'_> {
pub const SCORE_HOLDER_FLAG_ALLOW_MULTIPLE: u8 = 1;
#[must_use]
pub fn to_id(&self, version: &MinecraftVersion) -> i32 {
pub fn to_id(&self, version: &JavaMinecraftVersion) -> i32 {
// Safety: Since Self is repr(u32), it is guaranteed to hold the discriminant in the first 4 bytes
// See https://doc.rust-lang.org/reference/items/enumerations.html#pointer-casting
let id = unsafe { *std::ptr::from_ref::<Self>(self).cast::<i32>() };
// TODO: Should probably be extracting ViaVersion backward mapping data for this
if version < &MinecraftVersion::V_1_21_5 {
if version < &JavaMinecraftVersion::V_1_21_5 {
match id {
..=16 => id,
18..=46 => id - 1,
@ -264,7 +264,7 @@ impl ArgumentType<'_> {
// 54 Dialog => String
17 | 47 | 54 => 5,
}
} else if version < &MinecraftVersion::V_1_21_6 {
} else if version < &JavaMinecraftVersion::V_1_21_6 {
match id {
..=16 => id,
18..=53 => id - 1,
@ -284,7 +284,7 @@ impl ArgumentType<'_> {
pub fn write_to_buffer(
&self,
write: &mut impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let id = self.to_id(version);
write.write_var_int(&(id).into())?;

View File

@ -2,7 +2,7 @@ use std::io::Write;
use pumpkin_data::packet::clientbound::PLAY_CUSTOM_PAYLOAD;
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use crate::{
ClientPacket,
@ -27,7 +27,7 @@ impl ClientPacket for CCustomPayload<'_> {
fn write_packet_data(
&self,
write: impl Write,
_version: &MinecraftVersion,
_version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;

View File

@ -5,7 +5,7 @@ use pumpkin_data::{
packet::clientbound::PLAY_SET_ENTITY_DATA, tracked_data::TrackedId,
};
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use serde::Serialize;
use crate::{
@ -41,7 +41,7 @@ impl ClientPacket for CSetEntityMetadata {
fn write_packet_data(
&self,
write: impl Write,
_version: &MinecraftVersion,
_version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;
@ -72,7 +72,7 @@ impl<T> Metadata<T> {
pub fn write<W: std::io::Write>(
&self,
mut writer: W,
version: &pumpkin_util::version::MinecraftVersion,
version: &pumpkin_util::version::JavaMinecraftVersion,
) -> Result<(), WritingError>
where
T: Serialize,

View File

@ -5,7 +5,7 @@ use pumpkin_data::{
sound_id_remap::remap_sound_id_for_version,
};
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use crate::{ClientPacket, IdOr, SoundEvent, VarInt, WritingError, ser::NetworkWriteExt};
@ -58,7 +58,7 @@ impl ClientPacket for CEntitySoundEffect {
fn write_packet_data(
&self,
mut write: impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let sound_event = match &self.sound_event {
IdOr::Id(id) => IdOr::Id(remap_sound_id_for_version(*id, *version)),
@ -80,13 +80,13 @@ mod tests {
use pumpkin_data::sound::SoundCategory;
use pumpkin_data::sound_id_remap::remap_sound_id_for_version;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use crate::{ClientPacket, IdOr, SoundEvent, VarInt};
use super::CEntitySoundEffect;
fn first_remapped_sound_id(version: MinecraftVersion) -> u16 {
fn first_remapped_sound_id(version: JavaMinecraftVersion) -> u16 {
(0..=u16::MAX)
.find(|id| remap_sound_id_for_version(*id, version) != *id)
.expect("sound remap table should contain at least one changed id")
@ -98,7 +98,7 @@ mod tests {
#[test]
fn numeric_sound_id_remaps_for_1_21_11() {
let sound_id = first_remapped_sound_id(MinecraftVersion::V_1_21_11);
let sound_id = first_remapped_sound_id(JavaMinecraftVersion::V_1_21_11);
let packet = CEntitySoundEffect::new(
IdOr::Id(sound_id),
SoundCategory::Players,
@ -110,18 +110,18 @@ mod tests {
let mut bytes = Vec::new();
packet
.write_packet_data(&mut bytes, &MinecraftVersion::V_1_21_11)
.write_packet_data(&mut bytes, &JavaMinecraftVersion::V_1_21_11)
.unwrap();
assert_eq!(
first_var_int(bytes),
VarInt::from(remap_sound_id_for_version(sound_id, MinecraftVersion::V_1_21_11) + 1)
VarInt::from(remap_sound_id_for_version(sound_id, JavaMinecraftVersion::V_1_21_11) + 1)
);
}
#[test]
fn numeric_sound_id_stays_latest_for_26_1() {
let sound_id = first_remapped_sound_id(MinecraftVersion::V_1_21_11);
let sound_id = first_remapped_sound_id(JavaMinecraftVersion::V_1_21_11);
let packet = CEntitySoundEffect::new(
IdOr::Id(sound_id),
SoundCategory::Players,
@ -133,7 +133,7 @@ mod tests {
let mut bytes = Vec::new();
packet
.write_packet_data(&mut bytes, &MinecraftVersion::V_26_1)
.write_packet_data(&mut bytes, &JavaMinecraftVersion::V_26_1)
.unwrap();
assert_eq!(first_var_int(bytes), VarInt::from(sound_id + 1));
@ -155,7 +155,7 @@ mod tests {
let mut bytes = Vec::new();
packet
.write_packet_data(&mut bytes, &MinecraftVersion::V_1_21_11)
.write_packet_data(&mut bytes, &JavaMinecraftVersion::V_1_21_11)
.unwrap();
assert_eq!(first_var_int(bytes), VarInt::from(0));

View File

@ -2,7 +2,7 @@ use std::io::Write;
use pumpkin_data::packet::clientbound::PLAY_SET_ENTITY_MOTION;
use pumpkin_macros::java_packet;
use pumpkin_util::{math::vector3::Vector3, version::MinecraftVersion};
use pumpkin_util::{math::vector3::Vector3, version::JavaMinecraftVersion};
use crate::{
ClientPacket, VarInt, WritingError, codec::lp_vector_3d::LpVector3d, ser::NetworkWriteExt,
@ -34,14 +34,14 @@ impl ClientPacket for CEntityVelocity {
fn write_packet_data(
&self,
write: impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;
write.write_var_int(&self.entity_id)?;
// Protocol 773+ uses packed velocity; 772 and below use three i16 components.
if version >= &MinecraftVersion::V_1_21_9 {
if version >= &JavaMinecraftVersion::V_1_21_9 {
self.velocity.write(&mut write)?;
} else {
self.velocity.write_legacy(&mut write)?;
@ -53,7 +53,7 @@ impl ClientPacket for CEntityVelocity {
#[cfg(test)]
mod tests {
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use super::CEntityVelocity;
use crate::{
@ -61,7 +61,7 @@ mod tests {
codec::lp_vector_3d::{LpVector3d, encode_legacy_velocity_component},
};
fn encode_packet(version: MinecraftVersion) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
fn encode_packet(version: JavaMinecraftVersion) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let packet = CEntityVelocity::new(
VarInt(1),
pumpkin_util::math::vector3::Vector3::new(0.5, -0.5, 0.25),
@ -82,7 +82,7 @@ mod tests {
#[test]
fn entity_velocity_uses_legacy_format_for_1_21_8() -> Result<(), Box<dyn std::error::Error>> {
// V_1_21_7 enum variant represents protocol 772 (used by 1.21.7 and 1.21.8).
let encoded = encode_packet(MinecraftVersion::V_1_21_7)?;
let encoded = encode_packet(JavaMinecraftVersion::V_1_21_7)?;
let expected_legacy_tail = legacy_bytes(0.5, -0.5, 0.25);
assert_eq!(encoded, [&[1], expected_legacy_tail.as_slice()].concat());
@ -91,7 +91,7 @@ mod tests {
#[test]
fn entity_velocity_uses_packed_format_for_1_21_9() -> Result<(), Box<dyn std::error::Error>> {
let encoded = encode_packet(MinecraftVersion::V_1_21_9)?;
let encoded = encode_packet(JavaMinecraftVersion::V_1_21_9)?;
let legacy_like = legacy_bytes(0.5, -0.5, 0.25);
assert_ne!(&encoded[1..], legacy_like.as_slice());

View File

@ -9,7 +9,7 @@ use pumpkin_data::packet::clientbound::PLAY_LEVEL_EVENT;
use pumpkin_data::world::WorldEvent;
use pumpkin_macros::java_packet;
use pumpkin_util::math::position::BlockPos;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
/// Triggers a specific sound or particle effect at a world location.
///
@ -53,7 +53,7 @@ impl ClientPacket for CLevelEvent {
fn write_packet_data(
&self,
write: impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;
write.write_i32_be(self.event)?;

View File

@ -3,7 +3,7 @@ use crate::codec::bit_set::BitSet;
use crate::{ClientPacket, VarInt, ser::NetworkWriteExt};
use pumpkin_data::packet::clientbound::PLAY_LIGHT_UPDATE;
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use pumpkin_world::chunk::ChunkData;
use pumpkin_world::chunk::format::LightContainer;
use std::io::Write;
@ -19,7 +19,7 @@ impl ClientPacket for CLightUpdate<'_> {
fn write_packet_data(
&self,
write: impl Write,
_version: &MinecraftVersion,
_version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;

View File

@ -1,6 +1,6 @@
use pumpkin_data::{dimension::Dimension, packet::clientbound::PLAY_LOGIN};
use pumpkin_util::{
math::position::BlockPos, resource_location::ResourceLocation, version::MinecraftVersion,
math::position::BlockPos, resource_location::ResourceLocation, version::JavaMinecraftVersion,
};
use pumpkin_macros::java_packet;
@ -106,7 +106,7 @@ impl ClientPacket for CLogin {
fn write_packet_data(
&self,
mut write: impl std::io::Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
write.write_i32_be(self.entity_id)?;
write.write_bool(self.is_hardcore)?;
@ -117,7 +117,7 @@ impl ClientPacket for CLogin {
write.write_bool(self.reduced_debug_info)?;
write.write_bool(self.enabled_respawn_screen)?;
write.write_bool(self.limited_crafting)?;
if version >= &MinecraftVersion::V_1_21_2 {
if version >= &JavaMinecraftVersion::V_1_21_2 {
write.write_var_int(&VarInt(self.dimension.id as i32))?;
} else {
write.write_string("")?;
@ -134,7 +134,7 @@ impl ClientPacket for CLogin {
Ok(())
})?;
write.write_var_int(&self.portal_cooldown)?;
if version >= &MinecraftVersion::V_1_21_2 {
if version >= &JavaMinecraftVersion::V_1_21_2 {
write.write_var_int(&self.sealevel)?;
}
write.write_bool(self.enforce_secure_chat)?;

View File

@ -32,7 +32,7 @@ impl ClientPacket for CMapItemData<'_> {
fn write_packet_data(
&self,
mut write: impl Write,
_version: &pumpkin_util::version::MinecraftVersion,
_version: &pumpkin_util::version::JavaMinecraftVersion,
) -> Result<(), WritingError> {
write.write_var_int(&self.map_id)?;
write.write_i8(self.scale)?;

View File

@ -11,6 +11,7 @@ mod change_difficulty;
mod chunk_batch_end;
mod chunk_batch_start;
mod chunk_data;
mod clear_dialog;
mod clear_title;
mod close_container;
mod combat_death;
@ -78,6 +79,7 @@ mod set_player_team;
mod set_time;
mod set_title;
mod set_title_animation;
mod show_dialog;
mod sound_effect;
mod spawn_entity;
mod stop_sound;
@ -113,6 +115,7 @@ pub use change_difficulty::*;
pub use chunk_batch_end::*;
pub use chunk_batch_start::*;
pub use chunk_data::*;
pub use clear_dialog::*;
pub use clear_title::*;
pub use close_container::*;
pub use combat_death::*;
@ -180,6 +183,7 @@ pub use set_player_team::*;
pub use set_time::*;
pub use set_title::*;
pub use set_title_animation::*;
pub use show_dialog::*;
pub use sound_effect::*;
pub use spawn_entity::*;
pub use stop_sound::*;

View File

@ -4,7 +4,7 @@ use pumpkin_util::math::{
position::{BlockPos, chunk_section_from_pos, pack_local_chunk_section},
vector3::{self},
};
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use pumpkin_macros::java_packet;
use std::io::Write;
@ -55,7 +55,7 @@ impl ClientPacket for CMultiBlockUpdate {
fn write_packet_data(
&self,
write: impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;
write.write_i64_be(self.chunk_section)?;

View File

@ -2,7 +2,7 @@ use std::io::Write;
use pumpkin_data::packet::clientbound::PLAY_LEVEL_PARTICLES;
use pumpkin_macros::java_packet;
use pumpkin_util::{math::vector3::Vector3, version::MinecraftVersion};
use pumpkin_util::{math::vector3::Vector3, version::JavaMinecraftVersion};
use crate::{
ClientPacket, VarInt,
@ -68,7 +68,7 @@ impl ClientPacket for CParticle<'_> {
fn write_packet_data(
&self,
write: impl Write,
_version: &MinecraftVersion,
_version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;

View File

@ -2,7 +2,7 @@ use std::io::Write;
use pumpkin_data::packet::clientbound::PLAY_PLAYER_CHAT;
use pumpkin_macros::java_packet;
use pumpkin_util::{text::TextComponent, version::MinecraftVersion};
use pumpkin_util::{text::TextComponent, version::JavaMinecraftVersion};
use crate::{
ClientPacket, WritingError,
@ -91,7 +91,7 @@ impl ClientPacket for CPlayerChatMessage {
fn write_packet_data(
&self,
write: impl Write,
_version: &MinecraftVersion,
_version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;

View File

@ -3,7 +3,7 @@ use std::io::Write;
use bitflags::bitflags;
use pumpkin_data::packet::clientbound::PLAY_PLAYER_INFO_UPDATE;
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use crate::{ClientPacket, Property, WritingError, ser::NetworkWriteExt};
@ -66,7 +66,7 @@ impl ClientPacket for CPlayerInfoUpdate<'_> {
fn write_packet_data(
&self,
write: impl Write,
_version: &MinecraftVersion,
_version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;

View File

@ -2,7 +2,7 @@ use std::io::Write;
use pumpkin_data::packet::clientbound::PLAY_PLAYER_POSITION;
use pumpkin_macros::java_packet;
use pumpkin_util::{math::vector3::Vector3, version::MinecraftVersion};
use pumpkin_util::{math::vector3::Vector3, version::JavaMinecraftVersion};
use crate::{
ClientPacket, PositionFlag, ServerPacket, VarInt, WritingError, ser::NetworkReadExt,
@ -57,9 +57,9 @@ impl ClientPacket for CPlayerPosition {
fn write_packet_data(
&self,
mut write: impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
if version >= &MinecraftVersion::V_1_21_2 {
if version >= &JavaMinecraftVersion::V_1_21_2 {
write.write_var_int(&self.teleport_id)?;
write.write_f64_be(self.position.x)?;
write.write_f64_be(self.position.y)?;
@ -87,7 +87,7 @@ impl ClientPacket for CPlayerPosition {
impl ServerPacket for CPlayerPosition {
fn read(
mut read: impl std::io::Read,
_version: &MinecraftVersion,
_version: &JavaMinecraftVersion,
) -> Result<Self, crate::ser::ReadingError> {
Ok(Self {
teleport_id: read.get_var_int()?,

View File

@ -2,7 +2,7 @@ use std::io::Write;
use pumpkin_data::packet::clientbound::PLAY_SET_DEFAULT_SPAWN_POSITION;
use pumpkin_macros::java_packet;
use pumpkin_util::{math::position::BlockPos, version::MinecraftVersion};
use pumpkin_util::{math::position::BlockPos, version::JavaMinecraftVersion};
use crate::{
ClientPacket,
@ -42,17 +42,17 @@ impl ClientPacket for CPlayerSpawnPosition {
fn write_packet_data(
&self,
write: impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;
if *version >= MinecraftVersion::V_1_21_9 {
if *version >= JavaMinecraftVersion::V_1_21_9 {
write.write_string(&self.dimension_name)?;
}
write.write_block_pos(&self.location)?;
write.write_f32_be(self.yaw)?;
if *version >= MinecraftVersion::V_1_21_9 {
if *version >= JavaMinecraftVersion::V_1_21_9 {
write.write_f32_be(self.pitch)?;
}

View File

@ -9,7 +9,7 @@ use pumpkin_data::recipes::{
RecipeIngredientTypes, RecipeResultStruct,
};
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use crate::{
ClientPacket, VarInt, WritingError, codec::item_stack_seralizer::ItemStackSerializer,
@ -63,28 +63,28 @@ impl CRecipeBookAdd {
}
}
fn item_id_versioned(item: &Item, version: MinecraftVersion) -> i32 {
fn item_id_versioned(item: &Item, version: JavaMinecraftVersion) -> i32 {
remap_item_id_for_version(item.id, version) as i32
}
fn slot_display_item_type(version: MinecraftVersion) -> i32 {
if version >= MinecraftVersion::V_26_1 {
fn slot_display_item_type(version: JavaMinecraftVersion) -> i32 {
if version >= JavaMinecraftVersion::V_26_1 {
SLOT_DISPLAY_ITEM_26_1
} else {
SLOT_DISPLAY_ITEM_LEGACY
}
}
fn slot_display_composite_type(version: MinecraftVersion) -> i32 {
if version >= MinecraftVersion::V_26_1 {
fn slot_display_composite_type(version: JavaMinecraftVersion) -> i32 {
if version >= JavaMinecraftVersion::V_26_1 {
SLOT_DISPLAY_COMPOSITE_26_1
} else {
SLOT_DISPLAY_COMPOSITE_LEGACY
}
}
fn slot_display_item_stack_type(version: MinecraftVersion) -> i32 {
if version >= MinecraftVersion::V_26_1 {
fn slot_display_item_stack_type(version: JavaMinecraftVersion) -> i32 {
if version >= JavaMinecraftVersion::V_26_1 {
SLOT_DISPLAY_ITEM_STACK_26_1
} else {
SLOT_DISPLAY_ITEM_STACK_LEGACY
@ -94,7 +94,7 @@ fn slot_display_item_stack_type(version: MinecraftVersion) -> i32 {
fn write_item_slot_display(
write: &mut impl Write,
item: &Item,
version: MinecraftVersion,
version: JavaMinecraftVersion,
) -> Result<(), WritingError> {
write.write_var_int(&VarInt(slot_display_item_type(version)))?;
write.write_var_int(&VarInt(item_id_versioned(item, version)))?;
@ -105,7 +105,7 @@ fn write_item_stack_slot_display(
write: &mut impl Write,
item: &Item,
count: u8,
version: MinecraftVersion,
version: JavaMinecraftVersion,
) -> Result<(), WritingError> {
write.write_var_int(&VarInt(slot_display_item_stack_type(version)))?;
let static_item = Item::from_id(item.id)
@ -127,7 +127,7 @@ fn write_any_fuel_slot_display(write: &mut impl Write) -> Result<(), WritingErro
fn write_ingredient_slot_display(
write: &mut impl Write,
ingredient: &RecipeIngredientTypes,
version: MinecraftVersion,
version: JavaMinecraftVersion,
) -> Result<(), WritingError> {
match ingredient {
RecipeIngredientTypes::Simple(id) => {
@ -178,7 +178,7 @@ fn write_ingredient_slot_display(
fn write_ingredient_holderset(
write: &mut impl Write,
ingredient: Option<&RecipeIngredientTypes>,
version: MinecraftVersion,
version: JavaMinecraftVersion,
) -> Result<(), WritingError> {
match ingredient {
// Empty ingredient slot -> direct list of 0 items -> VarInt(0 + 1) = VarInt(1)
@ -223,7 +223,7 @@ fn write_ingredient_holderset(
fn write_crafting_requirements(
write: &mut impl Write,
slots: &[Option<&RecipeIngredientTypes>],
version: MinecraftVersion,
version: JavaMinecraftVersion,
) -> Result<(), WritingError> {
write.write_bool(true)?; // present
write.write_var_int(&VarInt(slots.len() as i32))?;
@ -236,7 +236,7 @@ fn write_crafting_requirements(
fn write_result_slot_display(
write: &mut impl Write,
result: &RecipeResultStruct,
version: MinecraftVersion,
version: JavaMinecraftVersion,
) -> Result<(), WritingError> {
let key = result.id.strip_prefix("minecraft:").unwrap_or(result.id);
if let Some(item) = Item::from_registry_key(key) {
@ -296,7 +296,7 @@ const fn crafting_category(cat: &RecipeCategoryTypes) -> i32 {
fn write_entry(
write: &mut impl Write,
display_id: i32,
version: MinecraftVersion,
version: JavaMinecraftVersion,
group_id: Option<i32>,
flags: u8,
crafting_table: &Item,
@ -467,7 +467,7 @@ impl ClientPacket for CRecipeBookAdd {
fn write_packet_data(
&self,
write: impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;

View File

@ -2,7 +2,7 @@ use std::io::Write;
use pumpkin_data::packet::clientbound::PLAY_RECIPE_BOOK_SETTINGS;
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use crate::{ClientPacket, WritingError, ser::NetworkWriteExt};
@ -42,7 +42,7 @@ impl ClientPacket for CRecipeBookSettings {
fn write_packet_data(
&self,
write: impl Write,
_version: &MinecraftVersion,
_version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;
write.write_bool(self.crafting_open)?;

View File

@ -6,7 +6,7 @@ use crate::{ClientPacket, WritingError, ser::NetworkWriteExt};
use pumpkin_data::packet::clientbound::PLAY_CONTAINER_SET_CONTENT;
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
#[java_packet(PLAY_CONTAINER_SET_CONTENT)]
pub struct CSetContainerContent<'a> {
@ -37,7 +37,7 @@ impl ClientPacket for CSetContainerContent<'_> {
fn write_packet_data(
&self,
write: impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;

View File

@ -6,7 +6,7 @@ use crate::{ClientPacket, WritingError, ser::NetworkWriteExt};
use pumpkin_data::packet::clientbound::PLAY_CONTAINER_SET_SLOT;
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
#[java_packet(PLAY_CONTAINER_SET_SLOT)]
pub struct CSetContainerSlot<'a> {
@ -37,7 +37,7 @@ impl ClientPacket for CSetContainerSlot<'_> {
fn write_packet_data(
&self,
write: impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;

View File

@ -5,7 +5,7 @@ use crate::{ClientPacket, WritingError};
use pumpkin_data::packet::clientbound::PLAY_SET_CURSOR_ITEM;
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
#[java_packet(PLAY_SET_CURSOR_ITEM)]
pub struct CSetCursorItem<'a> {
@ -23,7 +23,7 @@ impl ClientPacket for CSetCursorItem<'_> {
fn write_packet_data(
&self,
write: impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
self.stack.write_with_version(write, version)
}

View File

@ -3,7 +3,7 @@ use std::io::Write;
use crate::{WritingError, ser::NetworkWriteExt};
use pumpkin_data::packet::clientbound::PLAY_SET_EQUIPMENT;
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use crate::{
ClientPacket,
@ -33,7 +33,7 @@ impl ClientPacket for CSetEquipment {
fn write_packet_data(
&self,
write: impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;

View File

@ -1,5 +1,5 @@
use pumpkin_data::packet::clientbound::{PLAY_SET_CARRIED_ITEM, PLAY_SET_HELD_SLOT};
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use serde::Serialize;
use crate::packet::MultiVersionJavaPacket;
@ -17,10 +17,10 @@ impl CSetSelectedSlot {
}
impl MultiVersionJavaPacket for CSetSelectedSlot {
fn to_id(version: MinecraftVersion) -> i32 {
if version >= MinecraftVersion::V_1_21_2 {
fn to_id(version: JavaMinecraftVersion) -> i32 {
if version >= JavaMinecraftVersion::V_1_21_2 {
PLAY_SET_HELD_SLOT.to_id(version)
} else if version == MinecraftVersion::V_1_21 {
} else if version == JavaMinecraftVersion::V_1_21 {
PLAY_SET_CARRIED_ITEM.to_id(version)
} else {
PLAY_SET_HELD_SLOT.to_id(version)

View File

@ -6,7 +6,7 @@ use crate::{ClientPacket, WritingError, ser::NetworkWriteExt};
use pumpkin_data::packet::clientbound::PLAY_SET_PLAYER_INVENTORY;
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
#[java_packet(PLAY_SET_PLAYER_INVENTORY)]
pub struct CSetPlayerInventory<'a> {
@ -25,7 +25,7 @@ impl ClientPacket for CSetPlayerInventory<'_> {
fn write_packet_data(
&self,
write: impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;
write.write_var_int(&self.slot)?;

View File

@ -2,7 +2,7 @@ use std::io::Write;
use pumpkin_data::packet::clientbound::PLAY_SET_PLAYER_TEAM;
use pumpkin_macros::java_packet;
use pumpkin_util::{text::TextComponent, version::MinecraftVersion};
use pumpkin_util::{text::TextComponent, version::JavaMinecraftVersion};
use crate::{
ClientPacket,
@ -42,7 +42,7 @@ impl ClientPacket for CSetPlayerTeam<'_> {
fn write_packet_data(
&self,
mut write: impl Write,
_version: &MinecraftVersion,
_version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
write.write_string(&self.team_name)?;
write.write_i8(self.method as i8)?;

View File

@ -1,6 +1,6 @@
use pumpkin_data::packet::clientbound::PLAY_SET_TIME;
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use crate::{
ClientPacket,
@ -32,11 +32,11 @@ impl ClientPacket for CUpdateTime {
fn write_packet_data(
&self,
mut write: impl std::io::Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
write.write_i64_be(self.game_time)?;
if version >= &MinecraftVersion::V_26_1 {
if version >= &JavaMinecraftVersion::V_26_1 {
write.write_var_int(&VarInt(self.clock_updates.len() as i32))?;
for &(clock_id, total_ticks, partial_tick, rate) in &self.clock_updates {
write.write_var_int(&VarInt(clock_id))?;
@ -53,7 +53,7 @@ impl ClientPacket for CUpdateTime {
write.write_i64_be(day_time)?;
if version >= &MinecraftVersion::V_1_21_2 {
if version >= &JavaMinecraftVersion::V_1_21_2 {
let is_increasing = rate > 0.0;
write.write_bool(is_increasing)?;
}

View File

@ -0,0 +1,18 @@
use crate::IdOr;
use crate::java::client::dialog::DialogNBT;
use pumpkin_data::packet::clientbound::PLAY_SHOW_DIALOG;
use pumpkin_macros::java_packet;
use serde::Serialize;
#[derive(Serialize)]
#[java_packet(PLAY_SHOW_DIALOG)]
pub struct CPlayShowDialog<'a> {
pub dialog: IdOr<DialogNBT<'a>>,
}
impl<'a> CPlayShowDialog<'a> {
#[must_use]
pub const fn new(dialog: IdOr<DialogNBT<'a>>) -> Self {
Self { dialog }
}
}

View File

@ -5,7 +5,7 @@ use pumpkin_data::{
sound_id_remap::remap_sound_id_for_version,
};
use pumpkin_macros::java_packet;
use pumpkin_util::{math::vector3::Vector3, version::MinecraftVersion};
use pumpkin_util::{math::vector3::Vector3, version::JavaMinecraftVersion};
use crate::{ClientPacket, IdOr, SoundEvent, VarInt, WritingError, ser::NetworkWriteExt};
@ -48,7 +48,7 @@ impl ClientPacket for CSoundEffect {
fn write_packet_data(
&self,
mut write: impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let sound_event = match &self.sound_event {
IdOr::Id(id) => IdOr::Id(remap_sound_id_for_version(*id, *version)),
@ -70,13 +70,13 @@ mod tests {
use pumpkin_data::sound::SoundCategory;
use pumpkin_data::sound_id_remap::remap_sound_id_for_version;
use pumpkin_util::{math::vector3::Vector3, version::MinecraftVersion};
use pumpkin_util::{math::vector3::Vector3, version::JavaMinecraftVersion};
use crate::{ClientPacket, IdOr, SoundEvent, VarInt};
use super::CSoundEffect;
fn first_remapped_sound_id(version: MinecraftVersion) -> u16 {
fn first_remapped_sound_id(version: JavaMinecraftVersion) -> u16 {
(0..=u16::MAX)
.find(|id| remap_sound_id_for_version(*id, version) != *id)
.expect("sound remap table should contain at least one changed id")
@ -88,7 +88,7 @@ mod tests {
#[test]
fn numeric_sound_id_remaps_for_1_21_11() {
let sound_id = first_remapped_sound_id(MinecraftVersion::V_1_21_11);
let sound_id = first_remapped_sound_id(JavaMinecraftVersion::V_1_21_11);
let packet = CSoundEffect::new(
IdOr::Id(sound_id),
SoundCategory::Players,
@ -100,18 +100,18 @@ mod tests {
let mut bytes = Vec::new();
packet
.write_packet_data(&mut bytes, &MinecraftVersion::V_1_21_11)
.write_packet_data(&mut bytes, &JavaMinecraftVersion::V_1_21_11)
.unwrap();
assert_eq!(
first_var_int(bytes),
VarInt::from(remap_sound_id_for_version(sound_id, MinecraftVersion::V_1_21_11) + 1)
VarInt::from(remap_sound_id_for_version(sound_id, JavaMinecraftVersion::V_1_21_11) + 1)
);
}
#[test]
fn numeric_sound_id_stays_latest_for_26_1() {
let sound_id = first_remapped_sound_id(MinecraftVersion::V_1_21_11);
let sound_id = first_remapped_sound_id(JavaMinecraftVersion::V_1_21_11);
let packet = CSoundEffect::new(
IdOr::Id(sound_id),
SoundCategory::Players,
@ -123,7 +123,7 @@ mod tests {
let mut bytes = Vec::new();
packet
.write_packet_data(&mut bytes, &MinecraftVersion::V_26_1)
.write_packet_data(&mut bytes, &JavaMinecraftVersion::V_26_1)
.unwrap();
assert_eq!(first_var_int(bytes), VarInt::from(sound_id + 1));
@ -145,7 +145,7 @@ mod tests {
let mut bytes = Vec::new();
packet
.write_packet_data(&mut bytes, &MinecraftVersion::V_1_21_11)
.write_packet_data(&mut bytes, &JavaMinecraftVersion::V_1_21_11)
.unwrap();
assert_eq!(first_var_int(bytes), VarInt::from(0));

View File

@ -5,7 +5,7 @@ use pumpkin_data::entity::EntityType;
use pumpkin_data::entity_id_remap::remap_entity_id_for_version;
use pumpkin_data::packet::clientbound::PLAY_ADD_ENTITY;
use pumpkin_macros::java_packet;
use pumpkin_util::{math::vector3::Vector3, version::MinecraftVersion};
use pumpkin_util::{math::vector3::Vector3, version::JavaMinecraftVersion};
use crate::{
ClientPacket, VarInt,
@ -58,7 +58,7 @@ impl ClientPacket for CSpawnEntity {
fn write_packet_data(
&self,
write: impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;
@ -73,7 +73,7 @@ impl ClientPacket for CSpawnEntity {
write.write_f64_be(self.position.z)?;
// Angles
if version >= &MinecraftVersion::V_1_21_9 {
if version >= &JavaMinecraftVersion::V_1_21_9 {
self.velocity.write(&mut write)?;
}
write.write_u8(self.pitch)?;
@ -89,7 +89,7 @@ impl ClientPacket for CSpawnEntity {
};
write.write_var_int(&data)?;
if version < &MinecraftVersion::V_1_21_9 {
if version < &JavaMinecraftVersion::V_1_21_9 {
self.velocity.write_legacy(&mut write)?;
}
@ -101,7 +101,7 @@ impl ClientPacket for CSpawnEntity {
mod tests {
use super::CSpawnEntity;
use crate::{ClientPacket, VarInt, codec::lp_vector_3d::encode_legacy_velocity_component};
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
fn legacy_tail(velocity: pumpkin_util::math::vector3::Vector3<f64>) -> [u8; 6] {
let x = encode_legacy_velocity_component(velocity.x);
@ -113,7 +113,7 @@ mod tests {
[xb[0], xb[1], yb[0], yb[1], zb[0], zb[1]]
}
fn encode_spawn(version: MinecraftVersion) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
fn encode_spawn(version: JavaMinecraftVersion) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let velocity = pumpkin_util::math::vector3::Vector3::new(0.5, -0.5, 0.25);
let packet = CSpawnEntity::new(
VarInt(1),
@ -137,7 +137,7 @@ mod tests {
// V_1_21_7 enum variant represents protocol 772 (used by 1.21.7 and 1.21.8).
let velocity = pumpkin_util::math::vector3::Vector3::new(0.5, -0.5, 0.25);
let expected_tail = legacy_tail(velocity);
let encoded = encode_spawn(MinecraftVersion::V_1_21_7)?;
let encoded = encode_spawn(JavaMinecraftVersion::V_1_21_7)?;
assert!(encoded.ends_with(&expected_tail));
Ok(())
@ -148,7 +148,7 @@ mod tests {
-> Result<(), Box<dyn std::error::Error>> {
let velocity = pumpkin_util::math::vector3::Vector3::new(0.5, -0.5, 0.25);
let expected_tail = legacy_tail(velocity);
let encoded = encode_spawn(MinecraftVersion::V_1_21_9)?;
let encoded = encode_spawn(JavaMinecraftVersion::V_1_21_9)?;
assert!(!encoded.ends_with(&expected_tail));
Ok(())

View File

@ -6,7 +6,7 @@ use crate::{ClientPacket, WritingError};
use pumpkin_data::{packet::clientbound::PLAY_STOP_SOUND, sound::SoundCategory};
use pumpkin_macros::java_packet;
use pumpkin_util::resource_location::ResourceLocation;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
#[java_packet(PLAY_STOP_SOUND)]
pub struct CStopSound {
@ -25,7 +25,7 @@ impl ClientPacket for CStopSound {
fn write_packet_data(
&self,
write: impl Write,
_version: &MinecraftVersion,
_version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
const NO_CATEGORY_NO_SOUND: u8 = 0;
const CATEGORY_ONLY: u8 = 1;

View File

@ -2,7 +2,7 @@ use std::io::Write;
use pumpkin_data::packet::clientbound::PLAY_TELEPORT_ENTITY;
use pumpkin_macros::java_packet;
use pumpkin_util::{math::vector3::Vector3, version::MinecraftVersion};
use pumpkin_util::{math::vector3::Vector3, version::JavaMinecraftVersion};
use crate::{ClientPacket, PositionFlag, VarInt, WritingError, ser::NetworkWriteExt};
@ -46,7 +46,7 @@ impl ClientPacket for CTeleportEntity<'_> {
fn write_packet_data(
&self,
write: impl Write,
_version: &MinecraftVersion,
_version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;

View File

@ -2,7 +2,7 @@ use std::io::Write;
use pumpkin_data::packet::clientbound::PLAY_SET_OBJECTIVE;
use pumpkin_macros::java_packet;
use pumpkin_util::{text::TextComponent, version::MinecraftVersion};
use pumpkin_util::{text::TextComponent, version::JavaMinecraftVersion};
use crate::{ClientPacket, NumberFormat, VarInt, WritingError, ser::NetworkWriteExt};
@ -38,7 +38,7 @@ impl ClientPacket for CUpdateObjectives {
fn write_packet_data(
&self,
write: impl Write,
_version: &MinecraftVersion,
_version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;

View File

@ -8,7 +8,7 @@ use pumpkin_data::block_state_remap::remap_block_state_for_version;
use pumpkin_data::packet::clientbound::PLAY_LEVEL_EVENT;
use pumpkin_data::world::WorldEvent;
use pumpkin_util::math::position::BlockPos;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use pumpkin_macros::java_packet;
@ -54,7 +54,7 @@ impl ClientPacket for CWorldEvent {
fn write_packet_data(
&self,
write: impl Write,
version: &MinecraftVersion,
version: &JavaMinecraftVersion,
) -> Result<(), WritingError> {
let mut write = write;
write.write_i32_be(self.event)?;

View File

@ -337,7 +337,7 @@ mod tests {
use flate2::read::ZlibDecoder;
use pumpkin_data::packet::clientbound::STATUS_STATUS_RESPONSE;
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
use serde::Serialize;
/// Define a custom packet for testing maximum packet size
@ -398,8 +398,8 @@ mod tests {
let mut packet_buf = Vec::new();
let writer = &mut packet_buf;
writer.write_var_int(&VarInt(T::to_id(MinecraftVersion::V_1_21_11)))?;
packet.write_packet_data(writer, &MinecraftVersion::V_1_21_11)?;
writer.write_var_int(&VarInt(T::to_id(JavaMinecraftVersion::V_1_21_11)))?;
packet.write_packet_data(writer, &JavaMinecraftVersion::V_1_21_11)?;
encoder
.write_packet(packet_buf.into())
@ -434,13 +434,13 @@ mod tests {
let decoded_packet_id = decode_varint(&mut buffer).map_err(|e| e.to_string())?;
assert_eq!(
decoded_packet_id,
CStatusResponse::to_id(MinecraftVersion::V_1_21_11)
CStatusResponse::to_id(JavaMinecraftVersion::V_1_21_11)
);
// Remaining buffer is the payload
// We need to obtain the expected payload
let mut expected_payload = Vec::new();
packet.write_packet_data(&mut expected_payload, &MinecraftVersion::V_1_21_11)?;
packet.write_packet_data(&mut expected_payload, &JavaMinecraftVersion::V_1_21_11)?;
assert_eq!(buffer, expected_payload);
Ok(())
@ -469,9 +469,9 @@ mod tests {
// Read data length VarInt (uncompressed data length)
let data_length = decode_varint(&mut buffer).map_err(|e| e.to_string())?;
let mut expected_payload = Vec::new();
packet.write_packet_data(&mut expected_payload, &MinecraftVersion::V_1_21_11)?;
let uncompressed_data_length = VarInt(CStatusResponse::to_id(MinecraftVersion::V_1_21_11))
.written_size()
packet.write_packet_data(&mut expected_payload, &JavaMinecraftVersion::V_1_21_11)?;
let uncompressed_data_length =
VarInt(CStatusResponse::to_id(JavaMinecraftVersion::V_1_21_11)).written_size()
+ expected_payload.len();
assert_eq!(data_length as usize, uncompressed_data_length);
@ -489,7 +489,7 @@ mod tests {
decode_varint(&mut decompressed_buffer).map_err(|e| e.to_string())?;
assert_eq!(
decoded_packet_id,
CStatusResponse::to_id(MinecraftVersion::V_1_21_11)
CStatusResponse::to_id(JavaMinecraftVersion::V_1_21_11)
);
// Remaining buffer is the payload
@ -527,12 +527,12 @@ mod tests {
let decoded_packet_id = decode_varint(&mut buffer).map_err(|e| e.to_string())?;
assert_eq!(
decoded_packet_id,
CStatusResponse::to_id(MinecraftVersion::V_1_21_11)
CStatusResponse::to_id(JavaMinecraftVersion::V_1_21_11)
);
// Remaining buffer is the payload
let mut expected_payload = Vec::new();
packet.write_packet_data(&mut expected_payload, &MinecraftVersion::V_1_21_11)?;
packet.write_packet_data(&mut expected_payload, &JavaMinecraftVersion::V_1_21_11)?;
assert_eq!(buffer, expected_payload);
Ok(())
}
@ -567,9 +567,9 @@ mod tests {
// Read data length VarInt (uncompressed data length)
let data_length = decode_varint(&mut buffer).map_err(|e| e.to_string())?;
let mut expected_payload = Vec::new();
packet.write_packet_data(&mut expected_payload, &MinecraftVersion::V_1_21_11)?;
let uncompressed_data_length = VarInt(CStatusResponse::to_id(MinecraftVersion::V_1_21_11))
.written_size()
packet.write_packet_data(&mut expected_payload, &JavaMinecraftVersion::V_1_21_11)?;
let uncompressed_data_length =
VarInt(CStatusResponse::to_id(JavaMinecraftVersion::V_1_21_11)).written_size()
+ expected_payload.len();
assert_eq!(data_length as usize, uncompressed_data_length);
@ -587,7 +587,7 @@ mod tests {
decode_varint(&mut decompressed_buffer).map_err(|e| e.to_string())?;
assert_eq!(
decoded_packet_id,
CStatusResponse::to_id(MinecraftVersion::V_1_21_11)
CStatusResponse::to_id(JavaMinecraftVersion::V_1_21_11)
);
// Remaining buffer is the payload
@ -619,12 +619,12 @@ mod tests {
let decoded_packet_id = decode_varint(&mut buffer).map_err(|e| e.to_string())?;
assert_eq!(
decoded_packet_id,
CStatusResponse::to_id(MinecraftVersion::V_1_21_11)
CStatusResponse::to_id(JavaMinecraftVersion::V_1_21_11)
);
// Remaining buffer is the payload (empty)
let mut expected_payload = Vec::new();
packet.write_packet_data(&mut expected_payload, &MinecraftVersion::V_1_21_11)?;
packet.write_packet_data(&mut expected_payload, &JavaMinecraftVersion::V_1_21_11)?;
assert_eq!(
buffer.len(),
@ -668,12 +668,12 @@ mod tests {
// Assume packet ID is 0 for CStatusResponse
assert_eq!(
decoded_packet_id,
CStatusResponse::to_id(MinecraftVersion::V_1_21_11)
CStatusResponse::to_id(JavaMinecraftVersion::V_1_21_11)
);
// Remaining buffer is the payload
let mut expected_payload = Vec::new();
packet.write_packet_data(&mut expected_payload, &MinecraftVersion::V_1_21_11)?;
packet.write_packet_data(&mut expected_payload, &JavaMinecraftVersion::V_1_21_11)?;
assert_eq!(buffer, expected_payload);
Ok(())
@ -726,12 +726,12 @@ mod tests {
let decoded_packet_id = decode_varint(&mut buffer).map_err(|e| e.to_string())?;
assert_eq!(
decoded_packet_id,
CStatusResponse::to_id(MinecraftVersion::V_1_21_11)
CStatusResponse::to_id(JavaMinecraftVersion::V_1_21_11)
);
// Remaining buffer is the payload
let mut expected_payload = Vec::new();
packet.write_packet_data(&mut expected_payload, &MinecraftVersion::V_1_21_11)?;
packet.write_packet_data(&mut expected_payload, &JavaMinecraftVersion::V_1_21_11)?;
assert_eq!(buffer, expected_payload);
Ok(())

View File

@ -2,7 +2,7 @@ use std::io::Read;
use pumpkin_data::packet::serverbound::CONFIG_COOKIE_RESPONSE;
use pumpkin_macros::java_packet;
use pumpkin_util::{resource_location::ResourceLocation, version::MinecraftVersion};
use pumpkin_util::{resource_location::ResourceLocation, version::JavaMinecraftVersion};
use crate::{ReadingError, ServerPacket, ser::NetworkReadExt};
@ -24,7 +24,7 @@ pub struct SConfigCookieResponse {
}
impl ServerPacket for SConfigCookieResponse {
fn read(read: impl Read, _version: &MinecraftVersion) -> Result<Self, ReadingError> {
fn read(read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
let mut read = read;
let key = read.get_string()?;
let has_payload = read.get_bool()?;

View File

@ -1,6 +1,7 @@
mod acknowledge_finish_config;
mod client_information;
mod cookie_response;
mod custom_click_action;
mod known_packs;
mod plugin_message;
mod resource_pack_response;
@ -8,6 +9,7 @@ mod resource_pack_response;
pub use acknowledge_finish_config::*;
pub use client_information::*;
pub use cookie_response::*;
pub use custom_click_action::*;
pub use known_packs::*;
pub use plugin_message::*;
pub use resource_pack_response::*;

View File

@ -2,7 +2,7 @@ use std::io::Read;
use pumpkin_data::packet::serverbound::CONFIG_CUSTOM_PAYLOAD;
use pumpkin_macros::java_packet;
use pumpkin_util::{resource_location::ResourceLocation, version::MinecraftVersion};
use pumpkin_util::{resource_location::ResourceLocation, version::JavaMinecraftVersion};
use crate::{ReadingError, ServerPacket, ser::NetworkReadExt};
@ -23,7 +23,7 @@ pub struct SPluginMessage {
}
impl ServerPacket for SPluginMessage {
fn read(mut read: impl Read, _version: &MinecraftVersion) -> Result<Self, ReadingError> {
fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
Ok(Self {
channel: read.get_string()?,
data: read.read_remaining_to_boxed_slice(MAX_PAYLOAD_SIZE)?,

View File

@ -6,7 +6,7 @@ use crate::{
};
use pumpkin_data::packet::serverbound::HANDSHAKE_INTENTION;
use pumpkin_macros::java_packet;
use pumpkin_util::version::MinecraftVersion;
use pumpkin_util::version::JavaMinecraftVersion;
/// The very first packet sent by the client to initiate a connection
///
@ -25,7 +25,7 @@ pub struct SHandShake {
}
impl ServerPacket for SHandShake {
fn read(mut read: impl Read, _version: &MinecraftVersion) -> Result<Self, ReadingError> {
fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
Ok(Self {
protocol_version: read.get_var_int()?,
server_address: read.get_string_bounded(255)?,
@ -42,7 +42,7 @@ impl ClientPacket for SHandShake {
fn write_packet_data(
&self,
mut write: impl std::io::Write,
_version: &MinecraftVersion,
_version: &JavaMinecraftVersion,
) -> Result<(), crate::ser::WritingError> {
write.write_var_int(&self.protocol_version)?;
write.write_string(&self.server_address)?;

View File

@ -1,6 +1,6 @@
use pumpkin_data::packet::serverbound::LOGIN_COOKIE_RESPONSE;
use pumpkin_macros::java_packet;
use pumpkin_util::{resource_location::ResourceLocation, version::MinecraftVersion};
use pumpkin_util::{resource_location::ResourceLocation, version::JavaMinecraftVersion};
use std::io::Read;
use crate::{
@ -19,7 +19,7 @@ pub struct SLoginCookieResponse {
const MAX_COOKIE_LENGTH: usize = 5120;
impl ServerPacket for SLoginCookieResponse {
fn read(mut read: impl Read, _version: &MinecraftVersion) -> Result<Self, ReadingError> {
fn read(mut read: impl Read, _version: &JavaMinecraftVersion) -> Result<Self, ReadingError> {
let key = read.get_string()?;
let has_payload = read.get_bool()?;

Some files were not shown because too many files have changed in this diff Show More