summaryrefslogtreecommitdiff
path: root/shared/src
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-01-04 22:52:42 +0100
committermetamuffin <metamuffin@disroot.org>2025-01-04 22:52:42 +0100
commit2707f03617478e2a5e521961c46c9c6511d5088d (patch)
treea3516660f36614b006ea44eecf92bb4ff709fa3b /shared/src
parent2c1d8fdfd65ceb9361114f0105c23ff6a94bac2e (diff)
downloadweareserver-2707f03617478e2a5e521961c46c9c6511d5088d.tar
weareserver-2707f03617478e2a5e521961c46c9c6511d5088d.tar.bz2
weareserver-2707f03617478e2a5e521961c46c9c6511d5088d.tar.zst
a
Diffstat (limited to 'shared/src')
-rw-r--r--shared/src/lib.rs4
-rw-r--r--shared/src/packets.rs120
-rw-r--r--shared/src/store.rs33
-rw-r--r--shared/src/tree.rs70
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()
+ }
+}