aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/gateway/shard.rs25
-rw-r--r--src/ext/cache/mod.rs4
-rw-r--r--src/model/guild/guild_id.rs43
-rw-r--r--src/model/guild/mod.rs42
-rw-r--r--src/model/guild/partial_guild.rs42
-rw-r--r--src/model/invite.rs44
-rw-r--r--src/utils/mod.rs18
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
+}