internal DiscordEmbedThumbnail(DiscordApiData data) { Url = data.GetString("url"); ProxyUrl = data.GetString("proxy_url"); Width = data.GetInteger("width").Value; Height = data.GetInteger("height").Value; }
internal DiscordAttachment(DiscordApiData data) : base(data) { FileName = data.GetString("filename"); Size = data.GetInteger("size").Value; Url = data.GetString("url"); ProxyUrl = data.GetString("proxy_url"); Width = data.GetInteger("width"); Height = data.GetInteger("height"); }
public void Update(DiscordApiData data) { Name = data.GetString("name"); Icon = data.GetString("icon"); Splash = data.GetString("splash"); RegionId = data.GetString("region"); AfkTimeout = data.GetInteger("afk_timeout").Value; IsEmbedEnabled = data.GetBoolean("embed_enabled") ?? false; OwnerId = data.GetSnowflake("owner_id").Value; AfkChannelId = data.GetSnowflake("afk_channel_id"); EmbedChannelId = data.GetSnowflake("embed_channel_id"); ApplicationId = data.GetSnowflake("application_id"); IsWidgetEnabled = data.GetBoolean("widget_enabled") ?? false; WidgetChannelId = data.GetSnowflake("widget_channel_id"); SystemChannelId = data.GetSnowflake("system_channel_id"); ExplicitContentFilter = (GuildExplicitContentFilterLevel)data.GetInteger("explicit_content_filter").Value; VerificationLevel = (GuildVerificationLevel)data.GetInteger("verification_level").Value; DefaultMessageNotifications = (GuildNotificationOption)(data.GetInteger("default_message_notifications") ?? 0); MfaLevel = (GuildMfaLevel)data.GetInteger("mfa_level").Value; // Deserialize features IList <DiscordApiData> featuresArray = data.GetArray("features"); List <string> features = new List <string>(featuresArray.Count); for (int i = 0; i < features.Count; i++) { features[i] = featuresArray[i].ToString(); } Features = features; // Deserialize roles Roles.Clear(); IList <DiscordApiData> rolesArray = data.GetArray("roles"); for (int i = 0; i < rolesArray.Count; i++) { DiscordRole role = new DiscordRole(Http, Id, rolesArray[i]); Roles[role.Id] = role; } // Deserialize emojis Emojis.Clear(); IList <DiscordApiData> emojisArray = data.GetArray("emojis"); for (int i = 0; i < emojisArray.Count; i++) { DiscordEmoji emoji = new DiscordEmoji(emojisArray[i]); Emojis[emoji.Id] = emoji; } Dirty(); }
internal DiscordGuildMetadata(DiscordApiData data) { GuildId = data.GetSnowflake("id").Value; IsLarge = data.GetBoolean("large") ?? false; JoinedAt = data.GetDateTime("joined_at").Value; MemberCount = data.GetInteger("member_count").Value; }
void HandleDispatchPayload(DiscordApiData payload, DiscordApiData data) { sequence = payload.GetInteger("s").Value; string eventName = payload.GetString("t"); OnDispatch?.Invoke(this, new DispatchEventArgs(eventName, data)); }
/// <summary> /// Returns the number of members that would be kicked from a guild prune operation. /// <para>Requires <see cref="DiscordPermission.KickMembers"/>.</para> /// </summary> /// <param name="days">The number of days to count prune for (1 or more).</param> /// <exception cref="DiscordHttpApiException"></exception> public async Task <int> GetGuildPruneCount(Snowflake guildId, int days) { DiscordApiData data = await rest.Get($"guilds/{guildId}/prune?days={days}", $"guilds/{guildId}/prune").ConfigureAwait(false); return(data.GetInteger("pruned").Value); }
void HandleChannelUpdateEvent(DiscordApiData data) { Snowflake id = data.GetSnowflake("id").Value; DiscordChannelType type = (DiscordChannelType)data.GetInteger("type"); Snowflake guildId = data.GetSnowflake("guild_id").Value; DiscordGuildChannel channel = null; if (type == DiscordChannelType.GuildText) { channel = new DiscordGuildTextChannel(http, data, guildId); } else if (type == DiscordChannelType.GuildVoice) { channel = new DiscordGuildVoiceChannel(http, data, guildId); } else if (type == DiscordChannelType.GuildCategory) { channel = new DiscordGuildCategoryChannel(http, data, guildId); } if (channel != null) { cache.GuildChannels[id] = channel; OnGuildChannelUpdated?.Invoke(this, new GuildChannelEventArgs(shard, guildId, channel)); } else { log.LogWarning($"Failed to update channel {id} because the type ({type}) doesn't have an implementation!"); } }
/// <summary> /// Begins a member prune operation, /// kicking every member that has been offline for the specified number of days. /// <para>Requires <see cref="DiscordPermission.KickMembers"/>.</para> /// </summary> /// <param name="days">The number of days to prune (1-30).</param> /// <param name="includeRoles"> /// By default, prune will not remove users with roles. You can optionally include specific /// roles in your prune by providing the <paramref name="includeRoles"/> parameter. Any inactive /// user that has a subset of the provided role(s) will be counted in the prune and users with /// additional roles will not. /// </param> /// <param name="computePruneCount"> /// For large guilds it's recommended to set this to false. When false, this method will always return 0. /// </param> /// <exception cref="DiscordHttpApiException"></exception> public async Task <int> BeginGuildPrune( Snowflake guildId, int?days = null, IEnumerable <Snowflake> includeRoles = null, bool?computePruneCount = null) { DiscordApiData requestData = new DiscordApiData(DiscordApiDataType.Container); if (days != null) { requestData.Set("days", days); } if (includeRoles != null) { requestData.Set("include_roles", includeRoles.Select(r => r.ToString()).ToArray()); } if (computePruneCount != null) { requestData.Set("compute_prune_count", computePruneCount.Value); } DiscordApiData data = await rest.Post($"guilds/{guildId}/prune", requestData, $"guilds/{guildId}/prune").ConfigureAwait(false); return(data.GetInteger("pruned") ?? 0); }
internal DiscordChannelMention(DiscordApiData data) : base(data) { GuildId = data.GetSnowflake("guild_id").GetValueOrDefault(); Type = (DiscordChannelType)(data.GetInteger("type") ?? 0); Name = data.GetString("name"); }
void HandleChannelDeleteEvent(DiscordApiData data) { Snowflake id = data.GetSnowflake("id").Value; DiscordChannelType type = (DiscordChannelType)data.GetInteger("type").Value; if (type == DiscordChannelType.DirectMessage) { // DM channel DiscordDMChannel dm; if (cache.DMChannels.TryRemove(id, out MutableDMChannel mutableDM)) { mutableDM.ClearReferences(); dm = mutableDM.ImmutableEntity; } else { dm = new DiscordDMChannel(http, data); } OnDMChannelRemoved?.Invoke(this, new DMChannelEventArgs(shard, dm)); } else if (type == DiscordChannelType.GuildText || type == DiscordChannelType.GuildVoice || type == DiscordChannelType.GuildCategory) { // Guild channel Snowflake guildId = data.GetSnowflake("guild_id").Value; DiscordGuildChannel channel; if (type == DiscordChannelType.GuildText) { if (!cache.GuildChannels.TryRemove(id, out channel)) { channel = new DiscordGuildTextChannel(http, data, guildId); } } else if (type == DiscordChannelType.GuildVoice) { if (!cache.GuildChannels.TryRemove(id, out channel)) { channel = new DiscordGuildVoiceChannel(http, data, guildId); } } else if (type == DiscordChannelType.GuildCategory) { if (!cache.GuildChannels.TryRemove(id, out channel)) { channel = new DiscordGuildCategoryChannel(http, data, guildId); } } else { throw new NotImplementedException($"Guild channel type \"{type}\" has no implementation!"); } OnGuildChannelRemoved?.Invoke(this, new GuildChannelEventArgs(shard, guildId, channel)); } }
void HandleSpeaking(DiscordApiData payload, DiscordApiData data) { Snowflake userId = data.GetSnowflake("user_id").Value; int ssrc = data.GetInteger("ssrc").Value; bool isSpeaking = data.GetBoolean("speaking").Value; OnUserSpeaking?.Invoke(this, new VoiceSpeakingEventArgs(userId, ssrc, isSpeaking)); }
void HandleTypingStartEvent(DiscordApiData data) { Snowflake userId = data.GetSnowflake("user_id").Value; Snowflake channelId = data.GetSnowflake("channel_id").Value; int timestamp = data.GetInteger("timestamp").Value; OnTypingStarted?.Invoke(this, new TypingStartEventArgs(shard, userId, channelId, timestamp)); }
void HandleChannelCreateEvent(DiscordApiData data) { Snowflake id = data.GetSnowflake("id").Value; DiscordChannelType type = (DiscordChannelType)data.GetInteger("type").Value; if (type == DiscordChannelType.DirectMessage) { // DM channel DiscordApiData recipientData = data.GetArray("recipients").First(); Snowflake recipientId = recipientData.GetSnowflake("id").Value; MutableUser recipient; if (!cache.Users.TryGetValue(recipientId, out recipient)) { recipient = new MutableUser(recipientId, false, http); cache.Users[recipientId] = recipient; } recipient.Update(recipientData); MutableDMChannel mutableDMChannel; if (!cache.DMChannels.TryGetValue(id, out mutableDMChannel)) { mutableDMChannel = new MutableDMChannel(id, recipient, http); cache.DMChannels[id] = mutableDMChannel; } OnDMChannelCreated?.Invoke(this, new DMChannelEventArgs(shard, mutableDMChannel.ImmutableEntity)); } else if (type == DiscordChannelType.GuildText || type == DiscordChannelType.GuildVoice) { // Guild channel Snowflake guildId = data.GetSnowflake("guild_id").Value; DiscordGuildChannel channel; if (type == DiscordChannelType.GuildText) { channel = new DiscordGuildTextChannel(http, data, guildId); } else if (type == DiscordChannelType.GuildVoice) { channel = new DiscordGuildVoiceChannel(http, data, guildId); } else if (type == DiscordChannelType.GuildCategory) { channel = new DiscordGuildCategoryChannel(http, data, guildId); } else { throw new NotImplementedException($"Guild channel type \"{type}\" has no implementation!"); } cache.GuildChannels[id] = channel; OnGuildChannelCreated?.Invoke(this, new GuildChannelEventArgs(shard, guildId, channel)); } }
void HandleReadyPayload(DiscordApiData payload, DiscordApiData data) { int port = data.GetInteger("port").Value; int ssrc = data.GetInteger("ssrc").Value; IList <DiscordApiData> modesArray = data.GetArray("modes"); string[] modes = new string[modesArray.Count]; for (int i = 0; i < modes.Length; i++) { modes[i] = modesArray[i].ToString(); } log.LogVerbose($"[Ready] ssrc = {ssrc}, port = {port}"); // Notify ReadyQueue.Add(new VoiceReadyEventArgs(port, ssrc, modes)); }
/// <summary> /// Begins a member prune operation, /// kicking every member that has been offline for the specified number of days. /// <para>Requires <see cref="DiscordPermission.KickMembers"/>.</para> /// </summary> /// <param name="days">The number of days to prune (1 or more).</param> /// <exception cref="DiscordHttpApiException"></exception> public async Task <int> BeginGuildPrune(Snowflake guildId, int days) { DiscordApiData requestData = new DiscordApiData(DiscordApiDataType.Container); requestData.Set("days", days); DiscordApiData data = await rest.Post($"guilds/{guildId}/prune", requestData, $"guilds/{guildId}/prune").ConfigureAwait(false); return(data.GetInteger("pruned").Value); }
internal DiscordVoiceRegion(DiscordApiData data) { Id = data.GetString("id"); Name = data.GetString("name"); SampleHostname = data.GetString("sample_hostname"); SamplePort = data.GetInteger("sample_port").Value; IsVIPOnly = data.GetBoolean("vip").Value; IsOptimal = data.GetBoolean("optimal").Value; IsDeprecated = data.GetBoolean("deprecated").Value; IsCustom = data.GetBoolean("custom").Value; }
internal DiscordReaction(DiscordApiData data) { Count = data.GetInteger("count").Value; Me = data.GetBoolean("me").Value; DiscordApiData emojiData = data.Get("emoji"); if (emojiData != null) { Emoji = new DiscordReactionEmoji(emojiData); } }
void HandleHelloPayload(DiscordApiData payload, DiscordApiData data) { int heartbeatInterval = data.GetInteger("heartbeat_interval").Value; // TODO: Remove when Discord's heartbeat_interval bug is fixed heartbeatInterval = (int)Math.Floor(heartbeatInterval * 0.75f); log.LogVerbose($"[Hello] heartbeat_interval = {heartbeatInterval}ms"); HelloQueue.Add(heartbeatInterval); // Start heartbeat loop heartbeatCancellationSource = new CancellationTokenSource(); }
/// <summary> /// Returns the number of members that would be kicked from a guild prune operation. /// <para>Requires <see cref="DiscordPermission.KickMembers"/>.</para> /// </summary> /// <param name="days">The number of days to count prune for (1-30).</param> /// <param name="includeRoles"> /// By default, prune will not remove users with roles. You can optionally include specific /// roles in your prune by providing the <paramref name="includeRoles"/> parameter. Any inactive /// user that has a subset of the provided role(s) will be counted in the prune and users with /// additional roles will not. /// </param> /// <exception cref="DiscordHttpApiException"></exception> public async Task <int> GetGuildPruneCount(Snowflake guildId, int?days = null, IEnumerable <Snowflake> includeRoles = null) { UrlParametersBuilder parameters = new UrlParametersBuilder(); if (days != null) { parameters["days"] = days.Value.ToString(); } if (includeRoles != null) { parameters["include_roles"] = string.Join(",", includeRoles.Select(r => r.ToString())); } DiscordApiData data = await rest.Get($"guilds/{guildId}/prune{parameters.ToQueryString()}", $"guilds/{guildId}/prune").ConfigureAwait(false); return(data.GetInteger("pruned").Value); }
protected override Task OnPayloadReceived(DiscordApiData payload) { VoiceOPCode op = (VoiceOPCode)payload.GetInteger("op").Value; DiscordApiData d = payload.Get("d"); PayloadCallback callback; if (payloadHandlers.TryGetValue(op, out callback)) { callback(payload, d); } else { log.LogWarning($"Missing handler for payload: {op} ({(int)op})"); } return(Task.CompletedTask); }
async Task HandleHelloPayload(DiscordApiData payload, DiscordApiData data) { if (!receivedHello) { receivedHello = true; // Set heartbeat interval heartbeatInterval = data.GetInteger("heartbeat_interval").Value; log.LogVerbose($"[Hello] heartbeat_interval = {heartbeatInterval}ms"); // Begin heartbeat loop heartbeatCancellationSource = new CancellationTokenSource(); heartbeatTask = HeartbeatLoop(); // Notify so the IDENTIFY or RESUME payloads are sent await OnHello?.Invoke(); } else { log.LogWarning("Received more than one HELLO payload."); } }
protected override async Task OnPayloadReceived(DiscordApiData payload) { GatewayOPCode op = (GatewayOPCode)payload.GetInteger("op"); DiscordApiData data = payload.Get("d"); PayloadCallback callback; if (payloadHandlers.TryGetValue(op, out callback)) { if (callback.Synchronous != null) { callback.Synchronous(payload, data); } else { await callback.Asynchronous(payload, data).ConfigureAwait(false); } } else { log.LogWarning($"Missing handler for payload: {op} ({(int)op})"); } }
void HandleReadyEvent(DiscordApiData data) { // Check gateway protocol int protocolVersion = data.GetInteger("v").Value; if (protocolVersion != GATEWAY_VERSION) { log.LogError($"[Ready] Gateway protocol mismatch! Expected v{GATEWAY_VERSION}, got {protocolVersion}."); } // Check shard if (shard.Id != 0 || totalShards > 1) { IList <DiscordApiData> shardData = data.GetArray("shard"); if (shardData != null) { if (shardData.Count > 0 && shardData[0].ToInteger() != shard.Id) { log.LogError($"[Ready] Shard ID mismatch! Expected {shard.Id}, got {shardData[0].ToInteger()}"); } if (shardData.Count > 1 && shardData[1].ToInteger() != totalShards) { log.LogError($"[Ready] Total shards mismatch! Expected {totalShards}, got {shardData[1].ToInteger()}"); } } } // Clear the cache cache.Clear(); // Get the current bot's user object DiscordApiData userData = data.Get("user"); Snowflake userId = userData.GetSnowflake("id").Value; MutableUser user; if (!cache.Users.TryGetValue(userId, out user)) { user = new MutableUser(userId, false, http); cache.Users[userId] = user; } user.Update(userData); shard.UserId = userId; log.LogInfo($"[Ready] user = {user.Username}#{user.Discriminator}"); // Get session ID sessionId = data.GetString("session_id"); // Get unavailable guilds foreach (DiscordApiData unavailableGuildData in data.GetArray("guilds")) { Snowflake guildId = unavailableGuildData.GetSnowflake("id").Value; cache.AddGuildId(guildId); cache.SetGuildAvailability(guildId, false); } LogServerTrace("Ready", data); // Signal that the connection is ready handshakeCompleteEvent.Set(); }
internal DiscordInviteChannel(DiscordApiData data) { ChannelId = data.GetSnowflake("id").Value; Name = data.GetString("name"); Type = (DiscordChannelType)data.GetInteger("type"); }
internal DiscordGame(DiscordApiData data) { Name = data.GetString("name"); Type = (DiscordGameType)(data.GetInteger("type") ?? 0); Url = data.GetString("url"); }
void HandleReadyEvent(DiscordApiData data) { // Check gateway protocol int protocolVersion = data.GetInteger("v").Value; if (protocolVersion != GATEWAY_VERSION) { log.LogError($"[Ready] Gateway protocol mismatch! Expected v{GATEWAY_VERSION}, got {protocolVersion}."); } // Clear the cache cache.Clear(); // Get the current bot's user object DiscordApiData userData = data.Get("user"); Snowflake userId = userData.GetSnowflake("id").Value; MutableUser user; if (!cache.Users.TryGetValue(userId, out user)) { user = new MutableUser(userId, false, http); cache.Users[userId] = user; } user.Update(userData); shard.UserId = userId; log.LogInfo($"[Ready] user = {user.Username}#{user.Discriminator}"); // Get session ID sessionId = data.GetString("session_id"); // Get unavailable guilds foreach (DiscordApiData unavailableGuildData in data.GetArray("guilds")) { Snowflake guildId = unavailableGuildData.GetSnowflake("id").Value; cache.AddGuildId(guildId); cache.SetGuildAvailability(guildId, false); } // Get DM channels foreach (DiscordApiData dmChannelData in data.GetArray("private_channels")) { DiscordChannelType type = (DiscordChannelType)dmChannelData.GetInteger("type").Value; if (type != DiscordChannelType.DirectMessage) { // TODO: Support group DMs continue; } Snowflake channelId = dmChannelData.GetSnowflake("id").Value; DiscordApiData recipientData = dmChannelData.GetArray("recipients").First(); Snowflake recipientId = recipientData.GetSnowflake("id").Value; MutableUser recipient; if (!cache.Users.TryGetValue(recipientId, out recipient)) { recipient = new MutableUser(recipientId, false, http); cache.Users[recipientId] = recipient; } recipient.Update(recipientData); MutableDMChannel mutableDMChannel; if (!cache.DMChannels.TryGetValue(channelId, out mutableDMChannel)) { mutableDMChannel = new MutableDMChannel(channelId, recipient, http); cache.DMChannels[channelId] = mutableDMChannel; } mutableDMChannel.Update(dmChannelData); } LogServerTrace("Ready", data); // Signal that the connection is ready handshakeCompleteEvent.Set(); }
public GatewayBotResponse(DiscordApiData data) { Url = data.GetString("url"); Shards = data.GetInteger("shards").Value; }
internal DiscordMessageActivity(DiscordApiData data) { Type = (DiscordMessageActivityType)(data.GetInteger("type") ?? 0); PartyId = data.GetString("party_id"); }
internal DiscordEmbedVideo(DiscordApiData data) { Url = data.GetString("url"); Width = data.GetInteger("width").Value; Height = data.GetInteger("height").Value; }
void HandleGuildCreateEvent(DiscordApiData data) { Snowflake guildId = data.GetSnowflake("id").Value; bool wasUnavailable = !cache.IsGuildAvailable(guildId); // Update guild MutableGuild mutableGuild; if (!cache.Guilds.TryGetValue(guildId, out mutableGuild)) { mutableGuild = new MutableGuild(guildId, http); cache.Guilds[guildId] = mutableGuild; } mutableGuild.Update(data); // Ensure the cache guildId list contains this guild (it uses a hashset so don't worry about duplicates). cache.AddGuildId(guildId); // GUILD_CREATE specifics // Update metadata cache.GuildMetadata[guildId] = new DiscordGuildMetadata(data); // Deserialize members cache.GuildMembers.Clear(guildId); IList <DiscordApiData> membersArray = data.GetArray("members"); for (int i = 0; i < membersArray.Count; i++) { DiscordApiData memberData = membersArray[i]; DiscordApiData userData = memberData.Get("user"); Snowflake userId = userData.GetSnowflake("id").Value; MutableUser user; if (!cache.Users.TryGetValue(userId, out user)) { user = new MutableUser(userId, false, http); cache.Users[userId] = user; } user.Update(userData); MutableGuildMember member; if (!cache.GuildMembers.TryGetValue(guildId, userId, out member)) { member = new MutableGuildMember(user, guildId, http); cache.GuildMembers[guildId, userId] = member; } member.Update(memberData); } // Deserialize channels cache.ClearGuildChannels(guildId); IList <DiscordApiData> channelsArray = data.GetArray("channels"); for (int i = 0; i < channelsArray.Count; i++) { DiscordApiData channelData = channelsArray[i]; DiscordChannelType channelType = (DiscordChannelType)channelData.GetInteger("type"); DiscordGuildChannel channel = null; if (channelType == DiscordChannelType.GuildText) { channel = new DiscordGuildTextChannel(http, channelData, guildId); } else if (channelType == DiscordChannelType.GuildVoice) { channel = new DiscordGuildVoiceChannel(http, channelData, guildId); } else if (channelType == DiscordChannelType.GuildCategory) { channel = new DiscordGuildCategoryChannel(http, channelData, guildId); } if (channel != null) { cache.AddGuildChannel(channel); } } // Deserialize voice states cache.GuildVoiceStates.Clear(guildId); IList <DiscordApiData> voiceStatesArray = data.GetArray("voice_states"); for (int i = 0; i < voiceStatesArray.Count; i++) { DiscordVoiceState state = new DiscordVoiceState(guildId, voiceStatesArray[i]); UpdateMemberVoiceState(state); } // Deserialize presences cache.GuildPresences.Clear(guildId); IList <DiscordApiData> presencesArray = data.GetArray("presences"); for (int i = 0; i < presencesArray.Count; i++) { // Presence's in GUILD_CREATE do not contain full user objects, // so don't attempt to update them here. DiscordApiData presenceData = presencesArray[i]; Snowflake userId = presenceData.LocateSnowflake("user.id").Value; cache.GuildPresences[guildId, userId] = new DiscordUserPresence(userId, presenceData); } // Mark the guild as available cache.SetGuildAvailability(guildId, true); // Fire event if (wasUnavailable) { OnGuildAvailable?.Invoke(this, new GuildEventArgs(shard, mutableGuild.ImmutableEntity)); } else { OnGuildCreated?.Invoke(this, new GuildEventArgs(shard, mutableGuild.ImmutableEntity)); } }