diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/client/gateway/shard.rs | 25 | ||||
| -rw-r--r-- | src/ext/cache/mod.rs | 4 | ||||
| -rw-r--r-- | src/model/guild/guild_id.rs | 43 | ||||
| -rw-r--r-- | src/model/guild/mod.rs | 42 | ||||
| -rw-r--r-- | src/model/guild/partial_guild.rs | 42 | ||||
| -rw-r--r-- | src/model/invite.rs | 44 | ||||
| -rw-r--r-- | src/utils/mod.rs | 18 |
7 files changed, 217 insertions, 1 deletions
diff --git a/src/client/gateway/shard.rs b/src/client/gateway/shard.rs index 4706397..d26cc01 100644 --- a/src/client/gateway/shard.rs +++ b/src/client/gateway/shard.rs @@ -18,6 +18,7 @@ use ::internal::prelude::*; use ::internal::ws_impl::{ReceiverExt, SenderExt}; use ::model::event::{Event, GatewayEvent, ReadyEvent}; use ::model::{Game, GuildId, OnlineStatus}; +use ::utils; #[cfg(feature="cache")] use ::client::CACHE; @@ -482,7 +483,7 @@ impl Shard { Ok(()) } - /// Requests that one or multiple [`Guild`]s be synced. + /// Requests that one or multiple [`Guild`]s be chunked. /// /// This will ask Discord to start sending member chunks for large guilds /// (250 members+). If a guild is over 250 members, then a full member list @@ -507,6 +508,28 @@ impl Shard { let _ = self.keepalive_channel.send(GatewayStatus::SendMessage(msg)); } + /// Calculates the number of guilds that the shard is responsible for. + /// + /// If sharding is not being used (i.e. 1 shard), then the total number of + /// guilds in the [`Cache`] will be used. + /// + /// **Note**: Requires the `cache` feature be enabled. + /// + /// [`Cache`]: ../../ext/cache/struct.Cache.html + #[cfg(feature="cache")] + pub fn guilds_handled(&self) -> u16 { + let cache = CACHE.read().unwrap(); + + if let Some((shard_id, shard_count)) = self.shard_info.map(|s| (s[0], s[1])) { + cache.guilds + .keys() + .filter(|guild_id| utils::shard_id(guild_id.0, shard_count) == shard_id) + .count() as u16 + } else { + cache.guilds.len() as u16 + } + } + #[allow(unused_variables)] fn handle_dispatch(&mut self, event: &Event) { #[cfg(feature="voice")] diff --git a/src/ext/cache/mod.rs b/src/ext/cache/mod.rs index 84c21a7..d3479da 100644 --- a/src/ext/cache/mod.rs +++ b/src/ext/cache/mod.rs @@ -139,6 +139,8 @@ pub struct Cache { /// A map of direct message channels that the current user has open with /// other users. pub private_channels: HashMap<ChannelId, Arc<RwLock<PrivateChannel>>>, + /// The total number of shards being used by the bot. + pub shard_count: u64, /// A list of guilds which are "unavailable". Refer to the documentation for /// [`Event::GuildUnavailable`] for more information on when this can occur. /// @@ -877,6 +879,7 @@ impl Cache { } self.presences.extend(ready.presences); + self.shard_count = ready.shard.map_or(1, |s| s[1]); self.user = ready.user; } @@ -938,6 +941,7 @@ impl Default for Cache { notes: HashMap::default(), presences: HashMap::default(), private_channels: HashMap::default(), + shard_count: 1, unavailable_guilds: HashSet::default(), user: CurrentUser { avatar: None, diff --git a/src/model/guild/guild_id.rs b/src/model/guild/guild_id.rs index 1ef9a32..e5a0686 100644 --- a/src/model/guild/guild_id.rs +++ b/src/model/guild/guild_id.rs @@ -420,6 +420,49 @@ impl GuildId { rest::edit_member(self.0, user_id.into().0, &map) } + /// Returns the Id of the shard associated with the guild. + /// + /// When the cache is enabled this will automatically retrieve the total + /// number of shards. + /// + /// **Note**: When the cache is enabled, this function unlocks the cache to + /// retrieve the total number of shards in use. If you already have the + /// total, consider using [`utils::shard_id`]. + /// + /// [`utils::shard_id`]: ../utils/fn.shard_id.html + #[cfg(feature="cache")] + #[inline] + pub fn shard_id(&self) -> u64 { + ::utils::shard_id(self.0, CACHE.read().unwrap().shard_count) + } + + /// Returns the Id of the shard associated with the guild. + /// + /// When the cache is enabled this will automatically retrieve the total + /// number of shards. + /// + /// When the cache is not enabled, the total number of shards being used + /// will need to be passed. + /// + /// # Examples + /// + /// Retrieve the Id of the shard for a guild with Id `81384788765712384`, + /// using 17 shards: + /// + /// ```rust + /// use serenity::model::GuildId; + /// use serenity::utils; + /// + /// let guild_id = GuildId(81384788765712384); + /// + /// assert_eq!(guild_id.shard_id(17), 7); + /// ``` + #[cfg(not(feature="cache"))] + #[inline] + pub fn shard_id(&self, shard_count: u64) -> u64 { + ::utils::shard_id(self.0, shard_count) + } + /// Starts an integration sync for the given integration Id. /// /// Requires the [Manage Guild] permission. diff --git a/src/model/guild/mod.rs b/src/model/guild/mod.rs index 7299f84..bbf8ecc 100644 --- a/src/model/guild/mod.rs +++ b/src/model/guild/mod.rs @@ -887,6 +887,48 @@ impl Guild { permissions } + /// Returns the Id of the shard associated with the guild. + /// + /// When the cache is enabled this will automatically retrieve the total + /// number of shards. + /// + /// **Note**: When the cache is enabled, this function unlocks the cache to + /// retrieve the total number of shards in use. If you already have the + /// total, consider using [`utils::shard_id`]. + /// + /// [`utils::shard_id`]: ../utils/fn.shard_id.html + #[cfg(feature="cache")] + #[inline] + pub fn shard_id(&self) -> u64 { + self.id.shard_id() + } + + /// Returns the Id of the shard associated with the guild. + /// + /// When the cache is enabled this will automatically retrieve the total + /// number of shards. + /// + /// When the cache is not enabled, the total number of shards being used + /// will need to be passed. + /// + /// # Examples + /// + /// Retrieve the Id of the shard for a guild with Id `81384788765712384`, + /// using 17 shards: + /// + /// ```rust,ignore + /// use serenity::utils; + /// + /// // assumes a `guild` has already been bound + /// + /// assert_eq!(guild.shard_id(17), 7); + /// ``` + #[cfg(not(feature="cache"))] + #[inline] + pub fn shard_id(&self, shard_count: u64) -> u64 { + self.id.shard_id(shard_count) + } + /// Returns the formatted URL of the guild's splash image, if one exists. pub fn splash_url(&self) -> Option<String> { self.icon.as_ref().map(|icon| diff --git a/src/model/guild/partial_guild.rs b/src/model/guild/partial_guild.rs index 947de50..b6d027a 100644 --- a/src/model/guild/partial_guild.rs +++ b/src/model/guild/partial_guild.rs @@ -404,6 +404,48 @@ impl PartialGuild { self.id.move_member(user_id, channel_id) } + /// Returns the Id of the shard associated with the guild. + /// + /// When the cache is enabled this will automatically retrieve the total + /// number of shards. + /// + /// **Note**: When the cache is enabled, this function unlocks the cache to + /// retrieve the total number of shards in use. If you already have the + /// total, consider using [`utils::shard_id`]. + /// + /// [`utils::shard_id`]: ../utils/fn.shard_id.html + #[cfg(feature="cache")] + #[inline] + pub fn shard_id(&self) -> u64 { + self.id.shard_id() + } + + /// Returns the Id of the shard associated with the guild. + /// + /// When the cache is enabled this will automatically retrieve the total + /// number of shards. + /// + /// When the cache is not enabled, the total number of shards being used + /// will need to be passed. + /// + /// # Examples + /// + /// Retrieve the Id of the shard for a guild with Id `81384788765712384`, + /// using 17 shards: + /// + /// ```rust,ignore + /// use serenity::utils; + /// + /// // assumes a `guild` has already been bound + /// + /// assert_eq!(guild.shard_id(17), 7); + /// ``` + #[cfg(not(feature="cache"))] + #[inline] + pub fn shard_id(&self, shard_count: u64) -> u64 { + self.id.shard_id(shard_count) + } + /// Returns the formatted URL of the guild's splash image, if one exists. pub fn splash_url(&self) -> Option<String> { self.icon.as_ref().map(|icon| diff --git a/src/model/invite.rs b/src/model/invite.rs index d041d55..338d90c 100644 --- a/src/model/invite.rs +++ b/src/model/invite.rs @@ -112,6 +112,50 @@ pub struct InviteGuild { pub splash_hash: Option<String>, } +impl InviteGuild { + /// Returns the Id of the shard associated with the guild. + /// + /// When the cache is enabled this will automatically retrieve the total + /// number of shards. + /// + /// **Note**: When the cache is enabled, this function unlocks the cache to + /// retrieve the total number of shards in use. If you already have the + /// total, consider using [`utils::shard_id`]. + /// + /// [`utils::shard_id`]: ../utils/fn.shard_id.html + #[cfg(feature="cache")] + #[inline] + pub fn shard_id(&self) -> u64 { + self.id.shard_id() + } + + /// Returns the Id of the shard associated with the guild. + /// + /// When the cache is enabled this will automatically retrieve the total + /// number of shards. + /// + /// When the cache is not enabled, the total number of shards being used + /// will need to be passed. + /// + /// # Examples + /// + /// Retrieve the Id of the shard for a guild with Id `81384788765712384`, + /// using 17 shards: + /// + /// ```rust,ignore + /// use serenity::utils; + /// + /// // assumes a `guild` has already been bound + /// + /// assert_eq!(guild.shard_id(17), 7); + /// ``` + #[cfg(not(feature="cache"))] + #[inline] + pub fn shard_id(&self, shard_count: u64) -> u64 { + self.id.shard_id(shard_count) + } +} + /// Detailed information about an invite. /// This information can only be retrieved by anyone with the [Manage Guild] /// permission. Otherwise, a minimal amount of information can be retrieved via diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 235709e..adb2d45 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -233,3 +233,21 @@ pub fn parse_quotes(s: &str) -> Vec<String> { args } + +/// Calculates the Id of the shard responsible for a guild, given its Id and +/// total number of shards used. +/// +/// # Examples +/// +/// Retrieve the Id of the shard for a guild with Id `81384788765712384`, using +/// 17 shards: +/// +/// ```rust +/// use serenity::utils; +/// +/// assert_eq!(utils::shard_id(81384788765712384, 17), 7); +/// ``` +#[inline] +pub fn shard_id(guild_id: u64, shard_count: u64) -> u64 { + (guild_id >> 22) % shard_count +} |