Rename pending match to match config and add match state (#51)
CI / build-and-test (push) Successful in 1m17s
CI / production-build (push) Successful in 9m37s

Reviewed-on: #51
Co-authored-by: Álex Román Núñez <eirexe@eirteam.moe>
This commit was merged in pull request #51.
This commit is contained in:
2026-09-20 11:13:15 +00:00
committed by EIREXE
parent 769d82573a
commit 1276562890
7 changed files with 300 additions and 78 deletions
+26 -25
View File
@@ -12,16 +12,12 @@ use clap::ValueEnum;
use serde::{Deserialize, Serialize};
use crate::{
AppState,
args::Args,
input::FighterInputFrame,
match_loading::{MatchPlayer, PendingMatch},
netcode::GGRSCfg,
AppState, args::Args, input::FighterInputFrame, match_loading::MatchConfig, netcode::GGRSCfg,
schedule::GameplaySet,
};
const MAGIC: &[u8; 8] = b"SPRPLY01";
pub const REPLAY_VERSION: u32 = 1;
pub const REPLAY_VERSION: u32 = 2;
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, ValueEnum)]
pub enum ReplayFormat {
@@ -34,17 +30,11 @@ pub enum ReplayFormat {
pub struct Replay {
pub replay_version: u32,
pub game_version: String,
pub match_config: ReplayMatch,
pub match_config: MatchConfig,
pub frames: Vec<ReplayFrame>,
pub checksums: Vec<ReplayChecksum>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ReplayMatch {
pub stage: crate::stage::manifest::StageId,
pub players: Vec<MatchPlayer>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ReplayFrame {
pub frame: i32,
@@ -267,27 +257,27 @@ fn stop_recording(
mut commands: Commands,
stop_request: Option<Res<StopReplayRecording>>,
runtime: Option<ResMut<ReplayRuntime>>,
request: Option<Res<PendingMatch>>,
config: Option<Res<MatchConfig>>,
) {
if stop_request.is_none() {
return;
}
commands.remove_resource::<StopReplayRecording>();
finish_recording_inner(&mut commands, runtime, request);
finish_recording_inner(&mut commands, runtime, config);
}
fn finish_recording(
mut commands: Commands,
runtime: Option<ResMut<ReplayRuntime>>,
request: Option<Res<PendingMatch>>,
config: Option<Res<MatchConfig>>,
) {
finish_recording_inner(&mut commands, runtime, request);
finish_recording_inner(&mut commands, runtime, config);
}
fn finish_recording_inner(
commands: &mut Commands,
runtime: Option<ResMut<ReplayRuntime>>,
request: Option<Res<PendingMatch>>,
config: Option<Res<MatchConfig>>,
) {
let Some(mut runtime) = runtime else { return };
let ReplayMode::Record { path, format } = &runtime.mode else {
@@ -296,16 +286,13 @@ fn finish_recording_inner(
if runtime.finished || runtime.frames.is_empty() {
return;
}
let Some(request) = request else { return };
let Some(config) = config else { return };
let path = path.clone();
let format = *format;
let replay = Replay {
replay_version: REPLAY_VERSION,
game_version: env!("CARGO_PKG_VERSION").into(),
match_config: ReplayMatch {
stage: request.stage,
players: request.players.clone(),
},
match_config: config.as_ref().clone(),
frames: runtime
.frames
.iter()
@@ -355,7 +342,7 @@ mod tests {
use super::*;
use crate::{
fighter::FighterId,
match_loading::MatchPlayer,
match_loading::{MatchPlayer, MatchRules},
math::{int::FGi32, vec::FGVec2},
stage::manifest::StageId,
};
@@ -364,12 +351,15 @@ mod tests {
Replay {
replay_version: REPLAY_VERSION,
game_version: "test".into(),
match_config: ReplayMatch {
match_config: MatchConfig {
stage: StageId::TestStage,
players: vec![MatchPlayer {
handle: 0,
fighter: FighterId::TestFighter,
}],
rules: MatchRules::Timed {
time_limit_frames: 21_600,
},
},
frames: vec![ReplayFrame {
frame: 1,
@@ -406,4 +396,15 @@ mod tests {
replay.frames[0].inputs.clear();
assert!(validate(&replay).is_err());
}
#[test]
fn unsupported_replay_version_is_rejected() {
let mut replay = sample();
replay.replay_version = 1;
assert_eq!(
validate(&replay).unwrap_err(),
"unsupported replay version 1"
);
}
}