Embedding to custom host
CLEO Redux can be embedded and run JS scripts on an unknown (i.e. not supported officially) host. A host is an application in which process cleo_redux.asi
or cleo_redux64.asi
gets loaded or injected and where the CLEO runtime runs. This feature is highly experimental and subject to change at any moment.
Loading into custom process
There are multiple ways of loading ASI file into the target process. They include but not limited to Ultimate ASI Loader or any DLL injector available on GitHub. The host can load CLEO ASI file as a dynamic library when needed using WinAPI's LoadLibrary
function.
Launching the CLEO runtime
After injecting CLEO into the target process you should launch the runtime to execute scripts. There are two ways of doing it: automatic and manual.
Automatic launch
To launch the runtime on an unknown host immediately after loading, open the config file and set EnableSelfHost
to 1
. When loaded as a self host CLEO Redux scans the CLEO directory for plugins and scripts and runs them. This option is suitable if you don't have control over the host's source code and inject the library using an injector.
Manually Controlling the Runtime
The host can start the runtime and advance its main loop using SDK methods RuntimeInit
and RuntimeNextTick
. This option is suitable if you have control over the host's source code and can execute arbitrary instructions.
This is how it can be implemented in Rust:
[dependencies]
ctor = "0.1.21"
cleo_redux_sdk = "^0.0.6"
#![allow(unused)] fn main() { use ctor::*; #[cfg_attr(target_arch = "x86", link(name = "cleo_redux"))] #[cfg_attr(target_arch = "x86_64", link(name = "cleo_redux64"))] #[ctor] fn init() { use cleo_redux_sdk; use std::{thread, time}; // load CLEO scripts, FXT, enable file watcher cleo_redux_sdk::runtime_init(); // init time variables const FPS: i32 = 30; let time_step = 1000 / FPS; let started = time::Instant::now(); thread::spawn(move || loop { let current_time = started.elapsed().as_millis() as u32; // advance main loop providing current time and time step // current time is used to determine whether a script should "wake up" after wait command // time step is used to increment TIMERA and TIMERB variables cleo_redux_sdk::runtime_next_tick(current_time, time_step); // pause for at least time step ms thread::sleep(time::Duration::from_millis(time_step as u64)); }); } }
Available Commands
In the self-hosted mode CLEO Redux supports own bindings and commands made with SDK. It uses command definitions for the Unknown host from Sanny Builder Library (available for 32-bit and 64-bit).
You can use all standard JavaScript features. The list of available commands can be seen in the auto-generated file .config/unknown.d.ts
.
Manifest
Manifest is a file with static configuration for the given host. Only unknown hosts make use of it. The configuration should be stored in .config\manifest.json
with the following structure:
{
"host": string,
"host_name": string,
"compound": boolean
}
-
host
should match the host's executable name. E.g. if the host runs viaapplication.exe
, the value isapplication
. Available in scripts as the HOST variable. -
host_name
defines the host's custom name used in the log -
compound
defines whether the host uses compound definitions. By default the host uses definitions from the file matching<host>.json
, e.g.application.json
. This file should be provided by the person managing integration of CLEO Redux with the given host and placed in the.config
folder.When
compound
is set totrue
the host also uses command definitions for the Unknown host (e.g.unknown_x86.json
). If this file is missing CLEO downloads it from Sanny Builder Library.
Example
Host: Sanny Builder 3 (sanny.exe
)
{
"host": "sanny",
"host_name": "Sanny Builder 3",
"compound": true
}
Sanny Builder 3\CLEO\.config
folder contains sanny.json
and manifest.json
before the first run. The other files are downloaded or generated automatically.