4个版本
0.4.2 | 2023年5月13日 |
---|---|
0.4.1 | 2023年3月2日 |
0.4.0 | 2023年3月2日 |
0.3.1 | 2023年1月18日 |
0.3.0 |
|
1262 在 解析实现
每月下载量 34
140KB
1K SLoC
坦克世界Datfile解析器
用于解析游戏《坦克世界》生成的.dat
战斗结果文件的解析器。每当在游戏中查看战斗结果时,都会生成.dat
文件。对于Windows,这些文件通常位于
C:\Users\<YOUR_USER_NAME>\AppData\Roaming\Wargaming.net\WorldOfTanks\battle_results
.dat
文件只是pickle序列化输出。理论上,这意味着使用Python(v2.7)中的pickle模块打开这些文件应该很简单。然而,问题是没有任何字段标识符的信息。这意味着直接从文件读取将给出类似以下的结果
[-43243256354, 1673683215, 70, 1]
该crate通过基于校验和值(通常是上述值列表中的第一个项)来识别正确的标识符,并将上述内容转换为类似以下的内容
{
"arenaCreateTime": 1673683215,
"arenaTypeID": 70,
"bonusType": 1
}
简单示例
use wot_datfile_parser::DatFileParser;
let file = std::fs::read("input_files/WOT_1_19_1_0/19011713064132879.dat").unwrap();
// You must construct the parser first as it needs to
// do some initialization to parse the datfiles.
// You can then use this same parser to parse any number of datfiles
let parser = DatFileParser::new();
// The parser generates a Battle struct
let battle = parser.parse(&file).unwrap();
assert_eq!(
&battle.common["teamHealth"],
&serde_json::json!({ "1": 13595, "2": 12985 })
);
assert_eq!(&battle.common["duration"], &serde_json::json!(407));
// Battle implements serde::Serialize and serde::Deserialize.
// So, you can use other data formats as well.
// Here we will convert it to json and print it:
let battle_as_json = serde_json::to_string_pretty(&battle).unwrap();
println!("{battle_as_json}");
高级示例
如果您需要更改某些serde_pickle::Value
转换为serde_json::Value
的方式,您可以拦截它并提供自己的实现
use wot_datfile_parser::{DatFileParser, Intercept};
let file = std::fs::read("input_files/WOT_1_19_1_0/19011713064132879.dat").unwrap();
let parser = DatFileParser::new();
// We use the following closure to change how a serde_pickle::Value is
// converted to serde_json::Value. We can also use it to log any errors
// in the datfile_parser(by matching the Failed variant)
let intercept_fn = |intercept, _original_value| {
use Intercept::*;
match intercept {
Success(field, _) | NotPresent(field, _) |
ManuallyParsed(field, _) | Failed(field, _, _) => {
if field.name == "teamHealth" {
// Here we can inspect the original_value and provide our own impl
// for converting the serde_pickle::Value to serde_json::Value
// But for this example, we will just return the following:
serde_json::Value::String("My own parser for teamHealth".into())
} else {
intercept.original_result()
}
},
}
};
// The parser generates a Battle struct
let battle = parser.parse_intercept(&file, intercept_fn).unwrap();
assert_eq!(
&battle.common["teamHealth"],
&serde_json::json!("My own parser for teamHealth")
);
assert_eq!(&battle.common["duration"], &serde_json::json!(407));
支持的WoT版本
1.20.0
, 1.20.1
依赖项
~5.5MB
~116K SLoC