diff options
author | metamuffin <metamuffin@disroot.org> | 2025-03-12 17:54:43 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-03-12 17:54:43 +0100 |
commit | dc8304afefa71037bea99722bee29f7645753836 (patch) | |
tree | 4fd2b70d6faec18573bd590442b443b7d7a53c1a /world/src/main.rs | |
parent | 3ed621256f1e02032250477fa574eab38bd34976 (diff) | |
download | weareserver-dc8304afefa71037bea99722bee29f7645753836.tar weareserver-dc8304afefa71037bea99722bee29f7645753836.tar.bz2 weareserver-dc8304afefa71037bea99722bee29f7645753836.tar.zst |
rename crates and binaries
Diffstat (limited to 'world/src/main.rs')
-rw-r--r-- | world/src/main.rs | 304 |
1 files changed, 0 insertions, 304 deletions
diff --git a/world/src/main.rs b/world/src/main.rs deleted file mode 100644 index 554a2bd..0000000 --- a/world/src/main.rs +++ /dev/null @@ -1,304 +0,0 @@ -/* - wearechat - generic multiplayer game with voip - Copyright (C) 2025 metamuffin - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, version 3 of the License only. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ -#![feature(iter_array_chunks)] -#![allow(clippy::too_many_arguments, clippy::type_complexity)] -pub mod animation; -pub mod mesh; -pub mod physics; -pub mod prefab; -pub mod vrm; - -use anyhow::{Result, bail}; -use clap::Parser; -use gltf::{image::Source, scene::Transform}; -use humansize::BINARY; -use image::{ImageReader, codecs::webp::WebPEncoder}; -use log::{debug, info}; -use prefab::import_prefab; -use rand::random; -use std::{ - borrow::Cow, - collections::HashMap, - fs::File, - io::{BufWriter, Cursor, Read, Write}, - marker::PhantomData, - net::{SocketAddr, TcpStream}, - path::{Path, PathBuf}, - sync::{Arc, Mutex}, - thread::{self, sleep}, - time::Duration, -}; -use weareshared::{ - Affine3A, Vec3A, - helper::ReadWrite, - packets::{Data, Object, Packet, Resource}, - resources::{Image, RespackEntry}, - respack::save_respack, - store::ResourceStore, - vec3a, -}; - -#[derive(Parser)] -pub struct Args { - #[arg(short, long)] - address: Option<SocketAddr>, - - /// Output converted prefab as resource package - #[arg(short = 'o', long)] - pack: Option<PathBuf>, - - /// Path(s) to a glTF file, binary or json format - scene: Vec<PathBuf>, - /// Send all resources to the server then quit - #[arg(short, long)] - push: bool, - - /// Remove all other object from the world - #[arg(short, long)] - clear: bool, - /// Add the object to the world - #[arg(short, long)] - add: bool, - /// Transcode all textures to WebP - #[arg(short, long)] - webp: bool, - /// Add skybox - #[arg(long)] - skybox: Option<PathBuf>, - /// Override prefab name - #[arg(short, long)] - name: Option<String>, - #[arg(short, long)] - scale: Option<f32>, - #[arg(short, long)] - dry_run: bool, - #[arg(short, long)] - line_up: bool, - - #[arg(long)] - use_cache: bool, - - #[arg(short = 'S', long)] - with_default_sun: bool, - - #[arg(long)] - animation: Option<PathBuf>, - #[arg(long)] - animation_bone_map: Option<PathBuf>, - #[arg(long)] - animation_rotation_y: Option<f32>, - #[arg(long)] - animation_scale: Option<f32>, - #[arg(long)] - animation_apply_ibm: bool, - - /// Spins the object - #[arg(long)] - debug_spin: bool, - /// Adds a light - #[arg(long)] - debug_light: bool, - #[arg(long)] - no_particles: bool, - #[arg(long)] - no_animations: bool, -} - -fn main() -> Result<()> { - env_logger::init_from_env("LOG"); - let args = Args::parse(); - - let store = if args.use_cache && !args.pack.is_some() { - ResourceStore::new_env()? - } else { - ResourceStore::new_memory() - }; - - let mut prefabs = Vec::new(); - let texture_cache = Arc::new(Mutex::new(HashMap::new())); - - for scenepath in &args.scene { - prefabs.push(import_prefab(&store, &texture_cache, scenepath, &args)?); - } - - let mut size = 0; - store.iter(|_k, len| size += len).unwrap(); - info!( - "prefab has network size of {}", - humansize::format_size(size, BINARY) - ); - - if args.dry_run { - return Ok(()); - } - if let Some(outpath) = args.pack { - let entry = store.set(&RespackEntry { name: None })?; - let mut resources = Vec::new(); - store.iter(|r, _| resources.push(r))?; - save_respack( - BufWriter::new(File::create(outpath)?), - &store, - &resources, - Some(entry), - )?; - } else if let Some(address) = args.address { - let mut sock = TcpStream::connect(address)?; - Packet::Connect(random()).write(&mut sock)?; - for p in &prefabs { - Packet::AnnouncePrefab(p.clone()).write(&mut sock)?; - } - sock.flush()?; - - let mut obs = Vec::new(); - if args.add { - for (i, p) in prefabs.iter().enumerate() { - let ob = Object::new(); - info!("adding object {ob}"); - Packet::Add(ob, p.clone()).write(&mut sock)?; - if args.line_up { - Packet::Position(ob, vec3a(i as f32 * 1.2, 0., i as f32 * 0.3), Vec3A::ZERO) - .write(&mut sock)?; - } - obs.push(ob); - } - sock.flush()?; - } - - if args.debug_spin { - let ob = obs[0]; - let mut sock2 = sock.try_clone().unwrap(); - thread::spawn(move || { - let mut x = 0.; - loop { - Packet::Position(ob, Vec3A::ZERO, vec3a(0., x * 0.1, 0.)) - .write(&mut sock2) - .unwrap(); - sock2.flush().unwrap(); - x += 0.1; - sleep(Duration::from_millis(50)); - } - }); - } - if args.push { - if args.use_cache { - return Ok(()); - } - store.iter(|k, _| { - Packet::RespondResource(k, Data(store.get_raw(k).unwrap().unwrap())) - .write(&mut sock) - .unwrap(); - })?; - sock.flush()?; - } else { - loop { - let packet = Packet::read(&mut sock)?; - match packet { - Packet::RequestResource(hash) => { - if let Some(d) = store.get_raw(hash)? { - Packet::RespondResource(hash, Data(d)).write(&mut sock)?; - sock.flush()?; - } - } - Packet::Add(ob_a, _) => { - if args.clear && !obs.contains(&ob_a) { - info!("removing object {ob_a}"); - Packet::Remove(ob_a).write(&mut sock)?; - sock.flush()?; - } - } - _ => (), - } - } - } - } else { - bail!("no output option specified. either provide an address to a server or use --pack") - } - Ok(()) -} - -pub type TextureCache = Arc<Mutex<HashMap<String, Resource<Image<'static>>>>>; -fn load_texture( - name: &str, - store: &ResourceStore, - path: &Path, - buffers: &[gltf::buffer::Data], - source: &Source, - webp: bool, - texture_cache: &TextureCache, -) -> Result<Resource<Image<'static>>> { - let (mut image, uri) = match source { - gltf::image::Source::View { view, mime_type } => { - debug!("{name} texture is embedded and of type {mime_type:?}"); - let buf = - &buffers[view.buffer().index()].0[view.offset()..view.offset() + view.length()]; - (Image(Cow::Borrowed(buf)), None) - } - gltf::image::Source::Uri { - uri, - mime_type: Some(mime_type), - } => { - debug!("{name} texture is {uri:?} and of type {mime_type:?}"); - if let Some(res) = texture_cache.lock().unwrap().get(*uri) { - return Ok(res.to_owned()); - } - let path = path.join(uri); - let mut buf = Vec::new(); - File::open(path)?.read_to_end(&mut buf)?; - (Image(buf.into()), Some(uri.to_string())) - } - gltf::image::Source::Uri { - uri, - mime_type: None, - } => { - debug!("{name} texture is {uri:?} and has no type"); - if let Some(res) = texture_cache.lock().unwrap().get(*uri) { - return Ok(res.to_owned()); - } - let path = path.join(uri); - let mut buf = Vec::new(); - File::open(path)?.read_to_end(&mut buf)?; - (Image(buf.into()), Some(uri.to_string())) - } - }; - - if webp { - let mut image_out = Vec::new(); - - let len = image.0.len(); - ImageReader::new(Cursor::new(image.0)) - .with_guessed_format()? - .decode()? - .write_with_encoder(WebPEncoder::new_lossless(&mut image_out))?; - debug!("webp encode: {len} -> {}", image_out.len()); - image = Image(Cow::Owned(image_out)); - } - let res = Resource(store.set(&image)?.0, PhantomData); - if let Some(uri) = uri { - texture_cache.lock().unwrap().insert(uri, res.clone()); - } - Ok(res) -} - -pub fn transform_to_affine(trans: Transform) -> Affine3A { - let mat = trans.matrix(); - Affine3A::from_cols_array_2d(&[ - [mat[0][0], mat[0][1], mat[0][2]], - [mat[1][0], mat[1][1], mat[1][2]], - [mat[2][0], mat[2][1], mat[2][2]], - [mat[3][0], mat[3][1], mat[3][2]], - ]) -} |