mirror of
https://github.com/QRouland/SGTool.git
synced 2024-11-24 07:02:38 +00:00
Improve Code Documentation
This commit is contained in:
parent
bb4e163f45
commit
1d5fa1b860
13
src/lib.rs
13
src/lib.rs
@ -1,4 +1,13 @@
|
|||||||
#[macro_use] extern crate log;
|
#![warn(missing_docs)]
|
||||||
|
//! sgtool is a library for analyze of the replay of the Stormgate game.
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
//! # Example
|
||||||
|
//! ```
|
||||||
|
//! let replay_path = "replay.SGReplay";
|
||||||
|
//! let mut buffer : Vec<u8> = vec![];
|
||||||
|
//! let replay : Replay = Replay::load_file(replay_path, &mut buffer)?;
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
mod protos;
|
mod protos;
|
@ -1,3 +1,11 @@
|
|||||||
|
//! sgtool is a tool for analyze of the replay of the Stormgate game.
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
//! # Example
|
||||||
|
//! ```
|
||||||
|
//! sgtool -i replays/replay.SGReplay
|
||||||
|
//! ```
|
||||||
|
|
||||||
extern crate pretty_env_logger;
|
extern crate pretty_env_logger;
|
||||||
#[macro_use] extern crate log;
|
#[macro_use] extern crate log;
|
||||||
|
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
|
//! A parser for Stormgate Replay.
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
//! # Example
|
||||||
|
//! ```
|
||||||
|
//! let replay_path = "replay.SGReplay";
|
||||||
|
//! let mut buffer : Vec<u8> = vec![];
|
||||||
|
//! let replay : Replay = Replay::load_file(replay_path, &mut buffer)?;
|
||||||
|
//! ```
|
||||||
|
|
||||||
use std::{fs::OpenOptions, io::{BufRead, BufReader, Read}, path::Path};
|
use std::{fs::OpenOptions, io::{BufRead, BufReader, Read}, path::Path};
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
use flate2::bufread::GzDecoder;
|
use flate2::bufread::GzDecoder;
|
||||||
@ -6,7 +16,8 @@ use quick_protobuf::BytesReader;
|
|||||||
use crate::protos::stormgate::ReplayChunk;
|
use crate::protos::stormgate::ReplayChunk;
|
||||||
|
|
||||||
/// Stormgate Replay Header.
|
/// Stormgate Replay Header.
|
||||||
/// It consists of 16 bytes at the top of the replay
|
//
|
||||||
|
// It consists of 16 bytes at the top of the replay
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Header {
|
pub struct Header {
|
||||||
h1: u32, // 12 first bytes repsentation are unknown at the moment
|
h1: u32, // 12 first bytes repsentation are unknown at the moment
|
||||||
@ -14,20 +25,22 @@ pub struct Header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Stormgate Replay Payload.
|
/// Stormgate Replay Payload.
|
||||||
/// After the the 16 bytes header, the actual payload of the replay of Protobuf messages that are gzipped
|
///
|
||||||
/// Each Protobuf messages represents events that appended in the game from the differetns clients
|
// After the the 16 bytes header, the actual payload of the replay of Protobuf messages that are gzipped
|
||||||
|
// Each Protobuf messages represents events that appended in the game from the differetns clients
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Payload<'a> {
|
pub struct Payload<'a> {
|
||||||
chunks: Vec<ReplayChunk<'a>>,
|
chunks: Vec<ReplayChunk<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stormgate replay
|
/// Stormgate Replay.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Replay<'a> {
|
pub struct Replay<'a> {
|
||||||
header: Header, // header of the replay
|
header: Header, // header of the replay
|
||||||
payload: Payload<'a>, // the content of a replay is set of messages
|
payload: Payload<'a>, // the content of a replay is set of messages
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Load n bytes into a buffer.
|
||||||
fn load_part<'a, R: Read>(reader: &'a mut R) -> impl FnMut(usize) -> Result<Vec<u8>, std::io::Error> + 'a {
|
fn load_part<'a, R: Read>(reader: &'a mut R) -> impl FnMut(usize) -> Result<Vec<u8>, std::io::Error> + 'a {
|
||||||
move |size| {
|
move |size| {
|
||||||
let mut buf = vec![0u8; size];
|
let mut buf = vec![0u8; size];
|
||||||
@ -37,7 +50,7 @@ fn load_part<'a, R: Read>(reader: &'a mut R) -> impl FnMut(usize) -> Result<Vec<
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Header {
|
impl Header {
|
||||||
///
|
/// Load the 16 bytes as a `Header`.
|
||||||
fn load<T: BufRead>(reader: &mut T) -> Result<Header, std::io::Error> {
|
fn load<T: BufRead>(reader: &mut T) -> Result<Header, std::io::Error> {
|
||||||
let mut load = load_part(reader);
|
let mut load = load_part(reader);
|
||||||
let h1 = LittleEndian::read_u32(&load(12)?);
|
let h1 = LittleEndian::read_u32(&load(12)?);
|
||||||
@ -47,6 +60,7 @@ impl Header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Payload<'a> {
|
impl<'a> Payload<'a> {
|
||||||
|
/// Load the replay content as a `Payload`.
|
||||||
fn load<T: BufRead>(buf_reader: &mut T, buf: &'a mut Vec<u8>) -> Result<Payload<'a>, Box<dyn std::error::Error>> {
|
fn load<T: BufRead>(buf_reader: &mut T, buf: &'a mut Vec<u8>) -> Result<Payload<'a>, Box<dyn std::error::Error>> {
|
||||||
let mut d = GzDecoder::new(buf_reader);
|
let mut d = GzDecoder::new(buf_reader);
|
||||||
d.read_to_end(buf)?;
|
d.read_to_end(buf)?;
|
||||||
@ -65,6 +79,7 @@ impl<'a> Payload<'a> {
|
|||||||
|
|
||||||
|
|
||||||
impl<'a> Replay<'a> {
|
impl<'a> Replay<'a> {
|
||||||
|
|
||||||
fn load<T: BufRead>(buf_reader: &mut T, buf: &'a mut Vec<u8>) -> Result<Replay<'a>, Box<dyn std::error::Error>> {
|
fn load<T: BufRead>(buf_reader: &mut T, buf: &'a mut Vec<u8>) -> Result<Replay<'a>, Box<dyn std::error::Error>> {
|
||||||
// Get Header
|
// Get Header
|
||||||
let header = Header::load(buf_reader)?;
|
let header = Header::load(buf_reader)?;
|
||||||
@ -75,6 +90,18 @@ impl<'a> Replay<'a> {
|
|||||||
Ok(Replay { header, payload: data })
|
Ok(Replay { header, payload: data })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Load a replay file as `Replay`.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `path` : Path of the storgmate replay file.
|
||||||
|
/// * `buf` : Byte Buffer use by the parser.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
/// ```
|
||||||
|
/// let replay_path = "replay.SGReplay";
|
||||||
|
/// let mut buffer : Vec<u8> = vec![];
|
||||||
|
/// let replay : Replay = Replay::load_file(replay_path, &mut buffer)?;
|
||||||
|
/// ```
|
||||||
pub fn load_file(path: &Path, buf: &'a mut Vec<u8>) -> Result<Replay<'a>, Box<dyn std::error::Error>> {
|
pub fn load_file(path: &Path, buf: &'a mut Vec<u8>) -> Result<Replay<'a>, Box<dyn std::error::Error>> {
|
||||||
let file = OpenOptions::new().read(true).open(path).unwrap();
|
let file = OpenOptions::new().read(true).open(path).unwrap();
|
||||||
let mut buf_reader = BufReader::new(file);
|
let mut buf_reader = BufReader::new(file);
|
||||||
@ -90,7 +117,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn load_file() {
|
fn load_file() {
|
||||||
// Replay used is form Alpha phase of stormgate, threfore is not provided in the repo to avoid any problem with NDA at this time
|
// Replay used is form Alpha phase of stormgate, threfore is not provided in the repo to avoid any problem with NDA at this time
|
||||||
// TODO : when the game officially can out fix provide sample replay for testing directly in the repo
|
// TODO : when the game officially came out fix provide sample replay for testing directly in the repo
|
||||||
let replay_path = Path::new("replays/CL55366-2024.05.12-01.53.SGReplay");
|
let replay_path = Path::new("replays/CL55366-2024.05.12-01.53.SGReplay");
|
||||||
let mut buffer : Vec<u8> = vec![];
|
let mut buffer : Vec<u8> = vec![];
|
||||||
let r = Replay::load_file(replay_path, &mut buffer).unwrap();
|
let r = Replay::load_file(replay_path, &mut buffer).unwrap();
|
||||||
|
Loading…
Reference in New Issue
Block a user