more crash protection (#833)

* more crash protection

* more
This commit is contained in:
Logan McNaughton 2026-05-03 15:59:59 +02:00 committed by GitHub
parent 3d6ca17a9a
commit 17f3f2dc63
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 44 additions and 31 deletions

View File

@ -86,10 +86,11 @@ pub fn create_savestate(device: &device::Device) {
(&ra_state, "ra_state"),
];
let save_path = device.ui.storage.paths.savestate_file_path.clone();
let compressed_file = ui::storage::compress_file(data);
tokio::spawn(async move {
tokio::fs::write(save_path, compressed_file).await.unwrap();
});
if let Ok(compressed_file) = ui::storage::compress_file(data) {
tokio::spawn(async move {
tokio::fs::write(save_path, compressed_file).await.unwrap();
});
}
ui::video::onscreen_message(
&format!(
"Savestate created in slot {}",
@ -109,11 +110,11 @@ pub fn load_savestate(device: &mut device::Device) {
}
let savestate = std::fs::read(&device.ui.storage.paths.savestate_file_path);
if let Ok(savestate) = &savestate {
let device_bytes = ui::storage::decompress_file(savestate, "device");
let save_bytes = ui::storage::decompress_file(savestate, "saves");
let rdp_state = ui::storage::decompress_file(savestate, "rdp_state");
let ra_state = ui::storage::decompress_file(savestate, "ra_state");
if let Ok(state) = postcard::from_bytes::<device::Device>(&device_bytes)
if let Ok(device_bytes) = ui::storage::decompress_file(savestate, "device")
&& let Ok(save_bytes) = ui::storage::decompress_file(savestate, "saves")
&& let Ok(rdp_state) = ui::storage::decompress_file(savestate, "rdp_state")
&& let Ok(ra_state) = ui::storage::decompress_file(savestate, "ra_state")
&& let Ok(state) = postcard::from_bytes::<device::Device>(&device_bytes)
&& let Ok(saves) = postcard::from_bytes(&save_bytes)
{
device.ui.storage.saves = saves;

View File

@ -263,8 +263,10 @@ pub fn load_saves(ui: &mut ui::Ui, netplay: &mut Option<netplay::Netplay>) {
);
let mut compressed_sd = Vec::new();
if !ui.storage.saves.sdcard.data.is_empty() {
compressed_sd = compress_file(&[(&ui.storage.saves.sdcard.data, "save")]);
if !ui.storage.saves.sdcard.data.is_empty()
&& let Ok(file_data) = compress_file(&[(&ui.storage.saves.sdcard.data, "save")])
{
compressed_sd = file_data;
}
netplay::send_save(
netplay.as_mut().unwrap(),
@ -274,11 +276,13 @@ pub fn load_saves(ui: &mut ui::Ui, netplay: &mut Option<netplay::Netplay>) {
);
let mut compressed_romsave = Vec::new();
if !ui.storage.saves.romsave.data.is_empty() {
compressed_romsave = compress_file(&[(
if !ui.storage.saves.romsave.data.is_empty()
&& let Ok(file_data) = compress_file(&[(
&postcard::to_stdvec(&ui.storage.saves.romsave.data).unwrap(),
"save",
)]);
)])
{
compressed_romsave = file_data;
}
netplay::send_save(
netplay.as_mut().unwrap(),
@ -310,17 +314,19 @@ pub fn load_saves(ui: &mut ui::Ui, netplay: &mut Option<netplay::Netplay>) {
let mut compressed_sd = Vec::new();
netplay::receive_save(netplay.as_mut().unwrap(), "img", &mut compressed_sd);
if !compressed_sd.is_empty() {
ui.storage.saves.sdcard.data = decompress_file(&compressed_sd, "save");
if !compressed_sd.is_empty()
&& let Ok(file_data) = decompress_file(&compressed_sd, "save")
{
ui.storage.saves.sdcard.data = file_data;
}
let mut compressed_romsave = Vec::new();
netplay::receive_save(netplay.as_mut().unwrap(), "rom", &mut compressed_romsave);
if !compressed_romsave.is_empty() {
let romsave_bytes = decompress_file(&compressed_romsave, "save");
if let Ok(romsave_data) = postcard::from_bytes(&romsave_bytes) {
ui.storage.saves.romsave.data = romsave_data;
}
if !compressed_romsave.is_empty()
&& let Ok(romsave_bytes) = decompress_file(&compressed_romsave, "save")
&& let Ok(romsave_data) = postcard::from_bytes(&romsave_bytes)
{
ui.storage.saves.romsave.data = romsave_data;
}
}
}
@ -333,33 +339,39 @@ pub fn format_saves(device: &mut device::Device) {
device::controller::mempak::format_mempak(device);
}
pub fn decompress_file(input: &[u8], name: &str) -> Vec<u8> {
pub fn decompress_file(input: &[u8], name: &str) -> Result<Vec<u8>, zip::result::ZipError> {
let mut decompressed_file = Vec::new();
{
let mut reader = zip::ZipArchive::new(std::io::Cursor::new(input)).unwrap();
let mut file = reader.by_name(name).unwrap();
file.read_to_end(&mut decompressed_file).unwrap();
if let Ok(mut reader) = zip::ZipArchive::new(std::io::Cursor::new(input))
&& let Ok(mut file) = reader.by_name(name)
&& let Ok(_) = file.read_to_end(&mut decompressed_file)
{
return Ok(decompressed_file);
}
}
decompressed_file
Err(zip::result::ZipError::FileNotFound)
}
pub fn compress_file(data: &[(&[u8], &str)]) -> Vec<u8> {
pub fn compress_file(data: &[(&[u8], &str)]) -> Result<Vec<u8>, zip::result::ZipError> {
let mut compressed_file = Vec::new();
{
let mut writer = zip::ZipWriter::new(std::io::Cursor::new(&mut compressed_file));
for item in data {
writer
if writer
.start_file(
item.1,
zip::write::SimpleFileOptions::default()
.compression_method(zip::CompressionMethod::Zstd)
.compression_level(Some(1)),
)
.unwrap();
writer.write_all(item.0).unwrap();
.is_err()
|| writer.write_all(item.0).is_err()
{
return Err(zip::result::ZipError::FileNotFound);
}
}
}
compressed_file
Ok(compressed_file)
}
fn writeback_sdcard(device: &mut device::Device) {