feat(lib): send and receive private messages

Wire private messaging through the client:

- MessageFactory::build_message_user (code 22) and build_message_acked
  (code 23);
- the incoming MessageUser handler now acknowledges freshly delivered
  messages and forwards them to the client instead of only logging them;
- ClientContext buffers received UserMessages;
- Client::send_private_message and Client::take_private_messages expose the
  feature, and UserMessage (with accessors) is re-exported from the crate.

Verified end to end against soulfind: a_private_message_is_delivered_between_users
logs in two clients and asserts one receives the other's message.
This commit is contained in:
michel
2026-07-19 13:31:30 +02:00
parent f61e02e05c
commit a7372cc88e
6 changed files with 195 additions and 3 deletions
@@ -63,6 +63,23 @@ impl MessageFactory {
.write_string(query)
.clone()
}
/// Build a private message (server code 22) to send to another user.
#[must_use]
pub fn build_message_user(username: &str, message: &str) -> Message {
Message::new()
.write_int32(22)
.write_string(username)
.write_string(message)
.clone()
}
/// Acknowledge a received private message (server code 23) so the server
/// stops re-delivering it.
#[must_use]
pub fn build_message_acked(id: u32) -> Message {
Message::new().write_int32(23).write_int32(id).clone()
}
#[must_use]
pub fn build_set_status_message(status_code: u32) -> Message {
Message::new()
@@ -167,6 +184,25 @@ fn test_build_login_message() {
assert_eq!(expect, message.get_data());
}
#[test]
fn test_build_message_user() {
let message = MessageFactory::build_message_user("bob", "hi");
let expect: Vec<u8> = [
22, 0, 0, 0, // code
3, 0, 0, 0, 98, 111, 98, // username "bob"
2, 0, 0, 0, 104, 105, // message "hi"
]
.to_vec();
assert_eq!(expect, message.get_data());
}
#[test]
fn test_build_message_acked() {
let message = MessageFactory::build_message_acked(7);
let expect: Vec<u8> = [23, 0, 0, 0, 7, 0, 0, 0].to_vec();
assert_eq!(expect, message.get_data());
}
#[test]
fn test_build_file_search_message() {
let message = MessageFactory::build_file_search_message(12, "trance wax");