mirror of
				https://github.com/a2x/cs2-dumper.git
				synced 2025-10-31 21:20:03 +08:00 
			
		
		
		
	Revert to old method of generating schema files
This commit is contained in:
		| @@ -27,7 +27,7 @@ pub fn buttons(process: &mut IntoProcessInstanceArcBox<'_>) -> Result<Vec<Button | |||||||
|             "client.dll", |             "client.dll", | ||||||
|             signature!("48 8B 15 ? ? ? ? 48 85 D2 74 ? 0F 1F 40"), |             signature!("48 8B 15 ? ? ? ? 48 85 D2 74 ? 0F 1F 40"), | ||||||
|         ), |         ), | ||||||
|         _ => panic!("unsupported os"), |         os => panic!("unsupported os: {}", os), | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     let module = process.module_by_name(&module_name)?; |     let module = process.module_by_name(&module_name)?; | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ pub fn interfaces(process: &mut IntoProcessInstanceArcBox<'_>) -> Result<Interfa | |||||||
|     let sig = match env::consts::OS { |     let sig = match env::consts::OS { | ||||||
|         "linux" => signature!("48 8B 1D ? ? ? ? 48 85 DB 74 ? 49 89 FC"), |         "linux" => signature!("48 8B 1D ? ? ? ? 48 85 DB 74 ? 49 89 FC"), | ||||||
|         "windows" => signature!("4C 8B 0D ? ? ? ? 4C 8B D2 4C 8B D9"), |         "windows" => signature!("4C 8B 0D ? ? ? ? 4C 8B D2 4C 8B D9"), | ||||||
|         _ => panic!("unsupported os"), |         os => panic!("unsupported os: {}", os), | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     process |     process | ||||||
|   | |||||||
| @@ -16,14 +16,14 @@ use crate::source_engine::*; | |||||||
|  |  | ||||||
| pub type SchemaMap = BTreeMap<String, (Vec<Class>, Vec<Enum>)>; | pub type SchemaMap = BTreeMap<String, (Vec<Class>, Vec<Enum>)>; | ||||||
|  |  | ||||||
| #[derive(Debug, Eq, Ord, PartialEq, PartialOrd, Deserialize, Serialize)] | #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Deserialize, Serialize)] | ||||||
| pub enum ClassMetadata { | pub enum ClassMetadata { | ||||||
|     Unknown { name: String }, |     Unknown { name: String }, | ||||||
|     NetworkChangeCallback { name: String }, |     NetworkChangeCallback { name: String }, | ||||||
|     NetworkVarNames { name: String, ty: String }, |     NetworkVarNames { name: String, ty: String }, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Deserialize, Serialize)] | #[derive(Clone, Debug, Deserialize, Serialize)] | ||||||
| pub struct Class { | pub struct Class { | ||||||
|     pub name: String, |     pub name: String, | ||||||
|     pub module_name: String, |     pub module_name: String, | ||||||
| @@ -32,14 +32,14 @@ pub struct Class { | |||||||
|     pub fields: Vec<ClassField>, |     pub fields: Vec<ClassField>, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Deserialize, Serialize)] | #[derive(Clone, Debug, Deserialize, Serialize)] | ||||||
| pub struct ClassField { | pub struct ClassField { | ||||||
|     pub name: String, |     pub name: String, | ||||||
|     pub ty: String, |     pub ty: String, | ||||||
|     pub offset: u32, |     pub offset: u32, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Deserialize, Serialize)] | #[derive(Clone, Debug, Deserialize, Serialize)] | ||||||
| pub struct Enum { | pub struct Enum { | ||||||
|     pub name: String, |     pub name: String, | ||||||
|     pub ty: String, |     pub ty: String, | ||||||
| @@ -48,7 +48,7 @@ pub struct Enum { | |||||||
|     pub members: Vec<EnumMember>, |     pub members: Vec<EnumMember>, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Deserialize, Serialize)] | #[derive(Clone, Debug, Deserialize, Serialize)] | ||||||
| pub struct EnumMember { | pub struct EnumMember { | ||||||
|     pub name: String, |     pub name: String, | ||||||
|     pub value: i64, |     pub value: i64, | ||||||
| @@ -81,9 +81,9 @@ fn read_class_binding( | |||||||
|  |  | ||||||
|     let module_name = binding.module_name.read_string(process).map(|s| { |     let module_name = binding.module_name.read_string(process).map(|s| { | ||||||
|         let file_ext = match env::consts::OS { |         let file_ext = match env::consts::OS { | ||||||
|             "linux" => "so", |             "linux" => ".so", | ||||||
|             "windows" => "dll", |             "windows" => ".dll", | ||||||
|             _ => panic!("unsupported os"), |             os => panic!("unsupported os: {}", os), | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         format!("{}.{}", s, file_ext) |         format!("{}.{}", s, file_ext) | ||||||
| @@ -269,7 +269,7 @@ fn read_schema_system(process: &mut IntoProcessInstanceArcBox<'_>) -> Result<Sch | |||||||
|             "schemasystem.dll", |             "schemasystem.dll", | ||||||
|             signature!("48 89 05 ? ? ? ? 4C 8D 45"), |             signature!("48 89 05 ? ? ? ? 4C 8D 45"), | ||||||
|         ), |         ), | ||||||
|         _ => panic!("unsupported os"), |         os => panic!("unsupported os: {}", os), | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     let module = process.module_by_name(&module_name)?; |     let module = process.module_by_name(&module_name)?; | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ pub static CONFIG: LazyLock<Config> = LazyLock::new(|| { | |||||||
|     let file_name = match env::consts::OS { |     let file_name = match env::consts::OS { | ||||||
|         "linux" => "config_linux.json", |         "linux" => "config_linux.json", | ||||||
|         "windows" => "config_win.json", |         "windows" => "config_win.json", | ||||||
|         _ => panic!("unsupported os"), |         os => panic!("unsupported os: {}", os), | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     let content = fs::read_to_string(file_name).expect("unable to read config file"); |     let content = fs::read_to_string(file_name).expect("unable to read config file"); | ||||||
|   | |||||||
| @@ -150,7 +150,7 @@ fn extract_args( | |||||||
|         .unwrap_or_else(|| match env::consts::OS { |         .unwrap_or_else(|| match env::consts::OS { | ||||||
|             "linux" => "linux".to_string(), |             "linux" => "linux".to_string(), | ||||||
|             "windows" => "win32".to_string(), |             "windows" => "win32".to_string(), | ||||||
|             _ => panic!("unsupported os"), |             os => panic!("unsupported os: {}", os), | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|     let indent_size = *matches.get_one::<usize>("indent-size").unwrap(); |     let indent_size = *matches.get_one::<usize>("indent-size").unwrap(); | ||||||
|   | |||||||
| @@ -9,10 +9,10 @@ use crate::error::Result; | |||||||
| impl CodeGen for Vec<Button> { | impl CodeGen for Vec<Button> { | ||||||
|     fn to_cs(&self, results: &Results, indent_size: usize) -> Result<String> { |     fn to_cs(&self, results: &Results, indent_size: usize) -> Result<String> { | ||||||
|         self.write_content(results, indent_size, |fmt| { |         self.write_content(results, indent_size, |fmt| { | ||||||
|             fmt.block("namespace CS2Dumper", |fmt| { |             fmt.block("namespace CS2Dumper", false, |fmt| { | ||||||
|                 writeln!(fmt, "// Module: {}", get_module_name())?; |                 writeln!(fmt, "// Module: {}", get_module_name())?; | ||||||
|  |  | ||||||
|                 fmt.block("public static class Buttons", |fmt| { |                 fmt.block("public static class Buttons", false, |fmt| { | ||||||
|                     for button in self { |                     for button in self { | ||||||
|                         writeln!( |                         writeln!( | ||||||
|                             fmt, |                             fmt, | ||||||
| @@ -34,10 +34,10 @@ impl CodeGen for Vec<Button> { | |||||||
|             writeln!(fmt, "#pragma once\n")?; |             writeln!(fmt, "#pragma once\n")?; | ||||||
|             writeln!(fmt, "#include <cstddef>\n")?; |             writeln!(fmt, "#include <cstddef>\n")?; | ||||||
|  |  | ||||||
|             fmt.block("namespace cs2_dumper", |fmt| { |             fmt.block("namespace cs2_dumper", false, |fmt| { | ||||||
|                 writeln!(fmt, "// Module: {}", get_module_name())?; |                 writeln!(fmt, "// Module: {}", get_module_name())?; | ||||||
|  |  | ||||||
|                 fmt.block("namespace buttons", |fmt| { |                 fmt.block("namespace buttons", false, |fmt| { | ||||||
|                     for button in self { |                     for button in self { | ||||||
|                         writeln!( |                         writeln!( | ||||||
|                             fmt, |                             fmt, | ||||||
| @@ -71,10 +71,10 @@ impl CodeGen for Vec<Button> { | |||||||
|         self.write_content(results, indent_size, |fmt| { |         self.write_content(results, indent_size, |fmt| { | ||||||
|             writeln!(fmt, "#![allow(non_upper_case_globals, unused)]\n")?; |             writeln!(fmt, "#![allow(non_upper_case_globals, unused)]\n")?; | ||||||
|  |  | ||||||
|             fmt.block("pub mod cs2_dumper", |fmt| { |             fmt.block("pub mod cs2_dumper", false, |fmt| { | ||||||
|                 writeln!(fmt, "// Module: {}", get_module_name())?; |                 writeln!(fmt, "// Module: {}", get_module_name())?; | ||||||
|  |  | ||||||
|                 fmt.block("pub mod buttons", |fmt| { |                 fmt.block("pub mod buttons", false, |fmt| { | ||||||
|                     for button in self { |                     for button in self { | ||||||
|                         writeln!( |                         writeln!( | ||||||
|                             fmt, |                             fmt, | ||||||
|   | |||||||
| @@ -21,15 +21,15 @@ impl<'a> Formatter<'a> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     pub fn block<F>(&mut self, heading: &str, f: F) -> fmt::Result |     pub fn block<F>(&mut self, heading: &str, semicolon: bool, f: F) -> fmt::Result | ||||||
|     where |     where | ||||||
|         F: FnOnce(&mut Self) -> fmt::Result, |         F: FnOnce(&mut Self) -> fmt::Result, | ||||||
|     { |     { | ||||||
|         write!(self, "{} {{\n", heading)?; |         writeln!(self, "{} {{", heading)?; | ||||||
|  |  | ||||||
|         self.indent(f)?; |         self.indent(f)?; | ||||||
|  |  | ||||||
|         write!(self, "}}\n")?; |         writeln!(self, "{}", if semicolon { "};" } else { "}" })?; | ||||||
|  |  | ||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
| @@ -48,10 +48,10 @@ impl<'a> Formatter<'a> { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[inline] |     #[inline] | ||||||
|     #[rustfmt::skip] |  | ||||||
|     fn push_indentation(&mut self) { |     fn push_indentation(&mut self) { | ||||||
|         if self.indent_level > 0 { |         if self.indent_level > 0 { | ||||||
|             self.out.push_str(&" ".repeat(self.indent_level * self.indent_size)); |             self.out | ||||||
|  |                 .push_str(&" ".repeat(self.indent_level * self.indent_size)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -61,7 +61,6 @@ impl<'a> Write for Formatter<'a> { | |||||||
|         let mut lines = s.lines().peekable(); |         let mut lines = s.lines().peekable(); | ||||||
|  |  | ||||||
|         while let Some(line) = lines.next() { |         while let Some(line) = lines.next() { | ||||||
|             // Add indentation before the line if necessary. |  | ||||||
|             if self.out.ends_with('\n') && !line.is_empty() { |             if self.out.ends_with('\n') && !line.is_empty() { | ||||||
|                 self.push_indentation(); |                 self.push_indentation(); | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ use crate::error::Result; | |||||||
| impl CodeGen for InterfaceMap { | impl CodeGen for InterfaceMap { | ||||||
|     fn to_cs(&self, results: &Results, indent_size: usize) -> Result<String> { |     fn to_cs(&self, results: &Results, indent_size: usize) -> Result<String> { | ||||||
|         self.write_content(results, indent_size, |fmt| { |         self.write_content(results, indent_size, |fmt| { | ||||||
|             fmt.block("namespace CS2Dumper.Interfaces", |fmt| { |             fmt.block("namespace CS2Dumper.Interfaces", false, |fmt| { | ||||||
|                 for (module_name, ifaces) in self { |                 for (module_name, ifaces) in self { | ||||||
|                     writeln!(fmt, "// Module: {}", module_name)?; |                     writeln!(fmt, "// Module: {}", module_name)?; | ||||||
|  |  | ||||||
| @@ -19,6 +19,7 @@ impl CodeGen for InterfaceMap { | |||||||
|                             "public static class {}", |                             "public static class {}", | ||||||
|                             AsPascalCase(format_module_name(module_name)) |                             AsPascalCase(format_module_name(module_name)) | ||||||
|                         ), |                         ), | ||||||
|  |                         false, | ||||||
|                         |fmt| { |                         |fmt| { | ||||||
|                             for iface in ifaces { |                             for iface in ifaces { | ||||||
|                                 writeln!( |                                 writeln!( | ||||||
| @@ -45,13 +46,14 @@ impl CodeGen for InterfaceMap { | |||||||
|             writeln!(fmt, "#pragma once\n")?; |             writeln!(fmt, "#pragma once\n")?; | ||||||
|             writeln!(fmt, "#include <cstddef>\n")?; |             writeln!(fmt, "#include <cstddef>\n")?; | ||||||
|  |  | ||||||
|             fmt.block("namespace cs2_dumper", |fmt| { |             fmt.block("namespace cs2_dumper", false, |fmt| { | ||||||
|                 fmt.block("namespace interfaces", |fmt| { |                 fmt.block("namespace interfaces", false, |fmt| { | ||||||
|                     for (module_name, ifaces) in self { |                     for (module_name, ifaces) in self { | ||||||
|                         writeln!(fmt, "// Module: {}", module_name)?; |                         writeln!(fmt, "// Module: {}", module_name)?; | ||||||
|  |  | ||||||
|                         fmt.block( |                         fmt.block( | ||||||
|                             &format!("namespace {}", AsSnakeCase(format_module_name(module_name))), |                             &format!("namespace {}", AsSnakeCase(format_module_name(module_name))), | ||||||
|  |                             false, | ||||||
|                             |fmt| { |                             |fmt| { | ||||||
|                                 for iface in ifaces { |                                 for iface in ifaces { | ||||||
|                                     writeln!( |                                     writeln!( | ||||||
| @@ -94,13 +96,14 @@ impl CodeGen for InterfaceMap { | |||||||
|         self.write_content(results, indent_size, |fmt| { |         self.write_content(results, indent_size, |fmt| { | ||||||
|             writeln!(fmt, "#![allow(non_upper_case_globals, unused)]\n")?; |             writeln!(fmt, "#![allow(non_upper_case_globals, unused)]\n")?; | ||||||
|  |  | ||||||
|             fmt.block("pub mod cs2_dumper", |fmt| { |             fmt.block("pub mod cs2_dumper", false, |fmt| { | ||||||
|                 fmt.block("pub mod interfaces", |fmt| { |                 fmt.block("pub mod interfaces", false, |fmt| { | ||||||
|                     for (module_name, ifaces) in self { |                     for (module_name, ifaces) in self { | ||||||
|                         writeln!(fmt, "// Module: {}", module_name)?; |                         writeln!(fmt, "// Module: {}", module_name)?; | ||||||
|  |  | ||||||
|                         fmt.block( |                         fmt.block( | ||||||
|                             &format!("pub mod {}", AsSnakeCase(format_module_name(module_name))), |                             &format!("pub mod {}", AsSnakeCase(format_module_name(module_name))), | ||||||
|  |                             false, | ||||||
|                             |fmt| { |                             |fmt| { | ||||||
|                                 for iface in ifaces { |                                 for iface in ifaces { | ||||||
|                                     writeln!( |                                     writeln!( | ||||||
|   | |||||||
| @@ -147,22 +147,23 @@ impl Results { | |||||||
|         out_dir: P, |         out_dir: P, | ||||||
|         indent_size: usize, |         indent_size: usize, | ||||||
|     ) -> Result<()> { |     ) -> Result<()> { | ||||||
|  |         // TODO: Make this user-configurable. | ||||||
|  |         const FILE_EXTS: &[&str] = &["cs", "hpp", "json", "rs"]; | ||||||
|  |  | ||||||
|         let items = [ |         let items = [ | ||||||
|             ("buttons", Item::Buttons(&self.buttons)), |             ("buttons", Item::Buttons(&self.buttons)), | ||||||
|             ("interfaces", Item::Interfaces(&self.interfaces)), |             ("interfaces", Item::Interfaces(&self.interfaces)), | ||||||
|             ("offsets", Item::Offsets(&self.offsets)), |             ("offsets", Item::Offsets(&self.offsets)), | ||||||
|             ("schemas", Item::Schemas(&self.schemas)), |  | ||||||
|         ]; |         ]; | ||||||
|  |  | ||||||
|         // TODO: Make this user-configurable. |         self.dump_items(&items, out_dir.as_ref(), indent_size, FILE_EXTS)?; | ||||||
|         let file_exts = ["cs", "hpp", "json", "rs"]; |  | ||||||
|  |  | ||||||
|         for (file_name, item) in &items { |         for (module_name, (classes, enums)) in &self.schemas { | ||||||
|             for ext in file_exts { |             let schemas = [(module_name.clone(), (classes.clone(), enums.clone()))].into(); | ||||||
|                 let content = item.generate(self, indent_size, ext)?; |  | ||||||
|  |  | ||||||
|                 self.dump_file(out_dir.as_ref(), file_name, ext, &content)?; |             let item = Item::Schemas(&schemas); | ||||||
|             } |  | ||||||
|  |             self.dump_item(&item, out_dir.as_ref(), indent_size, FILE_EXTS, module_name)?; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         self.dump_info_file(process, out_dir)?; |         self.dump_info_file(process, out_dir)?; | ||||||
| @@ -189,19 +190,48 @@ impl Results { | |||||||
|         process: &mut IntoProcessInstanceArcBox<'_>, |         process: &mut IntoProcessInstanceArcBox<'_>, | ||||||
|         out_dir: P, |         out_dir: P, | ||||||
|     ) -> Result<()> { |     ) -> Result<()> { | ||||||
|         let info = json!({ |  | ||||||
|             "timestamp": self.timestamp.to_rfc3339(), |  | ||||||
|             "build_number": self.read_build_number(process).unwrap_or(0), |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         self.dump_file( |         self.dump_file( | ||||||
|             out_dir.as_ref(), |             out_dir.as_ref(), | ||||||
|             "info", |             "info", | ||||||
|             "json", |             "json", | ||||||
|             &serde_json::to_string_pretty(&info)?, |             &serde_json::to_string_pretty(&json!({ | ||||||
|  |                 "timestamp": self.timestamp.to_rfc3339(), | ||||||
|  |                 "build_number": self.read_build_number(process).unwrap_or(0), | ||||||
|  |             }))?, | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     fn dump_item<P: AsRef<Path>>( | ||||||
|  |         &self, | ||||||
|  |         item: &Item, | ||||||
|  |         out_dir: P, | ||||||
|  |         indent_size: usize, | ||||||
|  |         file_exts: &[&str], | ||||||
|  |         file_name: &str, | ||||||
|  |     ) -> Result<()> { | ||||||
|  |         for ext in file_exts { | ||||||
|  |             let content = item.generate(self, indent_size, ext)?; | ||||||
|  |  | ||||||
|  |             self.dump_file(out_dir.as_ref(), file_name, ext, &content)?; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn dump_items<P: AsRef<Path>>( | ||||||
|  |         &self, | ||||||
|  |         items: &[(&str, Item)], | ||||||
|  |         out_dir: P, | ||||||
|  |         indent_size: usize, | ||||||
|  |         file_exts: &[&str], | ||||||
|  |     ) -> Result<()> { | ||||||
|  |         for (file_name, item) in items { | ||||||
|  |             self.dump_item(item, out_dir.as_ref(), indent_size, file_exts, file_name)?; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  |  | ||||||
|     fn read_build_number(&self, process: &mut IntoProcessInstanceArcBox<'_>) -> Result<u32> { |     fn read_build_number(&self, process: &mut IntoProcessInstanceArcBox<'_>) -> Result<u32> { | ||||||
|         self.offsets |         self.offsets | ||||||
|             .iter() |             .iter() | ||||||
| @@ -230,7 +260,7 @@ pub fn format_module_name(module_name: &String) -> String { | |||||||
|     let file_ext = match env::consts::OS { |     let file_ext = match env::consts::OS { | ||||||
|         "linux" => ".so", |         "linux" => ".so", | ||||||
|         "windows" => ".dll", |         "windows" => ".dll", | ||||||
|         _ => panic!("unsupported os"), |         os => panic!("unsupported os: {}", os), | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     module_name.strip_suffix(file_ext).unwrap().to_string() |     module_name.strip_suffix(file_ext).unwrap().to_string() | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ use crate::error::Result; | |||||||
| impl CodeGen for OffsetMap { | impl CodeGen for OffsetMap { | ||||||
|     fn to_cs(&self, results: &Results, indent_size: usize) -> Result<String> { |     fn to_cs(&self, results: &Results, indent_size: usize) -> Result<String> { | ||||||
|         self.write_content(results, indent_size, |fmt| { |         self.write_content(results, indent_size, |fmt| { | ||||||
|             fmt.block("namespace CS2Dumper.Offsets", |fmt| { |             fmt.block("namespace CS2Dumper.Offsets", false, |fmt| { | ||||||
|                 for (module_name, offsets) in self { |                 for (module_name, offsets) in self { | ||||||
|                     writeln!(fmt, "// Module: {}", module_name)?; |                     writeln!(fmt, "// Module: {}", module_name)?; | ||||||
|  |  | ||||||
| @@ -19,6 +19,7 @@ impl CodeGen for OffsetMap { | |||||||
|                             "public static class {}", |                             "public static class {}", | ||||||
|                             AsPascalCase(format_module_name(module_name)) |                             AsPascalCase(format_module_name(module_name)) | ||||||
|                         ), |                         ), | ||||||
|  |                         false, | ||||||
|                         |fmt| { |                         |fmt| { | ||||||
|                             for offset in offsets { |                             for offset in offsets { | ||||||
|                                 writeln!( |                                 writeln!( | ||||||
| @@ -45,13 +46,14 @@ impl CodeGen for OffsetMap { | |||||||
|             writeln!(fmt, "#pragma once\n")?; |             writeln!(fmt, "#pragma once\n")?; | ||||||
|             writeln!(fmt, "#include <cstddef>\n")?; |             writeln!(fmt, "#include <cstddef>\n")?; | ||||||
|  |  | ||||||
|             fmt.block("namespace cs2_dumper", |fmt| { |             fmt.block("namespace cs2_dumper", false, |fmt| { | ||||||
|                 fmt.block("namespace offsets", |fmt| { |                 fmt.block("namespace offsets", false, |fmt| { | ||||||
|                     for (module_name, offsets) in self { |                     for (module_name, offsets) in self { | ||||||
|                         writeln!(fmt, "// Module: {}", module_name)?; |                         writeln!(fmt, "// Module: {}", module_name)?; | ||||||
|  |  | ||||||
|                         fmt.block( |                         fmt.block( | ||||||
|                             &format!("namespace {}", AsSnakeCase(format_module_name(module_name))), |                             &format!("namespace {}", AsSnakeCase(format_module_name(module_name))), | ||||||
|  |                             false, | ||||||
|                             |fmt| { |                             |fmt| { | ||||||
|                                 for offset in offsets { |                                 for offset in offsets { | ||||||
|                                     writeln!( |                                     writeln!( | ||||||
| @@ -94,13 +96,14 @@ impl CodeGen for OffsetMap { | |||||||
|         self.write_content(results, indent_size, |fmt| { |         self.write_content(results, indent_size, |fmt| { | ||||||
|             writeln!(fmt, "#![allow(non_upper_case_globals, unused)]\n")?; |             writeln!(fmt, "#![allow(non_upper_case_globals, unused)]\n")?; | ||||||
|  |  | ||||||
|             fmt.block("pub mod cs2_dumper", |fmt| { |             fmt.block("pub mod cs2_dumper", false, |fmt| { | ||||||
|                 fmt.block("pub mod offsets", |fmt| { |                 fmt.block("pub mod offsets", false, |fmt| { | ||||||
|                     for (module_name, offsets) in self { |                     for (module_name, offsets) in self { | ||||||
|                         writeln!(fmt, "// Module: {}", module_name)?; |                         writeln!(fmt, "// Module: {}", module_name)?; | ||||||
|  |  | ||||||
|                         fmt.block( |                         fmt.block( | ||||||
|                             &format!("pub mod {}", AsSnakeCase(format_module_name(module_name))), |                             &format!("pub mod {}", AsSnakeCase(format_module_name(module_name))), | ||||||
|  |                             false, | ||||||
|                             |fmt| { |                             |fmt| { | ||||||
|                                 for offset in offsets { |                                 for offset in offsets { | ||||||
|                                     writeln!( |                                     writeln!( | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ use crate::error::Result; | |||||||
| impl CodeGen for SchemaMap { | impl CodeGen for SchemaMap { | ||||||
|     fn to_cs(&self, results: &Results, indent_size: usize) -> Result<String> { |     fn to_cs(&self, results: &Results, indent_size: usize) -> Result<String> { | ||||||
|         self.write_content(results, indent_size, |fmt| { |         self.write_content(results, indent_size, |fmt| { | ||||||
|             fmt.block("namespace CS2Dumper.Schemas", |fmt| { |             fmt.block("namespace CS2Dumper.Schemas", false, |fmt| { | ||||||
|                 for (module_name, (classes, enums)) in self { |                 for (module_name, (classes, enums)) in self { | ||||||
|                     writeln!(fmt, "// Module: {}", module_name)?; |                     writeln!(fmt, "// Module: {}", module_name)?; | ||||||
|                     writeln!(fmt, "// Classes count: {}", classes.len())?; |                     writeln!(fmt, "// Classes count: {}", classes.len())?; | ||||||
| @@ -24,6 +24,7 @@ impl CodeGen for SchemaMap { | |||||||
|                             "public static class {}", |                             "public static class {}", | ||||||
|                             AsPascalCase(format_module_name(module_name)) |                             AsPascalCase(format_module_name(module_name)) | ||||||
|                         ), |                         ), | ||||||
|  |                         false, | ||||||
|                         |fmt| { |                         |fmt| { | ||||||
|                             for enum_ in enums { |                             for enum_ in enums { | ||||||
|                                 let ty = match enum_.ty.as_str() { |                                 let ty = match enum_.ty.as_str() { | ||||||
| @@ -39,6 +40,7 @@ impl CodeGen for SchemaMap { | |||||||
|  |  | ||||||
|                                 fmt.block( |                                 fmt.block( | ||||||
|                                     &format!("public enum {} : {}", sanitize_name(&enum_.name), ty), |                                     &format!("public enum {} : {}", sanitize_name(&enum_.name), ty), | ||||||
|  |                                     false, | ||||||
|                                     |fmt| { |                                     |fmt| { | ||||||
|                                         let members = enum_ |                                         let members = enum_ | ||||||
|                                             .members |                                             .members | ||||||
| @@ -70,6 +72,7 @@ impl CodeGen for SchemaMap { | |||||||
|  |  | ||||||
|                                 fmt.block( |                                 fmt.block( | ||||||
|                                     &format!("public static class {}", sanitize_name(&class.name)), |                                     &format!("public static class {}", sanitize_name(&class.name)), | ||||||
|  |                                     false, | ||||||
|                                     |fmt| { |                                     |fmt| { | ||||||
|                                         for field in &class.fields { |                                         for field in &class.fields { | ||||||
|                                             writeln!( |                                             writeln!( | ||||||
| @@ -101,8 +104,8 @@ impl CodeGen for SchemaMap { | |||||||
|             writeln!(fmt, "#pragma once\n")?; |             writeln!(fmt, "#pragma once\n")?; | ||||||
|             writeln!(fmt, "#include <cstddef>\n")?; |             writeln!(fmt, "#include <cstddef>\n")?; | ||||||
|  |  | ||||||
|             fmt.block("namespace cs2_dumper", |fmt| { |             fmt.block("namespace cs2_dumper", false, |fmt| { | ||||||
|                 fmt.block("namespace schemas", |fmt| { |                 fmt.block("namespace schemas", false, |fmt| { | ||||||
|                     for (module_name, (classes, enums)) in self { |                     for (module_name, (classes, enums)) in self { | ||||||
|                         writeln!(fmt, "// Module: {}", module_name)?; |                         writeln!(fmt, "// Module: {}", module_name)?; | ||||||
|                         writeln!(fmt, "// Classes count: {}", classes.len())?; |                         writeln!(fmt, "// Classes count: {}", classes.len())?; | ||||||
| @@ -110,6 +113,7 @@ impl CodeGen for SchemaMap { | |||||||
|  |  | ||||||
|                         fmt.block( |                         fmt.block( | ||||||
|                             &format!("namespace {}", AsSnakeCase(format_module_name(module_name))), |                             &format!("namespace {}", AsSnakeCase(format_module_name(module_name))), | ||||||
|  |                             false, | ||||||
|                             |fmt| { |                             |fmt| { | ||||||
|                                 for enum_ in enums { |                                 for enum_ in enums { | ||||||
|                                     let ty = match enum_.ty.as_str() { |                                     let ty = match enum_.ty.as_str() { | ||||||
| @@ -129,6 +133,7 @@ impl CodeGen for SchemaMap { | |||||||
|                                             sanitize_name(&enum_.name), |                                             sanitize_name(&enum_.name), | ||||||
|                                             ty |                                             ty | ||||||
|                                         ), |                                         ), | ||||||
|  |                                         true, | ||||||
|                                         |fmt| { |                                         |fmt| { | ||||||
|                                             let members = enum_ |                                             let members = enum_ | ||||||
|                                                 .members |                                                 .members | ||||||
| @@ -160,6 +165,7 @@ impl CodeGen for SchemaMap { | |||||||
|  |  | ||||||
|                                     fmt.block( |                                     fmt.block( | ||||||
|                                         &format!("namespace {}", sanitize_name(&class.name)), |                                         &format!("namespace {}", sanitize_name(&class.name)), | ||||||
|  |                                         false, | ||||||
|                                         |fmt| { |                                         |fmt| { | ||||||
|                                             for field in &class.fields { |                                             for field in &class.fields { | ||||||
|                                                 writeln!( |                                                 writeln!( | ||||||
| @@ -270,8 +276,8 @@ impl CodeGen for SchemaMap { | |||||||
|         self.write_content(results, indent_size, |fmt| { |         self.write_content(results, indent_size, |fmt| { | ||||||
|             writeln!(fmt, "#![allow(non_upper_case_globals, unused)]\n")?; |             writeln!(fmt, "#![allow(non_upper_case_globals, unused)]\n")?; | ||||||
|  |  | ||||||
|             fmt.block("pub mod cs2_dumper", |fmt| { |             fmt.block("pub mod cs2_dumper", false, |fmt| { | ||||||
|                 fmt.block("pub mod schemas", |fmt| { |                 fmt.block("pub mod schemas", false, |fmt| { | ||||||
|                     for (module_name, (classes, enums)) in self { |                     for (module_name, (classes, enums)) in self { | ||||||
|                         writeln!(fmt, "// Module: {}", module_name)?; |                         writeln!(fmt, "// Module: {}", module_name)?; | ||||||
|                         writeln!(fmt, "// Classes count: {}", classes.len())?; |                         writeln!(fmt, "// Classes count: {}", classes.len())?; | ||||||
| @@ -279,6 +285,7 @@ impl CodeGen for SchemaMap { | |||||||
|  |  | ||||||
|                         fmt.block( |                         fmt.block( | ||||||
|                             &format!("pub mod {}", AsSnakeCase(format_module_name(module_name))), |                             &format!("pub mod {}", AsSnakeCase(format_module_name(module_name))), | ||||||
|  |                             false, | ||||||
|                             |fmt| { |                             |fmt| { | ||||||
|                                 for enum_ in enums { |                                 for enum_ in enums { | ||||||
|                                     let ty = match enum_.ty.as_str() { |                                     let ty = match enum_.ty.as_str() { | ||||||
| @@ -298,6 +305,7 @@ impl CodeGen for SchemaMap { | |||||||
|                                             ty, |                                             ty, | ||||||
|                                             sanitize_name(&enum_.name), |                                             sanitize_name(&enum_.name), | ||||||
|                                         ), |                                         ), | ||||||
|  |                                         false, | ||||||
|                                         |fmt| { |                                         |fmt| { | ||||||
|                                             // TODO: Handle the case where multiple members share |                                             // TODO: Handle the case where multiple members share | ||||||
|                                             // the same value. |                                             // the same value. | ||||||
| @@ -331,6 +339,7 @@ impl CodeGen for SchemaMap { | |||||||
|  |  | ||||||
|                                     fmt.block( |                                     fmt.block( | ||||||
|                                         &format!("pub mod {}", sanitize_name(&class.name)), |                                         &format!("pub mod {}", sanitize_name(&class.name)), | ||||||
|  |                                         false, | ||||||
|                                         |fmt| { |                                         |fmt| { | ||||||
|                                             for field in &class.fields { |                                             for field in &class.fields { | ||||||
|                                                 writeln!( |                                                 writeln!( | ||||||
|   | |||||||
| @@ -1,44 +0,0 @@ | |||||||
| use memflow::prelude::v1::*; |  | ||||||
|  |  | ||||||
| use super::UtlMemory; |  | ||||||
|  |  | ||||||
| use crate::error::Result; |  | ||||||
|  |  | ||||||
| #[repr(C)] |  | ||||||
| pub struct ConCommandBase { |  | ||||||
|     pub name: Pointer64<ReprCString>, |  | ||||||
|     pub description: Pointer64<ReprCString>, |  | ||||||
|     pub flags: u64, |  | ||||||
|     pad_0018: [u8; 0x20], |  | ||||||
| } |  | ||||||
|  |  | ||||||
| unsafe impl Pod for ConCommandBase {} |  | ||||||
|  |  | ||||||
| #[repr(C)] |  | ||||||
| pub struct CVar { |  | ||||||
|     pad_0000: [u8; 0xD8], |  | ||||||
|     pub cmds: UtlMemory<ConCommandBase>, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl CVar { |  | ||||||
|     pub fn iter( |  | ||||||
|         &self, |  | ||||||
|         process: &mut IntoProcessInstanceArcBox<'_>, |  | ||||||
|     ) -> Result<impl Iterator<Item = ConCommandBase>> { |  | ||||||
|         let mut cmds = Vec::new(); |  | ||||||
|  |  | ||||||
|         for i in 0..self.cmds.alloc_count as usize { |  | ||||||
|             let cmd = self.cmds.get(process, i)?; |  | ||||||
|  |  | ||||||
|             if cmd.name.is_null() { |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             cmds.push(cmd); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         Ok(cmds.into_iter()) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| unsafe impl Pod for CVar {} |  | ||||||
| @@ -1,11 +1,7 @@ | |||||||
| pub use convar::*; |  | ||||||
| pub use interface::*; | pub use interface::*; | ||||||
| pub use utl_memory::*; |  | ||||||
| pub use utl_ts_hash::*; | pub use utl_ts_hash::*; | ||||||
| pub use utl_vector::*; | pub use utl_vector::*; | ||||||
|  |  | ||||||
| pub mod convar; |  | ||||||
| pub mod interface; | pub mod interface; | ||||||
| pub mod utl_memory; |  | ||||||
| pub mod utl_ts_hash; | pub mod utl_ts_hash; | ||||||
| pub mod utl_vector; | pub mod utl_vector; | ||||||
|   | |||||||
| @@ -1,30 +0,0 @@ | |||||||
| use std::mem; |  | ||||||
|  |  | ||||||
| use memflow::prelude::v1::*; |  | ||||||
|  |  | ||||||
| use crate::error::{Error, Result}; |  | ||||||
|  |  | ||||||
| #[repr(C)] |  | ||||||
| pub struct UtlMemory<T: Sized + Pod> { |  | ||||||
|     pub mem: Pointer64<T>, |  | ||||||
|     pub alloc_count: u32, |  | ||||||
|     pub grow_size: u32, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl<T: Sized + Pod> UtlMemory<T> { |  | ||||||
|     #[inline] |  | ||||||
|     pub fn get(&self, process: &mut IntoProcessInstanceArcBox<'_>, idx: usize) -> Result<T> { |  | ||||||
|         if idx >= self.alloc_count as usize { |  | ||||||
|             return Err(Error::IndexOutOfBounds { |  | ||||||
|                 idx, |  | ||||||
|                 len: self.alloc_count as usize, |  | ||||||
|             }); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         let ptr = Pointer64::from(self.mem.address() + (idx * mem::size_of::<T>())); |  | ||||||
|  |  | ||||||
|         Ok(ptr.read(process)?) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| unsafe impl<T: Sized + Pod> Pod for UtlMemory<T> {} |  | ||||||
		Reference in New Issue
	
	Block a user