1use crate::util::str_from_cstr_len;
2use std::ffi::c_char;
34#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
67/// An NPC chat message.
8///
9/// Strings are available for the duration of the call.
10/// If you need it for longer than that, consider converting it to [`NpcMessageOwned`].
11///
12/// ```no_run
13/// # use arcdps::extras::{NpcMessage, NpcMessageOwned};
14/// # let message: &NpcMessage = todo!();
15/// let owned = message.to_owned();
16/// let owned: NpcMessageOwned = message.into();
17/// ```
18#[derive(Debug, Clone)]
19#[repr(C)]
20pub struct NpcMessage {
21/// Null terminated character name of the NPC that sent the message.
22 ///
23 /// The string is only valid for the duration of the call.
24character_name: *const c_char,
25 character_name_length: u64,
2627/// Null terminated string containing the content of the message that was sent.
28 ///
29 /// The string is only valid for the duration of the call.
30text: *const c_char,
31 text_length: u64,
3233/// Time since epoch in nanoseconds.
34 ///
35 /// This can be used to sort messages, when they are out of order.
36pub timestamp: u64,
37}
3839impl NpcMessage {
40/// Converts the message to its owned counterpart.
41#[inline]
42pub fn to_owned(&self) -> NpcMessageOwned {
43self.into()
44 }
4546/// Returns the character name of the player that sent the message.
47#[inline]
48pub fn character_name(&self) -> &str {
49unsafe { str_from_cstr_len(self.character_name, self.character_name_length) }
50 }
5152/// Returns the character name as raw pointer.
53#[inline]
54pub fn character_name_ptr(&self) -> *const c_char {
55self.character_name
56 }
5758/// Returns the account name length.
59#[inline]
60pub fn character_name_len(&self) -> usize {
61self.character_name_length as _
62}
6364/// Returns the text content of the message.
65#[inline]
66pub fn text(&self) -> &str {
67unsafe { str_from_cstr_len(self.text, self.text_length) }
68 }
6970/// Returns the text as raw pointer.
71#[inline]
72pub fn text_ptr(&self) -> *const c_char {
73self.text
74 }
7576/// Returns the account name length.
77#[inline]
78pub fn text_len(&self) -> usize {
79self.text_length as _
80}
81}
8283/// [`NpcMessage`] with owned [`String`] fields.
84#[derive(Debug, Clone)]
85#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
86pub struct NpcMessageOwned {
87/// Character name of the NPC that sent the message.
88pub character_name: String,
8990/// Content of the message.
91pub text: String,
92}
9394impl From<NpcMessage> for NpcMessageOwned {
95#[inline]
96fn from(msg: NpcMessage) -> Self {
97 (&msg).into()
98 }
99}
100101impl From<&NpcMessage> for NpcMessageOwned {
102#[inline]
103fn from(msg: &NpcMessage) -> Self {
104Self {
105 character_name: msg.character_name().to_owned(),
106 text: msg.text().to_owned(),
107 }
108 }
109}