From 2ff5e4fd9d50d10e1a0b77fb62863214e03e055a Mon Sep 17 00:00:00 2001 From: kozabrada123 <“kozabrada123@users.noreply.github.com”> Date: Sun, 14 May 2023 14:03:18 +0200 Subject: [PATCH] Add Readies to Events, try to fix msg_create error --- src/api/types.rs | 116 +++++++++++++++++++++++++++++++++++++++++------ src/gateway.rs | 26 +++++++---- 2 files changed, 118 insertions(+), 24 deletions(-) diff --git a/src/api/types.rs b/src/api/types.rs index ae6d8ba..3ca9f9d 100644 --- a/src/api/types.rs +++ b/src/api/types.rs @@ -9,7 +9,7 @@ use std::collections::HashMap; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_json::from_value; -use serde_aux::field_attributes::{deserialize_number_from_string}; +use serde_aux::field_attributes::deserialize_option_number_from_string; use crate::{api::limits::Limits, instance::Instance}; @@ -290,7 +290,7 @@ pub struct RoleObject { //pub tags: Option } -#[derive(Serialize, Deserialize, Debug, Default, Clone)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq, Hash)] pub struct UserObject { pub id: String, username: String, @@ -305,18 +305,18 @@ pub struct UserObject { email: Option, /// This field comes as either a string or a number as a string /// So we need to account for that - #[serde(deserialize_with = "deserialize_number_from_string")] - flags: i32, + #[serde(deserialize_with = "deserialize_option_number_from_string")] + flags: Option, premium_since: Option, - premium_type: i8, + premium_type: Option, pronouns: Option, - public_flags: Option, + public_flags: Option, banner: Option, - bio: String, + bio: Option, theme_colors: Option>, phone: Option, - nsfw_allowed: bool, - premium: bool, + nsfw_allowed: Option, + premium: Option, purchased_flags: Option, premium_usage_flags: Option, disabled: Option, @@ -398,12 +398,43 @@ pub struct Message { } #[derive(Debug, Serialize, Deserialize, Default)] +/// See https://discord.com/developers/docs/topics/gateway-events#message-create pub struct MessageCreate { #[serde(flatten)] message: Message, guild_id: Option, member: Option, - mentions: Vec<(UserObject, GuildMember)>, // Not sure if this is correct: https://discord.com/developers/docs/topics/gateway-events#message-create + mentions: Vec, +} + +#[derive(Debug, Serialize, Deserialize, Default)] +/// See https://discord.com/developers/docs/topics/gateway-events#message-create-message-create-extra-fields +pub struct MessageCreateUser { + pub id: String, + username: String, + discriminator: String, + avatar: Option, + bot: Option, + system: Option, + mfa_enabled: Option, + accent_color: Option, + locale: Option, + verified: Option, + email: Option, + premium_since: Option, + premium_type: Option, + pronouns: Option, + public_flags: Option, + banner: Option, + bio: Option, + theme_colors: Option>, + phone: Option, + nsfw_allowed: Option, + premium: Option, + purchased_flags: Option, + premium_usage_flags: Option, + disabled: Option, + member: GuildMember } impl WebSocketEvent for MessageCreate {} @@ -700,17 +731,17 @@ pub struct MessageInteraction { pub member: Option, } -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, Default)] pub struct GuildMember { pub user: Option, pub nick: Option, pub avatar: Option, - pub roles: Vec, + pub roles: Vec, pub joined_at: String, pub premium_since: Option, pub deaf: bool, pub mute: bool, - pub flags: i32, + pub flags: Option, pub pending: Option, pub permissions: Option, pub communication_disabled_until: Option, @@ -924,7 +955,15 @@ pub struct GatewayIdentifyPayload { pub shard: Option>, #[serde(skip_serializing_if = "Option::is_none")] pub presence: Option, - pub intents: i32, + pub capabilities: i32, +} + +impl GatewayIdentifyPayload { + pub fn default_w_client_capabilities() -> Self { + let mut def = Self::default(); + def.capabilities = 8189; // Default capabilities for a client + def + } } impl WebSocketEvent for GatewayIdentifyPayload {} @@ -1031,6 +1070,55 @@ pub struct GatewayReady { impl WebSocketEvent for GatewayReady {} +#[derive(Debug, Deserialize, Serialize, Default)] +/// Officially Undocumented +/// Sent after the READY event when a client has capabilities +/// {"t":"READY_SUPPLEMENTAL","s":2,"op":0,"d":{"merged_presences":{"guilds":[[{"user_id":"463640391196082177","status":"online","game":null,"client_status":{"web":"online"},"activities":[]}]],"friends":[{"user_id":"463640391196082177","status":"online","last_modified":1684053508443,"client_status":{"web":"online"},"activities":[]}]},"merged_members":[[{"user_id":"463640391196082177","roles":[],"premium_since":null,"pending":false,"nick":"pog","mute":false,"joined_at":"2021-05-30T15:24:08.763000+00:00","flags":0,"deaf":false,"communication_disabled_until":null,"avatar":null}]],"lazy_private_channels":[],"guilds":[{"voice_states":[],"id":"848582562217590824","embedded_activities":[]}],"disclose":["pomelo"]}} +pub struct GatewayReadySupplemental { + pub merged_presences: MergedPresences, + pub merged_members: Vec>, + // ? + pub lazy_private_channels: Vec, + pub guilds: Vec, + // ? pomelo + pub disclose: Vec, +} + +impl WebSocketEvent for GatewayReadySupplemental {} + +#[derive(Debug, Deserialize, Serialize, Default)] +pub struct MergedPresences { + pub guilds: Vec>, + pub friends: Vec +} + +#[derive(Debug, Deserialize, Serialize, Default)] +pub struct MergedPresenceFriend { + pub user_id: String, + pub status: String, + /// Looks like ms?? + pub last_modified: u128, + pub client_status: ClientStatusObject, + pub activities: Vec +} + +#[derive(Debug, Deserialize, Serialize, Default)] +pub struct MergedPresenceGuild { + pub user_id: String, + pub status: String, + // ? + pub game: Option, + pub client_status: ClientStatusObject, + pub activities: Vec +} + +#[derive(Debug, Deserialize, Serialize, Default)] +pub struct SupplimentalGuild { + pub voice_states: Vec, + pub id: String, + pub embedded_activities: Vec +} + #[derive(Debug, Deserialize, Serialize, Default)] /// See https://discord.com/developers/docs/topics/gateway-events#request-guild-members-request-guild-members-structure pub struct GatewayRequestGuildMembers { diff --git a/src/gateway.rs b/src/gateway.rs index 6edf86f..a75a77d 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -187,11 +187,7 @@ impl Gateway { return; } - let msg_string = msg.to_string(); - - println!("{}", &msg_string); - - let gateway_payload: GatewayPayload = serde_json::from_str(&msg_string).unwrap(); + let gateway_payload: GatewayPayload = serde_json::from_str(msg.to_text().unwrap()).unwrap(); // See https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-opcodes match gateway_payload.op { @@ -205,8 +201,12 @@ impl Gateway { // See https://discord.com/developers/docs/topics/gateway-events#receive-events match gateway_payload_t.as_str() { "READY" => { - let data: GatewayReady = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); - println!("{:?}", data); + let new_data: GatewayReady = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); + self.events.lock().await.ready.ready.update_data(new_data).await; + }, + "READY_SUPPLEMENTAL" => { + let new_data: GatewayReadySupplemental = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); + self.events.lock().await.ready.ready_supplimental.update_data(new_data).await; } "RESUMED" => {} "APPLICATION_COMMAND_PERMISSIONS_UPDATE" => {} @@ -267,7 +267,7 @@ impl Gateway { self.events.lock().await.thread.members_update.update_data(new_data).await; } "GUILD_CREATE" => { - let new_data: GuildCreate = serde_json::from_str(&msg_string).unwrap(); + let new_data: GuildCreate = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); self.events.lock().await.guild.create.update_data(new_data).await; } "GUILD_UPDATE" => { @@ -361,8 +361,7 @@ impl Gateway { self.events.lock().await.user.typing_start_event.update_data(new_data).await; } "USER_UPDATE" => { - let user: UserObject = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); - let new_data = UserUpdate {user}; + let new_data: UserUpdate = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); self.events.lock().await.user.update.update_data(new_data).await; } "VOICE_STATE_UPDATE" => {} @@ -554,6 +553,7 @@ mod events { use super::*; #[derive(Default, Debug)] pub struct Events { + pub ready: Ready, pub message: Message, pub user: User, pub channel: Channel, @@ -564,6 +564,12 @@ mod events { pub gateway_resume: GatewayEvent, } + #[derive(Default, Debug)] + pub struct Ready { + pub ready: GatewayEvent, + pub ready_supplimental: GatewayEvent + } + #[derive(Default, Debug)] pub struct Message { pub create: GatewayEvent,