diff options
author | metamuffin <metamuffin@disroot.org> | 2025-01-06 14:28:02 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-01-06 14:28:02 +0100 |
commit | 814cc1cb01692aa934a40636c9226ff7bb911266 (patch) | |
tree | 47a50a5dc1861ace4bc1854a9156618b70df3847 /shared | |
parent | c2ee65a83838a0ce13402e2c4634bae409d55071 (diff) | |
download | weareserver-814cc1cb01692aa934a40636c9226ff7bb911266.tar weareserver-814cc1cb01692aa934a40636c9226ff7bb911266.tar.bz2 weareserver-814cc1cb01692aa934a40636c9226ff7bb911266.tar.zst |
new proto
Diffstat (limited to 'shared')
-rw-r--r-- | shared/src/lib.rs | 2 | ||||
-rw-r--r-- | shared/src/packets.rs | 92 | ||||
-rw-r--r-- | shared/src/resources.rs | 172 |
3 files changed, 173 insertions, 93 deletions
diff --git a/shared/src/lib.rs b/shared/src/lib.rs index fadbc35..45b31da 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(iter_array_chunks)] +#![feature(iter_array_chunks, array_try_map)] pub mod packets; pub mod resources; diff --git a/shared/src/packets.rs b/shared/src/packets.rs index 626da07..0ceed73 100644 --- a/shared/src/packets.rs +++ b/shared/src/packets.rs @@ -22,21 +22,24 @@ pub enum Packet { Sound(Object, Vec<u8>), } +pub trait ReadWrite: Sized { + fn write(&self, w: &mut dyn Write) -> Result<()>; + fn read(r: &mut dyn Read) -> Result<Self>; + + fn write_alloc(&self) -> Vec<u8> { + let mut buf = Vec::new(); + self.write(&mut buf).unwrap(); + buf + } +} + impl Object { pub fn new() -> Self { Self(rand::random()) } } - impl Packet { - pub fn serialize(&self, w: &mut impl Write) -> Result<()> { - let mut buf = Vec::new(); - self.serialize_inner(&mut buf)?; - w.write_all(&(buf.len() as u16).to_be_bytes())?; - w.write_all(&buf)?; - Ok(()) - } - pub fn serialize_inner(&self, w: &mut impl Write) -> Result<()> { + fn serialize_inner(&self, w: &mut impl Write) -> Result<()> { match self { Packet::RequestResource(resource) => { w.write_all(&[0x01])?; @@ -84,18 +87,27 @@ impl Packet { } Ok(()) } - pub fn deserialize(r: &mut impl Read) -> Result<Self> { +} +impl ReadWrite for Packet { + fn write(&self, w: &mut dyn Write) -> Result<()> { + let mut buf = Vec::new(); + self.serialize_inner(&mut buf)?; + w.write_all(&(buf.len() as u16).to_be_bytes())?; + w.write_all(&buf)?; + Ok(()) + } + fn read(r: &mut dyn Read) -> Result<Self> { let mut size_tag = [0u8; 3]; r.read_exact(&mut size_tag)?; Ok(match size_tag[2] { - 0x01 => Packet::RequestResource(read_res(r)?), + 0x01 => Packet::RequestResource(Resource::read(r)?), 0x02 => Packet::RespondResource(read_data(r)?), - 0x03 => Packet::Add(Object(read_u128(r)?), read_res(r)?), + 0x03 => Packet::Add(Object(read_u128(r)?), Resource::read(r)?), 0x04 => Packet::Remove(Object(read_u128(r)?)), 0x05 => Packet::Position( Object(read_u128(r)?), - Vec3::new(read_float(r)?, read_float(r)?, read_float(r)?), - Vec3::new(read_float(r)?, read_float(r)?, read_float(r)?), + Vec3::new(f32::read(r)?, f32::read(r)?, f32::read(r)?), + Vec3::new(f32::read(r)?, f32::read(r)?, f32::read(r)?), ), 0x06 => Packet::Pose(Object(read_u128(r)?), read_params(r)?), 0x07 => Packet::Parent(Object(read_u128(r)?), Object(read_u128(r)?)), @@ -110,17 +122,23 @@ impl Packet { } } -fn read_u128(r: &mut impl Read) -> Result<u128> { +fn read_u128(r: &mut dyn Read) -> Result<u128> { let mut buf = [0; 16]; r.read_exact(&mut buf)?; Ok(u128::from_be_bytes(buf)) } -fn read_res(r: &mut impl Read) -> Result<Resource> { - let mut buf = [0; 32]; - r.read_exact(&mut buf)?; - Ok(Resource(buf)) +impl ReadWrite for Resource { + fn write(&self, w: &mut dyn Write) -> Result<()> { + w.write_all(&self.0)?; + Ok(()) + } + fn read(r: &mut dyn Read) -> Result<Self> { + let mut s = Self([0; 32]); + r.read_exact(&mut s.0)?; + Ok(s) + } } -fn read_data(r: &mut impl Read) -> Result<Vec<u8>> { +fn read_data(r: &mut dyn Read) -> Result<Vec<u8>> { let mut size = [0; 2]; r.read_exact(&mut size)?; let size = u16::from_be_bytes(size); @@ -128,22 +146,29 @@ fn read_data(r: &mut impl Read) -> Result<Vec<u8>> { r.read_exact(&mut buf)?; Ok(buf) } -fn read_float(r: &mut impl Read) -> Result<f32> { - let mut buf = [0; 4]; - r.read_exact(&mut buf)?; - Ok(f32::from_be_bytes(buf)) -} -fn read_params(r: &mut impl Read) -> Result<Vec<f32>> { +fn read_params(r: &mut dyn Read) -> Result<Vec<f32>> { let mut size = [0; 2]; r.read_exact(&mut size)?; let size = u16::from_be_bytes(size); let mut v = Vec::with_capacity(size as usize); for _ in 0..size { - v.push(read_float(r)?); + v.push(f32::read(r)?); } Ok(v) } +impl ReadWrite for f32 { + fn write(&self, w: &mut dyn Write) -> Result<()> { + w.write_all(&self.to_be_bytes())?; + Ok(()) + } + fn read(r: &mut dyn Read) -> Result<Self> { + let mut buf = [0; 4]; + r.read_exact(&mut buf)?; + Ok(f32::from_be_bytes(buf)) + } +} + impl Display for Resource { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( @@ -162,3 +187,16 @@ impl Debug for Resource { write!(f, "{}", self) } } + +impl<T: ReadWrite, const N: usize> ReadWrite for [T; N] { + fn write(&self, w: &mut dyn Write) -> Result<()> { + for e in self { + e.write(w)?; + } + Ok(()) + } + + fn read(r: &mut dyn Read) -> Result<Self> { + [(); N].try_map(|()| T::read(r)) + } +} diff --git a/shared/src/resources.rs b/shared/src/resources.rs index a677755..cdf53bd 100644 --- a/shared/src/resources.rs +++ b/shared/src/resources.rs @@ -1,5 +1,5 @@ -use crate::packets::Resource; -use anyhow::{Result, anyhow}; +use crate::packets::{ReadWrite, Resource}; +use anyhow::{Result, bail}; use log::warn; use std::io::{Read, Write}; @@ -8,120 +8,130 @@ pub struct Prefab(pub Vec<Resource>); #[derive(Debug, Default, Clone)] pub struct Part { - pub vertex: Vec<Resource>, pub index: Option<Resource>, - pub armature: Option<Resource>, - pub fragment_shader: Option<Resource>, - pub fragment_shader_data: Option<Resource>, - pub vertex_shader: Option<Resource>, - pub vertex_shader_data: Option<Resource>, - pub texture: Vec<Resource>, + pub va_position: Option<[Attribute; 3]>, + pub va_normal: Option<[Attribute; 3]>, + pub va_texcoord: Option<[Attribute; 2]>, + pub va_pbr_roughness: Option<Attribute>, + pub va_pbr_metallic: Option<Attribute>, + pub va_pbr_albedo: Option<[Attribute; 3]>, + pub va_pbr_transmission: Option<Attribute>, +} + +#[derive(Debug, Clone)] +pub enum Attribute { + Constant(f32), + Vertex(Resource), + Texture(Resource), } #[derive(Debug, Default, Clone)] -pub struct VertexAttributes(pub Vec<f32>); +pub struct AttributeArray(pub Vec<f32>); #[derive(Debug, Default, Clone)] -pub struct Indecies(pub Vec<[u16; 3]>); +pub struct IndexArray(pub Vec<[u16; 3]>); -impl Prefab { - pub fn serialize(&self, w: &mut Vec<u8>) -> Result<()> { +impl ReadWrite for Prefab { + fn write(&self, w: &mut dyn Write) -> Result<()> { for x in self.0.clone() { w.write_all(&x.0)?; } Ok(()) } - pub fn deserialize(r: &[u8]) -> Result<Self> { + fn read(r: &mut dyn Read) -> Result<Self> { let mut s = Prefab::default(); - for x in r.iter().array_chunks::<32>() { + let mut g = Vec::new(); + r.read_to_end(&mut g)?; + for x in g.iter().array_chunks::<32>() { s.0.push(Resource(x.map(|x| *x))) } Ok(s) } } -impl Indecies { - pub fn serialize(&self, w: &mut Vec<u8>) -> Result<()> { +impl ReadWrite for IndexArray { + fn write(&self, w: &mut dyn Write) -> Result<()> { for x in self.0.clone() { w.write_all(x.map(|x| x.to_be_bytes()).as_flattened())?; } Ok(()) } - pub fn deserialize(r: &[u8]) -> Result<Self> { + fn read(r: &mut dyn Read) -> Result<Self> { let mut s = Self(Vec::new()); - for x in r.iter().array_chunks::<2>().array_chunks::<3>() { + let mut g = Vec::new(); + r.read_to_end(&mut g)?; + for x in g.iter().array_chunks::<2>().array_chunks::<3>() { s.0.push(x.map(|x| u16::from_be_bytes(x.map(|x| *x)))) } Ok(s) } } -impl VertexAttributes { - pub fn serialize(&self, w: &mut Vec<u8>) -> Result<()> { +impl ReadWrite for AttributeArray { + fn write(&self, w: &mut dyn Write) -> Result<()> { for x in self.0.clone() { w.write_all(&x.to_be_bytes())?; } Ok(()) } - pub fn deserialize(r: &[u8]) -> Result<Self> { + fn read(r: &mut dyn Read) -> Result<Self> { let mut s = Self(Vec::new()); - for x in r.iter().array_chunks::<4>() { + let mut g = Vec::new(); + r.read_to_end(&mut g)?; + for x in g.iter().array_chunks::<4>() { s.0.push(f32::from_be_bytes(x.map(|x| *x))) } Ok(s) } } -impl Part { - pub fn serialize(&self, w: &mut Vec<u8>) -> Result<()> { - for x in &self.vertex { - write_kv(w, b"vertex", &x.0); +impl ReadWrite for Part { + fn write(&self, w: &mut dyn Write) -> Result<()> { + if let Some(a) = &self.index { + write_kv(w, b"index", &a.write_alloc())?; } - if let Some(x) = &self.index { - write_kv(w, b"index", &x.0); + if let Some(a) = &self.va_position { + write_kv(w, b"va_position", &a.write_alloc())?; } - if let Some(x) = &self.armature { - write_kv(w, b"armature", &x.0); + if let Some(a) = &self.va_normal { + write_kv(w, b"va_normal", &a.write_alloc())?; } - if let Some(x) = &self.fragment_shader { - write_kv(w, b"fragment_shader", &x.0); + if let Some(a) = &self.va_texcoord { + write_kv(w, b"va_texcoord", &a.write_alloc())?; } - if let Some(x) = &self.fragment_shader_data { - write_kv(w, b"fragment_shader_data", &x.0); + if let Some(a) = &self.va_pbr_roughness { + write_kv(w, b"va_pbr_roughness", &a.write_alloc())?; } - if let Some(x) = &self.vertex_shader { - write_kv(w, b"vertex_shader", &x.0); + if let Some(a) = &self.va_pbr_metallic { + write_kv(w, b"va_pbr_metallic", &a.write_alloc())?; } - if let Some(x) = &self.vertex_shader_data { - write_kv(w, b"vertex_shader_data", &x.0); - } - for x in &self.vertex { - write_kv(w, b"texture", &x.0); + if let Some(a) = &self.va_pbr_albedo { + write_kv(w, b"va_pbr_albedo", &a.write_alloc())?; } Ok(()) } - pub fn deserialize(mut r: &[u8]) -> Result<Self> { + fn read(r: &mut dyn Read) -> Result<Self> { let mut s = Self::default(); - while !r.is_empty() { - let (k, v) = read_kv(&mut r)?; + let mut g = Vec::new(); + r.read_to_end(&mut g)?; + let mut g = g.as_slice(); + while !g.is_empty() { + let (k, v) = read_kv(&mut g)?; + let mut v = v.as_slice(); match k.as_slice() { - b"vertex" => s.vertex.push(slice_to_res(&v)?), - b"index" => s.index = Some(slice_to_res(&v)?), - b"armature" => s.armature = Some(slice_to_res(&v)?), - b"fragment_shader" => s.fragment_shader = Some(slice_to_res(&v)?), - b"fragment_shader_data" => s.fragment_shader_data = Some(slice_to_res(&v)?), - b"vertex_shader" => s.vertex_shader = Some(slice_to_res(&v)?), - b"vertex_shader_data" => s.vertex_shader_data = Some(slice_to_res(&v)?), - b"texture" => s.texture.push(slice_to_res(&v)?), + b"index" => s.index = Some(<_ as ReadWrite>::read(&mut v)?), + b"va_position" => s.va_position = Some(<_ as ReadWrite>::read(&mut v)?), + b"va_normal" => s.va_normal = Some(<_ as ReadWrite>::read(&mut v)?), + b"va_texcoord" => s.va_texcoord = Some(<_ as ReadWrite>::read(&mut v)?), + b"va_pbr_roughness" => s.va_pbr_roughness = Some(<_ as ReadWrite>::read(&mut v)?), + b"va_pbr_metallic" => s.va_pbr_metallic = Some(<_ as ReadWrite>::read(&mut v)?), + b"va_pbr_albedo" => s.va_pbr_albedo = Some(<_ as ReadWrite>::read(&mut v)?), + b"va_pbr_transmission" => { + s.va_pbr_transmission = Some(<_ as ReadWrite>::read(&mut v)?) + } _ => warn!("unknown part key"), } } Ok(s) } } -fn slice_to_res(s: &[u8]) -> Result<Resource> { - Ok(Resource( - s.try_into() - .map_err(|_| anyhow!("resource length incorrect"))?, - )) -} -fn read_kv(r: &mut &[u8]) -> Result<(Vec<u8>, Vec<u8>)> { +fn read_kv(r: &mut dyn Read) -> Result<(Vec<u8>, Vec<u8>)> { let mut key_size = [0; 2]; let mut value_size = [0; 2]; r.read_exact(&mut key_size)?; @@ -134,9 +144,41 @@ fn read_kv(r: &mut &[u8]) -> Result<(Vec<u8>, Vec<u8>)> { r.read_exact(&mut key)?; Ok((key, value)) } -fn write_kv(w: &mut Vec<u8>, key: &[u8], value: &[u8]) { - w.extend(&(key.len() as u16).to_be_bytes()); - w.extend(&(value.len() as u16).to_be_bytes()); - w.extend(key); - w.extend(value); + +fn write_kv(w: &mut dyn Write, key: &[u8], value: &[u8]) -> Result<()> { + w.write_all(&(key.len() as u16).to_be_bytes())?; + w.write_all(&(value.len() as u16).to_be_bytes())?; + w.write_all(key)?; + w.write_all(value)?; + Ok(()) +} + +impl ReadWrite for Attribute { + fn write(&self, w: &mut dyn Write) -> Result<()> { + match self { + Attribute::Constant(v) => { + w.write_all(&[0x01])?; + w.write_all(&v.to_be_bytes())?; + } + Attribute::Vertex(resource) => { + w.write_all(&[0x02])?; + resource.write(w)?; + } + Attribute::Texture(resource) => { + w.write_all(&[0x03])?; + resource.write(w)?; + } + } + Ok(()) + } + fn read(r: &mut dyn Read) -> Result<Self> { + let mut tag = [0u8; 1]; + r.read_exact(&mut tag)?; + Ok(match tag[0] { + 0x01 => Self::Constant(f32::read(r)?), + 0x02 => Self::Vertex(Resource::read(r)?), + 0x03 => Self::Texture(Resource::read(r)?), + _ => bail!("unknown attribute tag"), + }) + } } |