internal InviteCreatedEventArgs( DiscordClientBase client, CachedGuild guild, SnowflakeOptional <CachedChannel> channel, CachedUser inviter, string code, bool isTemporary, int maxUses, int maxAge, DateTimeOffset createdAt) : base(client) { Guild = guild; Channel = channel; Inviter = inviter; Code = code; IsTemporary = isTemporary; MaxUses = maxUses; MaxAge = maxAge; CreatedAt = createdAt; }
internal GuildUpdatedEventArgs(CachedGuild oldGuild, CachedGuild newGuild) : base(newGuild.Client) { OldGuild = oldGuild; NewGuild = newGuild; }
private static async Task PersistGuildAsync(CachedGuild guild, EspeonDbContext context) { await context.GetOrCreateAsync(guild.Id.RawValue, guildId => new GuildPrefixes(guildId)); await context.GetOrCreateAsync(guild.Id.RawValue, guildId => new GuildTags(guildId)); }
internal GuildEmojisUpdatedEventArgs(CachedGuild guild, IReadOnlyDictionary <Snowflake, CachedGuildEmoji> oldEmojis) : base(guild.Client) { Guild = guild; OldEmojis = oldEmojis; NewEmojis = guild.Emojis; }
// TODO: possible cache inconsistencies on unavailable guilds? No idea what Discord sends nor does while it's unavailable. private IGatewayGuild UpdateCache(GatewayGuildJsonModel model, bool isPending) { IGatewayGuild guild = null; if (CacheProvider.TryGetGuilds(out var guildCache)) { if (isPending) { guild = new CachedGuild(Client, model); guildCache.Add(model.Id, guild as CachedGuild); } else { guild = guildCache.GetValueOrDefault(model.Id); guild?.Update(model); } } guild ??= new TransientGatewayGuild(Client, model); if (CacheProvider.TryGetUsers(out var userCache) && CacheProvider.TryGetMembers(model.Id, out var memberCache)) { foreach (var memberModel in model.Members) { Dispatcher.GetOrAddMember(userCache, memberCache, model.Id, memberModel); } } if (CacheProvider.TryGetChannels(model.Id, out var channelCache)) { foreach (var channelModel in model.Channels) { if (isPending) { channelModel.GuildId = model.Id; var channel = CachedGuildChannel.Create(Client, channelModel); channelCache.Add(channel.Id, channel); } else { var channel = channelCache.GetValueOrDefault(channelModel.Id); channel?.Update(channelModel); } } foreach (var threadModel in model.Threads) { if (isPending) { threadModel.GuildId = model.Id; if (threadModel.Member.HasValue) { threadModel.Member.Value.Id = threadModel.Id; threadModel.Member.Value.UserId = Client.CurrentUser.Id; } var channel = new CachedThreadChannel(Client, threadModel); channelCache.Add(channel.Id, channel); } else { var channel = channelCache.GetValueOrDefault(threadModel.Id); channel?.Update(threadModel); } } } if (CacheProvider.TryGetRoles(model.Id, out var roleCache)) { foreach (var roleModel in model.Roles) { if (isPending) { var role = new CachedRole(Client, model.Id, roleModel); roleCache.Add(role.Id, role); } else { var role = roleCache.GetValueOrDefault(roleModel.Id); role?.Update(roleModel); } } } if (CacheProvider.TryGetVoiceStates(model.Id, out var voiceStateCache)) { foreach (var voiceStateModel in model.VoiceStates) { if (isPending) { var voiceState = new CachedVoiceState(Client, model.Id, voiceStateModel); voiceStateCache.Add(voiceState.MemberId, voiceState); } else { var voiceState = voiceStateCache.GetValueOrDefault(voiceStateModel.UserId); voiceState?.Update(voiceStateModel); } } } if (CacheProvider.TryGetPresences(model.Id, out var presenceCache)) { foreach (var presenceModel in model.Presences) { if (isPending) { var presence = new CachedPresence(Client, presenceModel); presenceCache.Add(presence.MemberId, presence); } else { var presence = presenceCache.GetValueOrDefault(presenceModel.User.Id); presence?.Update(presenceModel); } } } if (CacheProvider.TryGetStages(model.Id, out var stageCache)) { foreach (var stageModel in model.StageInstances) { if (isPending) { var stage = new CachedStage(Client, stageModel); stageCache.Add(stage.Id, stage); } else { var stage = stageCache.GetValueOrDefault(stageModel.Id); stage?.Update(stageModel); } } } return(guild); }
internal LeftGuildEventArgs(CachedGuild guild) : base(guild.Client) { Guild = guild; }
internal GuildUnavailableEventArgs(CachedGuild guild) : base(guild.Client) { Guild = guild; }
public static async Task <(bool success, string failureReason)> UnmuteUserAsync(CachedGuild guild, IMember user, Config config) { IRole mutedRole = await GetMutedRoleAsync(guild); if (mutedRole == null) { return(false, "Failed getting/creating muted role"); } await user.RevokeRoleAsync(mutedRole.Id); config.GetOrAddGuild(guild.Id).CurrentMutes.Remove(user.Id, out Mute muteInfo); foreach (ulong roleId in muteInfo?.RoleIds ?? new ulong[0]) { try { await user.GrantRoleAsync(roleId); } catch { // Do nothing, ignoring roles that stopped existing since the mute } } return(true, string.Empty); }
public static async Task <(bool success, string failureReason)> MuteUserAsync(CachedGuild guild, IMember user, string time, Config config) { IRole mutedRole = await GetMutedRoleAsync(guild); if (mutedRole == null) { return(false, "Failed getting/creating muted role"); } if (user.RoleIds.Contains(mutedRole.Id)) { return(false, "User is already muted"); } TimeSpan muteTime = ParseTime(time); if (muteTime == TimeSpan.Zero) { return(false, "Failed parsing mute time, please give in the format '1d6h30m'"); } List <ulong> revokedRoles = new(); foreach (ulong role in user.RoleIds) { try { await user.RevokeRoleAsync(role); revokedRoles.Add(role); } catch { // Do nothing, ignoring roles that the bot has no perms to remove } } await user.GrantRoleAsync(mutedRole.Id); config.GetOrAddGuild(guild.Id).CurrentMutes[user.Id] = new Mute { GuildId = guild.Id, UserId = user.Id, RoleIds = revokedRoles.ToArray(), UnmuteTime = DateTime.Now + muteTime }; return(true, string.Empty); }
private async Task SendByeMessageAsync(GuildsEntity guildDb, CachedUser user, CachedGuild guild) { if (guildDb is null) { return; } if (!guildDb.ByeNotification) { return; } if (string.IsNullOrEmpty(guildDb.ByeMessage)) { return; } if (guildDb.ByeWebhookId == 0) { return; } var currentMember = guild.CurrentMember; if (!currentMember.Permissions.ManageWebhooks) { return; } var guildWebhook = await guild.GetWebhookAsync(guildDb.ByeWebhookId); if (_webhooks.TryGetValue(guildDb.ByeWebhookId, out var webhook)) { if (guildWebhook is null) { _webhooks.TryRemove(guildDb.ByeWebhookId, out _); webhook.Dispose(); await DisableByeAsync(guild); return; } } else { if (guildWebhook != null) { webhook = new RestWebhookClient(guildWebhook); _webhooks.TryAdd(guildWebhook.Id, webhook); } else { await DisableByeAsync(guild); return; } } if (webhook is null) { return; } var byeMsg = ReplacePlaceholders(user, guildDb.ByeMessage); if (RiasUtilities.TryParseEmbed(byeMsg, out var embed)) { await webhook.ExecuteAsync(embeds : new[] { embed.Build() }); } else { await webhook.ExecuteAsync(byeMsg); } }
public override async ValueTask <EventArgs> HandleDispatchAsync(IGatewayApiClient shard, GatewayGuildJsonModel model) { IGatewayGuild guild = null; // Check if the event is guild availability or we joined a new guild. if (model.Unavailable.HasValue) { // A guild became available. var isPending = _readyHandler.IsPendingGuild(shard.Id, model.Id); try { if (CacheProvider.TryGetGuilds(out var guildCache)) { if (isPending) { guild = new CachedGuild(Client, model); guildCache.Add(model.Id, guild as CachedGuild); } else { guild = guildCache.GetValueOrDefault(model.Id); guild?.Update(model); } } if (guild == null) { guild = new TransientGatewayGuild(Client, model); } // TODO: optimise member cache retrieval if (CacheProvider.TryGetMembers(model.Id, out var memberCache)) { foreach (var memberModel in model.Members) { Dispatcher.GetOrAddMember(model.Id, memberModel); } } if (CacheProvider.TryGetChannels(model.Id, out var channelCache)) { foreach (var channelModel in model.Channels) { if (isPending) { var channel = CachedGuildChannel.Create(Client, model.Id, channelModel); channelCache.Add(channel.Id, channel); } else { var channel = channelCache.GetValueOrDefault(channelModel.Id); channel?.Update(channelModel); } } } if (CacheProvider.TryGetRoles(model.Id, out var roleCache)) { foreach (var roleModel in model.Roles) { if (isPending) { var role = new CachedRole(Client, model.Id, roleModel); roleCache.Add(role.Id, role); } else { var role = roleCache.GetValueOrDefault(roleModel.Id); role?.Update(roleModel); } } } if (CacheProvider.TryGetVoiceStates(model.Id, out var voiceStateCache)) { foreach (var voiceStateModel in model.VoiceStates) { if (isPending) { var voiceState = new CachedVoiceState(Client, model.Id, voiceStateModel); voiceStateCache.Add(voiceState.Id, voiceState); } else { var voiceState = voiceStateCache.GetValueOrDefault(voiceStateModel.UserId); voiceState?.Update(voiceStateModel); } } } var logLevel = isPending ? LogLevel.Debug : LogLevel.Information; var message = isPending ? "Pending guild {0} ({1}) is available." : "Guild {0} ({1}) became available."; shard.Logger.Log(logLevel, message, guild.Name, guild.Id.RawValue); // Invoke the event and possibly invoke ready afterwards. await InvokeEventAsync(new GuildAvailableEventArgs(guild)).ConfigureAwait(false); } finally { if (isPending) { _readyHandler.PopPendingGuild(shard.Id, model.Id); } } return(null); } else { // We joined a new guild. if (Client.CacheProvider.TryGetGuilds(out var cache)) { guild = new CachedGuild(Client, model); cache.Add(model.Id, guild as CachedGuild); } else { guild = new TransientGatewayGuild(Client, model); } // TODO: optimise member cache retrieval if (CacheProvider.TryGetMembers(model.Id, out var memberCache)) { foreach (var memberModel in model.Members) { Dispatcher.GetOrAddMember(model.Id, memberModel); } } if (CacheProvider.TryGetChannels(model.Id, out var channelCache)) { foreach (var channelModel in model.Channels) { var channel = CachedGuildChannel.Create(Client, model.Id, channelModel); channelCache.Add(channel.Id, channel); } } if (CacheProvider.TryGetRoles(model.Id, out var roleCache)) { foreach (var roleModel in model.Roles) { var role = new CachedRole(Client, model.Id, roleModel); roleCache.Add(role.Id, role); } } shard.Logger.LogInformation("Joined guild {0} ({1}).", guild.Name, guild.Id.RawValue); return(new JoinedGuildEventArgs(guild)); } }
public IEnumerable <CachedRole> GetIgnoredRoles(CachedGuild guild) { return(IgnoredRoles.Select(roleUlong => guild.GetRole(roleUlong))); }
public IEnumerable <CachedTextChannel> GetIgnoredChannels(CachedGuild guild) { return(IgnoredChannels.Select(channelUlong => guild.GetTextChannel(channelUlong))); }
internal VoiceServerUpdatedEventArgs(CachedGuild guild, string token, string endpoint) : base(guild.Client) { Guild = guild; Token = token; Endpoint = endpoint; }
public override async ValueTask <EventArgs> HandleDispatchAsync(IGatewayApiClient shard, UnavailableGuildJsonModel model) { CachedGuild guild = null; if (model.Unavailable.HasValue) { var isPending = _readyHandler.IsPendingGuild(shard.Id, model.Id); try { if (CacheProvider.TryGetGuilds(out var cache)) { if (isPending) { // TODO: cache the id or such if the guild isn't available } else { guild = cache.GetValueOrDefault(model.Id); guild?.Update(model); } } if (isPending) { shard.Logger.LogInformation("Pending guild {0} is unavailable.", model.Id.RawValue); } else { if (guild != null) { shard.Logger.LogInformation("Guild {0} ({1}) became unavailable.", guild.Name, guild.Id.RawValue); } else { shard.Logger.LogInformation("Uncached guild {0} became unavailable.", model.Id.RawValue); } } // Invoke the event and possibly invoke ready afterwards. await InvokeEventAsync(new GuildUnavailableEventArgs(model.Id, guild)).ConfigureAwait(false); } finally { if (isPending) { _readyHandler.PopPendingGuild(shard.Id, model.Id); } } return(null); } else { if (Client.CacheProvider.TryGetGuilds(out var cache)) { cache.TryRemove(model.Id, out guild); } Client.CacheProvider.TryRemoveCache <CachedGuildChannel>(model.Id, out _); Client.CacheProvider.TryRemoveCache <CachedRole>(model.Id, out _); Client.CacheProvider.TryRemoveCache <CachedVoiceState>(model.Id, out _); if (guild == null) { shard.Logger.LogInformation("Left uncached guild {0}.", model.Id.RawValue); return(null); } shard.Logger.LogInformation("Left guild '{0}' ({1}).", guild.Name, guild.Id.RawValue); return(new LeftGuildEventArgs(model.Id, guild)); } }
/// <summary> /// Initializes a new <see cref="LogMessage"/> struct with the severity, source, message of the event, and /// optionally, an exception. /// </summary> /// <param name="severity">The severity of the event.</param> /// <param name="source">The source of the event.</param> /// <param name="message">The message of the event.</param> /// <param name="exception">The exception of the event.</param> public LogMessage(LogSeverity severity, string source, string message, Exception exception = null, CachedGuild guild = null) { Severity = severity; Source = source; Message = message; Exception = exception; Guild = guild; }