# World of Tanks Datfile Parser A parser for `.dat` battle result files generated by the game World of Tanks. `.dat` files are generated whenever a battle's results are viewed in-game. For Windows, these files are found in a location like: ``` C:\Users\\AppData\Roaming\Wargaming.net\WorldOfTanks\battle_results ``` The `.dat` files are simply [pickle](https://docs.python.org/3/library/pickle.html) dumps. In theory, this would mean that reading these files are as simple as opening these files using the pickle module in Python (v2.7). However, the problem is that there is no information on the identifiers of a field. This means that reading from the file directly gives you results like this: ```python [-43243256354, 1673683215, 70, 1] ``` This crate simply identifies the correct identifiers based on the checksum value (which is usualy the first item in a list of values like above) and converts the above into something like this: ```json { "arenaCreateTime": 1673683215, "arenaTypeID": 70, "bonusType": 1 } ``` ## Simple Example ```rust 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}"); ``` ## Advanced Example If you need to change how some `serde_pickle::Value` are converted to `serde_json::Value`, you can intercept it and provide your own implementation: ```rust 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)); ``` ## Supported WoT Versions `1.20.0`, `1.20.1`