libgm 0.5.0

A tool for modding, unpacking and decompiling GameMaker games
Documentation
pub mod texture_entry;

pub use texture_entry::TextureEntry;

use crate::prelude::*;
use crate::wad::deserialize::reader::DataReader;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Data {
    pub version: i32,
    pub textures: Vec<TextureEntry>,
    pub json: String,
    pub atlas: String,
}

impl Data {
    // For reference: <https://github.com/UnderminersTeam/UndertaleModTool/commit/0dab19b91ed673520a2708aa9ea2bc7539dafb0c>
    fn decode_spine_blob(blob: &mut Vec<u8>) {
        // don't ask me, ask Nikita Krapivin (or don't)
        let mut k: u32 = 42;
        for byte in blob {
            *byte = byte.wrapping_sub(k as u8);
            k = k.wrapping_mul(k + 1);
        }
    }

    fn encode_spine_blob(blob: &mut Vec<u8>) {
        // don't ask me, ask Nikita Krapivin (or don't)
        let mut k: u32 = 42;
        for byte in blob {
            *byte = byte.wrapping_add(k as u8);
            k = k.wrapping_mul(k + 1);
        }
    }

    pub(super) fn read_weird_string(reader: &mut DataReader, size: u32) -> Result<String> {
        let ctx = || format!("reading weird string for Spine data with size {size}");
        let mut blob: Vec<u8> = reader.read_bytes_dyn(size).with_context(ctx)?.to_vec();
        Self::decode_spine_blob(&mut blob);
        let string: String = String::from_utf8(blob).with_context_src(ctx)?;
        Ok(string)
    }

    pub(super) fn build_weird_string(string: &String) -> Vec<u8> {
        let mut blob: Vec<u8> = string.as_bytes().to_vec();
        Self::encode_spine_blob(&mut blob);
        blob
    }
}