From b7e26eee5754ac1272a297e5752d21f861e9e410 Mon Sep 17 00:00:00 2001 From: Lucas Schwiderski Date: Fri, 3 Mar 2023 15:32:41 +0100 Subject: [PATCH 1/2] refactor(sdk): Split BundleFileType into its own file --- lib/sdk/src/bundle/database.rs | 2 +- lib/sdk/src/bundle/file.rs | 397 +------------------------------ lib/sdk/src/bundle/filetype.rs | 400 ++++++++++++++++++++++++++++++++ lib/sdk/src/bundle/mod.rs | 4 +- lib/sdk/src/filetype/package.rs | 11 +- 5 files changed, 408 insertions(+), 406 deletions(-) create mode 100644 lib/sdk/src/bundle/filetype.rs diff --git a/lib/sdk/src/bundle/database.rs b/lib/sdk/src/bundle/database.rs index 6152ede..fce26ee 100644 --- a/lib/sdk/src/bundle/database.rs +++ b/lib/sdk/src/bundle/database.rs @@ -13,7 +13,7 @@ use crate::binary::ToBinary; use crate::murmur::Murmur64; use crate::Bundle; -use super::file::BundleFileType; +use super::filetype::BundleFileType; const DATABASE_VERSION: u32 = 0x6; const FILE_VERSION: u32 = 0x4; diff --git a/lib/sdk/src/bundle/file.rs b/lib/sdk/src/bundle/file.rs index 4d6c56e..1780a5d 100644 --- a/lib/sdk/src/bundle/file.rs +++ b/lib/sdk/src/bundle/file.rs @@ -5,407 +5,12 @@ use bitflags::bitflags; use color_eyre::eyre::Context; use color_eyre::{eyre, Result}; use futures::future::join_all; -use serde::Serialize; use crate::binary::sync::*; use crate::filetype::*; use crate::murmur::{HashGroup, IdString64, Murmur64}; -#[derive(Debug, Hash, PartialEq, Eq, Copy, Clone)] -pub enum BundleFileType { - Animation, - AnimationCurves, - Apb, - BakedLighting, - Bik, - BlendSet, - Bones, - Chroma, - CommonPackage, - Config, - Crypto, - Data, - Entity, - Flow, - Font, - Ies, - Ini, - Input, - Ivf, - Keys, - Level, - Lua, - Material, - Mod, - MouseCursor, - NavData, - NetworkConfig, - OddleNet, - Package, - Particles, - PhysicsProperties, - RenderConfig, - RtPipeline, - Scene, - Shader, - ShaderLibrary, - ShaderLibraryGroup, - ShadingEnvionmentMapping, - ShadingEnvironment, - Slug, - SlugAlbum, - SoundEnvironment, - SpuJob, - StateMachine, - StaticPVS, - Strings, - SurfaceProperties, - Texture, - TimpaniBank, - TimpaniMaster, - Tome, - Ugg, - Unit, - Upb, - VectorField, - Wav, - WwiseBank, - WwiseDep, - WwiseEvent, - WwiseMetadata, - WwiseStream, - Xml, - - Unknown(Murmur64), -} - -impl BundleFileType { - pub fn ext_name(&self) -> String { - match self { - BundleFileType::AnimationCurves => String::from("animation_curves"), - BundleFileType::Animation => String::from("animation"), - BundleFileType::Apb => String::from("apb"), - BundleFileType::BakedLighting => String::from("baked_lighting"), - BundleFileType::Bik => String::from("bik"), - BundleFileType::BlendSet => String::from("blend_set"), - BundleFileType::Bones => String::from("bones"), - BundleFileType::Chroma => String::from("chroma"), - BundleFileType::CommonPackage => String::from("common_package"), - BundleFileType::Config => String::from("config"), - BundleFileType::Crypto => String::from("crypto"), - BundleFileType::Data => String::from("data"), - BundleFileType::Entity => String::from("entity"), - BundleFileType::Flow => String::from("flow"), - BundleFileType::Font => String::from("font"), - BundleFileType::Ies => String::from("ies"), - BundleFileType::Ini => String::from("ini"), - BundleFileType::Input => String::from("input"), - BundleFileType::Ivf => String::from("ivf"), - BundleFileType::Keys => String::from("keys"), - BundleFileType::Level => String::from("level"), - BundleFileType::Lua => String::from("lua"), - BundleFileType::Material => String::from("material"), - BundleFileType::Mod => String::from("mod"), - BundleFileType::MouseCursor => String::from("mouse_cursor"), - BundleFileType::NavData => String::from("nav_data"), - BundleFileType::NetworkConfig => String::from("network_config"), - BundleFileType::OddleNet => String::from("oodle_net"), - BundleFileType::Package => String::from("package"), - BundleFileType::Particles => String::from("particles"), - BundleFileType::PhysicsProperties => String::from("physics_properties"), - BundleFileType::RenderConfig => String::from("render_config"), - BundleFileType::RtPipeline => String::from("rt_pipeline"), - BundleFileType::Scene => String::from("scene"), - BundleFileType::ShaderLibraryGroup => String::from("shader_library_group"), - BundleFileType::ShaderLibrary => String::from("shader_library"), - BundleFileType::Shader => String::from("shader"), - BundleFileType::ShadingEnvionmentMapping => String::from("shading_environment_mapping"), - BundleFileType::ShadingEnvironment => String::from("shading_environment"), - BundleFileType::SlugAlbum => String::from("slug_album"), - BundleFileType::Slug => String::from("slug"), - BundleFileType::SoundEnvironment => String::from("sound_environment"), - BundleFileType::SpuJob => String::from("spu_job"), - BundleFileType::StateMachine => String::from("state_machine"), - BundleFileType::StaticPVS => String::from("static_pvs"), - BundleFileType::Strings => String::from("strings"), - BundleFileType::SurfaceProperties => String::from("surface_properties"), - BundleFileType::Texture => String::from("texture"), - BundleFileType::TimpaniBank => String::from("timpani_bank"), - BundleFileType::TimpaniMaster => String::from("timpani_master"), - BundleFileType::Tome => String::from("tome"), - BundleFileType::Ugg => String::from("ugg"), - BundleFileType::Unit => String::from("unit"), - BundleFileType::Upb => String::from("upb"), - BundleFileType::VectorField => String::from("vector_field"), - BundleFileType::Wav => String::from("wav"), - BundleFileType::WwiseBank => String::from("wwise_bank"), - BundleFileType::WwiseDep => String::from("wwise_dep"), - BundleFileType::WwiseEvent => String::from("wwise_event"), - BundleFileType::WwiseMetadata => String::from("wwise_metadata"), - BundleFileType::WwiseStream => String::from("wwise_stream"), - BundleFileType::Xml => String::from("xml"), - - BundleFileType::Unknown(s) => format!("{s:016X}"), - } - } - - pub fn decompiled_ext_name(&self) -> String { - match self { - BundleFileType::Texture => String::from("dds"), - BundleFileType::WwiseBank => String::from("bnk"), - BundleFileType::WwiseStream => String::from("ogg"), - _ => self.ext_name(), - } - } - - pub fn hash(&self) -> Murmur64 { - Murmur64::from(*self) - } -} - -impl std::str::FromStr for BundleFileType { - type Err = color_eyre::Report; - - fn from_str(s: &str) -> Result { - let val = match s { - "animation_curves" => BundleFileType::AnimationCurves, - "animation" => BundleFileType::Animation, - "apb" => BundleFileType::Apb, - "baked_lighting" => BundleFileType::BakedLighting, - "bik" => BundleFileType::Bik, - "blend_set" => BundleFileType::BlendSet, - "bones" => BundleFileType::Bones, - "chroma" => BundleFileType::Chroma, - "common_package" => BundleFileType::CommonPackage, - "config" => BundleFileType::Config, - "crypto" => BundleFileType::Crypto, - "data" => BundleFileType::Data, - "entity" => BundleFileType::Entity, - "flow" => BundleFileType::Flow, - "font" => BundleFileType::Font, - "ies" => BundleFileType::Ies, - "ini" => BundleFileType::Ini, - "input" => BundleFileType::Input, - "ivf" => BundleFileType::Ivf, - "keys" => BundleFileType::Keys, - "level" => BundleFileType::Level, - "lua" => BundleFileType::Lua, - "material" => BundleFileType::Material, - "mod" => BundleFileType::Mod, - "mouse_cursor" => BundleFileType::MouseCursor, - "nav_data" => BundleFileType::NavData, - "network_config" => BundleFileType::NetworkConfig, - "oodle_net" => BundleFileType::OddleNet, - "package" => BundleFileType::Package, - "particles" => BundleFileType::Particles, - "physics_properties" => BundleFileType::PhysicsProperties, - "render_config" => BundleFileType::RenderConfig, - "rt_pipeline" => BundleFileType::RtPipeline, - "scene" => BundleFileType::Scene, - "shader_library_group" => BundleFileType::ShaderLibraryGroup, - "shader_library" => BundleFileType::ShaderLibrary, - "shader" => BundleFileType::Shader, - "shading_environment_mapping" => BundleFileType::ShadingEnvionmentMapping, - "shading_environment" => BundleFileType::ShadingEnvironment, - "slug_album" => BundleFileType::SlugAlbum, - "slug" => BundleFileType::Slug, - "sound_environment" => BundleFileType::SoundEnvironment, - "spu_job" => BundleFileType::SpuJob, - "state_machine" => BundleFileType::StateMachine, - "static_pvs" => BundleFileType::StaticPVS, - "strings" => BundleFileType::Strings, - "surface_properties" => BundleFileType::SurfaceProperties, - "texture" => BundleFileType::Texture, - "timpani_bank" => BundleFileType::TimpaniBank, - "timpani_master" => BundleFileType::TimpaniMaster, - "tome" => BundleFileType::Tome, - "ugg" => BundleFileType::Ugg, - "unit" => BundleFileType::Unit, - "upb" => BundleFileType::Upb, - "vector_field" => BundleFileType::VectorField, - "wav" => BundleFileType::Wav, - "wwise_bank" => BundleFileType::WwiseBank, - "wwise_dep" => BundleFileType::WwiseDep, - "wwise_event" => BundleFileType::WwiseEvent, - "wwise_metadata" => BundleFileType::WwiseMetadata, - "wwise_stream" => BundleFileType::WwiseStream, - "xml" => BundleFileType::Xml, - s => eyre::bail!("Unknown type string '{}'", s), - }; - - Ok(val) - } -} - -impl Serialize for BundleFileType { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let value = self.ext_name(); - value.serialize(serializer) - } -} - -impl From for BundleFileType { - fn from(value: Murmur64) -> Self { - Self::from(Into::::into(value)) - } -} - -impl From for BundleFileType { - fn from(hash: u64) -> BundleFileType { - match hash { - 0x931e336d7646cc26 => BundleFileType::Animation, - 0xdcfb9e18fff13984 => BundleFileType::AnimationCurves, - 0x3eed05ba83af5090 => BundleFileType::Apb, - 0x7ffdb779b04e4ed1 => BundleFileType::BakedLighting, - 0xaa5965f03029fa18 => BundleFileType::Bik, - 0xe301e8af94e3b5a3 => BundleFileType::BlendSet, - 0x18dead01056b72e9 => BundleFileType::Bones, - 0xb7893adf7567506a => BundleFileType::Chroma, - 0xfe9754bd19814a47 => BundleFileType::CommonPackage, - 0x82645835e6b73232 => BundleFileType::Config, - 0x69108ded1e3e634b => BundleFileType::Crypto, - 0x8fd0d44d20650b68 => BundleFileType::Data, - 0x9831ca893b0d087d => BundleFileType::Entity, - 0x92d3ee038eeb610d => BundleFileType::Flow, - 0x9efe0a916aae7880 => BundleFileType::Font, - 0x8f7d5a2c0f967655 => BundleFileType::Ies, - 0xd526a27da14f1dc5 => BundleFileType::Ini, - 0x2bbcabe5074ade9e => BundleFileType::Input, - 0xfa4a8e091a91201e => BundleFileType::Ivf, - 0xa62f9297dc969e85 => BundleFileType::Keys, - 0x2a690fd348fe9ac5 => BundleFileType::Level, - 0xa14e8dfa2cd117e2 => BundleFileType::Lua, - 0xeac0b497876adedf => BundleFileType::Material, - 0x3fcdd69156a46417 => BundleFileType::Mod, - 0xb277b11fe4a61d37 => BundleFileType::MouseCursor, - 0x169de9566953d264 => BundleFileType::NavData, - 0x3b1fa9e8f6bac374 => BundleFileType::NetworkConfig, - 0xb0f2c12eb107f4d8 => BundleFileType::OddleNet, - 0xad9c6d9ed1e5e77a => BundleFileType::Package, - 0xa8193123526fad64 => BundleFileType::Particles, - 0xbf21403a3ab0bbb1 => BundleFileType::PhysicsProperties, - 0x27862fe24795319c => BundleFileType::RenderConfig, - 0x9ca183c2d0e76dee => BundleFileType::RtPipeline, - 0x9d0a795bfe818d19 => BundleFileType::Scene, - 0xcce8d5b5f5ae333f => BundleFileType::Shader, - 0xe5ee32a477239a93 => BundleFileType::ShaderLibrary, - 0x9e5c3cc74575aeb5 => BundleFileType::ShaderLibraryGroup, - 0x250e0a11ac8e26f8 => BundleFileType::ShadingEnvionmentMapping, - 0xfe73c7dcff8a7ca5 => BundleFileType::ShadingEnvironment, - 0xa27b4d04a9ba6f9e => BundleFileType::Slug, - 0xe9fc9ea7042e5ec0 => BundleFileType::SlugAlbum, - 0xd8b27864a97ffdd7 => BundleFileType::SoundEnvironment, - 0xf97af9983c05b950 => BundleFileType::SpuJob, - 0xa486d4045106165c => BundleFileType::StateMachine, - 0xe3f0baa17d620321 => BundleFileType::StaticPVS, - 0x0d972bab10b40fd3 => BundleFileType::Strings, - 0xad2d3fa30d9ab394 => BundleFileType::SurfaceProperties, - 0xcd4238c6a0c69e32 => BundleFileType::Texture, - 0x99736be1fff739a4 => BundleFileType::TimpaniBank, - 0x00a3e6c59a2b9c6c => BundleFileType::TimpaniMaster, - 0x19c792357c99f49b => BundleFileType::Tome, - 0x712d6e3dd1024c9c => BundleFileType::Ugg, - 0xe0a48d0be9a7453f => BundleFileType::Unit, - 0xa99510c6e86dd3c2 => BundleFileType::Upb, - 0xf7505933166d6755 => BundleFileType::VectorField, - 0x786f65c00a816b19 => BundleFileType::Wav, - 0x535a7bd3e650d799 => BundleFileType::WwiseBank, - 0xaf32095c82f2b070 => BundleFileType::WwiseDep, - 0xaabdd317b58dfc8a => BundleFileType::WwiseEvent, - 0xd50a8b7e1c82b110 => BundleFileType::WwiseMetadata, - 0x504b55235d21440e => BundleFileType::WwiseStream, - 0x76015845a6003765 => BundleFileType::Xml, - - _ => BundleFileType::Unknown(Murmur64::from(hash)), - } - } -} - -impl From for u64 { - fn from(t: BundleFileType) -> u64 { - match t { - BundleFileType::Animation => 0x931e336d7646cc26, - BundleFileType::AnimationCurves => 0xdcfb9e18fff13984, - BundleFileType::Apb => 0x3eed05ba83af5090, - BundleFileType::BakedLighting => 0x7ffdb779b04e4ed1, - BundleFileType::Bik => 0xaa5965f03029fa18, - BundleFileType::BlendSet => 0xe301e8af94e3b5a3, - BundleFileType::Bones => 0x18dead01056b72e9, - BundleFileType::Chroma => 0xb7893adf7567506a, - BundleFileType::CommonPackage => 0xfe9754bd19814a47, - BundleFileType::Config => 0x82645835e6b73232, - BundleFileType::Crypto => 0x69108ded1e3e634b, - BundleFileType::Data => 0x8fd0d44d20650b68, - BundleFileType::Entity => 0x9831ca893b0d087d, - BundleFileType::Flow => 0x92d3ee038eeb610d, - BundleFileType::Font => 0x9efe0a916aae7880, - BundleFileType::Ies => 0x8f7d5a2c0f967655, - BundleFileType::Ini => 0xd526a27da14f1dc5, - BundleFileType::Input => 0x2bbcabe5074ade9e, - BundleFileType::Ivf => 0xfa4a8e091a91201e, - BundleFileType::Keys => 0xa62f9297dc969e85, - BundleFileType::Level => 0x2a690fd348fe9ac5, - BundleFileType::Lua => 0xa14e8dfa2cd117e2, - BundleFileType::Material => 0xeac0b497876adedf, - BundleFileType::Mod => 0x3fcdd69156a46417, - BundleFileType::MouseCursor => 0xb277b11fe4a61d37, - BundleFileType::NavData => 0x169de9566953d264, - BundleFileType::NetworkConfig => 0x3b1fa9e8f6bac374, - BundleFileType::OddleNet => 0xb0f2c12eb107f4d8, - BundleFileType::Package => 0xad9c6d9ed1e5e77a, - BundleFileType::Particles => 0xa8193123526fad64, - BundleFileType::PhysicsProperties => 0xbf21403a3ab0bbb1, - BundleFileType::RenderConfig => 0x27862fe24795319c, - BundleFileType::RtPipeline => 0x9ca183c2d0e76dee, - BundleFileType::Scene => 0x9d0a795bfe818d19, - BundleFileType::Shader => 0xcce8d5b5f5ae333f, - BundleFileType::ShaderLibrary => 0xe5ee32a477239a93, - BundleFileType::ShaderLibraryGroup => 0x9e5c3cc74575aeb5, - BundleFileType::ShadingEnvionmentMapping => 0x250e0a11ac8e26f8, - BundleFileType::ShadingEnvironment => 0xfe73c7dcff8a7ca5, - BundleFileType::Slug => 0xa27b4d04a9ba6f9e, - BundleFileType::SlugAlbum => 0xe9fc9ea7042e5ec0, - BundleFileType::SoundEnvironment => 0xd8b27864a97ffdd7, - BundleFileType::SpuJob => 0xf97af9983c05b950, - BundleFileType::StateMachine => 0xa486d4045106165c, - BundleFileType::StaticPVS => 0xe3f0baa17d620321, - BundleFileType::Strings => 0x0d972bab10b40fd3, - BundleFileType::SurfaceProperties => 0xad2d3fa30d9ab394, - BundleFileType::Texture => 0xcd4238c6a0c69e32, - BundleFileType::TimpaniBank => 0x99736be1fff739a4, - BundleFileType::TimpaniMaster => 0x00a3e6c59a2b9c6c, - BundleFileType::Tome => 0x19c792357c99f49b, - BundleFileType::Ugg => 0x712d6e3dd1024c9c, - BundleFileType::Unit => 0xe0a48d0be9a7453f, - BundleFileType::Upb => 0xa99510c6e86dd3c2, - BundleFileType::VectorField => 0xf7505933166d6755, - BundleFileType::Wav => 0x786f65c00a816b19, - BundleFileType::WwiseBank => 0x535a7bd3e650d799, - BundleFileType::WwiseDep => 0xaf32095c82f2b070, - BundleFileType::WwiseEvent => 0xaabdd317b58dfc8a, - BundleFileType::WwiseMetadata => 0xd50a8b7e1c82b110, - BundleFileType::WwiseStream => 0x504b55235d21440e, - BundleFileType::Xml => 0x76015845a6003765, - - BundleFileType::Unknown(hash) => hash.into(), - } - } -} -impl From for Murmur64 { - fn from(t: BundleFileType) -> Murmur64 { - let hash: u64 = t.into(); - Murmur64::from(hash) - } -} - -impl std::fmt::Display for BundleFileType { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.ext_name()) - } -} +use super::filetype::BundleFileType; #[derive(Debug)] struct BundleFileHeader { diff --git a/lib/sdk/src/bundle/filetype.rs b/lib/sdk/src/bundle/filetype.rs new file mode 100644 index 0000000..0b4f292 --- /dev/null +++ b/lib/sdk/src/bundle/filetype.rs @@ -0,0 +1,400 @@ +use color_eyre::{eyre, Result}; +use serde::Serialize; + +use crate::murmur::Murmur64; + +#[derive(Debug, Hash, PartialEq, Eq, Copy, Clone)] +pub enum BundleFileType { + Animation, + AnimationCurves, + Apb, + BakedLighting, + Bik, + BlendSet, + Bones, + Chroma, + CommonPackage, + Config, + Crypto, + Data, + Entity, + Flow, + Font, + Ies, + Ini, + Input, + Ivf, + Keys, + Level, + Lua, + Material, + Mod, + MouseCursor, + NavData, + NetworkConfig, + OddleNet, + Package, + Particles, + PhysicsProperties, + RenderConfig, + RtPipeline, + Scene, + Shader, + ShaderLibrary, + ShaderLibraryGroup, + ShadingEnvionmentMapping, + ShadingEnvironment, + Slug, + SlugAlbum, + SoundEnvironment, + SpuJob, + StateMachine, + StaticPVS, + Strings, + SurfaceProperties, + Texture, + TimpaniBank, + TimpaniMaster, + Tome, + Ugg, + Unit, + Upb, + VectorField, + Wav, + WwiseBank, + WwiseDep, + WwiseEvent, + WwiseMetadata, + WwiseStream, + Xml, + + Unknown(Murmur64), +} + +impl BundleFileType { + pub fn ext_name(&self) -> String { + match self { + BundleFileType::AnimationCurves => String::from("animation_curves"), + BundleFileType::Animation => String::from("animation"), + BundleFileType::Apb => String::from("apb"), + BundleFileType::BakedLighting => String::from("baked_lighting"), + BundleFileType::Bik => String::from("bik"), + BundleFileType::BlendSet => String::from("blend_set"), + BundleFileType::Bones => String::from("bones"), + BundleFileType::Chroma => String::from("chroma"), + BundleFileType::CommonPackage => String::from("common_package"), + BundleFileType::Config => String::from("config"), + BundleFileType::Crypto => String::from("crypto"), + BundleFileType::Data => String::from("data"), + BundleFileType::Entity => String::from("entity"), + BundleFileType::Flow => String::from("flow"), + BundleFileType::Font => String::from("font"), + BundleFileType::Ies => String::from("ies"), + BundleFileType::Ini => String::from("ini"), + BundleFileType::Input => String::from("input"), + BundleFileType::Ivf => String::from("ivf"), + BundleFileType::Keys => String::from("keys"), + BundleFileType::Level => String::from("level"), + BundleFileType::Lua => String::from("lua"), + BundleFileType::Material => String::from("material"), + BundleFileType::Mod => String::from("mod"), + BundleFileType::MouseCursor => String::from("mouse_cursor"), + BundleFileType::NavData => String::from("nav_data"), + BundleFileType::NetworkConfig => String::from("network_config"), + BundleFileType::OddleNet => String::from("oodle_net"), + BundleFileType::Package => String::from("package"), + BundleFileType::Particles => String::from("particles"), + BundleFileType::PhysicsProperties => String::from("physics_properties"), + BundleFileType::RenderConfig => String::from("render_config"), + BundleFileType::RtPipeline => String::from("rt_pipeline"), + BundleFileType::Scene => String::from("scene"), + BundleFileType::ShaderLibraryGroup => String::from("shader_library_group"), + BundleFileType::ShaderLibrary => String::from("shader_library"), + BundleFileType::Shader => String::from("shader"), + BundleFileType::ShadingEnvionmentMapping => String::from("shading_environment_mapping"), + BundleFileType::ShadingEnvironment => String::from("shading_environment"), + BundleFileType::SlugAlbum => String::from("slug_album"), + BundleFileType::Slug => String::from("slug"), + BundleFileType::SoundEnvironment => String::from("sound_environment"), + BundleFileType::SpuJob => String::from("spu_job"), + BundleFileType::StateMachine => String::from("state_machine"), + BundleFileType::StaticPVS => String::from("static_pvs"), + BundleFileType::Strings => String::from("strings"), + BundleFileType::SurfaceProperties => String::from("surface_properties"), + BundleFileType::Texture => String::from("texture"), + BundleFileType::TimpaniBank => String::from("timpani_bank"), + BundleFileType::TimpaniMaster => String::from("timpani_master"), + BundleFileType::Tome => String::from("tome"), + BundleFileType::Ugg => String::from("ugg"), + BundleFileType::Unit => String::from("unit"), + BundleFileType::Upb => String::from("upb"), + BundleFileType::VectorField => String::from("vector_field"), + BundleFileType::Wav => String::from("wav"), + BundleFileType::WwiseBank => String::from("wwise_bank"), + BundleFileType::WwiseDep => String::from("wwise_dep"), + BundleFileType::WwiseEvent => String::from("wwise_event"), + BundleFileType::WwiseMetadata => String::from("wwise_metadata"), + BundleFileType::WwiseStream => String::from("wwise_stream"), + BundleFileType::Xml => String::from("xml"), + + BundleFileType::Unknown(s) => format!("{s:016X}"), + } + } + + pub fn decompiled_ext_name(&self) -> String { + match self { + BundleFileType::Texture => String::from("dds"), + BundleFileType::WwiseBank => String::from("bnk"), + BundleFileType::WwiseStream => String::from("ogg"), + _ => self.ext_name(), + } + } + + pub fn hash(&self) -> Murmur64 { + Murmur64::from(*self) + } +} + +impl std::str::FromStr for BundleFileType { + type Err = color_eyre::Report; + + fn from_str(s: &str) -> Result { + let val = match s { + "animation_curves" => BundleFileType::AnimationCurves, + "animation" => BundleFileType::Animation, + "apb" => BundleFileType::Apb, + "baked_lighting" => BundleFileType::BakedLighting, + "bik" => BundleFileType::Bik, + "blend_set" => BundleFileType::BlendSet, + "bones" => BundleFileType::Bones, + "chroma" => BundleFileType::Chroma, + "common_package" => BundleFileType::CommonPackage, + "config" => BundleFileType::Config, + "crypto" => BundleFileType::Crypto, + "data" => BundleFileType::Data, + "entity" => BundleFileType::Entity, + "flow" => BundleFileType::Flow, + "font" => BundleFileType::Font, + "ies" => BundleFileType::Ies, + "ini" => BundleFileType::Ini, + "input" => BundleFileType::Input, + "ivf" => BundleFileType::Ivf, + "keys" => BundleFileType::Keys, + "level" => BundleFileType::Level, + "lua" => BundleFileType::Lua, + "material" => BundleFileType::Material, + "mod" => BundleFileType::Mod, + "mouse_cursor" => BundleFileType::MouseCursor, + "nav_data" => BundleFileType::NavData, + "network_config" => BundleFileType::NetworkConfig, + "oodle_net" => BundleFileType::OddleNet, + "package" => BundleFileType::Package, + "particles" => BundleFileType::Particles, + "physics_properties" => BundleFileType::PhysicsProperties, + "render_config" => BundleFileType::RenderConfig, + "rt_pipeline" => BundleFileType::RtPipeline, + "scene" => BundleFileType::Scene, + "shader_library_group" => BundleFileType::ShaderLibraryGroup, + "shader_library" => BundleFileType::ShaderLibrary, + "shader" => BundleFileType::Shader, + "shading_environment_mapping" => BundleFileType::ShadingEnvionmentMapping, + "shading_environment" => BundleFileType::ShadingEnvironment, + "slug_album" => BundleFileType::SlugAlbum, + "slug" => BundleFileType::Slug, + "sound_environment" => BundleFileType::SoundEnvironment, + "spu_job" => BundleFileType::SpuJob, + "state_machine" => BundleFileType::StateMachine, + "static_pvs" => BundleFileType::StaticPVS, + "strings" => BundleFileType::Strings, + "surface_properties" => BundleFileType::SurfaceProperties, + "texture" => BundleFileType::Texture, + "timpani_bank" => BundleFileType::TimpaniBank, + "timpani_master" => BundleFileType::TimpaniMaster, + "tome" => BundleFileType::Tome, + "ugg" => BundleFileType::Ugg, + "unit" => BundleFileType::Unit, + "upb" => BundleFileType::Upb, + "vector_field" => BundleFileType::VectorField, + "wav" => BundleFileType::Wav, + "wwise_bank" => BundleFileType::WwiseBank, + "wwise_dep" => BundleFileType::WwiseDep, + "wwise_event" => BundleFileType::WwiseEvent, + "wwise_metadata" => BundleFileType::WwiseMetadata, + "wwise_stream" => BundleFileType::WwiseStream, + "xml" => BundleFileType::Xml, + s => eyre::bail!("Unknown type string '{}'", s), + }; + + Ok(val) + } +} + +impl Serialize for BundleFileType { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let value = self.ext_name(); + value.serialize(serializer) + } +} + +impl From for BundleFileType { + fn from(value: Murmur64) -> Self { + Self::from(Into::::into(value)) + } +} + +impl From for BundleFileType { + fn from(hash: u64) -> BundleFileType { + match hash { + 0x931e336d7646cc26 => BundleFileType::Animation, + 0xdcfb9e18fff13984 => BundleFileType::AnimationCurves, + 0x3eed05ba83af5090 => BundleFileType::Apb, + 0x7ffdb779b04e4ed1 => BundleFileType::BakedLighting, + 0xaa5965f03029fa18 => BundleFileType::Bik, + 0xe301e8af94e3b5a3 => BundleFileType::BlendSet, + 0x18dead01056b72e9 => BundleFileType::Bones, + 0xb7893adf7567506a => BundleFileType::Chroma, + 0xfe9754bd19814a47 => BundleFileType::CommonPackage, + 0x82645835e6b73232 => BundleFileType::Config, + 0x69108ded1e3e634b => BundleFileType::Crypto, + 0x8fd0d44d20650b68 => BundleFileType::Data, + 0x9831ca893b0d087d => BundleFileType::Entity, + 0x92d3ee038eeb610d => BundleFileType::Flow, + 0x9efe0a916aae7880 => BundleFileType::Font, + 0x8f7d5a2c0f967655 => BundleFileType::Ies, + 0xd526a27da14f1dc5 => BundleFileType::Ini, + 0x2bbcabe5074ade9e => BundleFileType::Input, + 0xfa4a8e091a91201e => BundleFileType::Ivf, + 0xa62f9297dc969e85 => BundleFileType::Keys, + 0x2a690fd348fe9ac5 => BundleFileType::Level, + 0xa14e8dfa2cd117e2 => BundleFileType::Lua, + 0xeac0b497876adedf => BundleFileType::Material, + 0x3fcdd69156a46417 => BundleFileType::Mod, + 0xb277b11fe4a61d37 => BundleFileType::MouseCursor, + 0x169de9566953d264 => BundleFileType::NavData, + 0x3b1fa9e8f6bac374 => BundleFileType::NetworkConfig, + 0xb0f2c12eb107f4d8 => BundleFileType::OddleNet, + 0xad9c6d9ed1e5e77a => BundleFileType::Package, + 0xa8193123526fad64 => BundleFileType::Particles, + 0xbf21403a3ab0bbb1 => BundleFileType::PhysicsProperties, + 0x27862fe24795319c => BundleFileType::RenderConfig, + 0x9ca183c2d0e76dee => BundleFileType::RtPipeline, + 0x9d0a795bfe818d19 => BundleFileType::Scene, + 0xcce8d5b5f5ae333f => BundleFileType::Shader, + 0xe5ee32a477239a93 => BundleFileType::ShaderLibrary, + 0x9e5c3cc74575aeb5 => BundleFileType::ShaderLibraryGroup, + 0x250e0a11ac8e26f8 => BundleFileType::ShadingEnvionmentMapping, + 0xfe73c7dcff8a7ca5 => BundleFileType::ShadingEnvironment, + 0xa27b4d04a9ba6f9e => BundleFileType::Slug, + 0xe9fc9ea7042e5ec0 => BundleFileType::SlugAlbum, + 0xd8b27864a97ffdd7 => BundleFileType::SoundEnvironment, + 0xf97af9983c05b950 => BundleFileType::SpuJob, + 0xa486d4045106165c => BundleFileType::StateMachine, + 0xe3f0baa17d620321 => BundleFileType::StaticPVS, + 0x0d972bab10b40fd3 => BundleFileType::Strings, + 0xad2d3fa30d9ab394 => BundleFileType::SurfaceProperties, + 0xcd4238c6a0c69e32 => BundleFileType::Texture, + 0x99736be1fff739a4 => BundleFileType::TimpaniBank, + 0x00a3e6c59a2b9c6c => BundleFileType::TimpaniMaster, + 0x19c792357c99f49b => BundleFileType::Tome, + 0x712d6e3dd1024c9c => BundleFileType::Ugg, + 0xe0a48d0be9a7453f => BundleFileType::Unit, + 0xa99510c6e86dd3c2 => BundleFileType::Upb, + 0xf7505933166d6755 => BundleFileType::VectorField, + 0x786f65c00a816b19 => BundleFileType::Wav, + 0x535a7bd3e650d799 => BundleFileType::WwiseBank, + 0xaf32095c82f2b070 => BundleFileType::WwiseDep, + 0xaabdd317b58dfc8a => BundleFileType::WwiseEvent, + 0xd50a8b7e1c82b110 => BundleFileType::WwiseMetadata, + 0x504b55235d21440e => BundleFileType::WwiseStream, + 0x76015845a6003765 => BundleFileType::Xml, + + _ => BundleFileType::Unknown(Murmur64::from(hash)), + } + } +} + +impl From for u64 { + fn from(t: BundleFileType) -> u64 { + match t { + BundleFileType::Animation => 0x931e336d7646cc26, + BundleFileType::AnimationCurves => 0xdcfb9e18fff13984, + BundleFileType::Apb => 0x3eed05ba83af5090, + BundleFileType::BakedLighting => 0x7ffdb779b04e4ed1, + BundleFileType::Bik => 0xaa5965f03029fa18, + BundleFileType::BlendSet => 0xe301e8af94e3b5a3, + BundleFileType::Bones => 0x18dead01056b72e9, + BundleFileType::Chroma => 0xb7893adf7567506a, + BundleFileType::CommonPackage => 0xfe9754bd19814a47, + BundleFileType::Config => 0x82645835e6b73232, + BundleFileType::Crypto => 0x69108ded1e3e634b, + BundleFileType::Data => 0x8fd0d44d20650b68, + BundleFileType::Entity => 0x9831ca893b0d087d, + BundleFileType::Flow => 0x92d3ee038eeb610d, + BundleFileType::Font => 0x9efe0a916aae7880, + BundleFileType::Ies => 0x8f7d5a2c0f967655, + BundleFileType::Ini => 0xd526a27da14f1dc5, + BundleFileType::Input => 0x2bbcabe5074ade9e, + BundleFileType::Ivf => 0xfa4a8e091a91201e, + BundleFileType::Keys => 0xa62f9297dc969e85, + BundleFileType::Level => 0x2a690fd348fe9ac5, + BundleFileType::Lua => 0xa14e8dfa2cd117e2, + BundleFileType::Material => 0xeac0b497876adedf, + BundleFileType::Mod => 0x3fcdd69156a46417, + BundleFileType::MouseCursor => 0xb277b11fe4a61d37, + BundleFileType::NavData => 0x169de9566953d264, + BundleFileType::NetworkConfig => 0x3b1fa9e8f6bac374, + BundleFileType::OddleNet => 0xb0f2c12eb107f4d8, + BundleFileType::Package => 0xad9c6d9ed1e5e77a, + BundleFileType::Particles => 0xa8193123526fad64, + BundleFileType::PhysicsProperties => 0xbf21403a3ab0bbb1, + BundleFileType::RenderConfig => 0x27862fe24795319c, + BundleFileType::RtPipeline => 0x9ca183c2d0e76dee, + BundleFileType::Scene => 0x9d0a795bfe818d19, + BundleFileType::Shader => 0xcce8d5b5f5ae333f, + BundleFileType::ShaderLibrary => 0xe5ee32a477239a93, + BundleFileType::ShaderLibraryGroup => 0x9e5c3cc74575aeb5, + BundleFileType::ShadingEnvionmentMapping => 0x250e0a11ac8e26f8, + BundleFileType::ShadingEnvironment => 0xfe73c7dcff8a7ca5, + BundleFileType::Slug => 0xa27b4d04a9ba6f9e, + BundleFileType::SlugAlbum => 0xe9fc9ea7042e5ec0, + BundleFileType::SoundEnvironment => 0xd8b27864a97ffdd7, + BundleFileType::SpuJob => 0xf97af9983c05b950, + BundleFileType::StateMachine => 0xa486d4045106165c, + BundleFileType::StaticPVS => 0xe3f0baa17d620321, + BundleFileType::Strings => 0x0d972bab10b40fd3, + BundleFileType::SurfaceProperties => 0xad2d3fa30d9ab394, + BundleFileType::Texture => 0xcd4238c6a0c69e32, + BundleFileType::TimpaniBank => 0x99736be1fff739a4, + BundleFileType::TimpaniMaster => 0x00a3e6c59a2b9c6c, + BundleFileType::Tome => 0x19c792357c99f49b, + BundleFileType::Ugg => 0x712d6e3dd1024c9c, + BundleFileType::Unit => 0xe0a48d0be9a7453f, + BundleFileType::Upb => 0xa99510c6e86dd3c2, + BundleFileType::VectorField => 0xf7505933166d6755, + BundleFileType::Wav => 0x786f65c00a816b19, + BundleFileType::WwiseBank => 0x535a7bd3e650d799, + BundleFileType::WwiseDep => 0xaf32095c82f2b070, + BundleFileType::WwiseEvent => 0xaabdd317b58dfc8a, + BundleFileType::WwiseMetadata => 0xd50a8b7e1c82b110, + BundleFileType::WwiseStream => 0x504b55235d21440e, + BundleFileType::Xml => 0x76015845a6003765, + + BundleFileType::Unknown(hash) => hash.into(), + } + } +} +impl From for Murmur64 { + fn from(t: BundleFileType) -> Murmur64 { + let hash: u64 = t.into(); + Murmur64::from(hash) + } +} + +impl std::fmt::Display for BundleFileType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.ext_name()) + } +} diff --git a/lib/sdk/src/bundle/mod.rs b/lib/sdk/src/bundle/mod.rs index 813df06..ca36393 100644 --- a/lib/sdk/src/bundle/mod.rs +++ b/lib/sdk/src/bundle/mod.rs @@ -12,8 +12,10 @@ use crate::murmur::{HashGroup, IdString64, Murmur64}; pub(crate) mod database; pub(crate) mod file; +pub(crate) mod filetype; -pub use file::{BundleFile, BundleFileType, BundleFileVariant}; +pub use file::{BundleFile, BundleFileVariant}; +pub use filetype::BundleFileType; #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] enum BundleFormat { diff --git a/lib/sdk/src/filetype/package.rs b/lib/sdk/src/filetype/package.rs index 1f50f81..a36719e 100644 --- a/lib/sdk/src/filetype/package.rs +++ b/lib/sdk/src/filetype/package.rs @@ -11,7 +11,8 @@ use path_slash::PathBufExt; use tokio::fs; use crate::binary::sync::{ReadExt, WriteExt}; -use crate::bundle::file::{BundleFileType, UserFile}; +use crate::bundle::file::UserFile; +use crate::bundle::filetype::BundleFileType; use crate::murmur::{HashGroup, Murmur64}; #[tracing::instrument] @@ -280,17 +281,11 @@ where Ok(vec![UserFile::new(s.into_bytes())]) } -// #[tracing::instrument(skip_all)] -// pub fn compile(_ctx: &crate::Context, data: String) -> Result> { -// let pkg = Package::from_sjson(data)?; -// pkg.to_binary() -// } - #[cfg(test)] mod test { use std::path::PathBuf; - use crate::BundleFileType; + use crate::bundle::filetype::BundleFileType; use super::resolve_wildcard; use super::Package; -- 2.45.3 From 95fc6c160b2176770ab54c4380f208bb664b76f4 Mon Sep 17 00:00:00 2001 From: Lucas Schwiderski Date: Wed, 4 Oct 2023 09:47:25 +0200 Subject: [PATCH 2/2] dtmt: Implement name overrides For most of the game files, we don't know the actual name, only the hash of that name. To still allow building bundles that contain files with that name (e.g. to override a game file with a custom one), there needs to be a way to tell DTMT to name a file such that its hash is the same as the one in the game. The initial idea was to just expect the file name on disk to be the hash, but that wouldn't allow for arbitrary folder structures anymore. So instead, there is now a new, optional setting in `dtmt.cfg`, where the modder can map a file path to an override name. --- crates/dtmm/src/controller/deploy.rs | 8 ++-- crates/dtmm/src/controller/import.rs | 1 + crates/dtmt/src/cmd/build.rs | 68 ++++++++++++++-------------- crates/dtmt/src/cmd/migrate.rs | 1 + crates/dtmt/src/cmd/watch.rs | 17 +++---- lib/dtmt-shared/src/lib.rs | 3 ++ lib/sdk/src/bundle/file.rs | 26 ++++------- lib/sdk/src/filetype/lua.rs | 13 ++---- lib/sdk/src/filetype/package.rs | 48 +++++++++++--------- lib/sdk/src/murmur/types.rs | 28 ++++++++++-- 10 files changed, 116 insertions(+), 97 deletions(-) diff --git a/crates/dtmm/src/controller/deploy.rs b/crates/dtmm/src/controller/deploy.rs index e2d9c0e..02b6860 100644 --- a/crates/dtmm/src/controller/deploy.rs +++ b/crates/dtmm/src/controller/deploy.rs @@ -324,11 +324,11 @@ async fn build_bundles(state: Arc) -> Result> { let mut bundles = Vec::new(); - let mut add_lua_asset = |name, data: &str| { + let mut add_lua_asset = |name: &str, data: &str| { let span = tracing::info_span!("Compiling Lua", name, data_len = data.len()); let _enter = span.enter(); - let file = lua::compile(name, data).wrap_err("Failed to compile Lua")?; + let file = lua::compile(name.to_string(), data).wrap_err("Failed to compile Lua")?; mod_bundle.add_file(file); @@ -517,8 +517,8 @@ async fn patch_boot_bundle( .wrap_err("Failed to render template `mod_main.lua`")?; tracing::trace!("Main script rendered:\n===========\n{}\n=============", lua); - let file = - lua::compile(MOD_BOOT_SCRIPT, lua).wrap_err("Failed to compile mod main Lua file")?; + let file = lua::compile(MOD_BOOT_SCRIPT.to_string(), lua) + .wrap_err("Failed to compile mod main Lua file")?; boot_bundle.add_file(file); } diff --git a/crates/dtmm/src/controller/import.rs b/crates/dtmm/src/controller/import.rs index 8e47d23..2f5f90b 100644 --- a/crates/dtmm/src/controller/import.rs +++ b/crates/dtmm/src/controller/import.rs @@ -297,6 +297,7 @@ fn extract_mod_config(archive: &mut ZipArchive) -> Result<(Mo packages: Vec::new(), resources, depends: Vec::new(), + name_overrides: Default::default(), }; Ok((cfg, root)) diff --git a/crates/dtmt/src/cmd/build.rs b/crates/dtmt/src/cmd/build.rs index 77ab629..fab072b 100644 --- a/crates/dtmt/src/cmd/build.rs +++ b/crates/dtmt/src/cmd/build.rs @@ -103,38 +103,41 @@ async fn find_project_config(dir: Option) -> Result { } #[tracing::instrument(skip_all)] -async fn compile_package_files

