Skip to content

Commit

Permalink
Add Deserialize and Serialize for Vector3
Browse files Browse the repository at this point in the history
  • Loading branch information
Snowiiii committed Dec 7, 2024
1 parent b2f627d commit e02f058
Show file tree
Hide file tree
Showing 13 changed files with 179 additions and 105 deletions.
1 change: 1 addition & 0 deletions pumpkin-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition.workspace = true
[dependencies]
pumpkin-nbt = { path = "../pumpkin-nbt" }
serde.workspace = true
bytes.workspace = true
uuid.workspace = true
num-traits.workspace = true
num-derive.workspace = true
Expand Down
107 changes: 107 additions & 0 deletions pumpkin-core/src/math/vector3.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use bytes::BufMut;
use std::ops::{Add, Div, Mul, Sub};

use num_traits::Float;
Expand Down Expand Up @@ -117,8 +118,114 @@ pub trait Math:
+ Sized
{
}
impl Math for i16 {}
impl Math for f64 {}
impl Math for f32 {}
impl Math for i32 {}
impl Math for i64 {}
impl Math for u8 {}

impl<'de> serde::Deserialize<'de> for Vector3<f32> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct Vector3Visitor;

impl<'de> serde::de::Visitor<'de> for Vector3Visitor {
type Value = Vector3<f32>;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a valid Vector<32>")
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
if let Some(x) = seq.next_element::<f32>()? {
if let Some(y) = seq.next_element::<f32>()? {
if let Some(z) = seq.next_element::<f32>()? {
return Ok(Vector3::new(x, y, z));
}
}
}
Err(serde::de::Error::custom("Failed to read Vector<f32>"))
}
}

deserializer.deserialize_seq(Vector3Visitor)
}
}

impl<'de> serde::Deserialize<'de> for Vector3<f64> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct Vector3Visitor;

impl<'de> serde::de::Visitor<'de> for Vector3Visitor {
type Value = Vector3<f64>;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a valid Vector<f64>")
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
if let Some(x) = seq.next_element::<f64>()? {
if let Some(y) = seq.next_element::<f64>()? {
if let Some(z) = seq.next_element::<f64>()? {
return Ok(Vector3::new(x, y, z));
}
}
}
Err(serde::de::Error::custom("Failed to read Vector<f64>"))
}
}

deserializer.deserialize_seq(Vector3Visitor)
}
}

impl serde::Serialize for Vector3<f32> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut buf = Vec::new();
buf.put_f32(self.x);
buf.put_f32(self.y);
buf.put_f32(self.z);
serializer.serialize_bytes(&buf)
}
}

impl serde::Serialize for Vector3<f64> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut buf = Vec::new();
buf.put_f64(self.x);
buf.put_f64(self.y);
buf.put_f64(self.z);
serializer.serialize_bytes(&buf)
}
}

impl serde::Serialize for Vector3<i16> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut buf = Vec::new();
buf.put_i16(self.x);
buf.put_i16(self.y);
buf.put_i16(self.z);
serializer.serialize_bytes(&buf)
}
}
5 changes: 3 additions & 2 deletions pumpkin-protocol/src/client/play/c_damage_event.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use pumpkin_core::math::vector3::Vector3;
use pumpkin_macros::client_packet;
use serde::Serialize;

Expand All @@ -10,7 +11,7 @@ pub struct CDamageEvent {
source_type_id: VarInt,
source_cause_id: VarInt,
source_direct_id: VarInt,
source_position: Option<(f64, f64, f64)>,
source_position: Option<Vector3<f64>>,
}

