Skip to main content

arcdps\extras/
mod.rs

1//! [Unofficial Extras](https://github.com/Krappa322/arcdps_unofficial_extras_releases) support.
2//!
3//! *Requires the `"extras"` feature.*
4
5mod globals;
6
7pub mod exports;
8
9use crate::{extras::globals::ExtrasGlobals, util::str_from_cstr};
10use std::ffi::c_char;
11use unofficial_extras::callbacks::{
12    RawExtrasChatMessageCallback, RawExtrasKeybindChangedCallback,
13    RawExtrasLanguageChangedCallback, RawExtrasSquadChatMessageCallback,
14    RawExtrasSquadUpdateCallback,
15};
16
17pub use unofficial_extras::*;
18
19/// Subscribes to unofficial extras callbacks after checking for compatibility.
20///
21/// Unsupported callbacks will be skipped.
22///
23/// # Safety
24/// Info needs to point to a valid to interpret as subscriber infos with minimum version of [`ExtrasVersion::MIN_SUB_INFO`].
25/// It is passed as pointer to prevent UB by creating a reference to the wrong type.
26///
27/// Name needs to be null-terminated.
28#[allow(clippy::too_many_arguments)]
29pub unsafe fn subscribe(
30    sub: *mut ExtrasSubscriberInfo,
31    extras_addon: &RawExtrasAddonInfo,
32    name: &'static str,
33    squad_update: Option<RawExtrasSquadUpdateCallback>,
34    language_changed: Option<RawExtrasLanguageChangedCallback>,
35    keybind_changed: Option<RawExtrasKeybindChangedCallback>,
36    squad_chat_message: Option<RawExtrasSquadChatMessageCallback>,
37    chat_message: Option<RawExtrasChatMessageCallback>,
38) {
39    let version = extras_addon.version();
40    if let Some(sub_info_version) = version.get_version_to_use() {
41        unsafe {
42            // initialize globals
43            ExtrasGlobals::init(
44                extras_addon.extras_handle,
45                str_from_cstr(extras_addon.string_version),
46            );
47
48            (*sub).header.info_version = sub_info_version;
49            (*sub).subscriber_name = name.as_ptr() as *const c_char;
50            (*sub).squad_update_callback = squad_update;
51            (*sub).language_changed_callback = language_changed;
52            (*sub).keybind_changed_callback = keybind_changed;
53
54            // only attempt to write additional callbacks if supported
55            if version.supports_squad_chat_message() {
56                (*sub).squad_chat_message_callback = squad_chat_message;
57            }
58            if version.supports_chat_message2() {
59                (*sub).chat_message_callback = chat_message;
60            }
61        }
62    }
63}