arcdps\extras\message/
npc.rs

1use crate::util::str_from_cstr_len;
2use std::ffi::c_char;
3
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6
7/// 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.
24    character_name: *const c_char,
25    character_name_length: u64,
26
27    /// 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.
30    text: *const c_char,
31    text_length: u64,
32
33    /// Time since epoch in nanoseconds.
34    ///
35    /// This can be used to sort messages, when they are out of order.
36    pub timestamp: u64,
37}
38
39impl NpcMessage {
40    /// Converts the message to its owned counterpart.
41    #[inline]
42    pub fn to_owned(&self) -> NpcMessageOwned {
43        self.into()
44    }
45
46    /// Returns the character name of the player that sent the message.
47    #[inline]
48    pub fn character_name(&self) -> &str {
49        unsafe { str_from_cstr_len(self.character_name, self.character_name_length) }
50    }
51
52    /// Returns the character name as raw pointer.
53    #[inline]
54    pub fn character_name_ptr(&self) -> *const c_char {
55        self.character_name
56    }
57
58    /// Returns the account name length.
59    #[inline]
60    pub fn character_name_len(&self) -> usize {
61        self.character_name_length as _
62    }
63
64    /// Returns the text content of the message.
65    #[inline]
66    pub fn text(&self) -> &str {
67        unsafe { str_from_cstr_len(self.text, self.text_length) }
68    }
69
70    /// Returns the text as raw pointer.
71    #[inline]
72    pub fn text_ptr(&self) -> *const c_char {
73        self.text
74    }
75
76    /// Returns the account name length.
77    #[inline]
78    pub fn text_len(&self) -> usize {
79        self.text_length as _
80    }
81}
82
83/// [`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.
88    pub character_name: String,
89
90    /// Content of the message.
91    pub text: String,
92}
93
94impl From<NpcMessage> for NpcMessageOwned {
95    #[inline]
96    fn from(msg: NpcMessage) -> Self {
97        (&msg).into()
98    }
99}
100
101impl From<&NpcMessage> for NpcMessageOwned {
102    #[inline]
103    fn from(msg: &NpcMessage) -> Self {
104        Self {
105            character_name: msg.character_name().to_owned(),
106            text: msg.text().to_owned(),
107        }
108    }
109}