#战斗 #解析器 #世界 #dat #wot #坦克 #结果

bin+lib wot_datfile_parser

用于解析游戏《坦克世界》生成的.dat文件的解析器

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 2023年1月18日

1262解析实现

每月下载量 34

MIT 许可证 MIT

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