// StarKingdoms.IO, a browser game about drifting through space // Copyright (C) 2024 ghostly_zsh, TerraMaster85, core // // 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, either version 3 of the License, or // (at your option) any later version. // // 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 base64::Engine; use hmac::{Hmac, Mac}; use serde::{Deserialize, Serialize}; use sha2::Sha256; use std::error::Error; #[derive(Serialize, Deserialize, Debug)] pub struct SaveData { // ---------------------------------------------------------------------- // HEY YOU // YES YOU // GHOSTLY // FILL THIS WITH STUFF // ---------------------------------------------------------------------- // THANKS! -core pub children: Vec>, } #[derive(Serialize, Deserialize, Debug)] pub struct SaveModule { pub part_type: PartType, pub children: Vec>, } #[derive(Clone, Copy, PartialEq, Serialize, Deserialize, Debug)] pub enum PartType { Placeholder, Hearty, Cargo, Hub, LandingThruster, LandingThrusterSuspension, } // no touchy. this is the struct that savefiles are actually represented in #[derive(Serialize, Deserialize)] pub struct Savefile { data_msgpack: Vec, mac: Vec, } pub fn pack_savefile(key: &str, save_data: SaveData) -> String { let mut mac: Hmac = Hmac::new_from_slice(key.as_bytes()).unwrap(); let save_data_bytes = rmp_serde::to_vec(&save_data).unwrap(); mac.update(&save_data_bytes); let mc_code = mac.finalize().into_bytes(); let save_file = Savefile { data_msgpack: save_data_bytes, mac: mc_code.to_vec(), }; let final_bytes = rmp_serde::to_vec(&save_file).unwrap(); base64::engine::general_purpose::STANDARD.encode(final_bytes) } pub fn unpack_savefile(key: &str, file: String) -> Result> { // << reverse! << let savefile_bytes = base64::engine::general_purpose::STANDARD.decode(file).map_err(|e| format!("error decoding b64: {e}"))?; let save_file: Savefile = rmp_serde::from_slice(&savefile_bytes).map_err(|e| format!("error decoding savefile wrapper: {e}"))?; let mut mac: Hmac = Hmac::new_from_slice(key.as_bytes()).map_err(|e| format!("error loading hmac-sha256: {e}"))?; mac.update(&save_file.data_msgpack); mac.verify_slice(&save_file.mac).map_err(|e| format!("error verifying signature: {e}"))?; let save_data = rmp_serde::from_slice(&save_file.data_msgpack).map_err(|e| format!("error decoding inner signature: {e}"))?; Ok(save_data) }