diff options
author | metamuffin <metamuffin@disroot.org> | 2025-01-05 18:20:49 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-01-05 18:20:49 +0100 |
commit | f2fa92e701b8da8e9d2e091ade21784623710374 (patch) | |
tree | 87d4fe19042fdabad4771967f89ea9cb436bdb1c /shared | |
parent | 72c23eb57070ab859ffde4f989aa85f7f2eedcf8 (diff) | |
download | weareserver-f2fa92e701b8da8e9d2e091ade21784623710374.tar weareserver-f2fa92e701b8da8e9d2e091ade21784623710374.tar.bz2 weareserver-f2fa92e701b8da8e9d2e091ade21784623710374.tar.zst |
a
Diffstat (limited to 'shared')
-rw-r--r-- | shared/Cargo.toml | 2 | ||||
-rw-r--r-- | shared/src/lib.rs | 2 | ||||
-rw-r--r-- | shared/src/packets.rs | 26 | ||||
-rw-r--r-- | shared/src/resources.rs | 141 | ||||
-rw-r--r-- | shared/src/store.rs | 14 |
5 files changed, 171 insertions, 14 deletions
diff --git a/shared/Cargo.toml b/shared/Cargo.toml index c39f586..6c37d07 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -8,3 +8,5 @@ anyhow = "1.0.95" bincode = "1.3.3" glam = { version = "0.29.2", features = ["serde"] } redb = "2.4.0" +sha2 = "0.11.0-pre.4" +log = "0.4.22" diff --git a/shared/src/lib.rs b/shared/src/lib.rs index a692a82..fadbc35 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -1,4 +1,6 @@ +#![feature(iter_array_chunks)] pub mod packets; +pub mod resources; pub mod store; pub mod tree; diff --git a/shared/src/packets.rs b/shared/src/packets.rs index 79dd1ea..c480ba8 100644 --- a/shared/src/packets.rs +++ b/shared/src/packets.rs @@ -3,14 +3,14 @@ use glam::Vec3; use std::io::{Read, Write}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Resource(pub u128); +pub struct Resource(pub [u8; 32]); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Object(pub u128); #[derive(Debug, Clone)] pub enum Packet { RequestResource(Resource), - RespondResource(Resource, Vec<u8>), + RespondResource(Vec<u8>), Add(Object, Resource), Remove(Object), Position(Object, Vec3, Vec3), @@ -24,18 +24,17 @@ impl Packet { match self { Packet::RequestResource(resource) => { w.write_all(&[0x01])?; - w.write_all(&resource.0.to_be_bytes())?; + w.write_all(&resource.0)?; } - Packet::RespondResource(resource, vec) => { + Packet::RespondResource(data) => { w.write_all(&[0x02])?; - w.write_all(&resource.0.to_be_bytes())?; - w.write_all(&(vec.len() as u16).to_be_bytes())?; - w.write_all(&vec)?; + w.write_all(&(data.len() as u16).to_be_bytes())?; + w.write_all(&data)?; } Packet::Add(object, resource) => { w.write_all(&[0x03])?; w.write_all(&object.0.to_be_bytes())?; - w.write_all(&resource.0.to_be_bytes())?; + w.write_all(&resource.0)?; } Packet::Remove(object) => { w.write_all(&[0x04])?; @@ -73,9 +72,9 @@ impl Packet { let mut tag = [0u8; 1]; r.read_exact(&mut tag)?; Ok(match tag[0] { - 0x01 => Packet::RequestResource(Resource(read_u128(r)?)), - 0x02 => Packet::RespondResource(Resource(read_u128(r)?), read_data(r)?), - 0x03 => Packet::Add(Object(read_u128(r)?), Resource(read_u128(r)?)), + 0x01 => Packet::RequestResource(read_res(r)?), + 0x02 => Packet::RespondResource(read_data(r)?), + 0x03 => Packet::Add(Object(read_u128(r)?), read_res(r)?), 0x04 => Packet::Remove(Object(read_u128(r)?)), 0x05 => Packet::Position( Object(read_u128(r)?), @@ -95,6 +94,11 @@ fn read_u128(r: &mut impl Read) -> Result<u128> { 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)) +} fn read_data(r: &mut impl Read) -> Result<Vec<u8>> { let mut size = [0; 2]; r.read_exact(&mut size)?; diff --git a/shared/src/resources.rs b/shared/src/resources.rs new file mode 100644 index 0000000..c54d10b --- /dev/null +++ b/shared/src/resources.rs @@ -0,0 +1,141 @@ +use crate::packets::Resource; +use anyhow::{Result, anyhow}; +use log::warn; +use std::io::{Read, Write}; + +#[derive(Debug, Default, Clone)] +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: Option<Resource>, +} + +pub struct VertexAttributes(Vec<f32>); +pub struct Indecies(Vec<[u16; 3]>); + +impl Prefab { + pub fn serialize(&self, w: &mut Vec<u8>) -> Result<()> { + for x in self.0.clone() { + w.write_all(&x.0)?; + } + Ok(()) + } + pub fn deserialize(r: &[u8]) -> Result<Self> { + let mut s = Prefab::default(); + for x in r.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<()> { + 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> { + let mut s = Self(Vec::new()); + for x in r.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<()> { + for x in self.0.clone() { + w.write_all(&x.to_be_bytes())?; + } + Ok(()) + } + pub fn deserialize(r: &[u8]) -> Result<Self> { + let mut s = Self(Vec::new()); + for x in r.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)?; + } + if let Some(x) = &self.index { + write_kv(w, b"index", &x.0)?; + } + if let Some(x) = &self.armature { + write_kv(w, b"armature", &x.0)?; + } + if let Some(x) = &self.fragment_shader { + write_kv(w, b"fragment_shader", &x.0)?; + } + if let Some(x) = &self.fragment_shader_data { + write_kv(w, b"fragment_shader_data", &x.0)?; + } + if let Some(x) = &self.vertex_shader { + write_kv(w, b"vertex_shader", &x.0)?; + } + if let Some(x) = &self.vertex_shader_data { + write_kv(w, b"vertex_shader_data", &x.0)?; + } + if let Some(x) = &self.texture { + write_kv(w, b"texture", &x.0)?; + } + Ok(()) + } + pub fn deserialize(mut r: &[u8]) -> Result<Self> { + let mut s = Self::default(); + while !r.is_empty() { + let (k, v) = read_kv(&mut r)?; + 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 = Some(slice_to_res(&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>)> { + let mut key_size = [0; 2]; + let mut value_size = [0; 2]; + r.read_exact(&mut key_size)?; + r.read_exact(&mut value_size)?; + let key_size = u16::from_be_bytes(key_size); + let value_size = u16::from_be_bytes(value_size); + let mut key = vec![0; key_size as usize]; + let mut value = vec![0; value_size as usize]; + r.read_exact(&mut value)?; + r.read_exact(&mut key)?; + Ok((key, value)) +} +fn write_kv(w: &mut Vec<u8>, 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(()) +} diff --git a/shared/src/store.rs b/shared/src/store.rs index 83f1a25..44e5e3d 100644 --- a/shared/src/store.rs +++ b/shared/src/store.rs @@ -1,9 +1,10 @@ use crate::packets::Resource; use anyhow::Result; use redb::{Database, TableDefinition}; +use sha2::{Digest, Sha256}; use std::path::Path; -const T_ENTRIES: TableDefinition<u128, &[u8]> = TableDefinition::new("e"); +const T_ENTRIES: TableDefinition<[u8; 32], &[u8]> = TableDefinition::new("e"); pub struct ResourceStore { db: Database, @@ -22,12 +23,19 @@ impl ResourceStore { None => Ok(None), } } - pub fn set(&self, key: Resource, value: &[u8]) -> Result<()> { + pub fn set(&self, value: &[u8]) -> Result<()> { + let key = sha256(value); let txn = self.db.begin_write()?; let mut ent = txn.open_table(T_ENTRIES)?; - ent.insert(key.0, value)?; + ent.insert(key, value)?; drop(ent); txn.commit()?; Ok(()) } } + +pub fn sha256(x: &[u8]) -> [u8; 32] { + let mut hasher = Sha256::new(); + hasher.update(x); + hasher.finalize().into() +} |