/*
wearechat - generic multiplayer game with voip
Copyright (C) 2025 metamuffin
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, version 3 of the License only.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
use crate::{packets::Resource, resources::RespackEntry, store::ResourceStore};
use anyhow::{Result, bail};
use log::{info, warn};
use std::{
collections::HashMap,
io::{Read, Seek, SeekFrom, Write},
marker::PhantomData,
};
const MAGIC: &[u8; 16] = b"\x0f\x0cWEARE\x01RESPACK\x02";
pub fn save_respack(
mut output: impl Write,
store: &ResourceStore,
resources: &[Resource],
entry: Option>,
) -> Result<()> {
info!("begin save");
output.write_all(MAGIC)?;
output.write_all(&entry.map(|e| e.0).unwrap_or([0u8; 32]))?;
output.write_all(&u64::to_be_bytes(resources.len() as u64))?;
let mut off =
(MAGIC.len() + 32 + size_of::() + (32 + size_of::() * 2) * resources.len())
as u64;
for r in resources {
let size = store.get_raw_size(*r)?.unwrap() as u64;
output.write_all(&r.0)?;
output.write_all(&u64::to_be_bytes(off))?;
output.write_all(&u64::to_be_bytes(size))?;
off += size;
}
for r in resources {
output.write_all(&store.get_raw(*r)?.unwrap())?;
}
info!("end save");
Ok(())
}
/// Copies the entire respack to the store. This is usually a dumb idea because the pack supportes on-demand reading.
pub fn load_respack(
input: impl Read + Seek,
store: &ResourceStore,
) -> Result