Skip to main content

unofficial_extras/
lib.rs

1//! Bindings for [ArcDPS Unofficial Extras](https://github.com/Krappa322/arcdps_unofficial_extras_releases).
2
3pub mod callbacks;
4pub mod keybinds;
5pub mod language;
6pub mod message;
7pub mod user;
8
9mod util;
10mod version;
11
12pub use keybinds::{Control, Key, KeyCode, Keybind, KeybindChange, MouseCode};
13pub use language::Language;
14pub use message::{
15    ChannelType, Message, NpcMessage, NpcMessageOwned, SquadMessage, SquadMessageOwned,
16};
17pub use user::{UserInfo, UserInfoIter, UserInfoOwned, UserRole};
18pub use util::strip_account_prefix;
19pub use version::ExtrasVersion;
20
21use callbacks::{
22    RawExtrasChatMessageCallback, RawExtrasKeybindChangedCallback,
23    RawExtrasLanguageChangedCallback, RawExtrasSquadChatMessageCallback,
24    RawExtrasSquadUpdateCallback,
25};
26use std::ffi::c_char;
27use util::str_from_cstr;
28use windows::Win32::Foundation::HMODULE;
29
30#[cfg(feature = "serde")]
31use serde::{Deserialize, Serialize};
32
33/// Information about the [Unofficial Extras](https://github.com/Krappa322/arcdps_unofficial_extras_releases) addon.
34#[derive(Debug, Clone)]
35#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
36pub struct ExtrasAddonInfo {
37    /// Version of the API.
38    ///
39    /// Gets incremented whenever a function signature or behavior changes in a breaking way.
40    pub api_version: u32,
41
42    /// Highest known version of the [`ExtrasSubscriberInfo`] struct.
43    ///
44    /// Also determines the size of the subscriber info buffer in the init call.
45    /// The buffer is only guaranteed to have enough space for known [`ExtrasSubscriberInfo`] versions.
46    pub max_info_version: u32,
47
48    /// String version of the Unofficial Extras addon.
49    ///
50    /// Gets changed on every release.
51    pub string_version: Option<&'static str>,
52}
53
54impl ExtrasAddonInfo {
55    /// Returns the corresponding [`ExtrasVersion`].
56    #[inline]
57    pub fn version(&self) -> ExtrasVersion {
58        ExtrasVersion::new(self.api_version, self.max_info_version)
59    }
60}
61
62impl From<RawExtrasAddonInfo> for ExtrasAddonInfo {
63    fn from(raw: RawExtrasAddonInfo) -> Self {
64        Self {
65            api_version: raw.api_version,
66            max_info_version: raw.max_info_version,
67            string_version: unsafe { str_from_cstr(raw.string_version) },
68        }
69    }
70}
71
72#[derive(Debug, Clone)]
73#[repr(C)]
74pub struct RawExtrasAddonInfo {
75    /// Version of the API.
76    ///
77    /// Gets incremented whenever a function signature or behavior changes in a breaking way.
78    pub api_version: u32,
79
80    /// Highest known version of the [`ExtrasSubscriberInfo`] struct.
81    ///
82    /// Also determines the size of the subscriber info buffer in the init call.
83    /// The buffer is only guaranteed to have enough space for known [`ExtrasSubscriberInfo`] versions.
84    pub max_info_version: u32,
85
86    /// String version of the Unofficial Extras addon.
87    ///
88    /// Gets changed on every release.
89    /// The string is valid for the entire lifetime of the Unofficial Extras DLL.
90    pub string_version: *const c_char,
91
92    /// Account name of the logged-in player, including leading `':'`.
93    ///
94    /// The string is only valid for the duration of the init call.
95    pub self_account_name: *const c_char,
96
97    /// The handle to the Unofficial Extras module.
98    ///
99    /// Use this to call the exports of the DLL.
100    pub extras_handle: HMODULE,
101}
102
103impl RawExtrasAddonInfo {
104    /// Returns the corresponding [`ExtrasVersion`].
105    #[inline]
106    pub fn version(&self) -> ExtrasVersion {
107        ExtrasVersion::new(self.api_version, self.max_info_version)
108    }
109}
110
111/// Subscriber header shared across different versions.
112#[derive(Debug)]
113#[repr(C)]
114pub struct ExtrasSubscriberInfoHeader {
115    /// The version of the following info struct.
116    /// This has to be set to the version you want to use.
117    pub info_version: u32,
118
119    /// Unused padding.
120    pub unused1: u32,
121}
122
123/// Information about a subscriber to updates from Unofficial Extras.
124#[derive(Debug)]
125#[repr(C)]
126pub struct ExtrasSubscriberInfo {
127    /// Header shared across different versions.
128    pub header: ExtrasSubscriberInfoHeader,
129
130    /// Name of the addon subscribing to the changes.
131    ///
132    /// Must be valid for the lifetime of the subscribing addon.
133    /// Set to `nullptr` if initialization fails.
134    pub subscriber_name: *const c_char,
135
136    /// Called whenever anything in the squad changes.
137    ///
138    /// Only the users that changed are sent.
139    /// If a user is removed from the squad, it will be sent with `role` set to [`UserRole::None`]
140    pub squad_update_callback: Option<RawExtrasSquadUpdateCallback>,
141
142    /// Called whenever the language is changed.
143    ///
144    /// Either by Changing it in the UI or by pressing the Right Ctrl (default) key.
145    /// Will also be called directly after initialization, with the current language, to get the startup language.
146    pub language_changed_callback: Option<RawExtrasLanguageChangedCallback>,
147
148    /// Called whenever a keybind is changed.
149    ///
150    /// By changing it in the ingame UI, by pressing the translation shortcut or with the Presets feature of this plugin.
151    /// It is called for every keybind separately.
152    ///
153    /// After initialization this is called for every current keybind that exists.
154    /// If you want to get a single keybind, at any time you want, call the exported function.
155    pub keybind_changed_callback: Option<RawExtrasKeybindChangedCallback>,
156
157    /// Called whenever a chat message is sent in your party/squad.
158    pub squad_chat_message_callback: Option<RawExtrasSquadChatMessageCallback>,
159
160    /// Called on different chat messages.
161    pub chat_message_callback: Option<RawExtrasChatMessageCallback>,
162}