(pkg: &Package, root: P) -> Result> -where - P: AsRef + std::fmt::Debug, -{ - let root = Arc::new(root.as_ref()); +async fn compile_package_files(pkg: &Package, cfg: &ModConfig) -> Result> { + let root = Arc::new(&cfg.dir); + let name_overrides = &cfg.name_overrides; let tasks = pkg .iter() - .flat_map(|(file_type, paths)| { - paths.iter().map(|path| { + .flat_map(|(file_type, names)| { + names.iter().map(|name| { ( *file_type, - path, + name, // Cloning the `Arc` here solves the issue that in the next `.map`, I need to // `move` the closure parameters, but can't `move` `root` before it was cloned. root.clone(), ) }) }) - .map(|(file_type, path, root)| async move { - let sjson = fs::read_to_string(&path).await?; + .map(|(file_type, name, root)| async move { + let path = PathBuf::from(name); + let sjson = fs::read_to_string(&path) + .await + .wrap_err_with(|| format!("Failed to read file '{}'", path.display()))?; - let mut path = path.clone(); - path.set_extension(""); - - BundleFile::from_sjson( - path.to_slash_lossy().to_string(), - file_type, - sjson, - root.as_ref(), - ) - .await + let name = path.with_extension("").to_slash_lossy().to_string(); + let name = if let Some(new_name) = name_overrides.get(&name) { + let new_name = match u64::from_str_radix(new_name, 16) { + Ok(hash) => IdString64::from(hash), + Err(_) => IdString64::from(new_name.clone()), + }; + tracing::info!("Overriding '{}' -> '{}'", name, new_name.display()); + new_name + } else { + IdString64::from(name.clone()) + }; + BundleFile::from_sjson(name, file_type, sjson, root.as_ref()).await }); let results = futures::stream::iter(tasks) @@ -146,12 +149,11 @@ where } #[tracing::instrument] -async fn build_package(package: P1, root: P2) -> Result -where - P1: AsRef + std::fmt::Debug, - P2: AsRef + std::fmt::Debug, -{ - let root = root.as_ref(); +async fn build_package( + cfg: &ModConfig, + package: impl AsRef + std::fmt::Debug, +) -> Result { + let root = &cfg.dir; let package = package.as_ref(); let mut path = root.join(package); @@ -165,7 +167,7 @@ where .await .wrap_err_with(|| format!("Invalid package file {}", &pkg_name))?; - let files = compile_package_files(&pkg, root).await?; + let files = compile_package_files(&pkg, cfg).await?; let mut bundle = Bundle::new(pkg_name); for file in files { bundle.add_file(file); @@ -254,14 +256,14 @@ pub(crate) async fn read_project_config(dir: Option) -> Result( +#[tracing::instrument] +pub(crate) async fn build

( cfg: &ModConfig, - out_path: P1, - game_dir: Arc>, + out_path: impl AsRef + std::fmt::Debug, + game_dir: Arc>, ) -> Result<()> where - P1: AsRef, - P2: AsRef, + P: AsRef + std::fmt::Debug, { let out_path = out_path.as_ref(); @@ -286,7 +288,7 @@ where ); } - let bundle = build_package(path, &cfg.dir).await.wrap_err_with(|| { + let bundle = build_package(&cfg, path).await.wrap_err_with(|| { format!( "Failed to build package '{}' at '{}'", path.display(), diff --git a/crates/dtmt/src/cmd/migrate.rs b/crates/dtmt/src/cmd/migrate.rs index 2eacded..d7bfa19 100644 --- a/crates/dtmt/src/cmd/migrate.rs +++ b/crates/dtmt/src/cmd/migrate.rs @@ -351,6 +351,7 @@ pub(crate) async fn run(_ctx: sdk::Context, matches: &ArgMatches) -> Result<()> }, depends: vec![ModDependency::ID(String::from("DMF"))], bundled: true, + name_overrides: HashMap::new(), }; tracing::debug!(?dtmt_cfg); diff --git a/crates/dtmt/src/cmd/watch.rs b/crates/dtmt/src/cmd/watch.rs index 79fab67..2abd0f7 100644 --- a/crates/dtmt/src/cmd/watch.rs +++ b/crates/dtmt/src/cmd/watch.rs @@ -77,17 +77,14 @@ pub(crate) fn command_definition() -> Command { ) } -async fn compile( +#[tracing::instrument] +async fn compile( cfg: &ModConfig, - out_path: P1, - archive_path: P2, - game_dir: Arc>, -) -> Result<()> -where - P1: AsRef + std::marker::Copy, - P2: AsRef, - P3: AsRef, -{ + out_path: impl AsRef + std::fmt::Debug, + archive_path: impl AsRef + std::fmt::Debug, + game_dir: Arc + std::fmt::Debug>>, +) -> Result<()> { + let out_path = out_path.as_ref(); build(cfg, out_path, game_dir) .await .wrap_err("Failed to build bundles")?; diff --git a/lib/dtmt-shared/src/lib.rs b/lib/dtmt-shared/src/lib.rs index 3c9530e..d1f69c7 100644 --- a/lib/dtmt-shared/src/lib.rs +++ b/lib/dtmt-shared/src/lib.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use std::path::PathBuf; use color_eyre::eyre::{OptionExt as _, WrapErr as _}; @@ -67,6 +68,8 @@ pub struct ModConfig { pub depends: Vec, #[serde(default = "default_true", skip_serializing_if = "is_true")] pub bundled: bool, + #[serde(default)] + pub name_overrides: HashMap, } pub const STEAMAPP_ID: u32 = 1361210; diff --git a/lib/sdk/src/bundle/file.rs b/lib/sdk/src/bundle/file.rs index 1780a5d..f387409 100644 --- a/lib/sdk/src/bundle/file.rs +++ b/lib/sdk/src/bundle/file.rs @@ -120,7 +120,7 @@ pub struct BundleFile { } impl BundleFile { - pub fn new(name: String, file_type: BundleFileType) -> Self { + pub fn new(name: impl Into, file_type: BundleFileType) -> Self { Self { file_type, name: name.into(), @@ -252,20 +252,15 @@ impl BundleFile { Ok(w.into_inner()) } - #[tracing::instrument(name = "File::from_sjson", skip(sjson))] - pub async fn from_sjson( - name: String, + #[tracing::instrument("File::from_sjson", skip(sjson, name), fields(name = %name.display()))] + pub async fn from_sjson( + name: IdString64, file_type: BundleFileType, - sjson: S, - root: P, - ) -> Result - where - P: AsRef + std::fmt::Debug, - S: AsRef, - { + sjson: impl AsRef, + root: impl AsRef + std::fmt::Debug, + ) -> Result { match file_type { - BundleFileType::Lua => lua::compile(name.clone(), sjson) - .wrap_err_with(|| format!("Failed to compile Lua file '{}'", name)), + BundleFileType::Lua => lua::compile(name, sjson).wrap_err("Failed to compile Lua file"), BundleFileType::Unknown(_) => { eyre::bail!("Unknown file type. Cannot compile from SJSON"); } @@ -304,10 +299,7 @@ impl BundleFile { s } - pub fn matches_name(&self, name: S) -> bool - where - S: Into, - { + pub fn matches_name(&self, name: impl Into) -> bool { let name = name.into(); if self.name == name { return true; diff --git a/lib/sdk/src/filetype/lua.rs b/lib/sdk/src/filetype/lua.rs index bfe6de7..14f0d6b 100644 --- a/lib/sdk/src/filetype/lua.rs +++ b/lib/sdk/src/filetype/lua.rs @@ -15,6 +15,7 @@ use tokio::fs; use crate::binary::sync::ReadExt; use crate::binary::sync::WriteExt; use crate::bundle::file::{BundleFileVariant, UserFile}; +use crate::murmur::IdString64; use crate::{BundleFile, BundleFileType}; const BITSQUID_LUAJIT_HEADER: u32 = 0x8253461B; @@ -117,17 +118,13 @@ where } #[tracing::instrument(skip_all)] -pub fn compile(name: S, code: C) -> Result -where - S: Into, - C: AsRef, -{ +pub fn compile(name: impl Into, code: impl AsRef) -> Result { let name = name.into(); let code = code.as_ref(); tracing::trace!( "Compiling '{}', {} bytes of code", - name, + name.display(), code.as_bytes().len() ); @@ -135,8 +132,8 @@ where let state = lua::luaL_newstate(); lua::luaL_openlibs(state); - let name = CString::new(format!("@{name}").into_bytes()) - .wrap_err_with(|| format!("Cannot convert name into CString: {}", name))?; + let name = CString::new(format!("@{}", name.display()).into_bytes()) + .wrap_err_with(|| format!("Cannot convert name into CString: {}", name.display()))?; match lua::luaL_loadbuffer( state, code.as_ptr() as _, diff --git a/lib/sdk/src/filetype/package.rs b/lib/sdk/src/filetype/package.rs index a36719e..6394e42 100644 --- a/lib/sdk/src/filetype/package.rs +++ b/lib/sdk/src/filetype/package.rs @@ -7,13 +7,12 @@ use std::str::FromStr; use async_recursion::async_recursion; use color_eyre::eyre::{self, Context}; use color_eyre::Result; -use path_slash::PathBufExt; use tokio::fs; use crate::binary::sync::{ReadExt, WriteExt}; use crate::bundle::file::UserFile; use crate::bundle::filetype::BundleFileType; -use crate::murmur::{HashGroup, Murmur64}; +use crate::murmur::{HashGroup, IdString64, Murmur64}; #[tracing::instrument] #[async_recursion] @@ -91,12 +90,12 @@ where Ok(paths) } -type PackageType = HashMap>; +type PackageType = HashMap>; type PackageDefinition = HashMap>; #[derive(Default)] pub struct Package { - _name: String, + _name: IdString64, _root: PathBuf, inner: PackageType, flags: u8, @@ -117,9 +116,9 @@ impl DerefMut for Package { } impl Package { - pub fn new(name: String, root: PathBuf) -> Self { + pub fn new(name: impl Into, root: PathBuf) -> Self { Self { - _name: name, + _name: name.into(), _root: root, inner: Default::default(), flags: 1, @@ -130,17 +129,22 @@ impl Package { self.values().fold(0, |total, files| total + files.len()) } - pub fn add_file>(&mut self, file_type: BundleFileType, name: P) { + pub fn add_file(&mut self, file_type: BundleFileType, name: impl Into) { self.inner.entry(file_type).or_default().insert(name.into()); } #[tracing::instrument("Package::from_sjson", skip(sjson), fields(sjson_len = sjson.as_ref().len()))] - pub async fn from_sjson(sjson: S, name: String, root: P) -> Result + pub async fn from_sjson( + sjson: S, + name: impl Into + std::fmt::Debug, + root: P, + ) -> Result where P: AsRef + std::fmt::Debug, S: AsRef, { let root = root.as_ref(); + let name = name.into(); let definition: PackageDefinition = serde_sjson::from_str(sjson.as_ref())?; let mut inner: PackageType = Default::default(); @@ -174,7 +178,11 @@ impl Package { continue; }; - inner.entry(t).or_default().insert(path); + tracing::debug!("Adding file {}", path.display()); + inner + .entry(t) + .or_default() + .insert(path.display().to_string()); } } } @@ -193,11 +201,9 @@ impl Package { pub fn to_sjson(&self) -> Result { let mut map: PackageDefinition = Default::default(); - for (t, paths) in self.iter() { - for path in paths.iter() { - map.entry(t.ext_name()) - .or_default() - .insert(path.display().to_string()); + for (t, names) in self.iter() { + for name in names.iter() { + map.entry(t.ext_name()).or_default().insert(name.clone()); } } @@ -223,11 +229,11 @@ impl Package { for _ in 0..file_count { let t = BundleFileType::from(r.read_u64()?); let hash = Murmur64::from(r.read_u64()?); - let path = ctx.lookup_hash(hash, HashGroup::Filename); + let name = ctx.lookup_hash(hash, HashGroup::Filename); inner .entry(t) .or_default() - .insert(PathBuf::from(path.display().to_string())); + .insert(name.display().to_string()); } let flags = r.read_u8()?; @@ -240,7 +246,7 @@ impl Package { let pkg = Self { inner, - _name: name, + _name: name.into(), _root: PathBuf::new(), flags, }; @@ -256,12 +262,10 @@ impl Package { w.write_u32(0x2b)?; w.write_u32(self.values().flatten().count() as u32)?; - for (t, paths) in self.iter() { - for path in paths.iter() { + for (t, names) in self.iter() { + for name in names.iter() { w.write_u64(t.hash().into())?; - - let hash = Murmur64::hash(path.to_slash_lossy().as_bytes()); - w.write_u64(hash.into())?; + w.write_u64(Murmur64::hash(name.as_bytes()).into())?; } } diff --git a/lib/sdk/src/murmur/types.rs b/lib/sdk/src/murmur/types.rs index e96b992..20bf46a 100644 --- a/lib/sdk/src/murmur/types.rs +++ b/lib/sdk/src/murmur/types.rs @@ -1,3 +1,7 @@ +use std::path::Path; + +use path_slash::PathExt; + use self::util::{parse_hex32, parse_hex64}; use super::*; @@ -263,11 +267,23 @@ impl IdString64 { IdString64::String(_) => false, } } + + // Would love to have this as a proper `impl From`, but + // rustc will complain that it overlaps with the `impl From>`. + pub fn from_path(p: impl AsRef) -> Self { + Self::String(p.as_ref().to_slash_lossy().to_string()) + } } -impl> From for IdString64 { - fn from(value: S) -> Self { - Self::String(value.into()) +impl From for IdString64 { + fn from(value: String) -> Self { + Self::String(value) + } +} + +impl From for IdString64 { + fn from(value: u64) -> Self { + Self::Hash(value.into()) } } @@ -283,6 +299,12 @@ impl From for Murmur64 { } } +impl Default for IdString64 { + fn default() -> Self { + Self::Hash(0.into()) + } +} + impl PartialEq for IdString64 { fn eq(&self, other: &Self) -> bool { self.to_murmur64() == other.to_murmur64() -- 2.45.3