1pub mod player_12_3;
2pub mod player_13_3;
3pub mod rofl_json;
4
5use std::{fs::File, io::Read, path::Path};
6
7use self::rofl_json::{MockRoflJson, RoflJson};
8
9pub struct Rofl {
10 rofl_string: String,
11 rofl_json: Option<RoflJson>,
12}
13
14impl Rofl {
15 pub const fn new() -> Rofl {
16 Rofl {
17 rofl_string: String::new(),
18 rofl_json: None,
19 }
20 }
21
22 fn read_rofl<P>(&self, file: P) -> Vec<u8>
23 where
24 P: AsRef<Path>,
25 {
26 let mut f = File::open(file).expect("Can't open file.");
27 let mut buf = Vec::new();
28 f.read_to_end(&mut buf).expect("Can't read file.");
29 buf
30 }
31
32 fn parse_rofl_to_string(&mut self, buf: &[u8]) {
33 let start = b"{\"gameLength\"";
34 let end = b"\"}]\"}";
35
36 let start_pos = buf
37 .windows(start.len())
38 .position(|w| w == start)
39 .expect("Can't find start position.");
40
41 let end_pos = buf
42 .windows(end.len())
43 .position(|w| w == end)
44 .expect("Can't find end position.");
45
46 self.rofl_string = std::str::from_utf8(&buf[start_pos..(end_pos + end.len())])
47 .expect("Can't parse rofl to string.")
48 .to_string();
49 }
50
51 pub fn parse_rofl_file<P>(&mut self, rofl_file: P) -> anyhow::Result<()>
52 where
53 P: AsRef<Path>,
54 {
55 let buf = self.read_rofl(rofl_file);
56 self.parse_rofl_to_string(&buf);
57
58 let mock_rofl_json: MockRoflJson = serde_json::from_str(&self.rofl_string)?;
59 let stats_json = mock_rofl_json.parse_stats_json()?;
60
61 self.rofl_json = Some(RoflJson {
62 gameLength: mock_rofl_json.gameLength,
63 gameVersion: mock_rofl_json.gameVersion,
64 lastGameChunkId: mock_rofl_json.lastGameChunkId,
65 lastKeyFrameId: mock_rofl_json.lastKeyFrameId,
66 statsJson: stats_json,
67 });
68
69 Ok(())
70 }
71
72 pub fn parse_rofl_data(&mut self, data: &[u8]) -> anyhow::Result<()> {
73 self.parse_rofl_to_string(data);
74
75 let mock_rofl_json: MockRoflJson = serde_json::from_str(&self.rofl_string)?;
76 let stats_json = mock_rofl_json.parse_stats_json()?;
77
78 self.rofl_json = Some(RoflJson {
79 gameLength: mock_rofl_json.gameLength,
80 gameVersion: mock_rofl_json.gameVersion,
81 lastGameChunkId: mock_rofl_json.lastGameChunkId,
82 lastKeyFrameId: mock_rofl_json.lastKeyFrameId,
83 statsJson: stats_json,
84 });
85
86 Ok(())
87 }
88
89 pub fn get_rofl_json(&self) -> Option<&RoflJson> {
90 self.rofl_json.as_ref()
91 }
92}