mirror of
https://codeberg.org/steam-vent/chat.git
synced 2026-06-03 09:54:20 +02:00
initial version
This commit is contained in:
parent
ffba791f3b
commit
5710d6858e
5 changed files with 394 additions and 3 deletions
127
Cargo.lock
generated
127
Cargo.lock
generated
|
|
@ -48,6 +48,56 @@ dependencies = [
|
||||||
"sha-1",
|
"sha-1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstream"
|
||||||
|
version = "0.6.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"anstyle-parse",
|
||||||
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"is_terminal_polyfill",
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle"
|
||||||
|
version = "1.0.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-parse"
|
||||||
|
version = "0.2.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
|
||||||
|
dependencies = [
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-query"
|
||||||
|
version = "1.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.60.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "3.0.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"once_cell_polyfill",
|
||||||
|
"windows-sys 0.60.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "array-init"
|
name = "array-init"
|
||||||
version = "2.1.0"
|
version = "2.1.0"
|
||||||
|
|
@ -310,6 +360,46 @@ dependencies = [
|
||||||
"libloading",
|
"libloading",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "4.5.47"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931"
|
||||||
|
dependencies = [
|
||||||
|
"clap_builder",
|
||||||
|
"clap_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_builder"
|
||||||
|
version = "4.5.47"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"clap_lex",
|
||||||
|
"strsim",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_derive"
|
||||||
|
version = "4.5.47"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "0.7.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cmake"
|
name = "cmake"
|
||||||
version = "0.1.54"
|
version = "0.1.54"
|
||||||
|
|
@ -319,6 +409,12 @@ dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "const-oid"
|
name = "const-oid"
|
||||||
version = "0.9.6"
|
version = "0.9.6"
|
||||||
|
|
@ -628,6 +724,12 @@ version = "0.15.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hmac"
|
name = "hmac"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
|
|
@ -902,6 +1004,12 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is_terminal_polyfill"
|
||||||
|
version = "1.70.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
|
|
@ -1154,6 +1262,12 @@ version = "1.21.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell_polyfill"
|
||||||
|
version = "1.70.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "option-ext"
|
name = "option-ext"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
|
@ -1810,6 +1924,7 @@ dependencies = [
|
||||||
name = "steam-vent-chat"
|
name = "steam-vent-chat"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"clap",
|
||||||
"steam-vent",
|
"steam-vent",
|
||||||
"steamid-ng",
|
"steamid-ng",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
|
@ -1869,6 +1984,12 @@ version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b23da1d8a59091a1e8805d1355f74181f8e13fb7b446c2de17b9fd1bacce6058"
|
checksum = "b23da1d8a59091a1e8805d1355f74181f8e13fb7b446c2de17b9fd1bacce6058"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "subtle"
|
name = "subtle"
|
||||||
version = "2.6.1"
|
version = "2.6.1"
|
||||||
|
|
@ -2246,6 +2367,12 @@ version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8parse"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "valuable"
|
name = "valuable"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ name = "steam-vent-chat"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
authors = ["Robin Appelman <robin@icewind.nl>"]
|
authors = ["Robin Appelman <robin@icewind.nl>"]
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
description = "Steam chat client"
|
description = "Steam chat client library"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://codeberg.org/steam-vent/chat"
|
repository = "https://codeberg.org/steam-vent/chat"
|
||||||
rust-version = "1.85.0"
|
rust-version = "1.85.0"
|
||||||
|
|
@ -11,8 +11,9 @@ rust-version = "1.85.0"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
steam-vent = "0.4.0"
|
steam-vent = "0.4.0"
|
||||||
steamid-ng = "2.0.0"
|
steamid-ng = "2.0.0"
|
||||||
|
tokio-stream = "0.1.17"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio = { version = "1.47.1", features = ["macros", "rt-multi-thread"] }
|
tokio = { version = "1.47.1", features = ["macros", "rt-multi-thread"] }
|
||||||
tokio-stream = "0.1.17"
|
tracing-subscriber = "0.3.20"
|
||||||
tracing-subscriber = "0.3.20"
|
clap = { version = "4.5.47", features = ["derive"] }
|
||||||
30
README.md
Normal file
30
README.md
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# steam-vent-chat
|
||||||
|
|
||||||
|
Steam chat client library.
|
||||||
|
|
||||||
|
A high-level companion library for
|
||||||
|
[steam-vent](https://codeberg.org/steam-vent/steam-vent) for sending and
|
||||||
|
receiving steam chat messages.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let friend_to_bother: steamid_ng::SteamID = get_steam_id();
|
||||||
|
let connection: steam_vent::Connection = get_steam_vent_connection();
|
||||||
|
|
||||||
|
let chat = ChatClient::new(connection);
|
||||||
|
chat.send_message(friend_to_bother, "Hey!".into()).await?;
|
||||||
|
|
||||||
|
let mut events = chat.listen();
|
||||||
|
while let Some(Ok(event)) = events.next().await {
|
||||||
|
match event {
|
||||||
|
ChatEvent::Typing(event) => println!("{} is tying...", event.source.steam64()),
|
||||||
|
ChatEvent::Message(event) => println!("{}: {}", event.source.steam64(), event.message_no_bbcode.unwrap_or(event.message)),
|
||||||
|
ChatEvent::EchoMessage(event) => println!("me: {}", event.message_no_bbcode.unwrap_or(event.message)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
See `examples/chat.rs` for a more complete example or
|
||||||
|
[steam-vent](https://codeberg.org/steam-vent/steam-vent) for more details about
|
||||||
|
getting a connection.
|
||||||
81
examples/chat.rs
Normal file
81
examples/chat.rs
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
use clap::Parser;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::io::stdin;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use steam_vent::auth::{
|
||||||
|
AuthConfirmationHandler, ConsoleAuthConfirmationHandler, DeviceConfirmationHandler,
|
||||||
|
FileGuardDataStore, SharedSecretAuthConfirmationHandler,
|
||||||
|
};
|
||||||
|
use steam_vent::{Connection, ServerList};
|
||||||
|
use steam_vent_chat::{ChatClient, ChatEvent};
|
||||||
|
use steamid_ng::SteamID;
|
||||||
|
use tokio::spawn;
|
||||||
|
use tokio_stream::StreamExt;
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
pub struct Args {
|
||||||
|
/// Username to log in with
|
||||||
|
username: String,
|
||||||
|
/// Password to log in with
|
||||||
|
password: String,
|
||||||
|
/// User to chat with
|
||||||
|
target: String,
|
||||||
|
/// base64 encoded steam-guard secret
|
||||||
|
#[arg(long)]
|
||||||
|
guard_secret: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
tracing_subscriber::fmt::init();
|
||||||
|
let args: Args = Args::parse();
|
||||||
|
|
||||||
|
let target_steam_id = SteamID::from_str(args.target.as_str()).expect("invalid steam id");
|
||||||
|
|
||||||
|
let server_list = ServerList::discover().await?;
|
||||||
|
let connection = match args.guard_secret {
|
||||||
|
Some(secret) => {
|
||||||
|
Connection::login(
|
||||||
|
&server_list,
|
||||||
|
&args.username,
|
||||||
|
&args.password,
|
||||||
|
FileGuardDataStore::user_cache(),
|
||||||
|
SharedSecretAuthConfirmationHandler::new(&secret),
|
||||||
|
)
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
Connection::login(
|
||||||
|
&server_list,
|
||||||
|
&args.username,
|
||||||
|
&args.password,
|
||||||
|
FileGuardDataStore::user_cache(),
|
||||||
|
ConsoleAuthConfirmationHandler::default().or(DeviceConfirmationHandler),
|
||||||
|
)
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let chat = ChatClient::new(connection);
|
||||||
|
|
||||||
|
let mut events = chat.listen();
|
||||||
|
spawn(async move {
|
||||||
|
while let Some(Ok(event)) = events.next().await {
|
||||||
|
match event {
|
||||||
|
ChatEvent::Typing(event) => println!("{} is tying...", event.source.steam64()),
|
||||||
|
ChatEvent::Message(event) => println!("{}: {}", event.source.steam64(), event.message_no_bbcode.unwrap_or(event.message)),
|
||||||
|
ChatEvent::EchoMessage(event) => println!("me: {}", event.message_no_bbcode.unwrap_or(event.message)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut read_buff = String::with_capacity(32);
|
||||||
|
loop {
|
||||||
|
read_buff.clear();
|
||||||
|
stdin().read_line(&mut read_buff).expect("stdin error");
|
||||||
|
let input = read_buff.trim();
|
||||||
|
if !input.is_empty() {
|
||||||
|
chat.send_message(target_steam_id, input.into()).await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
152
src/lib.rs
152
src/lib.rs
|
|
@ -0,0 +1,152 @@
|
||||||
|
use steam_vent::proto::steammessages_friendmessages_steamclient::{CFriendMessages_IncomingMessage_Notification, CFriendMessages_SendMessage_Request};
|
||||||
|
use steam_vent::{Connection, ConnectionTrait, NetworkError};
|
||||||
|
use steamid_ng::SteamID;
|
||||||
|
use tokio_stream::{Stream, StreamExt};
|
||||||
|
|
||||||
|
/// High level wrapper around steam-vent's [`Connection`] for implementing a chat client
|
||||||
|
pub struct ChatClient {
|
||||||
|
connection: Connection,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChatClient {
|
||||||
|
/// Create a chat client from a [`Connection`]
|
||||||
|
pub fn new(connection: Connection) -> Self {
|
||||||
|
ChatClient { connection }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Listen for incoming events
|
||||||
|
pub fn listen(&self) -> impl Stream<Item = Result<ChatEvent, NetworkError>> + 'static {
|
||||||
|
self.connection
|
||||||
|
.on_notification::<CFriendMessages_IncomingMessage_Notification>()
|
||||||
|
.filter_map(|notification| {
|
||||||
|
notification
|
||||||
|
.map(|notification| ChatEvent::try_from(notification).ok())
|
||||||
|
.transpose()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send a chat message to a user
|
||||||
|
pub async fn send_message(&self, target: SteamID, message: String) -> Result<MessageResult, NetworkError> {
|
||||||
|
let req = CFriendMessages_SendMessage_Request {
|
||||||
|
steamid: Some(target.into()),
|
||||||
|
message: Some(message),
|
||||||
|
chat_entry_type: Some(MessageType::Chat as i32),
|
||||||
|
..CFriendMessages_SendMessage_Request::default()
|
||||||
|
};
|
||||||
|
let result = self.connection.service_method(req).await?;
|
||||||
|
|
||||||
|
Ok(MessageResult {
|
||||||
|
server_timestamp: result.server_timestamp() as u64,
|
||||||
|
modified_message: result.modified_message,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Incoming chat event
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ChatEvent {
|
||||||
|
/// Another user sent a message
|
||||||
|
Message(MessageEvent),
|
||||||
|
/// The local user sent a message from another device
|
||||||
|
EchoMessage(MessageEvent),
|
||||||
|
/// Another user is typing
|
||||||
|
Typing(TypingEvent),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<CFriendMessages_IncomingMessage_Notification> for ChatEvent {
|
||||||
|
type Error = ();
|
||||||
|
|
||||||
|
fn try_from(
|
||||||
|
notification: CFriendMessages_IncomingMessage_Notification,
|
||||||
|
) -> Result<Self, Self::Error> {
|
||||||
|
let source = SteamID::try_from(notification.steamid_friend()).unwrap_or_default();
|
||||||
|
let message_type =
|
||||||
|
MessageType::try_from(notification.chat_entry_type()).unwrap_or_default();
|
||||||
|
Ok(match message_type {
|
||||||
|
MessageType::Chat if notification.local_echo() => ChatEvent::Message(MessageEvent {
|
||||||
|
source,
|
||||||
|
server_timestamp: notification.rtime32_server_timestamp() as u64,
|
||||||
|
message: notification.message.unwrap_or_default(),
|
||||||
|
message_no_bbcode: notification.message_no_bbcode,
|
||||||
|
}),
|
||||||
|
MessageType::Chat if notification.local_echo() => ChatEvent::EchoMessage(MessageEvent {
|
||||||
|
source,
|
||||||
|
server_timestamp: notification.rtime32_server_timestamp() as u64,
|
||||||
|
message: notification.message.unwrap_or_default(),
|
||||||
|
message_no_bbcode: notification.message_no_bbcode,
|
||||||
|
}),
|
||||||
|
MessageType::Typing => ChatEvent::Typing(TypingEvent {
|
||||||
|
source,
|
||||||
|
server_timestamp: notification.rtime32_server_timestamp() as u64,
|
||||||
|
}),
|
||||||
|
_ => return Err(()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Incoming chat message
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct MessageEvent {
|
||||||
|
/// SteamID of the sender
|
||||||
|
pub source: SteamID,
|
||||||
|
/// Raw message contents
|
||||||
|
pub message: String,
|
||||||
|
/// Message contents without any bbcode markup
|
||||||
|
pub message_no_bbcode: Option<String>,
|
||||||
|
/// Service side time when the message was sent
|
||||||
|
pub server_timestamp: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Incoming typing event
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct TypingEvent {
|
||||||
|
/// SteamID of the typer
|
||||||
|
pub source: SteamID,
|
||||||
|
/// Service side time when the user was typing
|
||||||
|
pub server_timestamp: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(i32)]
|
||||||
|
#[derive(Default)]
|
||||||
|
enum MessageType {
|
||||||
|
#[default]
|
||||||
|
Invalid,
|
||||||
|
Chat = 1,
|
||||||
|
Typing,
|
||||||
|
GameInvite,
|
||||||
|
Left = 6,
|
||||||
|
Entered,
|
||||||
|
Kicked,
|
||||||
|
Banned,
|
||||||
|
Disconnected,
|
||||||
|
Historical,
|
||||||
|
LinkBlocked = 14,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<i32> for MessageType {
|
||||||
|
type Error = ();
|
||||||
|
|
||||||
|
fn try_from(value: i32) -> Result<Self, Self::Error> {
|
||||||
|
Ok(match value {
|
||||||
|
1 => MessageType::Chat,
|
||||||
|
2 => MessageType::Typing,
|
||||||
|
3 => MessageType::GameInvite,
|
||||||
|
6 => MessageType::Left,
|
||||||
|
7 => MessageType::Entered,
|
||||||
|
8 => MessageType::Kicked,
|
||||||
|
9 => MessageType::Banned,
|
||||||
|
10 => MessageType::Disconnected,
|
||||||
|
11 => MessageType::Historical,
|
||||||
|
14 => MessageType::LinkBlocked,
|
||||||
|
_ => return Err(()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Result of a sent chat message
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct MessageResult {
|
||||||
|
/// Chat message with bbcode added
|
||||||
|
pub modified_message: Option<String>,
|
||||||
|
pub server_timestamp: u64,
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue