Replay check version from header
This commit is contained in:
parent
d34eb0bd33
commit
d2aded9e44
@ -135,6 +135,10 @@ impl StandaloneReplayManager {
|
|||||||
|
|
||||||
thread::spawn(move || match fs::read(path) {
|
thread::spawn(move || match fs::read(path) {
|
||||||
Ok(mut bytes) => {
|
Ok(mut bytes) => {
|
||||||
|
if let Err(e) = read_header(&mut bytes) {
|
||||||
|
return send.send(ReplayReadEvent::Error(e.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
let cursor = Cursor::new(&mut bytes);
|
let cursor = Cursor::new(&mut bytes);
|
||||||
let decoder = GzDecoder::new(cursor);
|
let decoder = GzDecoder::new(cursor);
|
||||||
|
|
||||||
@ -665,6 +669,7 @@ impl ReplayRecorder {
|
|||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let mut bytes = Vec::new();
|
let mut bytes = Vec::new();
|
||||||
|
bytes.extend(produce_header());
|
||||||
let encoder = GzEncoder::new(&mut bytes, Compression::default());
|
let encoder = GzEncoder::new(&mut bytes, Compression::default());
|
||||||
match ciborium::into_writer(&replay, encoder) {
|
match ciborium::into_writer(&replay, encoder) {
|
||||||
Ok(_) => match fs::write(path, bytes) {
|
Ok(_) => match fs::write(path, bytes) {
|
||||||
@ -928,3 +933,102 @@ pub struct ReplayTriggerableState {
|
|||||||
active: Option<u16>,
|
active: Option<u16>,
|
||||||
active_for: f64,
|
active_for: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const GAME_NAME: &str = "skullball";
|
||||||
|
const MAJOR: u8 = match u8::from_str_radix(env!("CARGO_PKG_VERSION_MAJOR"), 10) {
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(_) => 0,
|
||||||
|
};
|
||||||
|
const MINOR: u8 = match u8::from_str_radix(env!("CARGO_PKG_VERSION_MINOR"), 10) {
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(_) => 0,
|
||||||
|
};
|
||||||
|
const PATCH: u8 = match u8::from_str_radix(env!("CARGO_PKG_VERSION_PATCH"), 10) {
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(_) => 0,
|
||||||
|
};
|
||||||
|
const VERSION: Version = Version {
|
||||||
|
major: MAJOR,
|
||||||
|
minor: MINOR,
|
||||||
|
patch: PATCH,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn produce_header() -> Vec<u8> {
|
||||||
|
let mut bytes: Vec<u8> = Vec::new();
|
||||||
|
bytes.extend(GAME_NAME.as_bytes());
|
||||||
|
bytes.push(MAJOR);
|
||||||
|
bytes.push(MINOR);
|
||||||
|
bytes.push(PATCH);
|
||||||
|
bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_header(bytes: &mut Vec<u8>) -> Result<(), HeaderReadError> {
|
||||||
|
if bytes.len() < (GAME_NAME.len() + 3) {
|
||||||
|
return Err(HeaderReadError::ReadIncomplete);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut name_bytes = Vec::with_capacity(GAME_NAME.len());
|
||||||
|
for _ in 0..GAME_NAME.len() {
|
||||||
|
name_bytes.push(bytes.remove(0));
|
||||||
|
}
|
||||||
|
let name = String::from_utf8(name_bytes).map_err(|_| HeaderReadError::InvalidTitle)?;
|
||||||
|
if name != GAME_NAME {
|
||||||
|
return Err(HeaderReadError::InvalidTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
let major = bytes.remove(0);
|
||||||
|
let minor = bytes.remove(0);
|
||||||
|
let patch = bytes.remove(0);
|
||||||
|
let version = Version {
|
||||||
|
major,
|
||||||
|
minor,
|
||||||
|
patch,
|
||||||
|
};
|
||||||
|
if version != VERSION {
|
||||||
|
return Err(HeaderReadError::InvalidVersion(version));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum HeaderReadError {
|
||||||
|
ReadIncomplete,
|
||||||
|
InvalidTitle,
|
||||||
|
InvalidVersion(Version),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for HeaderReadError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
HeaderReadError::ReadIncomplete => {
|
||||||
|
write!(f, "Header read incomplete, invalid replay file")
|
||||||
|
}
|
||||||
|
HeaderReadError::InvalidTitle => {
|
||||||
|
write!(f, "Invalid title in header, invalid replay file")
|
||||||
|
}
|
||||||
|
HeaderReadError::InvalidVersion(version) => write!(
|
||||||
|
f,
|
||||||
|
"Replay game version mismatch: {} != {}",
|
||||||
|
version, VERSION
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, PartialOrd, Eq)]
|
||||||
|
pub struct Version {
|
||||||
|
pub major: u8,
|
||||||
|
pub minor: u8,
|
||||||
|
pub patch: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for Version {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
std::fmt::Display::fmt(&self.major, f)?;
|
||||||
|
write!(f, ".")?;
|
||||||
|
std::fmt::Display::fmt(&self.minor, f)?;
|
||||||
|
write!(f, ".")?;
|
||||||
|
std::fmt::Display::fmt(&self.patch, f)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user