[Feature] Audit Log Created gateway event support (#2627)
* add event to socket client * make `AuditLog` param optional * Some WIP audit log changes * api models * moar models * complete models * modelsss * forgot to push * oh lol forgot this too * api & rest guild method * revert VS being VS & formatting to file scoped namespace * socket entities * some work eh * moar stuff - switched to d.net's attribute for audit log deserialization * working socket guild updated event + reworked rest GuildInfo creation * a bit of refactoring + new models * +channel created * channel updated & channel deleted * refactor rest channel updated log + some nullable fixes * rest channel created + deleted logs * user banned socket log * kick + unban * moar log modelsssss * fixes & 4 more log types * overwrite logs * role logs * invite logs * webhook logs * switch to `ISocketAuditLogData` for socket log data * emote logs * move stuff around * move more stuff around * audit logs cache * scheduled event logs * thread logs * command permission update audit log * fetch scheduled event data from log * integration audit logs * sticker audit log data * stage instance audit logs * auto mod rule audit logs * fix * forgot couple props * command perm updated data from options * final automod ones * debugging goes away :( * merge cringe * ... * yup * fix xml doc * onboarding audit logs * changes --------- Co-authored-by: cat <lumitydev@gmail.com>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
internal class AuditLogCache
|
||||
{
|
||||
private readonly ConcurrentDictionary<ulong, SocketAuditLogEntry> _entries;
|
||||
private readonly ConcurrentQueue<ulong> _orderedEntries;
|
||||
|
||||
private readonly int _size;
|
||||
|
||||
public IReadOnlyCollection<SocketAuditLogEntry> AuditLogs => _entries.ToReadOnlyCollection();
|
||||
|
||||
public AuditLogCache(DiscordSocketClient client)
|
||||
{
|
||||
_size = client.AuditLogCacheSize;
|
||||
|
||||
_entries = new ConcurrentDictionary<ulong, SocketAuditLogEntry>(ConcurrentHashSet.DefaultConcurrencyLevel, (int)(_size * 1.05));
|
||||
_orderedEntries = new ConcurrentQueue<ulong>();
|
||||
}
|
||||
|
||||
public void Add(SocketAuditLogEntry entry)
|
||||
{
|
||||
if (_entries.TryAdd(entry.Id, entry))
|
||||
{
|
||||
_orderedEntries.Enqueue(entry.Id);
|
||||
|
||||
while (_orderedEntries.Count > _size && _orderedEntries.TryDequeue(out var entryId))
|
||||
_entries.TryRemove(entryId, out _);
|
||||
}
|
||||
}
|
||||
|
||||
public SocketAuditLogEntry Remove(ulong id)
|
||||
{
|
||||
_entries.TryRemove(id, out var entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
public SocketAuditLogEntry Get(ulong id)
|
||||
=> _entries.TryGetValue(id, out var result) ? result : null;
|
||||
|
||||
/// <exception cref="ArgumentOutOfRangeException"><paramref name="limit"/> is less than 0.</exception>
|
||||
public IReadOnlyCollection<SocketAuditLogEntry> GetMany(ulong? fromEntryId, Direction dir, int limit = DiscordConfig.MaxAuditLogEntriesPerBatch, ActionType ? action = null)
|
||||
{
|
||||
if (limit < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(limit));
|
||||
if (limit == 0)
|
||||
return ImmutableArray<SocketAuditLogEntry>.Empty;
|
||||
|
||||
IEnumerable<ulong> cachedEntriesIds;
|
||||
if (fromEntryId == null)
|
||||
cachedEntriesIds = _orderedEntries;
|
||||
else if (dir == Direction.Before)
|
||||
cachedEntriesIds = _orderedEntries.Where(x => x < fromEntryId.Value);
|
||||
else if (dir == Direction.After)
|
||||
cachedEntriesIds = _orderedEntries.Where(x => x > fromEntryId.Value);
|
||||
else //Direction.Around
|
||||
{
|
||||
if (!_entries.TryGetValue(fromEntryId.Value, out var entry))
|
||||
return ImmutableArray<SocketAuditLogEntry>.Empty;
|
||||
var around = limit / 2;
|
||||
var before = GetMany(fromEntryId, Direction.Before, around, action);
|
||||
var after = GetMany(fromEntryId, Direction.After, around, action).Reverse();
|
||||
|
||||
return after.Concat(new [] { entry }).Concat(before).ToImmutableArray();
|
||||
}
|
||||
|
||||
if (dir == Direction.Before)
|
||||
cachedEntriesIds = cachedEntriesIds.Reverse();
|
||||
if (dir == Direction.Around)
|
||||
limit = limit / 2 + 1;
|
||||
|
||||
return cachedEntriesIds
|
||||
.Select(x => _entries.TryGetValue(x, out var entry) ? entry : null)
|
||||
.Where(x => x != null && (action is null || x.Action == action))
|
||||
.Take(limit)
|
||||
.ToImmutableArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to message getting blocked by automod.
|
||||
/// </summary>
|
||||
public class SocketAutoModBlockedMessageAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
internal SocketAutoModBlockedMessageAuditLogData(ulong channelId, string autoModRuleName, AutoModTriggerType autoModRuleTriggerType)
|
||||
{
|
||||
ChannelId = channelId;
|
||||
AutoModRuleName = autoModRuleName;
|
||||
AutoModRuleTriggerType = autoModRuleTriggerType;
|
||||
}
|
||||
|
||||
internal static SocketAutoModBlockedMessageAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
return new(entry.Options.ChannelId!.Value, entry.Options.AutoModRuleName,
|
||||
entry.Options.AutoModRuleTriggerType!.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channel the message was sent in.
|
||||
/// </summary>
|
||||
public ulong ChannelId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the auto moderation rule that got triggered.
|
||||
/// </summary>
|
||||
public string AutoModRuleName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the trigger type of the auto moderation rule that got triggered.
|
||||
/// </summary>
|
||||
public AutoModTriggerType AutoModRuleTriggerType { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to message getting flagged by automod.
|
||||
/// </summary>
|
||||
public class SocketAutoModFlaggedMessageAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
internal SocketAutoModFlaggedMessageAuditLogData(ulong channelId, string autoModRuleName, AutoModTriggerType autoModRuleTriggerType)
|
||||
{
|
||||
ChannelId = channelId;
|
||||
AutoModRuleName = autoModRuleName;
|
||||
AutoModRuleTriggerType = autoModRuleTriggerType;
|
||||
}
|
||||
|
||||
internal static SocketAutoModFlaggedMessageAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
return new(entry.Options.ChannelId!.Value, entry.Options.AutoModRuleName,
|
||||
entry.Options.AutoModRuleTriggerType!.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channel the message was sent in.
|
||||
/// </summary>
|
||||
public ulong ChannelId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the auto moderation rule that got triggered.
|
||||
/// </summary>
|
||||
public string AutoModRuleName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the trigger type of the auto moderation rule that got triggered.
|
||||
/// </summary>
|
||||
public AutoModTriggerType AutoModRuleTriggerType { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to an auto moderation rule creation.
|
||||
/// </summary>
|
||||
public class SocketAutoModRuleCreatedAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketAutoModRuleCreatedAuditLogData(SocketAutoModRuleInfo data)
|
||||
{
|
||||
Data = data;
|
||||
}
|
||||
|
||||
internal static SocketAutoModRuleCreatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo<AutoModRuleInfoAuditLogModel>(changes, discord);
|
||||
|
||||
return new SocketAutoModRuleCreatedAuditLogData(new (data));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the auto moderation rule information after the changes.
|
||||
/// </summary>
|
||||
public SocketAutoModRuleInfo Data { get; }
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to an auto moderation rule removal.
|
||||
/// </summary>
|
||||
public class SocketAutoModRuleDeletedAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketAutoModRuleDeletedAuditLogData(SocketAutoModRuleInfo data)
|
||||
{
|
||||
Data = data;
|
||||
}
|
||||
|
||||
internal static SocketAutoModRuleDeletedAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo<AutoModRuleInfoAuditLogModel>(changes, discord);
|
||||
|
||||
return new SocketAutoModRuleDeletedAuditLogData(new (data));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the auto moderation rule information before the changes.
|
||||
/// </summary>
|
||||
public SocketAutoModRuleInfo Data { get; }
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
using Discord.API.AuditLogs;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Represents information for an auto moderation rule.
|
||||
/// </summary>
|
||||
public class SocketAutoModRuleInfo
|
||||
{
|
||||
internal SocketAutoModRuleInfo(AutoModRuleInfoAuditLogModel model)
|
||||
{
|
||||
Actions = model.Actions?.Select(x => new AutoModRuleAction(
|
||||
x.Type,
|
||||
x.Metadata.GetValueOrDefault()?.ChannelId.ToNullable(),
|
||||
x.Metadata.GetValueOrDefault()?.DurationSeconds.ToNullable(),
|
||||
x.Metadata.IsSpecified
|
||||
? x.Metadata.Value.CustomMessage.IsSpecified
|
||||
? x.Metadata.Value.CustomMessage.Value
|
||||
: null
|
||||
: null
|
||||
)).ToImmutableArray();
|
||||
KeywordFilter = model.TriggerMetadata?.KeywordFilter.GetValueOrDefault(Array.Empty<string>())?.ToImmutableArray();
|
||||
Presets = model.TriggerMetadata?.Presets.GetValueOrDefault(Array.Empty<KeywordPresetTypes>())?.ToImmutableArray();
|
||||
RegexPatterns = model.TriggerMetadata?.RegexPatterns.GetValueOrDefault(Array.Empty<string>())?.ToImmutableArray();
|
||||
AllowList = model.TriggerMetadata?.AllowList.GetValueOrDefault(Array.Empty<string>())?.ToImmutableArray();
|
||||
MentionTotalLimit = model.TriggerMetadata?.MentionLimit.IsSpecified ?? false
|
||||
? model.TriggerMetadata?.MentionLimit.Value
|
||||
: null;
|
||||
Name = model.Name;
|
||||
Enabled = model.Enabled;
|
||||
ExemptRoles = model.ExemptRoles?.ToImmutableArray();
|
||||
ExemptChannels = model.ExemptChannels?.ToImmutableArray();
|
||||
TriggerType = model.TriggerType;
|
||||
EventType = model.EventType;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IAutoModRule.Name"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IAutoModRule.EventType"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
public AutoModEventType? EventType { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IAutoModRule.TriggerType"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
public AutoModTriggerType? TriggerType { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IAutoModRule.Enabled"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
public bool? Enabled { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IAutoModRule.ExemptRoles"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
public IReadOnlyCollection<ulong> ExemptRoles { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IAutoModRule.ExemptChannels"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
public IReadOnlyCollection<ulong> ExemptChannels { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IAutoModRule.KeywordFilter"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
public IReadOnlyCollection<string> KeywordFilter { get; }
|
||||
|
||||
/// <inheritdoc cref="IAutoModRule.RegexPatterns"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
public IReadOnlyCollection<string> RegexPatterns { get; }
|
||||
|
||||
/// <inheritdoc cref="IAutoModRule.AllowList"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
public IReadOnlyCollection<string> AllowList { get; }
|
||||
|
||||
/// <inheritdoc cref="IAutoModRule.Presets"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
public IReadOnlyCollection<KeywordPresetTypes> Presets { get; }
|
||||
|
||||
/// <inheritdoc cref="IAutoModRule.MentionTotalLimit"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
public int? MentionTotalLimit { get; }
|
||||
|
||||
/// <inheritdoc cref="IAutoModRule.Actions"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
public IReadOnlyCollection<AutoModRuleAction> Actions { get; private set; }
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to an auto moderation rule update.
|
||||
/// </summary>
|
||||
public class AutoModRuleUpdatedAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private AutoModRuleUpdatedAuditLogData(SocketAutoModRuleInfo before, SocketAutoModRuleInfo after)
|
||||
{
|
||||
Before = before;
|
||||
After = after;
|
||||
}
|
||||
|
||||
internal static AutoModRuleUpdatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo<AutoModRuleInfoAuditLogModel>(changes, discord);
|
||||
|
||||
return new AutoModRuleUpdatedAuditLogData(new(before), new(after));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the auto moderation rule information before the changes.
|
||||
/// </summary>
|
||||
public SocketAutoModRuleInfo Before { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the auto moderation rule information after the changes.
|
||||
/// </summary>
|
||||
public SocketAutoModRuleInfo After { get; }
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to user getting in timeout by automod.
|
||||
/// </summary>
|
||||
public class SocketAutoModTimeoutUserAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
internal SocketAutoModTimeoutUserAuditLogData(ulong channelId, string autoModRuleName, AutoModTriggerType autoModRuleTriggerType)
|
||||
{
|
||||
ChannelId = channelId;
|
||||
AutoModRuleName = autoModRuleName;
|
||||
AutoModRuleTriggerType = autoModRuleTriggerType;
|
||||
}
|
||||
|
||||
internal static SocketAutoModTimeoutUserAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
return new(entry.Options.ChannelId!.Value, entry.Options.AutoModRuleName,
|
||||
entry.Options.AutoModRuleTriggerType!.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channel the message was sent in.
|
||||
/// </summary>
|
||||
public ulong ChannelId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the auto moderation rule that got triggered.
|
||||
/// </summary>
|
||||
public string AutoModRuleName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the trigger type of the auto moderation rule that got triggered.
|
||||
/// </summary>
|
||||
public AutoModTriggerType AutoModRuleTriggerType { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using Discord.Rest;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a ban.
|
||||
/// </summary>
|
||||
public class SocketBanAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketBanAuditLogData(Cacheable<SocketUser, RestUser, IUser, ulong> user)
|
||||
{
|
||||
Target = user;
|
||||
}
|
||||
|
||||
internal static SocketBanAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var cachedUser = discord.GetUser(entry.TargetId!.Value);
|
||||
var cacheableUser = new Cacheable<SocketUser, RestUser, IUser, ulong>(
|
||||
cachedUser,
|
||||
entry.TargetId.Value,
|
||||
cachedUser is not null,
|
||||
async () =>
|
||||
{
|
||||
var user = await discord.ApiClient.GetUserAsync(entry.TargetId.Value);
|
||||
return user is not null ? RestUser.Create(discord, user) : null;
|
||||
});
|
||||
|
||||
return new SocketBanAuditLogData(cacheableUser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user that was banned.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Download method may return <see langword="null"/> if the user is a 'Deleted User#....'
|
||||
/// because Discord does send user data for deleted users.
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// A cacheable user object representing the banned user.
|
||||
/// </returns>
|
||||
public Cacheable<SocketUser, RestUser, IUser, ulong> Target { get; }
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using Discord.Rest;
|
||||
using System.Linq;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a adding a bot to a guild.
|
||||
/// </summary>
|
||||
public class SocketBotAddAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketBotAddAuditLogData(Cacheable<SocketUser, RestUser, IUser, ulong> bot)
|
||||
{
|
||||
Target = bot;
|
||||
}
|
||||
|
||||
internal static SocketBotAddAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var cachedUser = discord.GetUser(entry.TargetId!.Value);
|
||||
var cacheableUser = new Cacheable<SocketUser, RestUser, IUser, ulong>(
|
||||
cachedUser,
|
||||
entry.TargetId.Value,
|
||||
cachedUser is not null,
|
||||
async () =>
|
||||
{
|
||||
var user = await discord.ApiClient.GetUserAsync(entry.TargetId.Value);
|
||||
return user is not null ? RestUser.Create(discord, user) : null;
|
||||
});
|
||||
return new SocketBotAddAuditLogData(cacheableUser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bot that was added.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Will be <see langword="null"/> if the bot is a 'Deleted User#....' because Discord does send user data for deleted users.
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// A cacheable user object representing the bot.
|
||||
/// </returns>
|
||||
public Cacheable<SocketUser, RestUser, IUser, ulong> Target { get; }
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
using Discord.Rest;
|
||||
using Discord.API.AuditLogs;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a channel creation.
|
||||
/// </summary>
|
||||
public class SocketChannelCreateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketChannelCreateAuditLogData(ChannelInfoAuditLogModel model, EntryModel entry)
|
||||
{
|
||||
ChannelId = entry.TargetId!.Value;
|
||||
ChannelName = model.Name;
|
||||
ChannelType = model.Type!.Value;
|
||||
SlowModeInterval = model.RateLimitPerUser;
|
||||
IsNsfw = model.IsNsfw;
|
||||
Bitrate = model.Bitrate;
|
||||
Topic = model.Topic;
|
||||
AutoArchiveDuration = model.AutoArchiveDuration;
|
||||
DefaultSlowModeInterval = model.DefaultThreadRateLimitPerUser;
|
||||
DefaultAutoArchiveDuration = model.DefaultArchiveDuration;
|
||||
|
||||
AvailableTags = model.AvailableTags?.Select(x => new ForumTag(x.Id,
|
||||
x.Name,
|
||||
x.EmojiId.GetValueOrDefault(null),
|
||||
x.EmojiName.GetValueOrDefault(null),
|
||||
x.Moderated)).ToImmutableArray();
|
||||
|
||||
|
||||
if (model.DefaultEmoji is not null)
|
||||
{
|
||||
if (model.DefaultEmoji.EmojiId.HasValue && model.DefaultEmoji.EmojiId.Value != 0)
|
||||
DefaultReactionEmoji = new Emote(model.DefaultEmoji.EmojiId.GetValueOrDefault(), null, false);
|
||||
else if (model.DefaultEmoji.EmojiName.IsSpecified)
|
||||
DefaultReactionEmoji = new Emoji(model.DefaultEmoji.EmojiName.Value);
|
||||
else
|
||||
DefaultReactionEmoji = null;
|
||||
}
|
||||
else
|
||||
DefaultReactionEmoji = null;
|
||||
|
||||
VideoQualityMode = model.VideoQualityMode;
|
||||
RtcRegion = model.Region;
|
||||
Flags = model.Flags;
|
||||
UserLimit = model.UserLimit;
|
||||
}
|
||||
|
||||
internal static SocketChannelCreateAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo<ChannelInfoAuditLogModel>(changes, discord);
|
||||
|
||||
return new SocketChannelCreateAuditLogData(data, entry);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the snowflake ID of the created channel.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier for the created channel.
|
||||
/// </returns>
|
||||
public ulong ChannelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the created channel.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string containing the name of the created channel.
|
||||
/// </returns>
|
||||
public string ChannelName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the created channel.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The type of channel that was created.
|
||||
/// </returns>
|
||||
public ChannelType ChannelType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current slow-mode delay of the created channel.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the time in seconds required before the user can send another
|
||||
/// message; <c>0</c> if disabled.
|
||||
/// <c>null</c> if this is not mentioned in this entry.
|
||||
/// </returns>
|
||||
public int? SlowModeInterval { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value that indicates whether the created channel is NSFW.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the created channel has the NSFW flag enabled; otherwise <c>false</c>.
|
||||
/// <c>null</c> if this is not mentioned in this entry.
|
||||
/// </returns>
|
||||
public bool? IsNsfw { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bit-rate that the clients in the created voice channel are requested to use.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the bit-rate (bps) that the created voice channel defines and requests the
|
||||
/// client(s) to use.
|
||||
/// <c>null</c> if this is not mentioned in this entry.
|
||||
/// </returns>
|
||||
public int? Bitrate { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the thread archive duration that was set in the created channel.
|
||||
/// </summary>
|
||||
public ThreadArchiveDuration? AutoArchiveDuration { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default thread archive duration that was set in the created channel.
|
||||
/// </summary>
|
||||
public ThreadArchiveDuration? DefaultAutoArchiveDuration { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default slow mode interval that will be set in child threads in the channel.
|
||||
/// </summary>
|
||||
public int? DefaultSlowModeInterval { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the topic that was set in the created channel.
|
||||
/// </summary>
|
||||
public string Topic { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets tags available in the created forum channel.
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<ForumTag> AvailableTags { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default reaction added to posts in the created forum channel.
|
||||
/// </summary>
|
||||
public IEmote DefaultReactionEmoji { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user limit configured in the created voice channel.
|
||||
/// </summary>
|
||||
public int? UserLimit { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the video quality mode configured in the created voice channel.
|
||||
/// </summary>
|
||||
public VideoQualityMode? VideoQualityMode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the region configured in the created voice channel.
|
||||
/// </summary>
|
||||
public string RtcRegion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets channel flags configured for the created channel.
|
||||
/// </summary>
|
||||
public ChannelFlags? Flags { get; }
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
using Discord.Rest;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
using Model = Discord.API.AuditLogs.ChannelInfoAuditLogModel;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a channel deletion.
|
||||
/// </summary>
|
||||
public class SocketChannelDeleteAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketChannelDeleteAuditLogData(Model model, EntryModel entry)
|
||||
{
|
||||
ChannelId = entry.TargetId!.Value;
|
||||
ChannelType = model.Type;
|
||||
ChannelName = model.Name;
|
||||
|
||||
Topic = model.Topic;
|
||||
IsNsfw = model.IsNsfw;
|
||||
Bitrate = model.Bitrate;
|
||||
DefaultArchiveDuration = model.DefaultArchiveDuration;
|
||||
SlowModeInterval = model.RateLimitPerUser;
|
||||
|
||||
ForumTags = model.AvailableTags?.Select(
|
||||
x => new ForumTag(x.Id,
|
||||
x.Name,
|
||||
x.EmojiId.GetValueOrDefault(null),
|
||||
x.EmojiName.GetValueOrDefault(null),
|
||||
x.Moderated)).ToImmutableArray();
|
||||
|
||||
if (model.DefaultEmoji is not null)
|
||||
{
|
||||
if (model.DefaultEmoji.EmojiId.HasValue && model.DefaultEmoji.EmojiId.Value != 0)
|
||||
DefaultReactionEmoji = new Emote(model.DefaultEmoji.EmojiId.GetValueOrDefault(), null, false);
|
||||
else if (model.DefaultEmoji.EmojiName.IsSpecified)
|
||||
DefaultReactionEmoji = new Emoji(model.DefaultEmoji.EmojiName.Value);
|
||||
else
|
||||
DefaultReactionEmoji = null;
|
||||
}
|
||||
else
|
||||
DefaultReactionEmoji = null;
|
||||
AutoArchiveDuration = model.AutoArchiveDuration;
|
||||
DefaultSlowModeInterval = model.DefaultThreadRateLimitPerUser;
|
||||
|
||||
VideoQualityMode = model.VideoQualityMode;
|
||||
RtcRegion = model.Region;
|
||||
Flags = model.Flags;
|
||||
UserLimit = model.UserLimit;
|
||||
|
||||
Overwrites = model.Overwrites?.Select(x
|
||||
=> new Overwrite(x.TargetId,
|
||||
x.TargetType,
|
||||
new OverwritePermissions(x.Allow, x.Deny))).ToImmutableArray();
|
||||
}
|
||||
|
||||
internal static SocketChannelDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo<Model>(changes, discord);
|
||||
|
||||
return new SocketChannelDeleteAuditLogData(data, entry);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the snowflake ID of the deleted channel.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier for the deleted channel.
|
||||
/// </returns>
|
||||
public ulong ChannelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the deleted channel.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string containing the name of the deleted channel.
|
||||
/// </returns>
|
||||
public string ChannelName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the deleted channel.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The type of channel that was deleted.
|
||||
/// </returns>
|
||||
public ChannelType? ChannelType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the slow-mode delay of the deleted channel.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the time in seconds required before the user can send another
|
||||
/// message; <c>0</c> if disabled.
|
||||
/// <c>null</c> if this is not mentioned in this entry.
|
||||
/// </returns>
|
||||
public int? SlowModeInterval { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value that indicates whether the deleted channel was NSFW.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this channel had the NSFW flag enabled; otherwise <c>false</c>.
|
||||
/// <c>null</c> if this is not mentioned in this entry.
|
||||
/// </returns>
|
||||
public bool? IsNsfw { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bit-rate of this channel if applicable.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the bit-rate set of the voice channel.
|
||||
/// <c>null</c> if this is not mentioned in this entry.
|
||||
/// </returns>
|
||||
public int? Bitrate { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of permission overwrites that was assigned to the deleted channel.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A collection of permission <see cref="Overwrite"/>.
|
||||
/// </returns>
|
||||
public IReadOnlyCollection<Overwrite> Overwrites { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user limit configured in the created voice channel.
|
||||
/// </summary>
|
||||
public int? UserLimit { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the video quality mode configured in the created voice channel.
|
||||
/// </summary>
|
||||
public VideoQualityMode? VideoQualityMode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the region configured in the created voice channel.
|
||||
/// </summary>
|
||||
public string RtcRegion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets channel flags configured for the created channel.
|
||||
/// </summary>
|
||||
public ChannelFlags? Flags { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the thread archive duration that was configured for the created channel.
|
||||
/// </summary>
|
||||
public ThreadArchiveDuration? AutoArchiveDuration { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default slow mode interval that was configured for the channel.
|
||||
/// </summary>
|
||||
public int? DefaultSlowModeInterval { get; }
|
||||
|
||||
/// <inheritdoc cref="ITextChannel.DefaultArchiveDuration"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not specified in this entry..
|
||||
/// </remarks>
|
||||
public ThreadArchiveDuration? DefaultArchiveDuration { get; }
|
||||
|
||||
/// <inheritdoc cref="IForumChannel.Tags"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not specified in this entry..
|
||||
/// </remarks>
|
||||
public IReadOnlyCollection<ForumTag> ForumTags { get; }
|
||||
|
||||
/// <inheritdoc cref="ITextChannel.Topic"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not specified in this entry..
|
||||
/// </remarks>
|
||||
public string Topic { get; }
|
||||
|
||||
/// <inheritdoc cref="IForumChannel.DefaultReactionEmoji"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not specified in this entry..
|
||||
/// </remarks>
|
||||
public IEmote DefaultReactionEmoji { get; }
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using Model = Discord.API.AuditLogs.ChannelInfoAuditLogModel;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Represents information for a channel.
|
||||
/// </summary>
|
||||
public struct SocketChannelInfo
|
||||
{
|
||||
internal SocketChannelInfo(Model model)
|
||||
{
|
||||
Name = model.Name;
|
||||
Topic = model.Topic;
|
||||
IsNsfw = model.IsNsfw;
|
||||
Bitrate = model.Bitrate;
|
||||
DefaultArchiveDuration = model.DefaultArchiveDuration;
|
||||
ChannelType = model.Type;
|
||||
SlowModeInterval = model.RateLimitPerUser;
|
||||
|
||||
ForumTags = model.AvailableTags?.Select(
|
||||
x => new ForumTag(x.Id,
|
||||
x.Name,
|
||||
x.EmojiId.GetValueOrDefault(null),
|
||||
x.EmojiName.GetValueOrDefault(null),
|
||||
x.Moderated)).ToImmutableArray();
|
||||
|
||||
if (model.DefaultEmoji is not null)
|
||||
{
|
||||
if (model.DefaultEmoji.EmojiId.HasValue && model.DefaultEmoji.EmojiId.Value != 0)
|
||||
DefaultReactionEmoji = new Emote(model.DefaultEmoji.EmojiId.GetValueOrDefault(), null, false);
|
||||
else if (model.DefaultEmoji.EmojiName.IsSpecified)
|
||||
DefaultReactionEmoji = new Emoji(model.DefaultEmoji.EmojiName.Value);
|
||||
else
|
||||
DefaultReactionEmoji = null;
|
||||
}
|
||||
else
|
||||
DefaultReactionEmoji = null;
|
||||
AutoArchiveDuration = model.AutoArchiveDuration;
|
||||
DefaultSlowModeInterval = model.DefaultThreadRateLimitPerUser;
|
||||
|
||||
VideoQualityMode = model.VideoQualityMode;
|
||||
RTCRegion = model.Region;
|
||||
Flags = model.Flags;
|
||||
UserLimit = model.UserLimit;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IChannel.Name"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public string Name { get; }
|
||||
|
||||
/// <inheritdoc cref="ITextChannel.Topic"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public string Topic { get; }
|
||||
|
||||
/// <inheritdoc cref="ITextChannel.SlowModeInterval"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public int? SlowModeInterval { get; }
|
||||
|
||||
/// <inheritdoc cref="ITextChannel.IsNsfw"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public bool? IsNsfw { get; }
|
||||
|
||||
/// <inheritdoc cref="IVoiceChannel.Bitrate"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public int? Bitrate { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of this channel.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The channel type of this channel; <c>null</c> if not applicable.
|
||||
/// </returns>
|
||||
public ChannelType? ChannelType { get; }
|
||||
|
||||
/// <inheritdoc cref="ITextChannel.DefaultArchiveDuration"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public ThreadArchiveDuration? DefaultArchiveDuration { get; }
|
||||
|
||||
/// <inheritdoc cref="IForumChannel.Tags"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public IReadOnlyCollection<ForumTag> ForumTags { get; }
|
||||
|
||||
/// <inheritdoc cref="IForumChannel.DefaultReactionEmoji"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public IEmote DefaultReactionEmoji { get; }
|
||||
|
||||
/// <inheritdoc cref="IVoiceChannel.UserLimit"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public int? UserLimit { get; }
|
||||
|
||||
/// <inheritdoc cref="IVoiceChannel.VideoQualityMode"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public VideoQualityMode? VideoQualityMode { get; }
|
||||
|
||||
/// <inheritdoc cref="IAudioChannel.RTCRegion"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public string RTCRegion { get; }
|
||||
|
||||
/// <inheritdoc cref="IGuildChannel.Flags"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public ChannelFlags? Flags { get; }
|
||||
|
||||
/// <inheritdoc cref="IThreadChannel.AutoArchiveDuration"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public ThreadArchiveDuration? AutoArchiveDuration { get; }
|
||||
|
||||
/// <inheritdoc cref="IForumChannel.DefaultSlowModeInterval"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public int? DefaultSlowModeInterval { get; }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using Discord.Rest;
|
||||
using Discord.API.AuditLogs;
|
||||
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a channel update.
|
||||
/// </summary>
|
||||
public class SocketChannelUpdateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketChannelUpdateAuditLogData(ulong id, SocketChannelInfo before, SocketChannelInfo after)
|
||||
{
|
||||
ChannelId = id;
|
||||
Before = before;
|
||||
After = after;
|
||||
}
|
||||
|
||||
internal static SocketChannelUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo<ChannelInfoAuditLogModel>(changes, discord);
|
||||
|
||||
return new SocketChannelUpdateAuditLogData(entry.TargetId!.Value, new(before), new(after));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the snowflake ID of the updated channel.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier for the updated channel.
|
||||
/// </returns>
|
||||
public ulong ChannelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channel information before the changes.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An information object containing the original channel information before the changes were made.
|
||||
/// </returns>
|
||||
public SocketChannelInfo Before { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channel information after the changes.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An information object containing the channel information after the changes were made.
|
||||
/// </returns>
|
||||
public SocketChannelInfo After { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to an application command permission update.
|
||||
/// </summary>
|
||||
public class SocketCommandPermissionUpdateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
internal SocketCommandPermissionUpdateAuditLogData(IReadOnlyCollection<ApplicationCommandPermission> before, IReadOnlyCollection<ApplicationCommandPermission> after,
|
||||
ulong commandId, ulong appId)
|
||||
{
|
||||
Before = before;
|
||||
After = after;
|
||||
ApplicationId = appId;
|
||||
CommandId = commandId;
|
||||
}
|
||||
|
||||
internal static SocketCommandPermissionUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var before = new List<ApplicationCommandPermission>();
|
||||
var after = new List<ApplicationCommandPermission>();
|
||||
|
||||
foreach (var change in changes)
|
||||
{
|
||||
var oldValue = change.OldValue?.ToObject<API.ApplicationCommandPermissions>();
|
||||
var newValue = change.NewValue?.ToObject<API.ApplicationCommandPermissions>();
|
||||
|
||||
if (oldValue is not null)
|
||||
before.Add(new ApplicationCommandPermission(oldValue.Id, oldValue.Type, oldValue.Permission));
|
||||
|
||||
if (newValue is not null)
|
||||
after.Add(new ApplicationCommandPermission(newValue.Id, newValue.Type, newValue.Permission));
|
||||
}
|
||||
|
||||
return new(before.ToImmutableArray(), after.ToImmutableArray(), entry.TargetId!.Value, entry.Options.ApplicationId!.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the app whose permissions were targeted.
|
||||
/// </summary>
|
||||
public ulong ApplicationId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the id of the application command which permissions were updated.
|
||||
/// </summary>
|
||||
public ulong CommandId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets values of the permissions before the change if available.
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<ApplicationCommandPermission> Before { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets values of the permissions after the change if available.
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<ApplicationCommandPermission> After { get; }
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System.Linq;
|
||||
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to an emoji creation.
|
||||
/// </summary>
|
||||
public class SocketEmoteCreateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketEmoteCreateAuditLogData(ulong id, string name)
|
||||
{
|
||||
EmoteId = id;
|
||||
Name = name;
|
||||
}
|
||||
|
||||
internal static SocketEmoteCreateAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var change = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name");
|
||||
|
||||
var emoteName = change.NewValue?.ToObject<string>(discord.ApiClient.Serializer);
|
||||
return new SocketEmoteCreateAuditLogData(entry.TargetId!.Value, emoteName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the snowflake ID of the created emoji.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier for the created emoji.
|
||||
/// </returns>
|
||||
public ulong EmoteId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the created emoji.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string containing the name of the created emoji.
|
||||
/// </returns>
|
||||
public string Name { get; }
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System.Linq;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to an emoji deletion.
|
||||
/// </summary>
|
||||
public class SocketEmoteDeleteAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketEmoteDeleteAuditLogData(ulong id, string name)
|
||||
{
|
||||
EmoteId = id;
|
||||
Name = name;
|
||||
}
|
||||
|
||||
internal static SocketEmoteDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var change = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name");
|
||||
|
||||
var emoteName = change.OldValue?.ToObject<string>(discord.ApiClient.Serializer);
|
||||
|
||||
return new SocketEmoteDeleteAuditLogData(entry.TargetId!.Value, emoteName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the snowflake ID of the deleted emoji.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier for the deleted emoji.
|
||||
/// </returns>
|
||||
public ulong EmoteId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the deleted emoji.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string containing the name of the deleted emoji.
|
||||
/// </returns>
|
||||
public string Name { get; }
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using System.Linq;
|
||||
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to an emoji update.
|
||||
/// </summary>
|
||||
public class SocketEmoteUpdateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketEmoteUpdateAuditLogData(ulong id, string oldName, string newName)
|
||||
{
|
||||
EmoteId = id;
|
||||
OldName = oldName;
|
||||
NewName = newName;
|
||||
}
|
||||
|
||||
internal static SocketEmoteUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var change = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name");
|
||||
|
||||
var newName = change.NewValue?.ToObject<string>(discord.ApiClient.Serializer);
|
||||
var oldName = change.OldValue?.ToObject<string>(discord.ApiClient.Serializer);
|
||||
|
||||
return new SocketEmoteUpdateAuditLogData(entry.TargetId!.Value, oldName, newName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the snowflake ID of the updated emoji.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier of the updated emoji.
|
||||
/// </returns>
|
||||
public ulong EmoteId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the new name of the updated emoji.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string containing the new name of the updated emoji.
|
||||
/// </returns>
|
||||
public string NewName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the old name of the updated emoji.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string containing the old name of the updated emoji.
|
||||
/// </returns>
|
||||
public string OldName { get; }
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
using Model = Discord.API.AuditLogs.GuildInfoAuditLogModel;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Represents information for a guild.
|
||||
/// </summary>
|
||||
public class SocketGuildInfo
|
||||
{
|
||||
internal static SocketGuildInfo Create(Model model)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Name = model.Name,
|
||||
AfkTimeout = model.AfkTimeout.GetValueOrDefault(),
|
||||
IsEmbeddable = model.IsEmbeddable,
|
||||
DefaultMessageNotifications = model.DefaultMessageNotifications,
|
||||
MfaLevel = model.MfaLevel,
|
||||
Description = model.Description,
|
||||
PreferredLocale = model.PreferredLocale,
|
||||
IconHash = model.IconHash,
|
||||
OwnerId = model.OwnerId,
|
||||
AfkChannelId = model.AfkChannelId,
|
||||
ApplicationId = model.ApplicationId,
|
||||
BannerId = model.Banner,
|
||||
DiscoverySplashId = model.DiscoverySplash,
|
||||
EmbedChannelId = model.EmbeddedChannelId,
|
||||
ExplicitContentFilter = model.ExplicitContentFilterLevel,
|
||||
IsBoostProgressBarEnabled = model.ProgressBarEnabled,
|
||||
NsfwLevel = model.NsfwLevel,
|
||||
PublicUpdatesChannelId = model.PublicUpdatesChannelId,
|
||||
RegionId = model.RegionId,
|
||||
RulesChannelId = model.RulesChannelId,
|
||||
SplashId = model.Splash,
|
||||
SystemChannelFlags = model.SystemChannelFlags,
|
||||
SystemChannelId = model.SystemChannelId,
|
||||
VanityURLCode = model.VanityUrl,
|
||||
VerificationLevel = model.VerificationLevel
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IGuild.Name"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public string Name { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.AFKTimeout"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public int? AfkTimeout { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.IsWidgetEnabled"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public bool? IsEmbeddable { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.DefaultMessageNotifications"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public DefaultMessageNotifications? DefaultMessageNotifications { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.MfaLevel"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public MfaLevel? MfaLevel { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.VerificationLevel"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public VerificationLevel? VerificationLevel { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.ExplicitContentFilter"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public ExplicitContentFilterLevel? ExplicitContentFilter { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.IconId"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public string IconHash { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.SplashId"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public string SplashId { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.DiscoverySplashId"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public string DiscoverySplashId { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.AFKChannelId"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public ulong? AfkChannelId { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.WidgetChannelId"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public ulong? EmbedChannelId { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.SystemChannelId"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public ulong? SystemChannelId { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.RulesChannelId"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public ulong? RulesChannelId { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.PublicUpdatesChannelId"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public ulong? PublicUpdatesChannelId { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.OwnerId"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public ulong? OwnerId { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.ApplicationId"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public ulong? ApplicationId { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.VoiceRegionId"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public string RegionId { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.BannerId"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public string BannerId { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.VanityURLCode"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public string VanityURLCode { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.SystemChannelFlags"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public SystemChannelMessageDeny? SystemChannelFlags { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.Description"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public string Description { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.PreferredLocale"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public string PreferredLocale { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.NsfwLevel"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public NsfwLevel? NsfwLevel { get; private set; }
|
||||
|
||||
/// <inheritdoc cref="IGuild.IsBoostProgressBarEnabled"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public bool? IsBoostProgressBarEnabled { get; private set; }
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System.Linq;
|
||||
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
using InfoModel = Discord.API.AuditLogs.GuildInfoAuditLogModel;
|
||||
|
||||
namespace Discord.WebSocket
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a guild update.
|
||||
/// </summary>
|
||||
public class SocketGuildUpdateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketGuildUpdateAuditLogData(SocketGuildInfo before, SocketGuildInfo after)
|
||||
{
|
||||
Before = before;
|
||||
After = after;
|
||||
}
|
||||
|
||||
internal static SocketGuildUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var info = Rest.AuditLogHelper.CreateAuditLogEntityInfo<InfoModel>(entry.Changes, discord);
|
||||
|
||||
var data = new SocketGuildUpdateAuditLogData(SocketGuildInfo.Create(info.Item1), SocketGuildInfo.Create(info.Item2));
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the guild information before the changes.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An information object containing the original guild information before the changes were made.
|
||||
/// </returns>
|
||||
public SocketGuildInfo Before { get; }
|
||||
/// <summary>
|
||||
/// Gets the guild information after the changes.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An information object containing the guild information after the changes were made.
|
||||
/// </returns>
|
||||
public SocketGuildInfo After { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to an integration authorization.
|
||||
/// </summary>
|
||||
public class SocketIntegrationCreatedAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
internal SocketIntegrationCreatedAuditLogData(SocketIntegrationInfo info)
|
||||
{
|
||||
Data = info;
|
||||
}
|
||||
|
||||
internal static SocketIntegrationCreatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo<IntegrationInfoAuditLogModel>(changes, discord);
|
||||
|
||||
return new(new SocketIntegrationInfo(data));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the integration information after the changes.
|
||||
/// </summary>
|
||||
public SocketIntegrationInfo Data { get; }
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to an integration removal.
|
||||
/// </summary>
|
||||
public class SocketIntegrationDeletedAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
internal SocketIntegrationDeletedAuditLogData(SocketIntegrationInfo info)
|
||||
{
|
||||
Data = info;
|
||||
}
|
||||
|
||||
internal static SocketIntegrationDeletedAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo<IntegrationInfoAuditLogModel>(changes, discord);
|
||||
|
||||
return new(new SocketIntegrationInfo(data));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the integration information before the changes.
|
||||
/// </summary>
|
||||
public SocketIntegrationInfo Data { get; }
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Represents information for an integration.
|
||||
/// </summary>
|
||||
public class SocketIntegrationInfo
|
||||
{
|
||||
internal SocketIntegrationInfo(IntegrationInfoAuditLogModel model)
|
||||
{
|
||||
Name = model.Name;
|
||||
Type = model.Type;
|
||||
EnableEmojis = model.EnableEmojis;
|
||||
Enabled = model.Enabled;
|
||||
Scopes = model.Scopes?.ToImmutableArray();
|
||||
ExpireBehavior = model.ExpireBehavior;
|
||||
ExpireGracePeriod = model.ExpireGracePeriod;
|
||||
Syncing = model.Syncing;
|
||||
RoleId = model.RoleId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the integration. <see landword="null"/> if the property was not mentioned in this audit log.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the integration. <see landword="null"/> if the property was not mentioned in this audit log.
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets if the integration is enabled. <see landword="null"/> if the property was not mentioned in this audit log.
|
||||
/// </summary>
|
||||
public bool? Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets if syncing is enabled for this integration. <see landword="null"/> if the property was not mentioned in this audit log.
|
||||
/// </summary>
|
||||
public bool? Syncing { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the id of the role that this integration uses for subscribers. <see landword="null"/> if the property was not mentioned in this audit log.
|
||||
/// </summary>
|
||||
public ulong? RoleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether emoticons should be synced for this integration. <see landword="null"/> if the property was not mentioned in this audit log.
|
||||
/// </summary>
|
||||
public bool? EnableEmojis { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the behavior of expiring subscribers. <see landword="null"/> if the property was not mentioned in this audit log.
|
||||
/// </summary>
|
||||
public IntegrationExpireBehavior? ExpireBehavior { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the grace period (in days) before expiring subscribers. <see landword="null"/> if the property was not mentioned in this audit log.
|
||||
/// </summary>
|
||||
public int? ExpireGracePeriod { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scopes the application has been authorized for. <see landword="null"/> if the property was not mentioned in this audit log.
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<string> Scopes { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to an integration update.
|
||||
/// </summary>
|
||||
public class SocketIntegrationUpdatedAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
internal SocketIntegrationUpdatedAuditLogData(SocketIntegrationInfo before, SocketIntegrationInfo after)
|
||||
{
|
||||
Before = before;
|
||||
After = after;
|
||||
}
|
||||
|
||||
internal static SocketIntegrationUpdatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo<IntegrationInfoAuditLogModel>(changes, discord);
|
||||
|
||||
return new(new SocketIntegrationInfo(before), new SocketIntegrationInfo(after));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the integration information before the changes.
|
||||
/// </summary>
|
||||
public SocketIntegrationInfo Before { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the integration information after the changes.
|
||||
/// </summary>
|
||||
public SocketIntegrationInfo After { get; }
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to an invite creation.
|
||||
/// </summary>
|
||||
public class SocketInviteCreateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketInviteCreateAuditLogData(InviteInfoAuditLogModel model, Cacheable<SocketUser, RestUser, IUser, ulong>? inviter)
|
||||
{
|
||||
MaxAge = model.MaxAge!.Value;
|
||||
Code = model.Code;
|
||||
Temporary = model.Temporary!.Value;
|
||||
ChannelId = model.ChannelId!.Value;
|
||||
Uses = model.Uses!.Value;
|
||||
MaxUses = model.MaxUses!.Value;
|
||||
|
||||
Creator = inviter;
|
||||
}
|
||||
|
||||
internal static SocketInviteCreateAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo<InviteInfoAuditLogModel>(changes, discord);
|
||||
|
||||
Cacheable<SocketUser, RestUser, IUser, ulong>? cacheableUser = null;
|
||||
|
||||
if (data.InviterId is not null)
|
||||
{
|
||||
var cachedUser = discord.GetUser(data.InviterId.Value);
|
||||
cacheableUser = new Cacheable<SocketUser, RestUser, IUser, ulong>(
|
||||
cachedUser,
|
||||
data.InviterId.Value,
|
||||
cachedUser is not null,
|
||||
async () =>
|
||||
{
|
||||
var user = await discord.ApiClient.GetUserAsync(data.InviterId.Value);
|
||||
return user is not null ? RestUser.Create(discord, user) : null;
|
||||
});
|
||||
}
|
||||
|
||||
return new SocketInviteCreateAuditLogData(data, cacheableUser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the time (in seconds) until the invite expires.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the time in seconds until this invite expires.
|
||||
/// </returns>
|
||||
public int MaxAge { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique identifier for this invite.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string containing the invite code (e.g. <c>FTqNnyS</c>).
|
||||
/// </returns>
|
||||
public string Code { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that determines whether the invite is a temporary one.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if users accepting this invite will be removed from the guild when they log off; otherwise
|
||||
/// <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Temporary { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user that created this invite if available.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Will be <see langword="null"/> if the user is a 'Deleted User#....' because Discord does send user data for deleted users.
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// A user that created this invite or <see langword="null"/>.
|
||||
/// </returns>
|
||||
public Cacheable<SocketUser, RestUser, IUser, ulong>? Creator { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the channel this invite is linked to.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the channel snowflake identifier that the invite points to.
|
||||
/// </returns>
|
||||
public ulong ChannelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of times this invite has been used.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the number of times this invite was used.
|
||||
/// </returns>
|
||||
public int Uses { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the max number of uses this invite may have.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the number of uses this invite may be accepted until it is removed
|
||||
/// from the guild; <c>null</c> if none is set.
|
||||
/// </returns>
|
||||
public int MaxUses { get; }
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to an invite removal.
|
||||
/// </summary>
|
||||
public class SocketInviteDeleteAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketInviteDeleteAuditLogData(InviteInfoAuditLogModel model, Cacheable<SocketUser, RestUser, IUser, ulong>? inviter)
|
||||
{
|
||||
MaxAge = model.MaxAge!.Value;
|
||||
Code = model.Code;
|
||||
Temporary = model.Temporary!.Value;
|
||||
Creator = inviter;
|
||||
ChannelId = model.ChannelId!.Value;
|
||||
Uses = model.Uses!.Value;
|
||||
MaxUses = model.MaxUses!.Value;
|
||||
}
|
||||
|
||||
internal static SocketInviteDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo<InviteInfoAuditLogModel>(changes, discord);
|
||||
|
||||
Cacheable<SocketUser, RestUser, IUser, ulong>? cacheableUser = null;
|
||||
|
||||
if (data.InviterId != null)
|
||||
{
|
||||
var cachedUser = discord.GetUser(data.InviterId.Value);
|
||||
cacheableUser = new Cacheable<SocketUser, RestUser, IUser, ulong>(
|
||||
cachedUser,
|
||||
data.InviterId.Value,
|
||||
cachedUser is not null,
|
||||
async () =>
|
||||
{
|
||||
var user = await discord.ApiClient.GetUserAsync(data.InviterId.Value);
|
||||
return user is not null ? RestUser.Create(discord, user) : null;
|
||||
});
|
||||
}
|
||||
|
||||
return new SocketInviteDeleteAuditLogData(data, cacheableUser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the time (in seconds) until the invite expires.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the time in seconds until this invite expires.
|
||||
/// </returns>
|
||||
public int MaxAge { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique identifier for this invite.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string containing the invite code (e.g. <c>FTqNnyS</c>).
|
||||
/// </returns>
|
||||
public string Code { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that indicates whether the invite is a temporary one.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if users accepting this invite will be removed from the guild when they log off; otherwise
|
||||
/// <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Temporary { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user that created this invite if available.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Will be <see langword="null"/> if the user is a 'Deleted User#....' because Discord does send user data for deleted users.
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// A user that created this invite or <see langword="null"/>.
|
||||
/// </returns>
|
||||
public Cacheable<SocketUser, RestUser, IUser, ulong>? Creator { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the channel this invite is linked to.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the channel snowflake identifier that the invite points to.
|
||||
/// </returns>
|
||||
public ulong ChannelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of times this invite has been used.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the number of times this invite has been used.
|
||||
/// </returns>
|
||||
public int Uses { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the max number of uses this invite may have.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the number of uses this invite may be accepted until it is removed
|
||||
/// from the guild; <c>null</c> if none is set.
|
||||
/// </returns>
|
||||
public int MaxUses { get; }
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using Model = Discord.API.AuditLogs.InviteInfoAuditLogModel;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Represents information for an invite.
|
||||
/// </summary>
|
||||
public struct SocketInviteInfo
|
||||
{
|
||||
internal SocketInviteInfo(Model model)
|
||||
{
|
||||
MaxAge = model.MaxAge;
|
||||
Code = model.Code;
|
||||
Temporary = model.Temporary;
|
||||
ChannelId = model.ChannelId;
|
||||
MaxUses = model.MaxUses;
|
||||
CreatorId = model.InviterId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the time (in seconds) until the invite expires.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the time in seconds until this invite expires; <c>null</c> if this
|
||||
/// invite never expires or not specified.
|
||||
/// </returns>
|
||||
public int? MaxAge { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique identifier for this invite.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string containing the invite code (e.g. <c>FTqNnyS</c>).
|
||||
/// </returns>
|
||||
public string Code { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that indicates whether the invite is a temporary one.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if users accepting this invite will be removed from the guild when they log off,
|
||||
/// <c>false</c> if not; <c>null</c> if not specified.
|
||||
/// </returns>
|
||||
public bool? Temporary { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the channel this invite is linked to.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the channel snowflake identifier that the invite points to;
|
||||
/// <c>null</c> if not specified.
|
||||
/// </returns>
|
||||
public ulong? ChannelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the max number of uses this invite may have.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the number of uses this invite may be accepted until it is removed
|
||||
/// from the guild; <c>null</c> if none is specified.
|
||||
/// </returns>
|
||||
public int? MaxUses { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the id of the user created this invite.
|
||||
/// </summary>
|
||||
public ulong? CreatorId { get; }
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data relating to an invite update.
|
||||
/// </summary>
|
||||
public class SocketInviteUpdateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketInviteUpdateAuditLogData(SocketInviteInfo before, SocketInviteInfo after)
|
||||
{
|
||||
Before = before;
|
||||
After = after;
|
||||
}
|
||||
|
||||
internal static SocketInviteUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo<InviteInfoAuditLogModel>(changes, discord);
|
||||
|
||||
return new SocketInviteUpdateAuditLogData(new(before), new(after));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the invite information before the changes.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An information object containing the original invite information before the changes were made.
|
||||
/// </returns>
|
||||
public SocketInviteInfo Before { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the invite information after the changes.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An information object containing the invite information after the changes were made.
|
||||
/// </returns>
|
||||
public SocketInviteInfo After { get; }
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using Discord.Rest;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a kick.
|
||||
/// </summary>
|
||||
public class SocketKickAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketKickAuditLogData(Cacheable<SocketUser, RestUser, IUser, ulong> user)
|
||||
{
|
||||
Target = user;
|
||||
}
|
||||
|
||||
internal static SocketKickAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var cachedUser = discord.GetUser(entry.Id);
|
||||
var cacheableUser = new Cacheable<SocketUser, RestUser, IUser, ulong>(
|
||||
cachedUser,
|
||||
entry.Id,
|
||||
cachedUser is not null,
|
||||
async () =>
|
||||
{
|
||||
var user = await discord.ApiClient.GetUserAsync(entry.TargetId!.Value);
|
||||
return user is not null ? RestUser.Create(discord, user) : null;
|
||||
});
|
||||
|
||||
return new SocketKickAuditLogData(cacheableUser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user that was kicked.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Download method may return <see langword="null"/> if the user is a 'Deleted User#....'
|
||||
/// because Discord does send user data for deleted users.
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// A cacheable user object representing the kicked user.
|
||||
/// </returns>
|
||||
public Cacheable<SocketUser, RestUser, IUser, ulong> Target { get; }
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to disconnecting members from voice channels.
|
||||
/// </summary>
|
||||
public class SocketMemberDisconnectAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketMemberDisconnectAuditLogData(int count)
|
||||
{
|
||||
MemberCount = count;
|
||||
}
|
||||
|
||||
internal static SocketMemberDisconnectAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
return new SocketMemberDisconnectAuditLogData(entry.Options.Count!.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of members that were disconnected.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the number of members that were disconnected from a voice channel.
|
||||
/// </returns>
|
||||
public int MemberCount { get; }
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to moving members between voice channels.
|
||||
/// </summary>
|
||||
public class SocketMemberMoveAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketMemberMoveAuditLogData(ulong channelId, int count)
|
||||
{
|
||||
ChannelId = channelId;
|
||||
MemberCount = count;
|
||||
}
|
||||
|
||||
internal static SocketMemberMoveAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
return new SocketMemberMoveAuditLogData(entry.Options.ChannelId!.Value, entry.Options.Count!.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the channel that the members were moved to.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier for the channel that the members were moved to.
|
||||
/// </returns>
|
||||
public ulong ChannelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of members that were moved.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the number of members that were moved to another voice channel.
|
||||
/// </returns>
|
||||
public int MemberCount { get; }
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using Discord.Rest;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a change in a guild member's roles.
|
||||
/// </summary>
|
||||
public class SocketMemberRoleAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketMemberRoleAuditLogData(IReadOnlyCollection<SocketMemberRoleEditInfo> roles, Cacheable<SocketUser, RestUser, IUser, ulong> target)
|
||||
{
|
||||
Roles = roles;
|
||||
Target = target;
|
||||
}
|
||||
|
||||
internal static SocketMemberRoleAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var roleInfos = changes.SelectMany(x => x.NewValue.ToObject<API.Role[]>(discord.ApiClient.Serializer),
|
||||
(model, role) => new { model.ChangedProperty, Role = role })
|
||||
.Select(x => new SocketMemberRoleEditInfo(x.Role.Name, x.Role.Id, x.ChangedProperty == "$add"))
|
||||
.ToList();
|
||||
|
||||
var cachedUser = discord.GetUser(entry.TargetId!.Value);
|
||||
var cacheableUser = new Cacheable<SocketUser, RestUser, IUser, ulong>(
|
||||
cachedUser,
|
||||
entry.TargetId.Value,
|
||||
cachedUser is not null,
|
||||
async () =>
|
||||
{
|
||||
var user = await discord.ApiClient.GetUserAsync(entry.TargetId.Value);
|
||||
return user is not null ? RestUser.Create(discord, user) : null;
|
||||
});
|
||||
|
||||
return new SocketMemberRoleAuditLogData(roleInfos.ToReadOnlyCollection(), cacheableUser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of role changes that were performed on the member.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A read-only collection of <see cref="SocketMemberRoleEditInfo"/>, containing the roles that were changed on
|
||||
/// the member.
|
||||
/// </returns>
|
||||
public IReadOnlyCollection<SocketMemberRoleEditInfo> Roles { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user that the roles changes were performed on.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A cacheable user object representing the user that the role changes were performed on.
|
||||
/// </returns>
|
||||
public Cacheable<SocketUser, RestUser, IUser, ulong> Target { get; }
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// An information object representing a change in one of a guild member's roles.
|
||||
/// </summary>
|
||||
public struct SocketMemberRoleEditInfo
|
||||
{
|
||||
internal SocketMemberRoleEditInfo(string name, ulong roleId, bool added)
|
||||
{
|
||||
Name = name;
|
||||
RoleId = roleId;
|
||||
Added = added;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the role that was changed.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string containing the name of the role that was changed.
|
||||
/// </returns>
|
||||
public string Name { get; }
|
||||
/// <summary>
|
||||
/// Gets the ID of the role that was changed.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier of the role that was changed.
|
||||
/// </returns>
|
||||
public ulong RoleId { get; }
|
||||
/// <summary>
|
||||
/// Gets a value that indicates whether the role was added to the user.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the role was added to the user; otherwise <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Added { get; }
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a change in a guild member.
|
||||
/// </summary>
|
||||
public class SocketMemberUpdateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketMemberUpdateAuditLogData(Cacheable<SocketUser, RestUser, IUser, ulong> target, MemberInfo before, MemberInfo after)
|
||||
{
|
||||
Target = target;
|
||||
Before = before;
|
||||
After = after;
|
||||
}
|
||||
|
||||
internal static SocketMemberUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo<MemberInfoAuditLogModel>(changes, discord);
|
||||
|
||||
var cachedUser = discord.GetUser(entry.TargetId!.Value);
|
||||
var cacheableUser = new Cacheable<SocketUser, RestUser, IUser, ulong>(
|
||||
cachedUser,
|
||||
entry.TargetId.Value,
|
||||
cachedUser is not null,
|
||||
async () =>
|
||||
{
|
||||
var user = await discord.ApiClient.GetUserAsync(entry.TargetId.Value);
|
||||
return user is not null ? RestUser.Create(discord, user) : null;
|
||||
});
|
||||
|
||||
return new SocketMemberUpdateAuditLogData(cacheableUser, new MemberInfo(before), new MemberInfo(after));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user that the changes were performed on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Will be <see langword="null"/> if the user is a 'Deleted User#....' because Discord does send user data for deleted users.
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// A user object representing the user who the changes were performed on.
|
||||
/// </returns>
|
||||
public Cacheable<SocketUser, RestUser, IUser, ulong> Target { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the member information before the changes.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An information object containing the original member information before the changes were made.
|
||||
/// </returns>
|
||||
public MemberInfo Before { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the member information after the changes.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An information object containing the member information after the changes were made.
|
||||
/// </returns>
|
||||
public MemberInfo After { get; }
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to message deletion(s).
|
||||
/// </summary>
|
||||
public class SocketMessageBulkDeleteAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketMessageBulkDeleteAuditLogData(ulong channelId, int count)
|
||||
{
|
||||
ChannelId = channelId;
|
||||
MessageCount = count;
|
||||
}
|
||||
|
||||
internal static SocketMessageBulkDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
return new SocketMessageBulkDeleteAuditLogData(entry.TargetId!.Value, entry.Options.Count!.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the channel that the messages were deleted from.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier for the channel that the messages were
|
||||
/// deleted from.
|
||||
/// </returns>
|
||||
public ulong ChannelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of messages that were deleted.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the number of messages that were deleted from the channel.
|
||||
/// </returns>
|
||||
public int MessageCount { get; }
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using Discord.Rest;
|
||||
using System;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to message deletion(s).
|
||||
/// </summary>
|
||||
public class SocketMessageDeleteAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketMessageDeleteAuditLogData(ulong channelId, int count, Cacheable<SocketUser, RestUser, IUser, ulong> user)
|
||||
{
|
||||
ChannelId = channelId;
|
||||
MessageCount = count;
|
||||
Target = user;
|
||||
}
|
||||
|
||||
internal static SocketMessageDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var cachedUser = discord.GetUser(entry.TargetId!.Value);
|
||||
var cacheableUser = new Cacheable<SocketUser, RestUser, IUser, ulong>(
|
||||
cachedUser,
|
||||
entry.TargetId.Value,
|
||||
cachedUser is not null,
|
||||
async () =>
|
||||
{
|
||||
var user = await discord.ApiClient.GetUserAsync(entry.TargetId.Value);
|
||||
return user is not null ? RestUser.Create(discord, user) : null;
|
||||
});
|
||||
|
||||
return new SocketMessageDeleteAuditLogData(entry.Options.ChannelId!.Value, entry.Options.Count!.Value, cacheableUser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of messages that were deleted.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the number of messages that were deleted from the channel.
|
||||
/// </returns>
|
||||
public int MessageCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the channel that the messages were deleted from.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier for the channel that the messages were
|
||||
/// deleted from.
|
||||
/// </returns>
|
||||
public ulong ChannelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user of the messages that were deleted.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Will be <see langword="null"/> if the user is a 'Deleted User#....' because Discord does send user data for deleted users.
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// A user object representing the user that created the deleted messages.
|
||||
/// </returns>
|
||||
public Cacheable<SocketUser, RestUser, IUser, ulong> Target { get; }
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using Discord.Rest;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a pinned message.
|
||||
/// </summary>
|
||||
public class SocketMessagePinAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketMessagePinAuditLogData(ulong messageId, ulong channelId, Cacheable<SocketUser, RestUser, IUser, ulong>? user)
|
||||
{
|
||||
MessageId = messageId;
|
||||
ChannelId = channelId;
|
||||
Target = user;
|
||||
}
|
||||
|
||||
internal static SocketMessagePinAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
Cacheable<SocketUser, RestUser, IUser, ulong>? cacheableUser = null;
|
||||
|
||||
if (entry.TargetId.HasValue)
|
||||
{
|
||||
var cachedUser = discord.GetUser(entry.TargetId.Value);
|
||||
cacheableUser = new Cacheable<SocketUser, RestUser, IUser, ulong>(
|
||||
cachedUser,
|
||||
entry.TargetId.Value,
|
||||
cachedUser is not null,
|
||||
async () =>
|
||||
{
|
||||
var user = await discord.ApiClient.GetUserAsync(entry.TargetId.Value);
|
||||
return user is not null ? RestUser.Create(discord, user) : null;
|
||||
});
|
||||
}
|
||||
|
||||
return new SocketMessagePinAuditLogData(entry.Options.MessageId!.Value, entry.Options.ChannelId!.Value, cacheableUser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the messages that was pinned.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier for the messages that was pinned.
|
||||
/// </returns>
|
||||
public ulong MessageId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the channel that the message was pinned from.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier for the channel that the message was pinned from.
|
||||
/// </returns>
|
||||
public ulong ChannelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user of the message that was pinned if available.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Will be <see langword="null"/> if the user is a 'Deleted User#....' because Discord does send user data for deleted users.
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// A user object representing the user that created the pinned message or <see langword="null"/>.
|
||||
/// </returns>
|
||||
public Cacheable<SocketUser, RestUser, IUser, ulong>? Target { get; }
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using Discord.Rest;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to an unpinned message.
|
||||
/// </summary>
|
||||
public class SocketMessageUnpinAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketMessageUnpinAuditLogData(ulong messageId, ulong channelId, Cacheable<SocketUser, RestUser, IUser, ulong>? user)
|
||||
{
|
||||
MessageId = messageId;
|
||||
ChannelId = channelId;
|
||||
Target = user;
|
||||
}
|
||||
|
||||
internal static SocketMessageUnpinAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
Cacheable<SocketUser, RestUser, IUser, ulong>? cacheableUser = null;
|
||||
if (entry.TargetId.HasValue)
|
||||
{
|
||||
var cachedUser = discord.GetUser(entry.TargetId.Value);
|
||||
cacheableUser = new Cacheable<SocketUser, RestUser, IUser, ulong>(
|
||||
cachedUser,
|
||||
entry.TargetId.Value,
|
||||
cachedUser is not null,
|
||||
async () =>
|
||||
{
|
||||
var user = await discord.ApiClient.GetUserAsync(entry.TargetId.Value);
|
||||
return user is not null ? RestUser.Create(discord, user) : null;
|
||||
});
|
||||
}
|
||||
|
||||
return new SocketMessageUnpinAuditLogData(entry.Options.MessageId!.Value, entry.Options.ChannelId!.Value, cacheableUser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the messages that was unpinned.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier for the messages that was unpinned.
|
||||
/// </returns>
|
||||
public ulong MessageId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the channel that the message was unpinned from.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier for the channel that the message was unpinned from.
|
||||
/// </returns>
|
||||
public ulong ChannelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user of the message that was unpinned if available.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Will be <see langword="null"/> if the user is a 'Deleted User#....' because Discord does send user data for deleted users.
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// A user object representing the user that created the unpinned message or <see langword="null"/>.
|
||||
/// </returns>
|
||||
public Cacheable<SocketUser, RestUser, IUser, ulong>? Target { get; }
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
public class SocketOnboardingInfo
|
||||
{
|
||||
internal SocketOnboardingInfo(OnboardingAuditLogModel model, DiscordSocketClient discord)
|
||||
{
|
||||
Prompts = model.Prompts?.Select(x => new RestGuildOnboardingPrompt(discord, x.Id, x)).ToImmutableArray();
|
||||
DefaultChannelIds = model.DefaultChannelIds;
|
||||
IsEnabled = model.Enabled;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IGuildOnboarding.Prompts"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
IReadOnlyCollection<IGuildOnboardingPrompt> Prompts { get; }
|
||||
|
||||
/// <inheritdoc cref="IGuildOnboarding.DefaultChannelIds"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
IReadOnlyCollection<ulong> DefaultChannelIds { get; }
|
||||
|
||||
/// <inheritdoc cref="IGuildOnboarding.IsEnabled"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
bool? IsEnabled { get; }
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to an onboarding prompt creation.
|
||||
/// </summary>
|
||||
public class SocketOnboardingPromptCreatedAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
internal SocketOnboardingPromptCreatedAuditLogData(SocketOnboardingPromptInfo data)
|
||||
{
|
||||
Data = data;
|
||||
}
|
||||
|
||||
internal static SocketOnboardingPromptCreatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo<OnboardingPromptAuditLogModel>(changes, discord);
|
||||
|
||||
return new SocketOnboardingPromptCreatedAuditLogData(new(data, discord));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the onboarding prompt information after the changes.
|
||||
/// </summary>
|
||||
SocketOnboardingPromptInfo Data { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
public class SocketOnboardingPromptInfo
|
||||
{
|
||||
internal SocketOnboardingPromptInfo(OnboardingPromptAuditLogModel model, DiscordSocketClient discord)
|
||||
{
|
||||
Title = model.Title;
|
||||
IsSingleSelect = model.IsSingleSelect;
|
||||
IsRequired = model.IsRequired;
|
||||
IsInOnboarding = model.IsInOnboarding;
|
||||
Type = model.Type;
|
||||
Options = model.Options?.Select(x => new RestGuildOnboardingPromptOption(discord, x.Id, x)).ToImmutableArray();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IGuildOnboardingPrompt.Title"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
string Title { get; }
|
||||
|
||||
/// <inheritdoc cref="IGuildOnboardingPrompt.IsSingleSelect"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
bool? IsSingleSelect { get; }
|
||||
|
||||
/// <inheritdoc cref="IGuildOnboardingPrompt.IsRequired"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
bool? IsRequired { get; }
|
||||
|
||||
/// <inheritdoc cref="IGuildOnboardingPrompt.IsInOnboarding"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
bool? IsInOnboarding { get; }
|
||||
|
||||
/// <inheritdoc cref="IGuildOnboardingPrompt.Type"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
GuildOnboardingPromptType? Type { get; }
|
||||
|
||||
/// <inheritdoc cref="IGuildOnboardingPrompt.Options"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this property is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
IReadOnlyCollection<IGuildOnboardingPromptOption> Options { get; }
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using Discord.Rest;
|
||||
using Discord.API.AuditLogs;
|
||||
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to an onboarding prompt update.
|
||||
/// </summary>
|
||||
public class SocketOnboardingPromptUpdatedAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
internal SocketOnboardingPromptUpdatedAuditLogData(SocketOnboardingPromptInfo before, SocketOnboardingPromptInfo after)
|
||||
{
|
||||
Before = before;
|
||||
After = after;
|
||||
}
|
||||
|
||||
internal static SocketOnboardingPromptUpdatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo<OnboardingPromptAuditLogModel>(changes, discord);
|
||||
|
||||
return new SocketOnboardingPromptUpdatedAuditLogData(new(before, discord), new(after, discord));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the onboarding prompt information after the changes.
|
||||
/// </summary>
|
||||
SocketOnboardingPromptInfo After { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the onboarding prompt information before the changes.
|
||||
/// </summary>
|
||||
SocketOnboardingPromptInfo Before { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
using Discord.Rest;
|
||||
using Discord.API.AuditLogs;
|
||||
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a guild update.
|
||||
/// </summary>
|
||||
public class SocketOnboardingUpdatedAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
internal SocketOnboardingUpdatedAuditLogData(SocketOnboardingInfo before, SocketOnboardingInfo after)
|
||||
{
|
||||
Before = before;
|
||||
After = after;
|
||||
}
|
||||
|
||||
internal static SocketOnboardingUpdatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo<OnboardingAuditLogModel>(changes, discord);
|
||||
|
||||
return new SocketOnboardingUpdatedAuditLogData(new(before, discord), new(after, discord));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the onboarding information after the changes.
|
||||
/// </summary>
|
||||
SocketOnboardingInfo After { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the onboarding information before the changes.
|
||||
/// </summary>
|
||||
SocketOnboardingInfo Before { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using System.Linq;
|
||||
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data for a permissions overwrite creation.
|
||||
/// </summary>
|
||||
public class SocketOverwriteCreateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketOverwriteCreateAuditLogData(ulong channelId, Overwrite overwrite)
|
||||
{
|
||||
ChannelId = channelId;
|
||||
Overwrite = overwrite;
|
||||
}
|
||||
|
||||
internal static SocketOverwriteCreateAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var denyModel = changes.FirstOrDefault(x => x.ChangedProperty == "deny");
|
||||
var allowModel = changes.FirstOrDefault(x => x.ChangedProperty == "allow");
|
||||
|
||||
var deny = denyModel.NewValue.ToObject<ulong>(discord.ApiClient.Serializer);
|
||||
var allow = allowModel.NewValue.ToObject<ulong>(discord.ApiClient.Serializer);
|
||||
|
||||
var permissions = new OverwritePermissions(allow, deny);
|
||||
|
||||
var id = entry.Options.OverwriteTargetId.Value;
|
||||
var type = entry.Options.OverwriteType;
|
||||
|
||||
return new SocketOverwriteCreateAuditLogData(entry.TargetId.Value, new Overwrite(id, type, permissions));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the channel that the overwrite was created from.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier for the channel that the overwrite was
|
||||
/// created from.
|
||||
/// </returns>
|
||||
public ulong ChannelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the permission overwrite object that was created.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="Overwrite"/> object representing the overwrite that was created.
|
||||
/// </returns>
|
||||
public Overwrite Overwrite { get; }
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System.Linq;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to the deletion of a permission overwrite.
|
||||
/// </summary>
|
||||
public class SocketOverwriteDeleteAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketOverwriteDeleteAuditLogData(ulong channelId, Overwrite deletedOverwrite)
|
||||
{
|
||||
ChannelId = channelId;
|
||||
Overwrite = deletedOverwrite;
|
||||
}
|
||||
|
||||
internal static SocketOverwriteDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var denyModel = changes.FirstOrDefault(x => x.ChangedProperty == "deny");
|
||||
var allowModel = changes.FirstOrDefault(x => x.ChangedProperty == "allow");
|
||||
|
||||
var deny = denyModel.OldValue.ToObject<ulong>(discord.ApiClient.Serializer);
|
||||
var allow = allowModel.OldValue.ToObject<ulong>(discord.ApiClient.Serializer);
|
||||
|
||||
var permissions = new OverwritePermissions(allow, deny);
|
||||
|
||||
var id = entry.Options.OverwriteTargetId.Value;
|
||||
var type = entry.Options.OverwriteType;
|
||||
|
||||
return new SocketOverwriteDeleteAuditLogData(entry.TargetId!.Value, new Overwrite(id, type, permissions));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the channel that the overwrite was deleted from.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier for the channel that the overwrite was
|
||||
/// deleted from.
|
||||
/// </returns>
|
||||
public ulong ChannelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the permission overwrite object that was deleted.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="Overwrite"/> object representing the overwrite that was deleted.
|
||||
/// </returns>
|
||||
public Overwrite Overwrite { get; }
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.Linq;
|
||||
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to the update of a permission overwrite.
|
||||
/// </summary>
|
||||
public class SocketOverwriteUpdateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketOverwriteUpdateAuditLogData(ulong channelId, OverwritePermissions before, OverwritePermissions after, ulong targetId, PermissionTarget targetType)
|
||||
{
|
||||
ChannelId = channelId;
|
||||
OldPermissions = before;
|
||||
NewPermissions = after;
|
||||
OverwriteTargetId = targetId;
|
||||
OverwriteType = targetType;
|
||||
}
|
||||
|
||||
internal static SocketOverwriteUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var denyModel = changes.FirstOrDefault(x => x.ChangedProperty == "deny");
|
||||
var allowModel = changes.FirstOrDefault(x => x.ChangedProperty == "allow");
|
||||
|
||||
var beforeAllow = allowModel?.OldValue?.ToObject<ulong>(discord.ApiClient.Serializer);
|
||||
var afterAllow = allowModel?.NewValue?.ToObject<ulong>(discord.ApiClient.Serializer);
|
||||
var beforeDeny = denyModel?.OldValue?.ToObject<ulong>(discord.ApiClient.Serializer);
|
||||
var afterDeny = denyModel?.NewValue?.ToObject<ulong>(discord.ApiClient.Serializer);
|
||||
|
||||
var beforePermissions = new OverwritePermissions(beforeAllow ?? 0, beforeDeny ?? 0);
|
||||
var afterPermissions = new OverwritePermissions(afterAllow ?? 0, afterDeny ?? 0);
|
||||
|
||||
var type = entry.Options.OverwriteType;
|
||||
|
||||
return new SocketOverwriteUpdateAuditLogData(entry.TargetId.Value, beforePermissions, afterPermissions, entry.Options.OverwriteTargetId.Value, type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the channel that the overwrite was updated from.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier for the channel that the overwrite was
|
||||
/// updated from.
|
||||
/// </returns>
|
||||
public ulong ChannelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the overwrite permissions before the changes.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An overwrite permissions object representing the overwrite permissions that the overwrite had before
|
||||
/// the changes were made.
|
||||
/// </returns>
|
||||
public OverwritePermissions OldPermissions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the overwrite permissions after the changes.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An overwrite permissions object representing the overwrite permissions that the overwrite had after the
|
||||
/// changes.
|
||||
/// </returns>
|
||||
public OverwritePermissions NewPermissions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the overwrite that was updated.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier of the overwrite that was updated.
|
||||
/// </returns>
|
||||
public ulong OverwriteTargetId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the target of the updated permission overwrite.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The target of the updated permission overwrite.
|
||||
/// </returns>
|
||||
public PermissionTarget OverwriteType { get; }
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a guild prune.
|
||||
/// </summary>
|
||||
public class SocketPruneAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketPruneAuditLogData(int pruneDays, int membersRemoved)
|
||||
{
|
||||
PruneDays = pruneDays;
|
||||
MembersRemoved = membersRemoved;
|
||||
}
|
||||
|
||||
internal static SocketPruneAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
return new SocketPruneAuditLogData(entry.Options.PruneDeleteMemberDays!.Value, entry.Options.PruneMembersRemoved!.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the threshold for a guild member to not be kicked.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the amount of days that a member must have been seen in the server,
|
||||
/// to avoid being kicked. (i.e. If a user has not been seen for more than <paramref cref="PruneDays"/>, they will be
|
||||
/// kicked from the server)
|
||||
/// </returns>
|
||||
public int PruneDays { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of members that were kicked during the purge.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the number of members that were removed from this guild for having
|
||||
/// not been seen within <paramref cref="PruneDays"/>.
|
||||
/// </returns>
|
||||
public int MembersRemoved { get; }
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using Discord.Rest;
|
||||
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
using Model = Discord.API.AuditLogs.RoleInfoAuditLogModel;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a role creation.
|
||||
/// </summary>
|
||||
public class SocketRoleCreateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketRoleCreateAuditLogData(ulong id, SocketRoleEditInfo props)
|
||||
{
|
||||
RoleId = id;
|
||||
Properties = props;
|
||||
}
|
||||
|
||||
internal static SocketRoleCreateAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo<Model>(changes, discord);
|
||||
|
||||
return new SocketRoleCreateAuditLogData(entry.TargetId!.Value,
|
||||
new SocketRoleEditInfo(data));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the role that was created.
|
||||
/// </summary>
|
||||
/// <return>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier to the role that was created.
|
||||
/// </return>
|
||||
public ulong RoleId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the role information that was created.
|
||||
/// </summary>
|
||||
/// <return>
|
||||
/// An information object representing the properties of the role that was created.
|
||||
/// </return>
|
||||
public SocketRoleEditInfo Properties { get; }
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using Discord.Rest;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
using Model = Discord.API.AuditLogs.RoleInfoAuditLogModel;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data relating to a role deletion.
|
||||
/// </summary>
|
||||
public class SocketRoleDeleteAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketRoleDeleteAuditLogData(ulong id, SocketRoleEditInfo props)
|
||||
{
|
||||
RoleId = id;
|
||||
Properties = props;
|
||||
}
|
||||
|
||||
internal static SocketRoleDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo<Model>(changes, discord);
|
||||
|
||||
return new SocketRoleDeleteAuditLogData(entry.TargetId!.Value,
|
||||
new SocketRoleEditInfo(data));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the role that was deleted.
|
||||
/// </summary>
|
||||
/// <return>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier to the role that was deleted.
|
||||
/// </return>
|
||||
public ulong RoleId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the role information that was deleted.
|
||||
/// </summary>
|
||||
/// <return>
|
||||
/// An information object representing the properties of the role that was deleted.
|
||||
/// </return>
|
||||
public SocketRoleEditInfo Properties { get; }
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
using Model = Discord.API.AuditLogs.RoleInfoAuditLogModel;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Represents information for a role edit.
|
||||
/// </summary>
|
||||
public struct SocketRoleEditInfo
|
||||
{
|
||||
internal SocketRoleEditInfo(Model model)
|
||||
{
|
||||
if (model.Color is not null)
|
||||
Color = new Color(model.Color.Value);
|
||||
else
|
||||
Color = null;
|
||||
|
||||
Mentionable = model.IsMentionable;
|
||||
Hoist = model.Hoist;
|
||||
Name = model.Name;
|
||||
|
||||
if(model.Permissions is not null)
|
||||
Permissions = new GuildPermissions(model.Permissions.Value);
|
||||
else
|
||||
Permissions = null;
|
||||
|
||||
IconId = model.IconHash;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color of this role.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A color object representing the color assigned to this role; <c>null</c> if this role does not have a
|
||||
/// color.
|
||||
/// </returns>
|
||||
public Color? Color { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that indicates whether this role is mentionable.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if other members can mention this role in a text channel; otherwise <c>false</c>;
|
||||
/// <c>null</c> if this is not mentioned in this entry.
|
||||
/// </returns>
|
||||
public bool? Mentionable { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that indicates whether this role is hoisted (i.e. its members will appear in a separate
|
||||
/// section on the user list).
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this role's members will appear in a separate section in the user list; otherwise
|
||||
/// <c>false</c>; <c>null</c> if this is not mentioned in this entry.
|
||||
/// </returns>
|
||||
public bool? Hoist { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of this role.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string containing the name of this role.
|
||||
/// </returns>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the permissions assigned to this role.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A guild permissions object representing the permissions that have been assigned to this role; <c>null</c>
|
||||
/// if no permissions have been assigned.
|
||||
/// </returns>
|
||||
public GuildPermissions? Permissions { get; }
|
||||
|
||||
/// <inheritdoc cref="IRole.Icon"/>
|
||||
/// <remarks>
|
||||
/// <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </remarks>
|
||||
public string IconId { get; }
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using Discord.Rest;
|
||||
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
using Model = Discord.API.AuditLogs.RoleInfoAuditLogModel;
|
||||
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a role update.
|
||||
/// </summary>
|
||||
public class SocketRoleUpdateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketRoleUpdateAuditLogData(ulong id, SocketRoleEditInfo oldProps, SocketRoleEditInfo newProps)
|
||||
{
|
||||
RoleId = id;
|
||||
Before = oldProps;
|
||||
After = newProps;
|
||||
}
|
||||
|
||||
internal static SocketRoleUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo<Model>(changes, discord);
|
||||
|
||||
return new SocketRoleUpdateAuditLogData(entry.TargetId!.Value, new(before), new(after));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the role that was changed.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier of the role that was changed.
|
||||
/// </returns>
|
||||
public ulong RoleId { get; }
|
||||
/// <summary>
|
||||
/// Gets the role information before the changes.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A role information object containing the role information before the changes were made.
|
||||
/// </returns>
|
||||
public SocketRoleEditInfo Before { get; }
|
||||
/// <summary>
|
||||
/// Gets the role information after the changes.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A role information object containing the role information after the changes were made.
|
||||
/// </returns>
|
||||
public SocketRoleEditInfo After { get; }
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using System;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a scheduled event creation.
|
||||
/// </summary>
|
||||
public class SocketScheduledEventCreateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketScheduledEventCreateAuditLogData(ulong id, ScheduledEventInfoAuditLogModel model)
|
||||
{
|
||||
Id = id;
|
||||
ChannelId = model.ChannelId;
|
||||
Name = model.Name;
|
||||
Description = model.Description;
|
||||
ScheduledStartTime = model.StartTime;
|
||||
ScheduledEndTime = model.EndTime;
|
||||
PrivacyLevel = model.PrivacyLevel!.Value;
|
||||
Status = model.EventStatus!.Value;
|
||||
EntityType = model.EventType!.Value;
|
||||
EntityId = model.EntityId;
|
||||
Location = model.Location;
|
||||
Image = model.Image;
|
||||
}
|
||||
|
||||
internal static SocketScheduledEventCreateAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo<ScheduledEventInfoAuditLogModel>(changes, discord);
|
||||
|
||||
return new SocketScheduledEventCreateAuditLogData(entry.TargetId!.Value, data);
|
||||
}
|
||||
|
||||
// Doc Note: Corresponds to the *current* data
|
||||
|
||||
/// <summary>
|
||||
/// Gets the snowflake id of the event.
|
||||
/// </summary>
|
||||
public ulong Id { get; }
|
||||
/// <summary>
|
||||
/// Gets the snowflake id of the channel the event is associated with.
|
||||
/// </summary>
|
||||
public ulong? ChannelId { get; }
|
||||
/// <summary>
|
||||
/// Gets name of the event.
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
/// <summary>
|
||||
/// Gets the description of the event. null if none is set.
|
||||
/// </summary>
|
||||
public string Description { get; }
|
||||
/// <summary>
|
||||
/// Gets the time the event was scheduled for.
|
||||
/// </summary>
|
||||
public DateTimeOffset? ScheduledStartTime { get; }
|
||||
/// <summary>
|
||||
/// Gets the time the event was scheduled to end.
|
||||
/// </summary>
|
||||
public DateTimeOffset? ScheduledEndTime { get; }
|
||||
/// <summary>
|
||||
/// Gets the privacy level of the event.
|
||||
/// </summary>
|
||||
public GuildScheduledEventPrivacyLevel PrivacyLevel { get; }
|
||||
/// <summary>
|
||||
/// Gets the status of the event.
|
||||
/// </summary>
|
||||
public GuildScheduledEventStatus Status { get; }
|
||||
/// <summary>
|
||||
/// Gets the type of the entity associated with the event (stage / void / external).
|
||||
/// </summary>
|
||||
public GuildScheduledEventType EntityType { get; }
|
||||
/// <summary>
|
||||
/// Gets the snowflake id of the entity associated with the event (stage / void / external).
|
||||
/// </summary>
|
||||
public ulong? EntityId { get; }
|
||||
/// <summary>
|
||||
/// Gets the metadata for the entity associated with the event.
|
||||
/// </summary>
|
||||
public string Location { get; }
|
||||
/// <summary>
|
||||
/// Gets the image hash of the image that was attached to the event. Null if not set.
|
||||
/// </summary>
|
||||
public string Image { get; }
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using System;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a scheduled event deletion.
|
||||
/// </summary>
|
||||
public class SocketScheduledEventDeleteAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketScheduledEventDeleteAuditLogData(ulong id, ScheduledEventInfoAuditLogModel model)
|
||||
{
|
||||
Id = id;
|
||||
ChannelId = model.ChannelId;
|
||||
Name = model.Name;
|
||||
Description = model.Description;
|
||||
ScheduledStartTime = model.StartTime;
|
||||
ScheduledEndTime = model.EndTime;
|
||||
PrivacyLevel = model.PrivacyLevel;
|
||||
Status = model.EventStatus;
|
||||
EntityType = model.EventType;
|
||||
EntityId = model.EntityId;
|
||||
Location = model.Location;
|
||||
Image = model.Image;
|
||||
}
|
||||
|
||||
internal static SocketScheduledEventDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo<ScheduledEventInfoAuditLogModel>(changes, discord);
|
||||
|
||||
return new SocketScheduledEventDeleteAuditLogData(entry.TargetId!.Value, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the snowflake id of the event.
|
||||
/// </summary>
|
||||
public ulong Id { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the snowflake id of the channel the event is associated with.
|
||||
/// </summary>
|
||||
public ulong? ChannelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets name of the event.
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the description of the event. null if none is set.
|
||||
/// </summary>
|
||||
public string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the time the event was scheduled for.
|
||||
/// </summary>
|
||||
public DateTimeOffset? ScheduledStartTime { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the time the event was scheduled to end.
|
||||
/// </summary>
|
||||
public DateTimeOffset? ScheduledEndTime { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the privacy level of the event.
|
||||
/// </summary>
|
||||
public GuildScheduledEventPrivacyLevel? PrivacyLevel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the status of the event.
|
||||
/// </summary>
|
||||
public GuildScheduledEventStatus? Status { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the entity associated with the event (stage / void / external).
|
||||
/// </summary>
|
||||
public GuildScheduledEventType? EntityType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the snowflake id of the entity associated with the event (stage / void / external).
|
||||
/// </summary>
|
||||
public ulong? EntityId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the metadata for the entity associated with the event.
|
||||
/// </summary>
|
||||
public string Location { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image hash of the image that was attached to the event. Null if not set.
|
||||
/// </summary>
|
||||
public string Image { get; }
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using System;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Represents information for a scheduled event.
|
||||
/// </summary>
|
||||
public class SocketScheduledEventInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the snowflake id of the channel the event is associated with.
|
||||
/// </summary>
|
||||
public ulong? ChannelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets name of the event.
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the description of the event. null if none is set.
|
||||
/// </summary>
|
||||
public string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the time the event was scheduled for.
|
||||
/// </summary>
|
||||
public DateTimeOffset? ScheduledStartTime { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the time the event was scheduled to end.
|
||||
/// </summary>
|
||||
public DateTimeOffset? ScheduledEndTime { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the privacy level of the event.
|
||||
/// </summary>
|
||||
public GuildScheduledEventPrivacyLevel? PrivacyLevel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the status of the event.
|
||||
/// </summary>
|
||||
public GuildScheduledEventStatus? Status { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the entity associated with the event (stage / void / external).
|
||||
/// </summary>
|
||||
public GuildScheduledEventType? EntityType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the snowflake id of the entity associated with the event (stage / void / external).
|
||||
/// </summary>
|
||||
public ulong? EntityId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the metadata for the entity associated with the event.
|
||||
/// </summary>
|
||||
public string Location { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image hash of the image that was attached to the event. Null if not set.
|
||||
/// </summary>
|
||||
public string Image { get; }
|
||||
|
||||
internal SocketScheduledEventInfo(ScheduledEventInfoAuditLogModel model)
|
||||
{
|
||||
ChannelId = model.ChannelId;
|
||||
Name = model.Name;
|
||||
Description = model.Description;
|
||||
ScheduledStartTime = model.StartTime;
|
||||
ScheduledEndTime = model.EndTime;
|
||||
PrivacyLevel = model.PrivacyLevel;
|
||||
Status = model.EventStatus;
|
||||
EntityType = model.EventType;
|
||||
EntityId = model.EntityId;
|
||||
Location = model.Location;
|
||||
Image = model.Image;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a scheduled event updates.
|
||||
/// </summary>
|
||||
public class SocketScheduledEventUpdateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketScheduledEventUpdateAuditLogData(ulong id, SocketScheduledEventInfo before, SocketScheduledEventInfo after)
|
||||
{
|
||||
Id = id;
|
||||
Before = before;
|
||||
After = after;
|
||||
}
|
||||
|
||||
internal static SocketScheduledEventUpdateAuditLogData Create(BaseDiscordClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo<ScheduledEventInfoAuditLogModel>(changes, discord);
|
||||
|
||||
return new SocketScheduledEventUpdateAuditLogData(entry.TargetId!.Value, new(before), new(after));
|
||||
}
|
||||
|
||||
// Doc Note: Corresponds to the *current* data
|
||||
|
||||
/// <summary>
|
||||
/// Gets the snowflake id of the event.
|
||||
/// </summary>
|
||||
public ulong Id { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the state before the change.
|
||||
/// </summary>
|
||||
public SocketScheduledEventInfo Before { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the state after the change.
|
||||
/// </summary>
|
||||
public SocketScheduledEventInfo After { get; }
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Represents information for a stage.
|
||||
/// </summary>
|
||||
public class SocketStageInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the topic of the stage channel.
|
||||
/// </summary>
|
||||
public string Topic { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the privacy level of the stage channel.
|
||||
/// </summary>
|
||||
public StagePrivacyLevel? PrivacyLevel { get; }
|
||||
|
||||
internal SocketStageInfo(StagePrivacyLevel? level, string topic)
|
||||
{
|
||||
Topic = topic;
|
||||
PrivacyLevel = level;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System.Linq;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a stage going live.
|
||||
/// </summary>
|
||||
public class SocketStageInstanceCreateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the topic of the stage channel.
|
||||
/// </summary>
|
||||
public string Topic { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the privacy level of the stage channel.
|
||||
/// </summary>
|
||||
public StagePrivacyLevel PrivacyLevel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Id of the stage channel.
|
||||
/// </summary>
|
||||
public ulong StageChannelId { get; }
|
||||
|
||||
internal SocketStageInstanceCreateAuditLogData(string topic, StagePrivacyLevel privacyLevel, ulong channelId)
|
||||
{
|
||||
Topic = topic;
|
||||
PrivacyLevel = privacyLevel;
|
||||
StageChannelId = channelId;
|
||||
}
|
||||
|
||||
internal static SocketStageInstanceCreateAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var topic = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "topic").NewValue.ToObject<string>(discord.ApiClient.Serializer);
|
||||
var privacyLevel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "privacy_level").NewValue.ToObject<StagePrivacyLevel>(discord.ApiClient.Serializer);
|
||||
var channelId = entry.Options.ChannelId;
|
||||
|
||||
return new SocketStageInstanceCreateAuditLogData(topic, privacyLevel, channelId ?? 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System.Linq;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a stage instance deleted.
|
||||
/// </summary>
|
||||
public class SocketStageInstanceDeleteAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the topic of the stage channel.
|
||||
/// </summary>
|
||||
public string Topic { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the privacy level of the stage channel.
|
||||
/// </summary>
|
||||
public StagePrivacyLevel PrivacyLevel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Id of the stage channel.
|
||||
/// </summary>
|
||||
public ulong StageChannelId { get; }
|
||||
|
||||
internal SocketStageInstanceDeleteAuditLogData(string topic, StagePrivacyLevel privacyLevel, ulong channelId)
|
||||
{
|
||||
Topic = topic;
|
||||
PrivacyLevel = privacyLevel;
|
||||
StageChannelId = channelId;
|
||||
}
|
||||
|
||||
internal static SocketStageInstanceDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var topic = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "topic").OldValue.ToObject<string>(discord.ApiClient.Serializer);
|
||||
var privacyLevel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "privacy_level").OldValue.ToObject<StagePrivacyLevel>(discord.ApiClient.Serializer);
|
||||
var channelId = entry.Options.ChannelId;
|
||||
|
||||
return new SocketStageInstanceDeleteAuditLogData(topic, privacyLevel, channelId ?? 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System.Linq;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a stage instance update.
|
||||
/// </summary>
|
||||
public class SocketStageInstanceUpdatedAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the Id of the stage channel.
|
||||
/// </summary>
|
||||
public ulong StageChannelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the stage information before the changes.
|
||||
/// </summary>
|
||||
public SocketStageInfo Before { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the stage information after the changes.
|
||||
/// </summary>
|
||||
public SocketStageInfo After { get; }
|
||||
|
||||
internal SocketStageInstanceUpdatedAuditLogData(ulong channelId, SocketStageInfo before, SocketStageInfo after)
|
||||
{
|
||||
StageChannelId = channelId;
|
||||
Before = before;
|
||||
After = after;
|
||||
}
|
||||
|
||||
internal static SocketStageInstanceUpdatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var channelId = entry.Options.ChannelId.Value;
|
||||
|
||||
var topic = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "topic");
|
||||
var privacy = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "privacy");
|
||||
|
||||
var oldTopic = topic?.OldValue.ToObject<string>();
|
||||
var newTopic = topic?.NewValue.ToObject<string>();
|
||||
var oldPrivacy = privacy?.OldValue.ToObject<StagePrivacyLevel>();
|
||||
var newPrivacy = privacy?.NewValue.ToObject<StagePrivacyLevel>();
|
||||
|
||||
return new SocketStageInstanceUpdatedAuditLogData(channelId, new SocketStageInfo(oldPrivacy, oldTopic), new SocketStageInfo(newPrivacy, newTopic));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a sticker creation.
|
||||
/// </summary>
|
||||
public class SocketStickerCreatedAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
internal SocketStickerCreatedAuditLogData(SocketStickerInfo data)
|
||||
{
|
||||
Data = data;
|
||||
}
|
||||
|
||||
internal static SocketStickerCreatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo<StickerInfoAuditLogModel>(changes, discord);
|
||||
|
||||
return new SocketStickerCreatedAuditLogData(new(data));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sticker information after the changes.
|
||||
/// </summary>
|
||||
public SocketStickerInfo Data { get; }
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a sticker removal.
|
||||
/// </summary>
|
||||
public class SocketStickerDeletedAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
internal SocketStickerDeletedAuditLogData(SocketStickerInfo data)
|
||||
{
|
||||
Data = data;
|
||||
}
|
||||
|
||||
internal static SocketStickerDeletedAuditLogData Create(BaseDiscordClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo<StickerInfoAuditLogModel>(changes, discord);
|
||||
|
||||
return new SocketStickerDeletedAuditLogData(new(data));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sticker information before the changes.
|
||||
/// </summary>
|
||||
public SocketStickerInfo Data { get; }
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using Discord.API.AuditLogs;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Represents information for a guild.
|
||||
/// </summary>
|
||||
public class SocketStickerInfo
|
||||
{
|
||||
internal SocketStickerInfo(StickerInfoAuditLogModel model)
|
||||
{
|
||||
Name = model.Name;
|
||||
Tags = model.Tags;
|
||||
Description = model.Description;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the sticker. <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets tags of the sticker. <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </summary>
|
||||
public string Tags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the description of the sticker. <see langword="null" /> if the value was not updated in this entry.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a sticker update.
|
||||
/// </summary>
|
||||
public class SocketStickerUpdatedAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
internal SocketStickerUpdatedAuditLogData(SocketStickerInfo before, SocketStickerInfo after)
|
||||
{
|
||||
Before = before;
|
||||
After = after;
|
||||
}
|
||||
|
||||
internal static SocketStickerUpdatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo<StickerInfoAuditLogModel>(changes, discord);
|
||||
|
||||
return new SocketStickerUpdatedAuditLogData(new(before), new (after));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sticker information before the changes.
|
||||
/// </summary>
|
||||
public SocketStickerInfo Before { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sticker information after the changes.
|
||||
/// </summary>
|
||||
public SocketStickerInfo After { get; }
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using System.Collections.Generic;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a thread creation.
|
||||
/// </summary>
|
||||
public class SocketThreadCreateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketThreadCreateAuditLogData(ulong id, ThreadInfoAuditLogModel model)
|
||||
{
|
||||
ThreadId = id;
|
||||
|
||||
ThreadName = model.Name;
|
||||
IsArchived = model.IsArchived!.Value;
|
||||
AutoArchiveDuration = model.ArchiveDuration!.Value;
|
||||
IsLocked = model.IsLocked!.Value;
|
||||
SlowModeInterval = model.SlowModeInterval;
|
||||
AppliedTags = model.AppliedTags;
|
||||
Flags = model.ChannelFlags;
|
||||
ThreadType = model.Type;
|
||||
}
|
||||
|
||||
internal static SocketThreadCreateAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo<ThreadInfoAuditLogModel>(changes, discord);
|
||||
|
||||
return new SocketThreadCreateAuditLogData(entry.TargetId!.Value, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the snowflake ID of the thread.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier for the thread.
|
||||
/// </returns>
|
||||
public ulong ThreadId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the thread.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string containing the name of the thread.
|
||||
/// </returns>
|
||||
public string ThreadName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the thread.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The type of thread.
|
||||
/// </returns>
|
||||
public ThreadType ThreadType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value that indicates whether the thread is archived.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this thread has the Archived flag enabled; otherwise <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsArchived { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the auto archive duration of the thread.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The thread auto archive duration of the thread.
|
||||
/// </returns>
|
||||
public ThreadArchiveDuration AutoArchiveDuration { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value that indicates whether the thread is locked.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this thread has the Locked flag enabled; otherwise <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsLocked { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the slow-mode delay of the thread.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the time in seconds required before the user can send another
|
||||
/// message; <c>0</c> if disabled.
|
||||
/// <c>null</c> if this is not mentioned in this entry.
|
||||
/// </returns>
|
||||
public int? SlowModeInterval { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the applied tags of this thread.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if the property was not updated.
|
||||
/// </remarks>
|
||||
public IReadOnlyCollection<ulong> AppliedTags { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the flags of the thread channel.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if the property was not updated.
|
||||
/// </remarks>
|
||||
public ChannelFlags? Flags { get; }
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using System.Collections.Generic;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a thread deletion.
|
||||
/// </summary>
|
||||
public class SocketThreadDeleteAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketThreadDeleteAuditLogData(ulong id, ThreadInfoAuditLogModel model)
|
||||
{
|
||||
ThreadId = id;
|
||||
|
||||
ThreadName = model.Name;
|
||||
IsArchived = model.IsArchived!.Value;
|
||||
AutoArchiveDuration = model.ArchiveDuration!.Value;
|
||||
IsLocked = model.IsLocked!.Value;
|
||||
SlowModeInterval = model.SlowModeInterval;
|
||||
AppliedTags = model.AppliedTags;
|
||||
Flags = model.ChannelFlags;
|
||||
ThreadType = model.Type;
|
||||
}
|
||||
|
||||
internal static SocketThreadDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo<ThreadInfoAuditLogModel>(changes, discord);
|
||||
|
||||
return new SocketThreadDeleteAuditLogData(entry.TargetId!.Value, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the snowflake ID of the deleted thread.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier for the deleted thread.
|
||||
///
|
||||
/// </returns>
|
||||
public ulong ThreadId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the deleted thread.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string containing the name of the deleted thread.
|
||||
///
|
||||
/// </returns>
|
||||
public string ThreadName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the deleted thread.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The type of thread that was deleted.
|
||||
/// </returns>
|
||||
public ThreadType ThreadType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value that indicates whether the deleted thread was archived.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this thread had the Archived flag enabled; otherwise <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsArchived { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the thread auto archive duration of the deleted thread.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The thread auto archive duration of the thread that was deleted.
|
||||
/// </returns>
|
||||
public ThreadArchiveDuration AutoArchiveDuration { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value that indicates whether the deleted thread was locked.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this thread had the Locked flag enabled; otherwise <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsLocked { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the slow-mode delay of the deleted thread.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="int"/> representing the time in seconds required before the user can send another
|
||||
/// message; <c>0</c> if disabled.
|
||||
/// <c>null</c> if this is not mentioned in this entry.
|
||||
/// </returns>
|
||||
public int? SlowModeInterval { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the applied tags of this thread.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
public IReadOnlyCollection<ulong> AppliedTags { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the flags of the thread channel.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if this is not mentioned in this entry.
|
||||
/// </remarks>
|
||||
public ChannelFlags? Flags { get; }
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Represents information for a thread.
|
||||
/// </summary>
|
||||
public class SocketThreadInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name of the thread.
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value that indicates whether the thread is archived.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if the property was not updated.
|
||||
/// </remarks>
|
||||
public bool? IsArchived { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the auto archive duration of thread.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if the property was not updated.
|
||||
/// </remarks>
|
||||
public ThreadArchiveDuration? AutoArchiveDuration { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value that indicates whether the thread is locked.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if the property was not updated.
|
||||
/// </remarks>
|
||||
public bool? IsLocked { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the slow-mode delay of the thread.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if the property was not updated.
|
||||
/// </remarks>
|
||||
public int? SlowModeInterval { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the applied tags of this thread.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if the property was not updated.
|
||||
/// </remarks>
|
||||
public IReadOnlyCollection<ulong> AppliedTags { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the flags of the thread channel.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if the property was not updated.
|
||||
/// </remarks>
|
||||
public ChannelFlags? Flags { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the thread.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <see langword="null"/> if the property was not updated.
|
||||
/// </remarks>
|
||||
public ThreadType Type { get; }
|
||||
|
||||
internal SocketThreadInfo(ThreadInfoAuditLogModel model)
|
||||
{
|
||||
Name = model.Name;
|
||||
IsArchived = model.IsArchived;
|
||||
AutoArchiveDuration = model.ArchiveDuration;
|
||||
IsLocked = model.IsLocked;
|
||||
SlowModeInterval = model.SlowModeInterval;
|
||||
AppliedTags = model.AppliedTags;
|
||||
Flags = model.ChannelFlags;
|
||||
Type = model.Type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using Discord.API.AuditLogs;
|
||||
using Discord.Rest;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a thread update.
|
||||
/// </summary>
|
||||
public class SocketThreadUpdateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketThreadUpdateAuditLogData(ThreadType type, ThreadInfo before, ThreadInfo after)
|
||||
{
|
||||
ThreadType = type;
|
||||
Before = before;
|
||||
After = after;
|
||||
}
|
||||
|
||||
internal static SocketThreadUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo<ThreadInfoAuditLogModel>(changes, discord);
|
||||
|
||||
return new SocketThreadUpdateAuditLogData(before.Type, new(before), new (after));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the thread.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The type of thread.
|
||||
/// </returns>
|
||||
public ThreadType ThreadType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the thread information before the changes.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A thread information object representing the thread before the changes were made.
|
||||
/// </returns>
|
||||
public ThreadInfo Before { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the thread information after the changes.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A thread information object representing the thread after the changes were made.
|
||||
/// </returns>
|
||||
public ThreadInfo After { get; }
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using Discord.Rest;
|
||||
using System.Linq;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to an unban.
|
||||
/// </summary>
|
||||
public class SocketUnbanAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketUnbanAuditLogData(Cacheable<SocketUser, RestUser, IUser, ulong> user)
|
||||
{
|
||||
Target = user;
|
||||
}
|
||||
|
||||
internal static SocketUnbanAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var cachedUser = discord.GetUser(entry.TargetId!.Value);
|
||||
var cacheableUser = new Cacheable<SocketUser, RestUser, IUser, ulong>(
|
||||
cachedUser,
|
||||
entry.TargetId.Value,
|
||||
cachedUser is not null,
|
||||
async () =>
|
||||
{
|
||||
var user = await discord.ApiClient.GetUserAsync(entry.TargetId.Value);
|
||||
return user is not null ? RestUser.Create(discord, user) : null;
|
||||
});
|
||||
return new SocketUnbanAuditLogData(cacheableUser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user that was unbanned.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A cacheable user object representing the user that was unbanned.
|
||||
/// </returns>
|
||||
public Cacheable<SocketUser, RestUser, IUser, ulong> Target { get; }
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using Discord.Rest;
|
||||
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
using Model = Discord.API.AuditLogs.WebhookInfoAuditLogModel;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a webhook creation.
|
||||
/// </summary>
|
||||
public class SocketWebhookCreateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketWebhookCreateAuditLogData(ulong webhookId, Model model)
|
||||
{
|
||||
WebhookId = webhookId;
|
||||
Name = model.Name;
|
||||
Type = model.Type!.Value;
|
||||
ChannelId = model.ChannelId!.Value;
|
||||
Avatar = model.AvatarHash;
|
||||
}
|
||||
|
||||
internal static SocketWebhookCreateAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (_, data) = AuditLogHelper.CreateAuditLogEntityInfo<Model>(changes, discord);
|
||||
|
||||
return new SocketWebhookCreateAuditLogData(entry.TargetId!.Value, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the webhook id.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The webhook identifier.
|
||||
/// </returns>
|
||||
public ulong WebhookId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of webhook that was created.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The type of webhook that was created.
|
||||
/// </returns>
|
||||
public WebhookType Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the webhook.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string containing the name of the webhook.
|
||||
/// </returns>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the channel that the webhook could send to.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier of the channel that the webhook could send
|
||||
/// to.
|
||||
/// </returns>
|
||||
public ulong ChannelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the hash value of the webhook's avatar.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string containing the hash of the webhook's avatar.
|
||||
/// </returns>
|
||||
public string Avatar { get; }
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using Discord.Rest;
|
||||
|
||||
using Model = Discord.API.AuditLogs.WebhookInfoAuditLogModel;
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a webhook deletion.
|
||||
/// </summary>
|
||||
public class SocketWebhookDeleteAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketWebhookDeleteAuditLogData(ulong id, Model model)
|
||||
{
|
||||
WebhookId = id;
|
||||
ChannelId = model.ChannelId!.Value;
|
||||
Name = model.Name;
|
||||
Type = model.Type!.Value;
|
||||
Avatar = model.AvatarHash;
|
||||
}
|
||||
|
||||
internal static SocketWebhookDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo<Model>(changes, discord);
|
||||
|
||||
return new SocketWebhookDeleteAuditLogData(entry.TargetId!.Value,data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the webhook that was deleted.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier of the webhook that was deleted.
|
||||
/// </returns>
|
||||
public ulong WebhookId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the channel that the webhook could send to.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier of the channel that the webhook could send
|
||||
/// to.
|
||||
/// </returns>
|
||||
public ulong ChannelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the webhook that was deleted.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The type of webhook that was deleted.
|
||||
/// </returns>
|
||||
public WebhookType Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the webhook that was deleted.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string containing the name of the webhook that was deleted.
|
||||
/// </returns>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the hash value of the webhook's avatar.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string containing the hash of the webhook's avatar.
|
||||
/// </returns>
|
||||
public string Avatar { get; }
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using Model = Discord.API.AuditLogs.WebhookInfoAuditLogModel;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Represents information for a webhook.
|
||||
/// </summary>
|
||||
public struct SocketWebhookInfo
|
||||
{
|
||||
internal SocketWebhookInfo(Model model)
|
||||
{
|
||||
Name = model.Name;
|
||||
ChannelId = model.ChannelId;
|
||||
Avatar = model.AvatarHash;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of this webhook.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string containing the name of this webhook.
|
||||
/// </returns>
|
||||
public string Name { get; }
|
||||
/// <summary>
|
||||
/// Gets the ID of the channel that this webhook sends to.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="ulong"/> representing the snowflake identifier of the channel that this webhook can send
|
||||
/// to.
|
||||
/// </returns>
|
||||
public ulong? ChannelId { get; }
|
||||
/// <summary>
|
||||
/// Gets the hash value of this webhook's avatar.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string containing the hash of this webhook's avatar.
|
||||
/// </returns>
|
||||
public string Avatar { get; }
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using Discord.Rest;
|
||||
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
using Model = Discord.API.AuditLogs.WebhookInfoAuditLogModel;
|
||||
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a webhook update.
|
||||
/// </summary>
|
||||
public class SocketWebhookUpdateAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketWebhookUpdateAuditLogData(SocketWebhookInfo before, SocketWebhookInfo after)
|
||||
{
|
||||
Before = before;
|
||||
After = after;
|
||||
}
|
||||
|
||||
internal static SocketWebhookUpdateAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (before, after) = AuditLogHelper.CreateAuditLogEntityInfo<Model>(changes, discord);
|
||||
|
||||
return new SocketWebhookUpdateAuditLogData(new(before), new(after));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the webhook information before the changes.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A webhook information object representing the webhook before the changes were made.
|
||||
/// </returns>
|
||||
public SocketWebhookInfo Before { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the webhook information after the changes.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A webhook information object representing the webhook after the changes were made.
|
||||
/// </returns>
|
||||
public SocketWebhookInfo After { get; }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Represents data applied to a <see cref="SocketAuditLogEntry"/>.
|
||||
/// </summary>
|
||||
public interface ISocketAuditLogData : IAuditLogData
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using Discord.Rest;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using Model = Discord.API.AuditLog;
|
||||
using EntryModel = Discord.API.Gateway.AuditLogCreatedEvent;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a Socket-based audit log entry.
|
||||
/// </summary>
|
||||
public class SocketAuditLogEntry : SocketEntity<ulong>, IAuditLogEntry
|
||||
{
|
||||
private SocketAuditLogEntry(DiscordSocketClient discord, EntryModel model)
|
||||
: base(discord, model.Id)
|
||||
{
|
||||
Action = model.Action;
|
||||
Data = SocketAuditLogHelper.CreateData(discord, model);
|
||||
Reason = model.Reason;
|
||||
|
||||
var guild = discord.State.GetGuild(model.GuildId);
|
||||
User = guild?.GetUser(model.UserId ?? 0);
|
||||
}
|
||||
|
||||
internal static SocketAuditLogEntry Create(DiscordSocketClient discord, EntryModel model)
|
||||
{
|
||||
return new SocketAuditLogEntry(discord, model);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ActionType Action { get; }
|
||||
|
||||
/// <inheritdoc cref="IAuditLogEntry.Data"/>
|
||||
public ISocketAuditLogData Data { get; }
|
||||
|
||||
/// <inheritdoc cref="IAuditLogEntry.User" />
|
||||
public SocketUser User { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Reason { get; }
|
||||
|
||||
#region IAuditLogEntry
|
||||
|
||||
/// <inheritdoc/>
|
||||
IUser IAuditLogEntry.User => User;
|
||||
|
||||
/// <inheritdoc/>
|
||||
IAuditLogData IAuditLogEntry.Data => Data;
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
internal static class SocketAuditLogHelper
|
||||
{
|
||||
private static readonly Dictionary<ActionType, Func<DiscordSocketClient, EntryModel, ISocketAuditLogData>> CreateMapping
|
||||
= new ()
|
||||
{
|
||||
[ActionType.GuildUpdated] = SocketGuildUpdateAuditLogData.Create,
|
||||
|
||||
[ActionType.ChannelCreated] = SocketChannelCreateAuditLogData.Create,
|
||||
[ActionType.ChannelUpdated] = SocketChannelUpdateAuditLogData.Create,
|
||||
[ActionType.ChannelDeleted] = SocketChannelDeleteAuditLogData.Create,
|
||||
|
||||
[ActionType.OverwriteCreated] = SocketOverwriteCreateAuditLogData.Create,
|
||||
[ActionType.OverwriteUpdated] = SocketOverwriteUpdateAuditLogData.Create,
|
||||
[ActionType.OverwriteDeleted] = SocketOverwriteDeleteAuditLogData.Create,
|
||||
|
||||
[ActionType.Kick] = SocketKickAuditLogData.Create,
|
||||
[ActionType.Prune] = SocketPruneAuditLogData.Create,
|
||||
[ActionType.Ban] = SocketBanAuditLogData.Create,
|
||||
[ActionType.Unban] = SocketUnbanAuditLogData.Create,
|
||||
[ActionType.MemberUpdated] = SocketMemberUpdateAuditLogData.Create,
|
||||
[ActionType.MemberRoleUpdated] = SocketMemberRoleAuditLogData.Create,
|
||||
[ActionType.MemberMoved] = SocketMemberMoveAuditLogData.Create,
|
||||
[ActionType.MemberDisconnected] = SocketMemberDisconnectAuditLogData.Create,
|
||||
[ActionType.BotAdded] = SocketBotAddAuditLogData.Create,
|
||||
|
||||
[ActionType.RoleCreated] = SocketRoleCreateAuditLogData.Create,
|
||||
[ActionType.RoleUpdated] = SocketRoleUpdateAuditLogData.Create,
|
||||
[ActionType.RoleDeleted] = SocketRoleDeleteAuditLogData.Create,
|
||||
|
||||
[ActionType.InviteCreated] = SocketInviteCreateAuditLogData.Create,
|
||||
[ActionType.InviteUpdated] = SocketInviteUpdateAuditLogData.Create,
|
||||
[ActionType.InviteDeleted] = SocketInviteDeleteAuditLogData.Create,
|
||||
|
||||
[ActionType.WebhookCreated] = SocketWebhookCreateAuditLogData.Create,
|
||||
[ActionType.WebhookUpdated] = SocketWebhookUpdateAuditLogData.Create,
|
||||
[ActionType.WebhookDeleted] = SocketWebhookDeleteAuditLogData.Create,
|
||||
|
||||
[ActionType.EmojiCreated] = SocketEmoteCreateAuditLogData.Create,
|
||||
[ActionType.EmojiUpdated] = SocketEmoteUpdateAuditLogData.Create,
|
||||
[ActionType.EmojiDeleted] = SocketEmoteDeleteAuditLogData.Create,
|
||||
|
||||
[ActionType.MessageDeleted] = SocketMessageDeleteAuditLogData.Create,
|
||||
[ActionType.MessageBulkDeleted] = SocketMessageBulkDeleteAuditLogData.Create,
|
||||
[ActionType.MessagePinned] = SocketMessagePinAuditLogData.Create,
|
||||
[ActionType.MessageUnpinned] = SocketMessageUnpinAuditLogData.Create,
|
||||
|
||||
[ActionType.EventCreate] = SocketScheduledEventCreateAuditLogData.Create,
|
||||
[ActionType.EventUpdate] = SocketScheduledEventUpdateAuditLogData.Create,
|
||||
[ActionType.EventDelete] = SocketScheduledEventDeleteAuditLogData.Create,
|
||||
|
||||
[ActionType.ThreadCreate] = SocketThreadCreateAuditLogData.Create,
|
||||
[ActionType.ThreadUpdate] = SocketThreadUpdateAuditLogData.Create,
|
||||
[ActionType.ThreadDelete] = SocketThreadDeleteAuditLogData.Create,
|
||||
|
||||
[ActionType.ApplicationCommandPermissionUpdate] = SocketCommandPermissionUpdateAuditLogData.Create,
|
||||
|
||||
[ActionType.IntegrationCreated] = SocketIntegrationCreatedAuditLogData.Create,
|
||||
[ActionType.IntegrationUpdated] = SocketIntegrationUpdatedAuditLogData.Create,
|
||||
[ActionType.IntegrationDeleted] = SocketIntegrationDeletedAuditLogData.Create,
|
||||
|
||||
[ActionType.StageInstanceCreated] = SocketStageInstanceCreateAuditLogData.Create,
|
||||
[ActionType.StageInstanceUpdated] = SocketStageInstanceUpdatedAuditLogData.Create,
|
||||
[ActionType.StageInstanceDeleted] = SocketStageInstanceDeleteAuditLogData.Create,
|
||||
|
||||
[ActionType.StickerCreated] = SocketStickerCreatedAuditLogData.Create,
|
||||
[ActionType.StickerUpdated] = SocketStickerUpdatedAuditLogData.Create,
|
||||
[ActionType.StickerDeleted] = SocketStickerDeletedAuditLogData.Create,
|
||||
|
||||
[ActionType.AutoModerationRuleCreate] = SocketAutoModRuleCreatedAuditLogData.Create,
|
||||
[ActionType.AutoModerationRuleUpdate] = AutoModRuleUpdatedAuditLogData.Create,
|
||||
[ActionType.AutoModerationRuleDelete] = SocketAutoModRuleDeletedAuditLogData.Create,
|
||||
|
||||
[ActionType.AutoModerationBlockMessage] = SocketAutoModBlockedMessageAuditLogData.Create,
|
||||
[ActionType.AutoModerationFlagToChannel] = SocketAutoModFlaggedMessageAuditLogData.Create,
|
||||
[ActionType.AutoModerationUserCommunicationDisabled] = SocketAutoModTimeoutUserAuditLogData.Create,
|
||||
|
||||
[ActionType.OnboardingQuestionCreated] = SocketOnboardingPromptCreatedAuditLogData.Create,
|
||||
[ActionType.OnboardingQuestionUpdated] = SocketOnboardingPromptUpdatedAuditLogData.Create,
|
||||
[ActionType.OnboardingUpdated] = SocketOnboardingUpdatedAuditLogData.Create,
|
||||
};
|
||||
|
||||
public static ISocketAuditLogData CreateData(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
if (CreateMapping.TryGetValue(entry.Action, out var func))
|
||||
return func(discord, entry);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -81,7 +81,7 @@ namespace Discord.WebSocket
|
||||
|
||||
DefaultSortOrder = model.DefaultSortOrder.GetValueOrDefault();
|
||||
|
||||
Tags = model.ForumTags.GetValueOrDefault(Array.Empty<API.ForumTags>()).Select(
|
||||
Tags = model.ForumTags.GetValueOrDefault(Array.Empty<API.ForumTag>()).Select(
|
||||
x => new ForumTag(x.Id, x.Name, x.EmojiId.GetValueOrDefault(null), x.EmojiName.GetValueOrDefault(), x.Moderated)
|
||||
).ToImmutableArray();
|
||||
|
||||
|
||||
@@ -49,6 +49,8 @@ namespace Discord.WebSocket
|
||||
private ConcurrentDictionary<ulong, SocketAutoModRule> _automodRules;
|
||||
private ImmutableArray<GuildEmote> _emotes;
|
||||
|
||||
private readonly AuditLogCache _auditLogs;
|
||||
|
||||
private AudioClient _audioClient;
|
||||
private VoiceStateUpdateParams _voiceStateUpdateParams;
|
||||
#pragma warning restore IDISP002, IDISP006
|
||||
@@ -415,6 +417,7 @@ namespace Discord.WebSocket
|
||||
_audioLock = new SemaphoreSlim(1, 1);
|
||||
_emotes = ImmutableArray.Create<GuildEmote>();
|
||||
_automodRules = new ConcurrentDictionary<ulong, SocketAutoModRule>();
|
||||
_auditLogs = new AuditLogCache(client);
|
||||
}
|
||||
internal static SocketGuild Create(DiscordSocketClient discord, ClientState state, ExtendedModel model)
|
||||
{
|
||||
@@ -1403,9 +1406,36 @@ namespace Discord.WebSocket
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous get operation. The task result contains a read-only collection
|
||||
/// of the requested audit log entries.
|
||||
/// </returns>
|
||||
/// </returns>
|
||||
public IAsyncEnumerable<IReadOnlyCollection<RestAuditLogEntry>> GetAuditLogsAsync(int limit, RequestOptions options = null, ulong? beforeId = null, ulong? userId = null, ActionType? actionType = null, ulong? afterId = null)
|
||||
=> GuildHelper.GetAuditLogsAsync(this, Discord, beforeId, limit, options, userId: userId, actionType: actionType, afterId: afterId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all cached audit log entries from this guild.
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<SocketAuditLogEntry> CachedAuditLogs => _auditLogs?.AuditLogs ?? ImmutableArray.Create<SocketAuditLogEntry>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets cached audit log entry with the provided id.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Returns <see langword="null"/> if no entry with provided id was found in cache.
|
||||
/// </remarks>
|
||||
public SocketAuditLogEntry GetCachedAuditLog(ulong id)
|
||||
=> _auditLogs.Get(id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets audit log entries with the specified type from cache.
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<SocketAuditLogEntry> GetCachedAuditLogs(int limit = DiscordConfig.MaxAuditLogEntriesPerBatch, ActionType? action = null,
|
||||
ulong? fromEntryId = null, Direction direction = Direction.Before)
|
||||
{
|
||||
return _auditLogs.GetMany(fromEntryId, direction, limit, action);
|
||||
}
|
||||
|
||||
internal void AddAuditLog(SocketAuditLogEntry entry)
|
||||
=> _auditLogs.Add(entry);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Webhooks
|
||||
|
||||
Reference in New Issue
Block a user