mirror of
https://github.com/a2x/cs2-dumper.git
synced 2025-04-24 22:35:35 +08:00
Revert to old method of generating schema files
This commit is contained in:
parent
42ecdf593a
commit
acb0c73f00
@ -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> {}
|
|
Loading…
x
Reference in New Issue
Block a user