Skip to content

Commit

Permalink
Add lo_get_early_loading_plugins()
Browse files Browse the repository at this point in the history
Now that the list of implicitly active plugins can include plugins
without hardcoded positions (which was already true for Skyrim's
Update.esm, but it is treated as hardcoded),
lo_get_early_loading_plugins() exposes the old list of implicitly active
plugins, i.e. those with hardcoded positions.
  • Loading branch information
Ortham committed Sep 24, 2023
1 parent 33bcaed commit 4fdea60
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 3 deletions.
55 changes: 52 additions & 3 deletions ffi/src/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,11 +254,60 @@ pub unsafe extern "C" fn lo_fix_plugin_lists(handle: lo_game_handle) -> c_uint {
/// Get the list of implicitly active plugins for the given handle's game.
///
/// The list may be empty if the game has no implicitly active plugins. The list
/// may include plugins that are not installed. Plugins are not necessarily
/// listed in their load order.
///
/// If the list is empty, the `plugins` pointer will be null and `num_plugins`
/// will be `0`.
///
/// Returns `LIBLO_OK` if successful, otherwise a `LIBLO_ERROR_*` code is
/// returned.
#[no_mangle]
pub unsafe extern "C" fn lo_get_implicitly_active_plugins(
handle: lo_game_handle,
plugins: *mut *mut *mut c_char,
num_plugins: *mut size_t,
) -> c_uint {
catch_unwind(|| {
if handle.is_null() || plugins.is_null() || num_plugins.is_null() {
return error(LIBLO_ERROR_INVALID_ARGS, "Null pointer passed");
}

let handle = match (*handle).read() {
Err(e) => return error(LIBLO_ERROR_POISONED_THREAD_LOCK, &e.to_string()),
Ok(h) => h,
};

*plugins = ptr::null_mut();
*num_plugins = 0;

let plugin_names = handle.game_settings().implicitly_active_plugins();

if plugin_names.is_empty() {
return LIBLO_OK;
}

match to_c_string_array(plugin_names) {
Ok((pointer, size)) => {
*plugins = pointer;
*num_plugins = size;
}
Err(x) => return error(x, "A filename contained a null byte"),
}

LIBLO_OK
})
.unwrap_or(LIBLO_ERROR_PANICKED)
}

/// Get the list of implicitly active plugins for the given handle's game.
///
/// The list may be empty if the game has no early loading plugins. The list
/// may include plugins that are not installed. Plugins are listed in their
/// hardcoded load order.
///
/// Note that for the original Skyrim, `Update.esm` is hardcoded to always load,
/// but not in a specific location, unlike all other implicitly active plugins
/// but not in a specific location, unlike all other early loading plugins
/// for all games, which must load in the given order, before any other plugins.
///
/// The order of Creation Club plugins as listed in `Fallout4.ccc` or
Expand All @@ -270,7 +319,7 @@ pub unsafe extern "C" fn lo_fix_plugin_lists(handle: lo_game_handle) -> c_uint {
/// Returns `LIBLO_OK` if successful, otherwise a `LIBLO_ERROR_*` code is
/// returned.
#[no_mangle]
pub unsafe extern "C" fn lo_get_implicitly_active_plugins(
pub unsafe extern "C" fn lo_get_early_loading_plugins(
handle: lo_game_handle,
plugins: *mut *mut *mut c_char,
num_plugins: *mut size_t,
Expand All @@ -288,7 +337,7 @@ pub unsafe extern "C" fn lo_get_implicitly_active_plugins(
*plugins = ptr::null_mut();
*num_plugins = 0;

let plugin_names = handle.game_settings().implicitly_active_plugins();
let plugin_names = handle.game_settings().early_loading_plugins();

if plugin_names.is_empty() {
return LIBLO_OK;
Expand Down
17 changes: 17 additions & 0 deletions ffi/tests/ffi.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,22 @@ void test_lo_get_implicitly_active_plugins() {
lo_destroy_handle(handle);
}

void test_lo_get_early_loading_plugins() {
printf("testing lo_get_load_order()...\n");
lo_game_handle handle = create_fo4_handle();

char ** plugins = NULL;
size_t num_plugins = 0;
unsigned int return_code = lo_get_early_loading_plugins(handle, &plugins, &num_plugins);

assert(return_code == 0);
assert(num_plugins == 8);
assert(strcmp(plugins[0], "Fallout4.esm") == 0);
assert(strcmp(plugins[4], "DLCworkshop02.esm") == 0);
lo_free_string_array(plugins, num_plugins);
lo_destroy_handle(handle);
}

void test_lo_get_active_plugins_file_path() {
printf("testing lo_get_active_plugins_file_path()...\n");
lo_game_handle handle = create_handle();
Expand Down Expand Up @@ -315,6 +331,7 @@ int main(void) {
test_lo_is_ambiguous();
test_lo_fix_plugin_lists();
test_lo_get_implicitly_active_plugins();
test_lo_get_early_loading_plugins();
test_lo_get_active_plugins_file_path();
test_lo_set_additional_plugins_directories();

Expand Down
17 changes: 17 additions & 0 deletions ffi/tests/ffi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,22 @@ void test_lo_get_implicitly_active_plugins() {
lo_destroy_handle(handle);
}

void test_lo_get_early_loading_plugins() {
printf("testing lo_get_load_order()...\n");
lo_game_handle handle = create_fo4_handle();

char ** plugins = nullptr;
size_t num_plugins = 0;
unsigned int return_code = lo_get_early_loading_plugins(handle, &plugins, &num_plugins);

assert(return_code == 0);
assert(num_plugins == 8);
assert(strcmp(plugins[0], "Fallout4.esm") == 0);
assert(strcmp(plugins[4], "DLCworkshop02.esm") == 0);
lo_free_string_array(plugins, num_plugins);
lo_destroy_handle(handle);
}

void test_lo_get_active_plugins_file_path() {
printf("testing lo_get_active_plugins_file_path()...\n");
lo_game_handle handle = create_handle();
Expand Down Expand Up @@ -340,6 +356,7 @@ int main(void) {
test_lo_is_ambiguous();
test_lo_fix_plugin_lists();
test_lo_get_implicitly_active_plugins();
test_lo_get_early_loading_plugins();
test_lo_get_active_plugins_file_path();
test_lo_set_additional_plugins_directories();

Expand Down

0 comments on commit 4fdea60

Please sign in to comment.