fix(plugin-wit): map protocol i8 fields to WIT s8 in v0.2 (#4413)

This commit is contained in:
Gavin Holmes
2026-10-30 04:43:16 -07:00
committed by GitHub
parent 90ac8d8253
commit 5152bb5c1d
6 changed files with 106 additions and 49 deletions

View File

@@ -1844,7 +1844,7 @@ interface bedrock-packets {
tick: s64,
}
variant metadata-value {
byte(u8),
byte(s8),
short(s32),
int(s32),
float(f32),
@@ -2032,9 +2032,9 @@ interface bedrock-packets {
enable-itemstack-net-manager: bool,
/// Version string of the server software.
server-version: string,
compound-id: u8,
compound-id: s8,
compound-len: s32,
compound-end: u8,
compound-end: s8,
/// CRC64 checksum of the block state registry.
block-registry-checksum: s64,
/// UUID of the world template if created from a template.
@@ -2130,7 +2130,7 @@ interface bedrock-packets {
edu-shared-uri-button-name: string,
edu-shared-uri-link-uri: string,
override-force-experimental-gameplay-has-value: bool,
chat-restriction-level: u8,
chat-restriction-level: s8,
disable-player-interactions: bool,
server-editor-connection-policy: s32,
allow-anonymous-block-drops-in-editor-worlds: bool,

View File

@@ -8,7 +8,7 @@ interface java-packets {
/// The language code used by the client (e.g., "`en_us`")
locale: string,
/// The maximum number of chunks the client renders
view-distance: u8,
view-distance: s8,
/// Visibility of chat messages (0: Enabled, 1: Commands Only, 2: Hidden)
chat-mode: s32,
/// Whether the client wants chat colors/formatting rendered
@@ -152,7 +152,7 @@ interface java-packets {
sync-id: s32,
revision: s32,
slot: s32,
button: u8,
button: s8,
mode: slot-action-type,
length-of-array: s32,
/// WARNING: Could not fully translate type `Vec < (i16 , OptionalItemStackHash) >` to WIT
@@ -184,7 +184,7 @@ interface java-packets {
}
record s-client-information-play {
locale: string,
view-distance: u8,
view-distance: s8,
chat-mode: s32,
chat-colors: bool,
skin-parts: u8,
@@ -297,12 +297,12 @@ interface java-packets {
payload: s64,
}
record s-place-recipe {
container-id: u8,
container-id: s8,
recipe-display-id: s32,
use-max-items: bool,
}
record s-player-abilities {
%flags: u8,
%flags: s8,
fly-speed: option<f32>,
walk-speed: option<f32>,
}
@@ -353,7 +353,7 @@ interface java-packets {
on-ground: bool,
}
record s-player-input {
input: u8,
input: s8,
}
record s-player-position {
position: tuple<f64, f64, f64>,
@@ -426,7 +426,7 @@ interface java-packets {
/// - 0x01: Track output
/// - 0x02: Is conditional
/// - 0x04: Automatic
%flags: u8,
%flags: s8,
}
enum command-block-mode {
chain,
@@ -469,9 +469,9 @@ interface java-packets {
action: s32,
mode: s32,
name: string,
offset-x: u8,
offset-y: u8,
offset-z: u8,
offset-x: s8,
offset-y: s8,
offset-z: s8,
size-x: u8,
size-y: u8,
size-z: u8,
@@ -759,7 +759,7 @@ interface java-packets {
location: tuple<s32, s32, s32>,
/// The destruction stage, typically a value from 0 to 9.
/// Any value outside 0-9 (like -1) will remove the destruction overlay.
destroy-stage: u8,
destroy-stage: s8,
}
/// Updates the NBT data of a block entity (e.g., signs, chests, or banners).
///
@@ -1322,7 +1322,7 @@ interface java-packets {
entity-id: s32,
/// The ID of the status/event to trigger.
/// See the table below for common entity statuses.
entity-status: u8,
entity-status: s8,
}
/// Updates the velocity of an entity.
///
@@ -1527,7 +1527,7 @@ interface java-packets {
}
record c-map-item-data {
map-id: s32,
scale: u8,
scale: s8,
tracking-position: bool,
locked: bool,
icons: option<list<map-icon>>,
@@ -1535,16 +1535,16 @@ interface java-packets {
}
record map-icon {
icon-type: s32,
x: u8,
z: u8,
direction: u8,
x: s8,
z: s8,
direction: s8,
display-name: option<string>,
}
record map-patch {
columns: u8,
rows: u8,
x: u8,
z: u8,
x: s8,
z: s8,
data: list<u8>,
}
record merchant-offer {
@@ -1691,7 +1691,7 @@ interface java-packets {
/// Bit 1 (0x02): Flying
/// Bit 2 (0x04): Allow Flying
/// Bit 3 (0x08): Creative Mode (Instant Break)
%flags: u8,
%flags: s8,
/// The multiplier for flying speed.
/// Default is 0.05.
flying-speed: f32,
@@ -1839,7 +1839,7 @@ interface java-packets {
hashed-seed: s64,
game-mode: u8,
/// The previous gamemode (used for the F3+F4 toggle UI). -1 if none.
previous-gamemode: u8,
previous-gamemode: s8,
/// If true, the world is a debug world (all blocks shown in a grid).
debug: bool,
/// If true, the world is a flat world (affects the horizon rendering).
@@ -1974,7 +1974,7 @@ interface java-packets {
value: s32,
}
record c-set-container-slot {
window-id: u8,
window-id: s8,
state-id: s32,
slot: s32,
/// WARNING: Could not fully translate type `& 'a ItemStackSerializer < 'a >` to WIT
@@ -1993,7 +1993,7 @@ interface java-packets {
record c-set-equipment {
entity-id: s32,
/// WARNING: Could not fully translate type `Vec < (i8 , ItemStackSerializer < 'static >) >` to WIT
equipment: list<tuple<u8, inexpressible-host-type>>,
equipment: list<tuple<s8, inexpressible-host-type>>,
}
record c-set-experience {
progress: f32,
@@ -2006,7 +2006,7 @@ interface java-packets {
food-saturation: f32,
}
record c-set-selected-slot {
slot: u8,
slot: s8,
}
record c-set-passengers {
entity-id: s32,
@@ -2026,7 +2026,7 @@ interface java-packets {
}
record team-parameters {
display-name: string,
options: u8,
options: s8,
nametag-visibility: string,
collision-rule: string,
color: s32,
@@ -2174,7 +2174,7 @@ interface java-packets {
record attribute-modifier {
id: string,
amount: f64,
operation: u8,
operation: s8,
}
record c-update-entity-pos {
entity-id: s32,
@@ -2199,7 +2199,7 @@ interface java-packets {
effect-id: s32,
amplifier: s32,
duration: s32,
%flags: u8,
%flags: s8,
}
record c-update-objectives {
objective-name: string,

View File

@@ -142,7 +142,7 @@ pub fn serialize_java_packet(
data.location.1,
data.location.2,
),
destroy_stage: data.destroy_stage.try_into().unwrap(),
destroy_stage: data.destroy_stage,
};
let mut buf = Vec::new();
pumpkin_core::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf)
@@ -370,7 +370,7 @@ pub fn serialize_java_packet(
ClientboundPacket::CEntityStatus(data) => {
let p = pumpkin_protocol::java::client::play::CEntityStatus {
entity_id: data.entity_id.try_into().unwrap(),
entity_status: data.entity_status.try_into().unwrap(),
entity_status: data.entity_status,
};
let mut buf = Vec::new();
pumpkin_core::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf)
@@ -603,7 +603,7 @@ pub fn serialize_java_packet(
}
ClientboundPacket::CPlayerAbilities(data) => {
let p = pumpkin_protocol::java::client::play::CPlayerAbilities {
flags: data.flags.try_into().unwrap(),
flags: data.flags,
flying_speed: data.flying_speed.try_into().unwrap(),
field_of_view: data.field_of_view.try_into().unwrap(),
};
@@ -1042,7 +1042,7 @@ pub fn serialize_java_packet(
effect_id: VarInt(data.effect_id),
amplifier: VarInt(data.amplifier),
duration: VarInt(data.duration),
flags: data.flags.try_into().unwrap(),
flags: data.flags,
};
let mut buf = Vec::new();
pumpkin_core::net::java::JavaClient::write_packet_for_version(&p, version, &mut buf)
@@ -1111,7 +1111,7 @@ pub fn deserialize_java_serverbound_packet(
Some(ServerboundPacket::ConfigSClientInformationConfig(
crate::pumpkin::plugin::java_packets::ConfigSClientInformationConfig {
locale: p.locale.into(),
view_distance: p.view_distance.try_into().unwrap(),
view_distance: p.view_distance,
chat_mode: p.chat_mode.0.try_into().unwrap(),
chat_colors: p.chat_colors.try_into().unwrap(),
skin_parts: p.skin_parts.try_into().unwrap(),
@@ -1235,7 +1235,7 @@ pub fn deserialize_java_serverbound_packet(
Some(ServerboundPacket::SClientInformationPlay(
crate::pumpkin::plugin::java_packets::SClientInformationPlay {
locale: p.locale.into(),
view_distance: p.view_distance.try_into().unwrap(),
view_distance: p.view_distance,
chat_mode: p.chat_mode.0.try_into().unwrap(),
chat_colors: p.chat_colors.try_into().unwrap(),
skin_parts: p.skin_parts.try_into().unwrap(),
@@ -1416,7 +1416,7 @@ pub fn deserialize_java_serverbound_packet(
let p = <pumpkin_protocol::java::server::play::SPlaceRecipe as pumpkin_protocol::ServerPacket>::read(&mut payload, &version).ok()?;
Some(ServerboundPacket::SPlaceRecipe(
crate::pumpkin::plugin::java_packets::SPlaceRecipe {
container_id: p.container_id.try_into().unwrap(),
container_id: p.container_id,
recipe_display_id: p.recipe_display_id.0.try_into().unwrap(),
use_max_items: p.use_max_items.try_into().unwrap(),
},
@@ -1447,9 +1447,7 @@ pub fn deserialize_java_serverbound_packet(
use pumpkin_protocol::ServerPacket;
let p = <pumpkin_protocol::java::server::play::SPlayerInput as pumpkin_protocol::ServerPacket>::read(&mut payload, &version).ok()?;
Some(ServerboundPacket::SPlayerInput(
crate::pumpkin::plugin::java_packets::SPlayerInput {
input: p.input.try_into().unwrap(),
},
crate::pumpkin::plugin::java_packets::SPlayerInput { input: p.input },
))
}
id if id == pumpkin_protocol::java::server::play::SPlayerPosition::to_id(version) => {
@@ -1590,7 +1588,7 @@ pub fn deserialize_java_serverbound_packet(
pos: (p.pos.0.x, p.pos.0.y, p.pos.0.z),
command: p.command.into(),
mode: p.mode.0.try_into().unwrap(),
flags: p.flags.try_into().unwrap(),
flags: p.flags,
},
))
}
@@ -1639,9 +1637,9 @@ pub fn deserialize_java_serverbound_packet(
action: p.action.0.try_into().unwrap(),
mode: p.mode.0.try_into().unwrap(),
name: p.name.into(),
offset_x: p.offset_x.try_into().unwrap(),
offset_y: p.offset_y.try_into().unwrap(),
offset_z: p.offset_z.try_into().unwrap(),
offset_x: p.offset_x,
offset_y: p.offset_y,
offset_z: p.offset_z,
size_x: p.size_x.try_into().unwrap(),
size_y: p.size_y.try_into().unwrap(),
size_z: p.size_z.try_into().unwrap(),
@@ -1863,7 +1861,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CSetBlockDes
crate::pumpkin::plugin::java_packets::CSetBlockDestroyStage {
entity_id: self.entity_id.0.try_into().unwrap(),
location: (self.location.0.x, self.location.0.y, self.location.0.z),
destroy_stage: self.destroy_stage.try_into().unwrap(),
destroy_stage: self.destroy_stage,
},
)
}
@@ -2069,7 +2067,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CEntityStatu
fn to_wit(&self) -> ClientboundPacket {
ClientboundPacket::CEntityStatus(crate::pumpkin::plugin::java_packets::CEntityStatus {
entity_id: self.entity_id.try_into().unwrap(),
entity_status: self.entity_status.try_into().unwrap(),
entity_status: self.entity_status,
})
}
}
@@ -2274,7 +2272,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CPlayerAbili
fn to_wit(&self) -> ClientboundPacket {
ClientboundPacket::CPlayerAbilities(
crate::pumpkin::plugin::java_packets::CPlayerAbilities {
flags: self.flags.try_into().unwrap(),
flags: self.flags,
flying_speed: self.flying_speed.try_into().unwrap(),
field_of_view: self.field_of_view.try_into().unwrap(),
},
@@ -2684,7 +2682,7 @@ impl ToWitClientboundJava for pumpkin_protocol::java::client::play::CUpdateMobEf
effect_id: self.effect_id.0.try_into().unwrap(),
amplifier: self.amplifier.0.try_into().unwrap(),
duration: self.duration.0.try_into().unwrap(),
flags: self.flags.try_into().unwrap(),
flags: self.flags,
},
)
}

View File

@@ -550,3 +550,49 @@ pub async fn init_plugin(
Ok((plugin, store, metadata))
}
#[cfg(test)]
mod tests {
use crate::generated_packets::{clientbound_java_any_to_wit, serialize_java_packet};
use crate::pumpkin::plugin::java_packets::{CSetBlockDestroyStage, ClientboundPacket};
use pumpkin_protocol::VarInt;
use pumpkin_protocol::java::client::play::CSetBlockDestroyStage as ProtocolCSetBlockDestroyStage;
use pumpkin_util::math::position::BlockPos;
use pumpkin_util::version::JavaMinecraftVersion;
#[test]
fn serializes_destroy_stage() {
for destroy_stage in -1..=9 {
let packet = ClientboundPacket::CSetBlockDestroyStage(CSetBlockDestroyStage {
entity_id: 1,
location: (0, 64, 0),
destroy_stage,
});
let bytes = serialize_java_packet(&packet, JavaMinecraftVersion::V_26_3);
assert_eq!(
bytes.as_ref().and_then(|bytes| bytes.last()),
Some(&(destroy_stage as u8))
);
}
}
#[test]
fn converts_negative_destroy_stage_to_wit() {
let packet = ProtocolCSetBlockDestroyStage {
entity_id: VarInt(1),
location: BlockPos::new(0, 64, 0),
destroy_stage: -1,
};
assert!(matches!(
clientbound_java_any_to_wit(&packet),
Some(ClientboundPacket::CSetBlockDestroyStage(
CSetBlockDestroyStage {
destroy_stage: -1,
..
}
))
));
}
}

View File

@@ -25,7 +25,8 @@ pub fn map_type(ty: &Type, defined_types: &HashSet<String>) -> (WitType, bool) {
"bool" => (WitType::Bool, true),
"f32" => (WitType::F32, true),
"f64" => (WitType::F64, true),
"u8" | "i8" => (WitType::U8, true),
"u8" => (WitType::U8, true),
"i8" => (WitType::S8, true),
"u16" | "i16" => (WitType::S32, true),
"Bytes" | "BoxedU8Slice" | "ChunkData" => (WitType::list(WitType::U8), true),
"BitSet" | "Bitset" => (WitType::list(WitType::S64), true),

View File

@@ -507,6 +507,12 @@ fn convert_value(
} else {
format!("VarInt({})", src)
}
} else if type_ident == "i8" {
if is_ref {
format!("&{}", src)
} else {
src.to_string()
}
} else {
if is_ref {
prep.push_str(&format!(
@@ -528,6 +534,12 @@ fn convert_value(
}
} else if type_ident == "VarInt" {
format!("{}.0.try_into().unwrap()", src)
} else if type_ident == "i8" {
if is_ref {
format!("*{}", src)
} else {
src.to_string()
}
} else {
format!("{}.try_into().unwrap()", src)
}