~starkingdoms/starkingdoms

ref: 7baddd1c84b0cf50d49ececd97ea631725533ad3 starkingdoms/starkingdoms-common/src/lib.rs -rw-r--r-- 3.2 KiB
7baddd1c — ghostlyzsh squishy joints and fix thruster turning 1 year, 8 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// 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 <https://www.gnu.org/licenses/>.

use base64::Engine;
use hmac::{Hmac, Mac};
use serde::{Deserialize, Serialize};
use sha2::Sha256;
use std::error::Error;

#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
pub struct SaveData {
    // ----------------------------------------------------------------------
    // HEY YOU
    // YES YOU
    // GHOSTLY
    // FILL THIS WITH STUFF
    // ----------------------------------------------------------------------
    // THANKS! -core
    pub children: Vec<Option<SaveModule>>,
    pub unused_modules: Vec<(PartType, u32)>,
}

#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
pub struct SaveModule {
    pub part_type: PartType,
    pub children: Vec<Option<SaveModule>>,
}

#[derive(Clone, Copy, PartialEq, Hash, Eq, 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, Clone, PartialEq, Debug)]
pub struct Savefile {
    data_msgpack: Vec<u8>,
    mac: Vec<u8>,
}

pub fn pack_savefile(key: &[u8], save_data: SaveData) -> String {
    let mut mac: Hmac<Sha256> = Hmac::new_from_slice(key).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: &[u8], file: String) -> Result<SaveData, Box<dyn Error>> {
    // << 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<Sha256> =
        Hmac::new_from_slice(key).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)
}