diff options
author | metamuffin <metamuffin@disroot.org> | 2025-01-04 22:52:42 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-01-04 22:52:42 +0100 |
commit | 2707f03617478e2a5e521961c46c9c6511d5088d (patch) | |
tree | a3516660f36614b006ea44eecf92bb4ff709fa3b /shared/src | |
parent | 2c1d8fdfd65ceb9361114f0105c23ff6a94bac2e (diff) | |
download | weareserver-2707f03617478e2a5e521961c46c9c6511d5088d.tar weareserver-2707f03617478e2a5e521961c46c9c6511d5088d.tar.bz2 weareserver-2707f03617478e2a5e521961c46c9c6511d5088d.tar.zst |
a
Diffstat (limited to 'shared/src')
-rw-r--r-- | shared/src/lib.rs | 4 | ||||
-rw-r--r-- | shared/src/packets.rs | 120 | ||||
-rw-r--r-- | shared/src/store.rs | 33 | ||||
-rw-r--r-- | shared/src/tree.rs | 70 |
4 files changed, 227 insertions, 0 deletions
diff --git a/shared/src/lib.rs b/shared/src/lib.rs new file mode 100644 index 0000000..a692a82 --- /dev/null +++ b/shared/src/lib.rs @@ -0,0 +1,4 @@ + +pub mod packets; +pub mod store; +pub mod tree; diff --git a/shared/src/packets.rs b/shared/src/packets.rs new file mode 100644 index 0000000..79dd1ea --- /dev/null +++ b/shared/src/packets.rs @@ -0,0 +1,120 @@ +use anyhow::{Result, bail}; +use glam::Vec3; +use std::io::{Read, Write}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Resource(pub u128); +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Object(pub u128); + +#[derive(Debug, Clone)] +pub enum Packet { + RequestResource(Resource), + RespondResource(Resource, Vec<u8>), + Add(Object, Resource), + Remove(Object), + Position(Object, Vec3, Vec3), + Pose(Object, Vec<f32>), + Parent(Object, Object), + Sound(Object, Vec<u8>), +} + +impl Packet { + pub fn serialize(&self, w: &mut impl Write) -> Result<()> { + match self { + Packet::RequestResource(resource) => { + w.write_all(&[0x01])?; + w.write_all(&resource.0.to_be_bytes())?; + } + Packet::RespondResource(resource, vec) => { + 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)?; + } + Packet::Add(object, resource) => { + w.write_all(&[0x03])?; + w.write_all(&object.0.to_be_bytes())?; + w.write_all(&resource.0.to_be_bytes())?; + } + Packet::Remove(object) => { + w.write_all(&[0x04])?; + w.write_all(&object.0.to_be_bytes())?; + } + Packet::Position(object, pos, rot) => { + w.write_all(&[0x05])?; + w.write_all(&object.0.to_be_bytes())?; + w.write_all(&pos.x.to_be_bytes())?; + w.write_all(&pos.y.to_be_bytes())?; + w.write_all(&pos.z.to_be_bytes())?; + w.write_all(&rot.x.to_be_bytes())?; + w.write_all(&rot.y.to_be_bytes())?; + w.write_all(&rot.z.to_be_bytes())?; + } + Packet::Pose(object, vec) => { + w.write_all(&[0x06])?; + w.write_all(&object.0.to_be_bytes())?; + w.write_all(&(vec.len() as u16).to_be_bytes())?; + } + Packet::Parent(parent, child) => { + w.write_all(&[0x07])?; + w.write_all(&parent.0.to_be_bytes())?; + w.write_all(&child.0.to_be_bytes())?; + } + Packet::Sound(object, vec) => { + w.write_all(&[0x08])?; + w.write_all(&object.0.to_be_bytes())?; + w.write_all(&(vec.len() as u16).to_be_bytes())?; + } + } + Ok(()) + } + pub fn deserialize(r: &mut impl Read) -> Result<Self> { + 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)?)), + 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)?), + ), + 0x06 => Packet::Pose(Object(read_u128(r)?), read_params(r)?), + 0x07 => Packet::Parent(Object(read_u128(r)?), Object(read_u128(r)?)), + 0x08 => Packet::Sound(Object(read_u128(r)?), read_data(r)?), + _ => bail!("unknown packet tag"), + }) + } +} + +fn read_u128(r: &mut impl Read) -> Result<u128> { + let mut buf = [0; 16]; + r.read_exact(&mut buf)?; + Ok(u128::from_be_bytes(buf)) +} +fn read_data(r: &mut impl Read) -> Result<Vec<u8>> { + let mut size = [0; 2]; + r.read_exact(&mut size)?; + let size = u16::from_be_bytes(size); + let mut buf = vec![0; size as usize]; + 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>> { + 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)?); + } + Ok(v) +} diff --git a/shared/src/store.rs b/shared/src/store.rs new file mode 100644 index 0000000..83f1a25 --- /dev/null +++ b/shared/src/store.rs @@ -0,0 +1,33 @@ +use crate::packets::Resource; +use anyhow::Result; +use redb::{Database, TableDefinition}; +use std::path::Path; + +const T_ENTRIES: TableDefinition<u128, &[u8]> = TableDefinition::new("e"); + +pub struct ResourceStore { + db: Database, +} +impl ResourceStore { + pub fn new(path: &Path) -> Result<Self> { + Ok(Self { + db: Database::create(path)?, + }) + } + pub fn get(&self, key: Resource) -> Result<Option<Vec<u8>>> { + let txn = self.db.begin_read()?; + let ent = txn.open_table(T_ENTRIES)?; + match ent.get(key.0)? { + Some(x) => Ok(Some(x.value().to_vec())), + None => Ok(None), + } + } + pub fn set(&self, key: Resource, value: &[u8]) -> Result<()> { + let txn = self.db.begin_write()?; + let mut ent = txn.open_table(T_ENTRIES)?; + ent.insert(key.0, value)?; + drop(ent); + txn.commit()?; + Ok(()) + } +} diff --git a/shared/src/tree.rs b/shared/src/tree.rs new file mode 100644 index 0000000..fce6f8a --- /dev/null +++ b/shared/src/tree.rs @@ -0,0 +1,70 @@ +use crate::packets::{Object, Packet, Resource}; +use glam::Vec3; +use std::collections::HashMap; + +pub struct SceneTree { + objects: HashMap<Object, ObjectData>, +} +struct ObjectData { + pos: Vec3, + rot: Vec3, + parent: Object, + pose: Vec<f32>, + res: Resource, +} +impl Default for SceneTree { + fn default() -> Self { + Self { + objects: Default::default(), + } + } +} +impl SceneTree { + pub fn update(&mut self, p: &Packet) { + match p { + Packet::Add(object, res) => { + self.objects.insert(*object, ObjectData { + parent: Object(0), + pos: Vec3::ZERO, + rot: Vec3::ZERO, + pose: Vec::new(), + res: *res, + }); + } + Packet::Remove(object) => { + self.objects.remove(&object); + } + Packet::Position(object, pos, rot) => { + if let Some(o) = self.objects.get_mut(&object) { + o.pos = *pos; + o.rot = *rot; + } + } + Packet::Pose(object, pose) => { + if let Some(o) = self.objects.get_mut(&object) { + o.pose = pose.to_vec(); + } + } + Packet::Parent(parent, child) => { + if let Some(o) = self.objects.get_mut(&parent) { + o.parent = *child + } + } + _ => (), + } + } + + pub fn prime_client(&self) -> impl Iterator<Item = Packet> { + self.objects + .iter() + .map(|(object, data)| { + [ + Packet::Add(*object, data.res), + Packet::Parent(*object, data.parent), + Packet::Position(*object, data.pos, data.rot), + Packet::Pose(*object, data.pose.clone()), + ] + }) + .flatten() + } +} |