Skip to content

Commit

Permalink
Merge pull request #10 from Krappa322/master
Browse files Browse the repository at this point in the history
Basic support for new unofficial extras api version
  • Loading branch information
greaka authored Aug 5, 2022
2 parents 0dbe5b2 + c71ef30 commit 295f458
Show file tree
Hide file tree
Showing 8 changed files with 772 additions and 34 deletions.
78 changes: 70 additions & 8 deletions codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,15 @@ pub fn arcdps_export(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
input.raw_unofficial_extras_squad_update,
input.unofficial_extras_squad_update,
);
let (abstract_extras_chat_message, extras_chat_message) = build_extras_chat_message(
input.raw_unofficial_extras_chat_message,
input.unofficial_extras_chat_message,
);
let abstract_extras_init = build_extras_init(
input.raw_unofficial_extras_init,
input.unofficial_extras_init,
extras_squad_update,
extras_chat_message,
&out_name,
);

Expand Down Expand Up @@ -105,6 +110,7 @@ pub fn arcdps_export(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
#abstract_wnd_filter
#abstract_wnd_nofilter
#abstract_extras_squad_update
#abstract_extras_chat_message
#abstract_extras_init

static EXPORT: ArcDpsExport = #export;
Expand Down Expand Up @@ -202,14 +208,74 @@ fn build_extras_squad_update(
(abstract_wrapper, cb_safe)
}

fn build_extras_chat_message(
raw: Option<Expr>,
safe: Option<Expr>,
) -> (TokenStream, Option<TokenStream>) {
let mut abstract_wrapper = quote! {};
let cb_safe = match (raw, safe) {
(Some(raw), _) => {
let span = syn::Error::new_spanned(&raw, "").span();
Some(quote_spanned!(span => Some(#raw as _) ))
}
(_, Some(safe)) => {
let span = syn::Error::new_spanned(&safe, "").span();
abstract_wrapper = quote_spanned!(span =>
unsafe extern "C" fn abstract_extras_chat_message(msg: *const ::arcdps::RawChatMessageInfo) {
let _ = #safe as ::arcdps::ExtrasChatMessageCallback;
let msg = ::arcdps::helpers::convert_extras_chat_message(&*msg);
#safe(&msg)
});
Some(
quote_spanned!(span => Some(__arcdps_gen_export::abstract_extras_chat_message as _) ),
)
}
_ => None,
};
(abstract_wrapper, cb_safe)
}

fn build_extras_init(
raw: Option<Expr>,
safe: Option<Expr>,
squad_update: Option<TokenStream>,
chat_message: Option<TokenStream>,
name: &LitStr,
) -> TokenStream {
let has_update = squad_update.is_some();
let needs_init = squad_update.is_some() || chat_message.is_some();
let squad_cb = squad_update.unwrap_or(quote! { None });
let chat_cb = chat_message.unwrap_or(quote! { None });

let basic_init = quote!(
if addon.api_version != 2 {
return;
}
if addon.max_info_version < 1 {
return;
}

if addon.max_info_version == 1 {
let sub: *mut ::arcdps::RawExtrasSubscriberInfoHeader = sub;
let sub = &mut *(sub as *mut ::arcdps::RawExtrasSubscriberInfoV1);

sub.info_version = 1;
sub.subscriber_name = #name.as_ptr();
sub.squad_update_callback = #squad_cb;
sub.language_changed_callback = None;
sub.key_bind_changed_callback = None;
} else {
let sub: *mut ::arcdps::RawExtrasSubscriberInfoHeader = sub;
let sub = &mut *(sub as *mut ::arcdps::RawExtrasSubscriberInfoV2);

sub.info_version = 2;
sub.subscriber_name = #name.as_ptr();
sub.squad_update_callback = #squad_cb;
sub.language_changed_callback = None;
sub.key_bind_changed_callback = None;
sub.chat_message_callback = #chat_cb;
}
);

let abstract_wrapper = match (raw, safe) {
(Some(raw), _) => {
let span = syn::Error::new_spanned(&raw, "").span();
Expand All @@ -222,8 +288,7 @@ fn build_extras_init(
(_, Some(safe)) => {
let span = syn::Error::new_spanned(&safe, "").span();
quote_spanned!(span =>
sub.subscriber_name = #name.as_ptr();
sub.squad_update_callback = #squad_cb;
#basic_init

let _ = #safe as ::arcdps::ExtrasInitFunc;
use ::arcdps::helpers::get_str_from_pc_char as pc;
Expand All @@ -233,17 +298,14 @@ fn build_extras_init(
#safe(user, version)
)
}
_ if has_update => quote! {
sub.subscriber_name = #name.as_ptr();
sub.squad_update_callback = #squad_cb;
},
_ if needs_init => basic_init,
_ => return quote! {},
};
use syn::spanned::Spanned;
quote_spanned!(abstract_wrapper.span() =>
#[no_mangle]
unsafe extern "system" fn arcdps_unofficial_extras_subscriber_init(
addon: &::arcdps::RawExtrasAddonInfo, sub: &mut ::arcdps::RawExtrasSubscriberInfo) {
addon: &::arcdps::RawExtrasAddonInfo, sub: &mut ::arcdps::RawExtrasSubscriberInfoHeader) {

#abstract_wrapper
}
Expand Down
7 changes: 6 additions & 1 deletion codegen/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub(crate) struct ArcDpsGen {
pub raw_combat_local: Option<Expr>,
pub raw_unofficial_extras_init: Option<Expr>,
pub raw_unofficial_extras_squad_update: Option<Expr>,
pub raw_unofficial_extras_chat_message: Option<Expr>,
pub wnd_nofilter: Option<Expr>,
pub combat: Option<Expr>,
pub imgui: Option<Expr>,
Expand All @@ -62,6 +63,7 @@ pub(crate) struct ArcDpsGen {
pub options_windows: Option<Expr>,
pub unofficial_extras_init: Option<Expr>,
pub unofficial_extras_squad_update: Option<Expr>,
pub unofficial_extras_chat_message: Option<Expr>,
}

impl syn::parse::Parse for ArcDpsGen {
Expand All @@ -84,6 +86,7 @@ impl syn::parse::Parse for ArcDpsGen {
wnd_nofilter: None,
unofficial_extras_init: None,
unofficial_extras_squad_update: None,
unofficial_extras_chat_message: None,

raw_combat: None,
raw_combat_local: None,
Expand All @@ -94,6 +97,7 @@ impl syn::parse::Parse for ArcDpsGen {
raw_wnd_nofilter: None,
raw_unofficial_extras_init: None,
raw_unofficial_extras_squad_update: None,
raw_unofficial_extras_chat_message: None,
};

let mut sig_done = false;
Expand Down Expand Up @@ -144,7 +148,8 @@ impl syn::parse::Parse for ArcDpsGen {
wnd_filter,
wnd_nofilter,
unofficial_extras_init,
unofficial_extras_squad_update
unofficial_extras_squad_update,
unofficial_extras_chat_message
)
}
};
Expand Down
3 changes: 2 additions & 1 deletion core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ license = "MIT/Apache-2.0"

[dependencies]
once_cell = "1.4.1"
chrono = "0.4.19"

[dependencies.arcdps_codegen]
version = "0.7.1"
#path = "../codegen"
path = "../codegen"

[dependencies.imgui]
package = "arcdps-imgui"
Expand Down
29 changes: 29 additions & 0 deletions core/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ pub unsafe fn get_str_from_pc_char(src: PCCHAR) -> Option<&'static str> {
}
}

/// Converts a pointer and length into a &str with a lifetime. The pointer must not be null
#[inline(always)]
pub unsafe fn get_str_from_ptr_and_len(src: *const u8, len: u64) -> &'static str {
let buff = std::slice::from_raw_parts(src, len as usize);
std::str::from_utf8_unchecked(buff)
}

/// A helper function to convert raw arguments to safe abstractions
#[inline(always)]
pub fn convert_extras_user(user: &RawUserInfo) -> UserInfo {
Expand All @@ -50,6 +57,28 @@ pub fn convert_extras_user(user: &RawUserInfo) -> UserInfo {
}
}

#[inline(always)]
pub fn convert_extras_chat_message(msg: &RawChatMessageInfo) -> ChatMessageInfo {
let timestamp = unsafe { get_str_from_ptr_and_len(msg.timestamp, msg.timestamp_length) };
let timestamp = chrono::DateTime::parse_from_rfc3339(timestamp).unwrap();

let account_name = unsafe { get_str_from_ptr_and_len(msg.account_name, msg.account_name_length) };
let character_name = unsafe { get_str_from_ptr_and_len(msg.character_name, msg.character_name_length) };
let text = unsafe { get_str_from_ptr_and_len(msg.text, msg.text_length) };
let is_broadcast = (msg.is_broadcast & 0x01) != 0;

ChatMessageInfo {
channel_id: msg.channel_id,
channel_type: msg.channel_type,
subgroup: msg.subgroup,
is_broadcast,
timestamp,
account_name: account_name.trim_start_matches(':'),
character_name,
text,
}
}

pub struct CombatEventArgs<'a> {
pub ev: Option<&'a CombatEvent>,
pub src: Option<Agent<'a>>,
Expand Down
2 changes: 2 additions & 0 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub struct SupportedFields {
pub raw_combat_local: Option<RawCombatCallback>,
pub raw_unofficial_extras_init: Option<RawExtrasSubscriberInitSignature>,
pub raw_unofficial_extras_squad_update: Option<RawSquadUpdateCallbackSignature>,
pub raw_unofficial_extras_chat_message: Option<RawChatMessageCallbackSignature>,
pub wnd_nofilter: Option<WndProcCallback>,
pub combat: Option<CombatCallback>,
pub imgui: Option<ImguiCallback>,
Expand All @@ -60,4 +61,5 @@ pub struct SupportedFields {
pub options_windows: Option<OptionsWindowsCallback>,
pub unofficial_extras_init: Option<ExtrasInitFunc>,
pub unofficial_extras_squad_update: Option<ExtrasSquadUpdateCallback>,
pub unofficial_extras_chat_message: Option<ExtrasChatMessageCallback>,
}
1 change: 1 addition & 0 deletions core/src/unofficial_extras/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub(crate) mod raw_structs_keybinds;
pub(crate) mod raw_structs;
Loading

0 comments on commit 295f458

Please sign in to comment.