cleo_redux_sdk 0.0.2

Rust SDK for CLEO Redux plugins
Documentation
pub const SDK_STRING_MAX_LEN: usize = 128;

#[allow(non_camel_case_types)]
#[repr(C)]
pub enum HandlerResult {
    CONTINUE = 0,
    TERMINATE = 1,
    ERR = -1,
}

#[allow(non_camel_case_types)]
#[repr(C)]
pub enum HostId {
    RE3 = 1,
    REVC = 2,
    GTA3 = 3,
    VC = 4,
    SA = 5,
    GTA3_UNREAL = 6,
    VC_UNREAL = 7,
    SA_UNREAL = 8,
}

#[allow(non_camel_case_types)]
type c_char = i8;
pub type Context = *const std::ffi::c_void;
pub type CustomCommand = extern "C" fn(Context) -> HandlerResult;

#[cfg_attr(target_arch = "x86", link(name = "cleo_redux"))]
#[cfg_attr(target_arch = "x86_64", link(name = "cleo_redux64"))]
extern "C" {
    /// Returns the current SDK version as an integer number.
    fn GetSDKVersion() -> i32;
    /// Returns the current host (game) id
    fn GetHostId() -> HostId;
    /// Returns the absolute path to the CLEO directory
    fn GetCLEOFolder(buf: *mut c_char);
    /// Prints a new entry to the cleo_redux.log
    fn Log(text: *const c_char);
    /// Registers a new callback handler for the command with the given name. Permission token is required for unsafe operations interacting with the user environment (e.g. mem, fs, net)
    fn RegisterCommand(name: *const c_char, cb: CustomCommand, permission: *const c_char);
    /// Reads an integer argument (32 or 64 bit depending on target platform)
    fn GetIntParam(ctx: Context) -> isize;
    /// Reads a floating-point argument
    fn GetFloatParam(ctx: Context) -> f32;
    /// Reads a string argument
    fn GetStringParam(ctx: Context, buf: *mut c_char, len: u8);
    /// Writes the integer value (32 or 64 bit depending on target platform)
    fn SetIntParam(ctx: Context, value: isize);
    /// Writes the floating-point value
    fn SetFloatParam(ctx: Context, value: f32);
    /// Writes the string value
    fn SetStringParam(ctx: Context, buf: *const c_char, len: u8);
    /// Sets the status of the current condition
    fn UpdateCompareFlag(ctx: Context, result: bool);
}

macro_rules! sz {
    ($name:expr) => {
        std::ffi::CString::new($name).unwrap().as_ptr()
    };
}

/// Registers a new callback handler for the command with the given name. Permission token is required for unsafe operations interacting with the user environment (e.g. mem, fs, net)
#[allow(dead_code)]
pub fn register_command(name: &str, cb: CustomCommand, permission: Option<&str>) {
    unsafe {
        match permission {
            Some(token) => RegisterCommand(sz!(name), cb, sz!(token)),
            None => RegisterCommand(sz!(name), cb, std::ptr::null()),
        };
    }
}

/// Prints a new entry to the cleo_redux.log
pub fn log<T: Into<Vec<u8>>>(text: T) {
    unsafe { Log(sz!(text)) };
}

/// Returns the current SDK version as an integer number.
pub fn get_sdk_version() -> i32 {
    unsafe { GetSDKVersion() }
}

/// Returns the current host (game) id
pub fn get_host_id() -> HostId {
    unsafe { GetHostId() }
}

/// Reads a string argument
pub fn get_string_param(ctx: Context) -> String {
    let mut buf = [0i8; SDK_STRING_MAX_LEN];
    unsafe { GetStringParam(ctx, buf.as_mut_ptr(), SDK_STRING_MAX_LEN as _) };
    to_rust_string(buf.as_ptr())
}

/// Writes the string value
pub fn set_string_param(ctx: Context, value: String) {
    let len = value.len() as u8;
    unsafe { SetStringParam(ctx, sz!(value), len) };
}

/// Reads an integer argument (32 or 64 bit depending on target platform)
pub fn get_int_param(ctx: Context) -> isize {
    unsafe { GetIntParam(ctx) }
}

/// Writes the integer value (32 or 64 bit depending on target platform)
pub fn set_int_param(ctx: Context, value: isize) {
    unsafe { SetIntParam(ctx, value) };
}

/// Returns the absolute path to the CLEO directory
pub fn get_cleo_folder() -> std::path::PathBuf {
    let mut buf = [0i8; 255];
    unsafe { GetCLEOFolder(buf.as_mut_ptr()) };
    std::path::Path::new(&to_rust_string(buf.as_ptr())).into()
}

/// Reads a floating-point argument
pub fn get_float_param(ctx: Context) -> f32 {
    unsafe { GetFloatParam(ctx) }
}

/// Writes the floating-point value
pub fn set_float_param(ctx: Context, value: f32) {
    unsafe { SetFloatParam(ctx, value) };
}

/// Sets the status of the current condition
pub fn update_compare_flag(ctx: Context, value: bool) {
    unsafe { UpdateCompareFlag(ctx, value) }
}

fn to_rust_string(addr: *const i8) -> String {
    unsafe {
        std::ffi::CStr::from_ptr(addr)
            .to_owned()
            .into_string()
            .unwrap_or_default()
    }
}