mirror of
https://github.com/a2x/cs2-dumper.git
synced 2025-04-05 00:25:36 +08:00
Change json structure and add comments for modules
This commit is contained in:
parent
0a86db6b40
commit
7bf035aaf6
@ -17,8 +17,12 @@ impl FileBuilder for CppFileBuilder {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_namespace(&mut self, output: &mut dyn Write, name: &str) -> Result<()> {
|
fn write_namespace(&mut self, output: &mut dyn Write, name: &str, comment: Option<&str>) -> Result<()> {
|
||||||
write!(output, "namespace {} {{\n", name)?;
|
if let Some(comment) = comment {
|
||||||
|
write!(output, "namespace {} {{ // {}\n", name, comment)?;
|
||||||
|
} else {
|
||||||
|
write!(output, "namespace {} {{\n", name)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,12 @@ impl FileBuilder for CSharpFileBuilder {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_namespace(&mut self, output: &mut dyn Write, name: &str) -> Result<()> {
|
fn write_namespace(&mut self, output: &mut dyn Write, name: &str, comment: Option<&str>) -> Result<()> {
|
||||||
write!(output, "public static class {} {{\n", name)?;
|
if let Some(comment) = comment {
|
||||||
|
write!(output, "public static class {} {{ // {}\n", name, comment)?;
|
||||||
|
} else {
|
||||||
|
write!(output, "public static class {} {{\n", name)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ pub trait FileBuilder {
|
|||||||
|
|
||||||
fn write_top_level(&mut self, output: &mut dyn Write) -> Result<()>;
|
fn write_top_level(&mut self, output: &mut dyn Write) -> Result<()>;
|
||||||
|
|
||||||
fn write_namespace(&mut self, output: &mut dyn Write, name: &str) -> Result<()>;
|
fn write_namespace(&mut self, output: &mut dyn Write, name: &str, comment: Option<&str>) -> Result<()>;
|
||||||
|
|
||||||
fn write_variable(
|
fn write_variable(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -1,22 +1,26 @@
|
|||||||
use std::io::{Result, Write};
|
use std::{io::{Result, Write}, collections::BTreeMap};
|
||||||
|
|
||||||
use serde_json::{json, Map, Value};
|
use serde::Serialize;
|
||||||
|
|
||||||
use super::FileBuilder;
|
use super::FileBuilder;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
pub struct JsonFileBuilder {
|
#[derive(Debug, PartialEq, Default, Serialize)]
|
||||||
json: Value,
|
struct JsonOffsetValue {
|
||||||
current_namespace: String,
|
value: usize,
|
||||||
|
comment: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for JsonFileBuilder {
|
#[derive(Debug, PartialEq, Default, Serialize)]
|
||||||
fn default() -> Self {
|
struct JsonMod {
|
||||||
Self {
|
data: BTreeMap<String, JsonOffsetValue>,
|
||||||
json: Value::Object(Map::new()),
|
comment: Option<String>,
|
||||||
current_namespace: String::new(),
|
}
|
||||||
}
|
|
||||||
}
|
#[derive(Debug, PartialEq, Default)]
|
||||||
|
pub struct JsonFileBuilder {
|
||||||
|
data: BTreeMap<String, JsonMod>,
|
||||||
|
current_namespace: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileBuilder for JsonFileBuilder {
|
impl FileBuilder for JsonFileBuilder {
|
||||||
@ -28,8 +32,9 @@ impl FileBuilder for JsonFileBuilder {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_namespace(&mut self, _output: &mut dyn Write, name: &str) -> Result<()> {
|
fn write_namespace(&mut self, _output: &mut dyn Write, name: &str, comment: Option<&str>) -> Result<()> {
|
||||||
self.current_namespace = name.to_string();
|
self.current_namespace = name.to_string();
|
||||||
|
self.data.entry(name.to_string()).or_default().comment = comment.map(str::to_string);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -39,26 +44,22 @@ impl FileBuilder for JsonFileBuilder {
|
|||||||
_output: &mut dyn Write,
|
_output: &mut dyn Write,
|
||||||
name: &str,
|
name: &str,
|
||||||
value: usize,
|
value: usize,
|
||||||
_comment: Option<&str>,
|
comment: Option<&str>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
if let Some(map) = self.json.as_object_mut() {
|
self.data.entry(self.current_namespace.clone()).or_default().data
|
||||||
let entry = map
|
.insert(name.to_string(), JsonOffsetValue {
|
||||||
.entry(&self.current_namespace)
|
value: value,
|
||||||
.or_insert_with(|| json!({}));
|
comment: comment.map(str::to_string)
|
||||||
|
});
|
||||||
if let Some(object) = entry.as_object_mut() {
|
|
||||||
object.insert(name.to_string(), json!(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_closure(&mut self, output: &mut dyn Write, eof: bool) -> Result<()> {
|
fn write_closure(&mut self, output: &mut dyn Write, eof: bool) -> Result<()> {
|
||||||
if eof {
|
if eof {
|
||||||
write!(output, "{}", serde_json::to_string_pretty(&self.json)?)?;
|
write!(output, "{}", serde_json::to_string_pretty(&self.data)?)?;
|
||||||
|
|
||||||
self.json = json!({});
|
self.data = BTreeMap::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -32,8 +32,8 @@ impl FileBuilder for FileBuilderEnum {
|
|||||||
self.as_mut().write_top_level(output)
|
self.as_mut().write_top_level(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_namespace(&mut self, output: &mut dyn Write, name: &str) -> Result<()> {
|
fn write_namespace(&mut self, output: &mut dyn Write, name: &str, comment: Option<&str>) -> Result<()> {
|
||||||
self.as_mut().write_namespace(output, name)
|
self.as_mut().write_namespace(output, name, comment)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_variable(
|
fn write_variable(
|
||||||
|
@ -14,8 +14,12 @@ impl FileBuilder for PythonFileBuilder {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_namespace(&mut self, output: &mut dyn Write, name: &str) -> Result<()> {
|
fn write_namespace(&mut self, output: &mut dyn Write, name: &str, comment: Option<&str>) -> Result<()> {
|
||||||
write!(output, "class {}:\n", name)?;
|
if let Some(comment) = comment {
|
||||||
|
write!(output, "class {}: # {}\n", name, comment)?;
|
||||||
|
} else {
|
||||||
|
write!(output, "class {}:\n", name)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,12 @@ impl FileBuilder for RustFileBuilder {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_namespace(&mut self, output: &mut dyn Write, name: &str) -> Result<()> {
|
fn write_namespace(&mut self, output: &mut dyn Write, name: &str, comment: Option<&str>) -> Result<()> {
|
||||||
write!(output, "pub mod {} {{\n", name)?;
|
if let Some(comment) = comment {
|
||||||
|
write!(output, "pub mod {} {{ // {}\n", name, comment)?;
|
||||||
|
} else {
|
||||||
|
write!(output, "pub mod {} {{\n", name)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ pub fn dump_interfaces(builders: &mut Vec<FileBuilderEnum>, process: &Process) -
|
|||||||
.to_case(Case::Pascal),
|
.to_case(Case::Pascal),
|
||||||
)
|
)
|
||||||
.or_default()
|
.or_default()
|
||||||
|
.data
|
||||||
.push(Entry {
|
.push(Entry {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
value: ptr - module.base(),
|
value: ptr - module.base(),
|
||||||
|
@ -21,7 +21,13 @@ pub struct Entry {
|
|||||||
pub comment: Option<String>,
|
pub comment: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Entries = BTreeMap<String, Vec<Entry>>;
|
#[derive(Default)]
|
||||||
|
pub struct EntriesContainer {
|
||||||
|
pub data: Vec<Entry>,
|
||||||
|
pub comment: Option<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Entries = BTreeMap<String, EntriesContainer>;
|
||||||
|
|
||||||
pub fn generate_file(
|
pub fn generate_file(
|
||||||
builder: &mut FileBuilderEnum,
|
builder: &mut FileBuilderEnum,
|
||||||
@ -43,9 +49,9 @@ pub fn generate_file(
|
|||||||
let len = entries.len();
|
let len = entries.len();
|
||||||
|
|
||||||
for (i, pair) in entries.iter().enumerate() {
|
for (i, pair) in entries.iter().enumerate() {
|
||||||
builder.write_namespace(&mut file, pair.0)?;
|
builder.write_namespace(&mut file, pair.0, pair.1.comment.as_deref())?;
|
||||||
|
|
||||||
pair.1.iter().try_for_each(|entry| {
|
pair.1.data.iter().try_for_each(|entry| {
|
||||||
builder.write_variable(
|
builder.write_variable(
|
||||||
&mut file,
|
&mut file,
|
||||||
&entry.name,
|
&entry.name,
|
||||||
|
@ -84,6 +84,7 @@ pub fn dump_offsets(builders: &mut Vec<FileBuilderEnum>, process: &Process) -> R
|
|||||||
log::info!("Dumping offsets...");
|
log::info!("Dumping offsets...");
|
||||||
|
|
||||||
for signature in config.signatures {
|
for signature in config.signatures {
|
||||||
|
log::info!("Searching for {}...", signature.name);
|
||||||
let module = process.get_module_by_name(&signature.module)?;
|
let module = process.get_module_by_name(&signature.module)?;
|
||||||
|
|
||||||
let mut address = match process.find_pattern(&signature.module, &signature.pattern) {
|
let mut address = match process.find_pattern(&signature.module, &signature.pattern) {
|
||||||
@ -156,6 +157,7 @@ pub fn dump_offsets(builders: &mut Vec<FileBuilderEnum>, process: &Process) -> R
|
|||||||
.to_case(Case::Pascal),
|
.to_case(Case::Pascal),
|
||||||
)
|
)
|
||||||
.or_default()
|
.or_default()
|
||||||
|
.data
|
||||||
.push(Entry {
|
.push(Entry {
|
||||||
name,
|
name,
|
||||||
value,
|
value,
|
||||||
|
@ -19,6 +19,9 @@ pub fn dump_schemas(builders: &mut Vec<FileBuilderEnum>, process: &Process) -> R
|
|||||||
for class in type_scope.classes()? {
|
for class in type_scope.classes()? {
|
||||||
log::debug!(" {}", class.name());
|
log::debug!(" {}", class.name());
|
||||||
|
|
||||||
|
let container = entries.entry(class.name().replace("::", "_")).or_default();
|
||||||
|
container.comment = class.parent()?.map(|p| p.name().to_string());
|
||||||
|
|
||||||
for field in class.fields()? {
|
for field in class.fields()? {
|
||||||
let field_name = field.name()?;
|
let field_name = field.name()?;
|
||||||
let field_offset = field.offset()?;
|
let field_offset = field.offset()?;
|
||||||
@ -31,14 +34,11 @@ pub fn dump_schemas(builders: &mut Vec<FileBuilderEnum>, process: &Process) -> R
|
|||||||
field_type_name
|
field_type_name
|
||||||
);
|
);
|
||||||
|
|
||||||
entries
|
container.data.push(Entry {
|
||||||
.entry(class.name().replace("::", "_"))
|
name: field_name,
|
||||||
.or_default()
|
value: field_offset as usize,
|
||||||
.push(Entry {
|
comment: Some(field_type_name),
|
||||||
name: field_name,
|
});
|
||||||
value: field_offset as usize,
|
|
||||||
comment: Some(field_type_name),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,4 +45,15 @@ impl<'a> SchemaClassInfo<'a> {
|
|||||||
pub fn fields_count(&self) -> Result<u16> {
|
pub fn fields_count(&self) -> Result<u16> {
|
||||||
self.process.read_memory::<u16>(self.address + 0x1C)
|
self.process.read_memory::<u16>(self.address + 0x1C)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parent(&self) -> Result<Option<SchemaClassInfo>> {
|
||||||
|
let addr = self.process.read_memory::<u64>(self.address + 0x38)?;
|
||||||
|
if addr == 0 {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
let parent = self.process.read_memory::<u64>(addr as usize + 0x8)?;
|
||||||
|
let name = self.process.read_string(self.process.read_memory::<usize>(parent as usize + 0x8)?)?;
|
||||||
|
Ok(Some(SchemaClassInfo::new(self.process, parent as usize, &name)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user