impl CDamageEvent {
Expand All @@ -19,7 +20,7 @@ impl CDamageEvent {
source_type_id: VarInt,
source_cause_id: Option<VarInt>,
source_direct_id: Option<VarInt>,
source_position: Option<(f64, f64, f64)>,
source_position: Option<Vector3<f64>>,
) -> Self {
Self {
entity_id,
Expand Down
2 changes: 1 addition & 1 deletion pumpkin-protocol/src/client/play/c_entity_velocity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub struct CEntityVelocity<'a> {
}

impl<'a> CEntityVelocity<'a> {
pub fn new(entity_id: &'a VarInt, velocity_x: f32, velocity_y: f32, velocity_z: f32) -> Self {
pub fn new(entity_id: &'a VarInt, velocity_x: f64, velocity_y: f64, velocity_z: f64) -> Self {
Self {
entity_id,
velocity_x: (velocity_x.clamp(-3.9, 3.9) * 8000.0) as i16,
Expand Down
26 changes: 7 additions & 19 deletions pumpkin-protocol/src/client/play/c_particle.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use pumpkin_core::math::vector3::Vector3;
use pumpkin_macros::client_packet;
use serde::Serialize;

Expand All @@ -8,41 +9,28 @@ use crate::VarInt;
pub struct CParticle<'a> {
/// If true, particle distance increases from 256 to 65536.
long_distance: bool,
x: f64,
y: f64,
z: f64,
offset_x: f32,
offset_y: f32,
offset_z: f32,
position: Vector3<f64>,
offset: Vector3<f64>,
max_speed: f32,
particle_count: i32,
pariticle_id: VarInt,
data: &'a [u8],
}

impl<'a> CParticle<'a> {
#[expect(clippy::too_many_arguments)]
pub fn new(
long_distance: bool,
x: f64,
y: f64,
z: f64,
offset_x: f32,
offset_y: f32,
offset_z: f32,
position: Vector3<f64>,
offset: Vector3<f64>,
max_speed: f32,
particle_count: i32,
pariticle_id: VarInt,
data: &'a [u8],
) -> Self {
Self {
long_distance,
x,
y,
z,
offset_x,
offset_y,
offset_z,
position,
offset,
max_speed,
particle_count,
pariticle_id,
Expand Down
17 changes: 4 additions & 13 deletions pumpkin-protocol/src/client/play/c_update_entity_pos.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use pumpkin_core::math::vector3::Vector3;
use pumpkin_macros::client_packet;
use serde::Serialize;

Expand All @@ -7,25 +8,15 @@ use crate::VarInt;
#[client_packet("play:move_entity_pos")]
pub struct CUpdateEntityPos {
entity_id: VarInt,
delta_x: i16,
delta_y: i16,
delta_z: i16,
delta: Vector3<i16>,
on_ground: bool,
}

impl CUpdateEntityPos {
pub fn new(
entity_id: VarInt,
delta_x: i16,
delta_y: i16,
delta_z: i16,
on_ground: bool,
) -> Self {
pub fn new(entity_id: VarInt, delta: Vector3<i16>, on_ground: bool) -> Self {
Self {
entity_id,
delta_x,
delta_y,
delta_z,
delta,
on_ground,
}
}
Expand Down
13 changes: 4 additions & 9 deletions pumpkin-protocol/src/client/play/c_update_entity_pos_rot.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use pumpkin_core::math::vector3::Vector3;
use pumpkin_macros::client_packet;
use serde::Serialize;

Expand All @@ -7,9 +8,7 @@ use crate::VarInt;
#[client_packet("play:move_entity_pos_rot")]
pub struct CUpdateEntityPosRot {
entity_id: VarInt,
delta_x: i16,
delta_y: i16,
delta_z: i16,
delta: Vector3<i16>,
yaw: u8,
pitch: u8,
on_ground: bool,
Expand All @@ -18,18 +17,14 @@ pub struct CUpdateEntityPosRot {
impl CUpdateEntityPosRot {
pub fn new(
entity_id: VarInt,
delta_x: i16,
delta_y: i16,
delta_z: i16,
delta: Vector3<i16>,
yaw: u8,
pitch: u8,
on_ground: bool,
) -> Self {
Self {
entity_id,
delta_x,
delta_y,
delta_z,
delta,
yaw,
pitch,
on_ground,
Expand Down
13 changes: 8 additions & 5 deletions pumpkin-protocol/src/server/play/s_interact.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use num_derive::FromPrimitive;
use num_traits::FromPrimitive;
use pumpkin_core::math::vector3::Vector3;
use pumpkin_macros::server_packet;

use crate::{bytebuf::DeserializerError, ServerPacket, VarInt};
Expand All @@ -8,7 +9,7 @@ use crate::{bytebuf::DeserializerError, ServerPacket, VarInt};
pub struct SInteract {
pub entity_id: VarInt,
pub typ: VarInt,
pub target_position: Option<(f32, f32, f32)>,
pub target_position: Option<Vector3<f32>>,
pub hand: Option<VarInt>,
pub sneaking: bool,
}
Expand All @@ -23,12 +24,14 @@ impl ServerPacket for SInteract {
let action = ActionType::from_i32(typ.0).ok_or(DeserializerError::Message(
"invalid action type".to_string(),
))?;
let target_position: Option<(f32, f32, f32)> = match action {
let target_position: Option<Vector3<f32>> = match action {
ActionType::Interact => None,
ActionType::Attack => None,
ActionType::InteractAt => {
Some((bytebuf.get_f32()?, bytebuf.get_f32()?, bytebuf.get_f32()?))
}
ActionType::InteractAt => Some(Vector3::new(
bytebuf.get_f32()?,
bytebuf.get_f32()?,
bytebuf.get_f32()?,
)),
};
let hand = match action {
ActionType::Interact => Some(bytebuf.get_var_int()?),
Expand Down
5 changes: 2 additions & 3 deletions pumpkin-protocol/src/server/play/s_player_position.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use pumpkin_core::math::vector3::Vector3;
use pumpkin_macros::server_packet;

#[derive(serde::Deserialize)]
#[server_packet("play:move_player_pos")]
pub struct SPlayerPosition {
pub x: f64,
pub feet_y: f64,
pub z: f64,
pub position: Vector3<f64>,
pub ground: bool,
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use pumpkin_core::math::vector3::Vector3;
use pumpkin_macros::server_packet;

#[derive(serde::Deserialize)]
#[server_packet("play:move_player_pos_rot")]
pub struct SPlayerPositionRotation {
pub x: f64,
pub feet_y: f64,
pub z: f64,
pub position: Vector3<f64>,
pub yaw: f32,
pub pitch: f32,
pub ground: bool,
Expand Down
6 changes: 2 additions & 4 deletions pumpkin-protocol/src/server/play/s_use_item_on.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use pumpkin_core::math::position::WorldPosition;
use pumpkin_core::math::{position::WorldPosition, vector3::Vector3};
use pumpkin_macros::server_packet;
use serde::Deserialize;

Expand All @@ -10,9 +10,7 @@ pub struct SUseItemOn {
pub hand: VarInt,
pub location: WorldPosition,
pub face: VarInt,
pub cursor_pos_x: f32,
pub cursor_pos_y: f32,
pub cursor_pos_z: f32,
pub cursor_pos: Vector3<f32>,
pub inside_block: bool,
pub is_against_world_border: bool,
pub sequence: VarInt,
Expand Down
14 changes: 5 additions & 9 deletions pumpkin/src/client/combat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ pub async fn handle_knockback(

let packet = &CEntityVelocity::new(
&entity_id,
victim_velocity.x as f32,
victim_velocity.y as f32,
victim_velocity.z as f32,
victim_velocity.x,
victim_velocity.y,
victim_velocity.z,
);
let velocity = attacker_entity.velocity.load();
attacker_entity
Expand All @@ -105,12 +105,8 @@ pub async fn spawn_sweep_particle(attacker_entity: &Entity, world: &World, pos:
world
.broadcast_packet_all(&CParticle::new(
false,
pos.x + d,
body_y,
pos.z + e,
0.0,
0.0,
0.0,
Vector3::new(pos.x + d, body_y, pos.z + e),
Vector3::new(0.0, 0.0, 0.0),
0.0,
0,
VarInt(i32::from(particle!("sweep_attack"))), // sweep
Expand Down
Loading

0 comments on commit e02f058

Please sign in to comment.