Audit Logs implementation (#1055)
* Copy audit logs impl from old branch and clean up I suck at using git, so I'm gonna use brute force. * Remove unnecessary TODOs Category channels do not provide any new information, and the other I forgot to remove beforehand * Add invite update data, clean up after feedback * Remove TODOs, add WebhookType enum for future use WebhookType is a future-use type, as currently audit logs are the only thing which may return it.
This commit is contained in:
committed by
Christopher F
parent
97c893107b
commit
39dffe8585
@@ -20,6 +20,7 @@ namespace Discord
|
|||||||
public const int MaxMessagesPerBatch = 100;
|
public const int MaxMessagesPerBatch = 100;
|
||||||
public const int MaxUsersPerBatch = 1000;
|
public const int MaxUsersPerBatch = 1000;
|
||||||
public const int MaxGuildsPerBatch = 100;
|
public const int MaxGuildsPerBatch = 100;
|
||||||
|
public const int MaxAuditLogEntriesPerBatch = 100;
|
||||||
|
|
||||||
/// <summary> Gets or sets how a request should act in the case of an error, by default. </summary>
|
/// <summary> Gets or sets how a request should act in the case of an error, by default. </summary>
|
||||||
public RetryMode DefaultRetryMode { get; set; } = RetryMode.AlwaysRetry;
|
public RetryMode DefaultRetryMode { get; set; } = RetryMode.AlwaysRetry;
|
||||||
|
|||||||
50
src/Discord.Net.Core/Entities/AuditLogs/ActionType.cs
Normal file
50
src/Discord.Net.Core/Entities/AuditLogs/ActionType.cs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Discord
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The action type within a <see cref="IAuditLogEntry"/>
|
||||||
|
/// </summary>
|
||||||
|
public enum ActionType
|
||||||
|
{
|
||||||
|
GuildUpdated = 1,
|
||||||
|
|
||||||
|
ChannelCreated = 10,
|
||||||
|
ChannelUpdated = 11,
|
||||||
|
ChannelDeleted = 12,
|
||||||
|
|
||||||
|
OverwriteCreated = 13,
|
||||||
|
OverwriteUpdated = 14,
|
||||||
|
OverwriteDeleted = 15,
|
||||||
|
|
||||||
|
Kick = 20,
|
||||||
|
Prune = 21,
|
||||||
|
Ban = 22,
|
||||||
|
Unban = 23,
|
||||||
|
|
||||||
|
MemberUpdated = 24,
|
||||||
|
MemberRoleUpdated = 25,
|
||||||
|
|
||||||
|
RoleCreated = 30,
|
||||||
|
RoleUpdated = 31,
|
||||||
|
RoleDeleted = 32,
|
||||||
|
|
||||||
|
InviteCreated = 40,
|
||||||
|
InviteUpdated = 41,
|
||||||
|
InviteDeleted = 42,
|
||||||
|
|
||||||
|
WebhookCreated = 50,
|
||||||
|
WebhookUpdated = 51,
|
||||||
|
WebhookDeleted = 52,
|
||||||
|
|
||||||
|
EmojiCreated = 60,
|
||||||
|
EmojiUpdated = 61,
|
||||||
|
EmojiDeleted = 62,
|
||||||
|
|
||||||
|
MessageDeleted = 72
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/Discord.Net.Core/Entities/AuditLogs/IAuditLogData.cs
Normal file
14
src/Discord.Net.Core/Entities/AuditLogs/IAuditLogData.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Discord
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents data applied to an <see cref="IAuditLogEntry"/>
|
||||||
|
/// </summary>
|
||||||
|
public interface IAuditLogData
|
||||||
|
{ }
|
||||||
|
}
|
||||||
34
src/Discord.Net.Core/Entities/AuditLogs/IAuditLogEntry.cs
Normal file
34
src/Discord.Net.Core/Entities/AuditLogs/IAuditLogEntry.cs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Discord
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an entry in an audit log
|
||||||
|
/// </summary>
|
||||||
|
public interface IAuditLogEntry : IEntity<ulong>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The action which occured to create this entry
|
||||||
|
/// </summary>
|
||||||
|
ActionType Action { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The data for this entry. May be <see cref="null"/> if no data was available.
|
||||||
|
/// </summary>
|
||||||
|
IAuditLogData Data { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The user responsible for causing the changes
|
||||||
|
/// </summary>
|
||||||
|
IUser User { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The reason behind the change. May be <see cref="null"/> if no reason was provided.
|
||||||
|
/// </summary>
|
||||||
|
string Reason { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -139,6 +139,10 @@ namespace Discord
|
|||||||
/// <summary> Removes all users from this guild if they have not logged on in a provided number of days or, if simulate is true, returns the number of users that would be removed. </summary>
|
/// <summary> Removes all users from this guild if they have not logged on in a provided number of days or, if simulate is true, returns the number of users that would be removed. </summary>
|
||||||
Task<int> PruneUsersAsync(int days = 30, bool simulate = false, RequestOptions options = null);
|
Task<int> PruneUsersAsync(int days = 30, bool simulate = false, RequestOptions options = null);
|
||||||
|
|
||||||
|
/// <summary> Gets the specified number of audit log entries for this guild. </summary>
|
||||||
|
Task<IReadOnlyCollection<IAuditLogEntry>> GetAuditLogAsync(int limit = DiscordConfig.MaxAuditLogEntriesPerBatch,
|
||||||
|
CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
|
||||||
|
|
||||||
/// <summary> Gets the webhook in this guild with the provided id, or null if not found. </summary>
|
/// <summary> Gets the webhook in this guild with the provided id, or null if not found. </summary>
|
||||||
Task<IWebhook> GetWebhookAsync(ulong id, RequestOptions options = null);
|
Task<IWebhook> GetWebhookAsync(ulong id, RequestOptions options = null);
|
||||||
/// <summary> Gets a collection of all webhooks for this guild. </summary>
|
/// <summary> Gets a collection of all webhooks for this guild. </summary>
|
||||||
|
|||||||
14
src/Discord.Net.Core/Entities/Webhooks/WebhookType.cs
Normal file
14
src/Discord.Net.Core/Entities/Webhooks/WebhookType.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
namespace Discord
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the type of a webhook.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This type is currently unused, and is only returned in audit log responses.
|
||||||
|
/// </remarks>
|
||||||
|
public enum WebhookType
|
||||||
|
{
|
||||||
|
/// <summary> An incoming webhook </summary>
|
||||||
|
Incoming = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/Discord.Net.Rest/API/Common/AuditLog.cs
Normal file
16
src/Discord.Net.Rest/API/Common/AuditLog.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Discord.API
|
||||||
|
{
|
||||||
|
internal class AuditLog
|
||||||
|
{
|
||||||
|
[JsonProperty("webhooks")]
|
||||||
|
public Webhook[] Webhooks { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("users")]
|
||||||
|
public User[] Users { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("audit_log_entries")]
|
||||||
|
public AuditLogEntry[] Entries { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/Discord.Net.Rest/API/Common/AuditLogChange.cs
Normal file
17
src/Discord.Net.Rest/API/Common/AuditLogChange.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace Discord.API
|
||||||
|
{
|
||||||
|
internal class AuditLogChange
|
||||||
|
{
|
||||||
|
[JsonProperty("key")]
|
||||||
|
public string ChangedProperty { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("new_value")]
|
||||||
|
public JToken NewValue { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("old_value")]
|
||||||
|
public JToken OldValue { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/Discord.Net.Rest/API/Common/AuditLogEntry.cs
Normal file
26
src/Discord.Net.Rest/API/Common/AuditLogEntry.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Discord.API
|
||||||
|
{
|
||||||
|
internal class AuditLogEntry
|
||||||
|
{
|
||||||
|
[JsonProperty("target_id")]
|
||||||
|
public ulong? TargetId { get; set; }
|
||||||
|
[JsonProperty("user_id")]
|
||||||
|
public ulong UserId { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("changes")]
|
||||||
|
public AuditLogChange[] Changes { get; set; }
|
||||||
|
[JsonProperty("options")]
|
||||||
|
public AuditLogOptions Options { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("id")]
|
||||||
|
public ulong Id { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("action_type")]
|
||||||
|
public ActionType Action { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("reason")]
|
||||||
|
public string Reason { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/Discord.Net.Rest/API/Common/AuditLogOptions.cs
Normal file
27
src/Discord.Net.Rest/API/Common/AuditLogOptions.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Discord.API
|
||||||
|
{
|
||||||
|
internal class AuditLogOptions
|
||||||
|
{
|
||||||
|
//Message delete
|
||||||
|
[JsonProperty("count")]
|
||||||
|
public int? MessageDeleteCount { get; set; }
|
||||||
|
[JsonProperty("channel_id")]
|
||||||
|
public ulong? MessageDeleteChannelId { get; set; }
|
||||||
|
|
||||||
|
//Prune
|
||||||
|
[JsonProperty("delete_member_days")]
|
||||||
|
public int? PruneDeleteMemberDays { get; set; }
|
||||||
|
[JsonProperty("members_removed")]
|
||||||
|
public int? PruneMembersRemoved { get; set; }
|
||||||
|
|
||||||
|
//Overwrite Update
|
||||||
|
[JsonProperty("role_name")]
|
||||||
|
public string OverwriteRoleName { get; set; }
|
||||||
|
[JsonProperty("type")]
|
||||||
|
public string OverwriteType { get; set; }
|
||||||
|
[JsonProperty("id")]
|
||||||
|
public ulong? OverwriteTargetId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/Discord.Net.Rest/API/Rest/GetAuditLogsParams.cs
Normal file
8
src/Discord.Net.Rest/API/Rest/GetAuditLogsParams.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Discord.API.Rest
|
||||||
|
{
|
||||||
|
class GetAuditLogsParams
|
||||||
|
{
|
||||||
|
public Optional<int> Limit { get; set; }
|
||||||
|
public Optional<ulong> BeforeEntryId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1206,6 +1206,26 @@ namespace Discord.API
|
|||||||
return await SendAsync<IReadOnlyCollection<VoiceRegion>>("GET", () => $"guilds/{guildId}/regions", ids, options: options).ConfigureAwait(false);
|
return await SendAsync<IReadOnlyCollection<VoiceRegion>>("GET", () => $"guilds/{guildId}/regions", ids, options: options).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Audit logs
|
||||||
|
public async Task<AuditLog> GetAuditLogsAsync(ulong guildId, GetAuditLogsParams args, RequestOptions options = null)
|
||||||
|
{
|
||||||
|
Preconditions.NotEqual(guildId, 0, nameof(guildId));
|
||||||
|
Preconditions.NotNull(args, nameof(args));
|
||||||
|
options = RequestOptions.CreateOrClone(options);
|
||||||
|
|
||||||
|
int limit = args.Limit.GetValueOrDefault(int.MaxValue);
|
||||||
|
|
||||||
|
var ids = new BucketIds(guildId: guildId);
|
||||||
|
Expression<Func<string>> endpoint;
|
||||||
|
|
||||||
|
if (args.BeforeEntryId.IsSpecified)
|
||||||
|
endpoint = () => $"guilds/{guildId}/audit-logs?limit={limit}&before={args.BeforeEntryId.Value}";
|
||||||
|
else
|
||||||
|
endpoint = () => $"guilds/{guildId}/audit-logs?limit={limit}";
|
||||||
|
|
||||||
|
return await SendAsync<AuditLog>("GET", endpoint, ids, options: options).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
//Webhooks
|
//Webhooks
|
||||||
public async Task<Webhook> CreateWebhookAsync(ulong channelId, CreateWebhookParams args, RequestOptions options = null)
|
public async Task<Webhook> CreateWebhookAsync(ulong channelId, CreateWebhookParams args, RequestOptions options = null)
|
||||||
{
|
{
|
||||||
|
|||||||
58
src/Discord.Net.Rest/Entities/AuditLogs/AuditLogHelper.cs
Normal file
58
src/Discord.Net.Rest/Entities/AuditLogs/AuditLogHelper.cs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
internal static class AuditLogHelper
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<ActionType, Func<BaseDiscordClient, Model, EntryModel, IAuditLogData>> CreateMapping
|
||||||
|
= new Dictionary<ActionType, Func<BaseDiscordClient, Model, EntryModel, IAuditLogData>>()
|
||||||
|
{
|
||||||
|
[ActionType.GuildUpdated] = GuildUpdateAuditLogData.Create,
|
||||||
|
|
||||||
|
[ActionType.ChannelCreated] = ChannelCreateAuditLogData.Create,
|
||||||
|
[ActionType.ChannelUpdated] = ChannelUpdateAuditLogData.Create,
|
||||||
|
[ActionType.ChannelDeleted] = ChannelDeleteAuditLogData.Create,
|
||||||
|
|
||||||
|
[ActionType.OverwriteCreated] = OverwriteCreateAuditLogData.Create,
|
||||||
|
[ActionType.OverwriteUpdated] = OverwriteUpdateAuditLogData.Create,
|
||||||
|
[ActionType.OverwriteDeleted] = OverwriteDeleteAuditLogData.Create,
|
||||||
|
|
||||||
|
[ActionType.Kick] = KickAuditLogData.Create,
|
||||||
|
[ActionType.Prune] = PruneAuditLogData.Create,
|
||||||
|
[ActionType.Ban] = BanAuditLogData.Create,
|
||||||
|
[ActionType.Unban] = UnbanAuditLogData.Create,
|
||||||
|
[ActionType.MemberUpdated] = MemberUpdateAuditLogData.Create,
|
||||||
|
[ActionType.MemberRoleUpdated] = MemberRoleAuditLogData.Create,
|
||||||
|
|
||||||
|
[ActionType.RoleCreated] = RoleCreateAuditLogData.Create,
|
||||||
|
[ActionType.RoleUpdated] = RoleUpdateAuditLogData.Create,
|
||||||
|
[ActionType.RoleDeleted] = RoleDeleteAuditLogData.Create,
|
||||||
|
|
||||||
|
[ActionType.InviteCreated] = InviteCreateAuditLogData.Create,
|
||||||
|
[ActionType.InviteUpdated] = InviteUpdateAuditLogData.Create,
|
||||||
|
[ActionType.InviteDeleted] = InviteDeleteAuditLogData.Create,
|
||||||
|
|
||||||
|
[ActionType.WebhookCreated] = WebhookCreateAuditLogData.Create,
|
||||||
|
[ActionType.WebhookUpdated] = WebhookUpdateAuditLogData.Create,
|
||||||
|
[ActionType.WebhookDeleted] = WebhookDeleteAuditLogData.Create,
|
||||||
|
|
||||||
|
[ActionType.EmojiCreated] = EmoteCreateAuditLogData.Create,
|
||||||
|
[ActionType.EmojiUpdated] = EmoteUpdateAuditLogData.Create,
|
||||||
|
[ActionType.EmojiDeleted] = EmoteDeleteAuditLogData.Create,
|
||||||
|
|
||||||
|
[ActionType.MessageDeleted] = MessageDeleteAuditLogData.Create,
|
||||||
|
};
|
||||||
|
|
||||||
|
public static IAuditLogData CreateData(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
if (CreateMapping.TryGetValue(entry.Action, out var func))
|
||||||
|
return func(discord, log, entry);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class BanAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private BanAuditLogData(IUser user)
|
||||||
|
{
|
||||||
|
Target = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static BanAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId);
|
||||||
|
return new BanAuditLogData(RestUser.Create(discord, userInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
public IUser Target { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class ChannelCreateAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private ChannelCreateAuditLogData(ulong id, string name, ChannelType type, IReadOnlyCollection<Overwrite> overwrites)
|
||||||
|
{
|
||||||
|
ChannelId = id;
|
||||||
|
ChannelName = name;
|
||||||
|
ChannelType = type;
|
||||||
|
Overwrites = overwrites;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static ChannelCreateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var changes = entry.Changes;
|
||||||
|
var overwrites = new List<Overwrite>();
|
||||||
|
|
||||||
|
var overwritesModel = changes.FirstOrDefault(x => x.ChangedProperty == "permission_overwrites");
|
||||||
|
var typeModel = changes.FirstOrDefault(x => x.ChangedProperty == "type");
|
||||||
|
var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name");
|
||||||
|
|
||||||
|
var type = typeModel.NewValue.ToObject<ChannelType>();
|
||||||
|
var name = nameModel.NewValue.ToObject<string>();
|
||||||
|
|
||||||
|
foreach (var overwrite in overwritesModel.NewValue)
|
||||||
|
{
|
||||||
|
var deny = overwrite.Value<ulong>("deny");
|
||||||
|
var _type = overwrite.Value<string>("type");
|
||||||
|
var id = overwrite.Value<ulong>("id");
|
||||||
|
var allow = overwrite.Value<ulong>("allow");
|
||||||
|
|
||||||
|
PermissionTarget permType = _type == "member" ? PermissionTarget.User : PermissionTarget.Role;
|
||||||
|
|
||||||
|
overwrites.Add(new Overwrite(id, permType, new OverwritePermissions(allow, deny)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ChannelCreateAuditLogData(entry.TargetId.Value, name, type, overwrites.ToReadOnlyCollection());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong ChannelId { get; }
|
||||||
|
public string ChannelName { get; }
|
||||||
|
public ChannelType ChannelType { get; }
|
||||||
|
public IReadOnlyCollection<Overwrite> Overwrites { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class ChannelDeleteAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private ChannelDeleteAuditLogData(ulong id, string name, ChannelType type, IReadOnlyCollection<Overwrite> overwrites)
|
||||||
|
{
|
||||||
|
ChannelId = id;
|
||||||
|
ChannelName = name;
|
||||||
|
ChannelType = type;
|
||||||
|
Overwrites = overwrites;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static ChannelDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var changes = entry.Changes;
|
||||||
|
|
||||||
|
var overwritesModel = changes.FirstOrDefault(x => x.ChangedProperty == "permission_overwrites");
|
||||||
|
var typeModel = changes.FirstOrDefault(x => x.ChangedProperty == "type");
|
||||||
|
var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name");
|
||||||
|
|
||||||
|
var overwrites = overwritesModel.OldValue.ToObject<API.Overwrite[]>()
|
||||||
|
.Select(x => new Overwrite(x.TargetId, x.TargetType, new OverwritePermissions(x.Allow, x.Deny)))
|
||||||
|
.ToList();
|
||||||
|
var type = typeModel.OldValue.ToObject<ChannelType>();
|
||||||
|
var name = nameModel.OldValue.ToObject<string>();
|
||||||
|
var id = entry.TargetId.Value;
|
||||||
|
|
||||||
|
return new ChannelDeleteAuditLogData(id, name, type, overwrites.ToReadOnlyCollection());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong ChannelId { get; }
|
||||||
|
public string ChannelName { get; }
|
||||||
|
public ChannelType ChannelType { get; }
|
||||||
|
public IReadOnlyCollection<Overwrite> Overwrites { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public struct ChannelInfo
|
||||||
|
{
|
||||||
|
internal ChannelInfo(string name, string topic, int? bitrate, int? limit)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Topic = topic;
|
||||||
|
Bitrate = bitrate;
|
||||||
|
UserLimit = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name { get; }
|
||||||
|
public string Topic { get; }
|
||||||
|
public int? Bitrate { get; }
|
||||||
|
public int? UserLimit { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class ChannelUpdateAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private ChannelUpdateAuditLogData(ulong id, ChannelInfo before, ChannelInfo after)
|
||||||
|
{
|
||||||
|
ChannelId = id;
|
||||||
|
Before = before;
|
||||||
|
After = after;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static ChannelUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var changes = entry.Changes;
|
||||||
|
|
||||||
|
var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name");
|
||||||
|
var topicModel = changes.FirstOrDefault(x => x.ChangedProperty == "topic");
|
||||||
|
var bitrateModel = changes.FirstOrDefault(x => x.ChangedProperty == "bitrate");
|
||||||
|
var userLimitModel = changes.FirstOrDefault(x => x.ChangedProperty == "user_limit");
|
||||||
|
|
||||||
|
string oldName = nameModel?.OldValue?.ToObject<string>(),
|
||||||
|
newName = nameModel?.NewValue?.ToObject<string>();
|
||||||
|
string oldTopic = topicModel?.OldValue?.ToObject<string>(),
|
||||||
|
newTopic = topicModel?.NewValue?.ToObject<string>();
|
||||||
|
int? oldBitrate = bitrateModel?.OldValue?.ToObject<int>(),
|
||||||
|
newBitrate = bitrateModel?.NewValue?.ToObject<int>();
|
||||||
|
int? oldLimit = userLimitModel?.OldValue?.ToObject<int>(),
|
||||||
|
newLimit = userLimitModel?.NewValue?.ToObject<int>();
|
||||||
|
|
||||||
|
var before = new ChannelInfo(oldName, oldTopic, oldBitrate, oldLimit);
|
||||||
|
var after = new ChannelInfo(newName, newTopic, newBitrate, newLimit);
|
||||||
|
|
||||||
|
return new ChannelUpdateAuditLogData(entry.TargetId.Value, before, after);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong ChannelId { get; }
|
||||||
|
public ChannelInfo Before { get; set; }
|
||||||
|
public ChannelInfo After { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class EmoteCreateAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private EmoteCreateAuditLogData(ulong id, string name)
|
||||||
|
{
|
||||||
|
EmoteId = id;
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static EmoteCreateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var change = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name");
|
||||||
|
|
||||||
|
var emoteName = change.NewValue?.ToObject<string>();
|
||||||
|
return new EmoteCreateAuditLogData(entry.TargetId.Value, emoteName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong EmoteId { get; }
|
||||||
|
public string Name { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class EmoteDeleteAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private EmoteDeleteAuditLogData(ulong id, string name)
|
||||||
|
{
|
||||||
|
EmoteId = id;
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static EmoteDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var change = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name");
|
||||||
|
|
||||||
|
var emoteName = change.OldValue?.ToObject<string>();
|
||||||
|
|
||||||
|
return new EmoteDeleteAuditLogData(entry.TargetId.Value, emoteName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong EmoteId { get; }
|
||||||
|
public string Name { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class EmoteUpdateAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private EmoteUpdateAuditLogData(ulong id, string oldName, string newName)
|
||||||
|
{
|
||||||
|
EmoteId = id;
|
||||||
|
OldName = oldName;
|
||||||
|
NewName = newName;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static EmoteUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var change = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name");
|
||||||
|
|
||||||
|
var newName = change.NewValue?.ToObject<string>();
|
||||||
|
var oldName = change.OldValue?.ToObject<string>();
|
||||||
|
|
||||||
|
return new EmoteUpdateAuditLogData(entry.TargetId.Value, oldName, newName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong EmoteId { get; }
|
||||||
|
public string NewName { get; }
|
||||||
|
public string OldName { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public struct GuildInfo
|
||||||
|
{
|
||||||
|
internal GuildInfo(int? afkTimeout, DefaultMessageNotifications? defaultNotifs,
|
||||||
|
ulong? afkChannel, string name, string region, string icon,
|
||||||
|
VerificationLevel? verification, IUser owner, MfaLevel? mfa, int? filter)
|
||||||
|
{
|
||||||
|
AfkTimeout = afkTimeout;
|
||||||
|
DefaultMessageNotifications = defaultNotifs;
|
||||||
|
AfkChannelId = afkChannel;
|
||||||
|
Name = name;
|
||||||
|
RegionId = region;
|
||||||
|
IconHash = icon;
|
||||||
|
VerificationLevel = verification;
|
||||||
|
Owner = owner;
|
||||||
|
MfaLevel = mfa;
|
||||||
|
ContentFilterLevel = filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int? AfkTimeout { get; }
|
||||||
|
public DefaultMessageNotifications? DefaultMessageNotifications { get; }
|
||||||
|
public ulong? AfkChannelId { get; }
|
||||||
|
public string Name { get; }
|
||||||
|
public string RegionId { get; }
|
||||||
|
public string IconHash { get; }
|
||||||
|
public VerificationLevel? VerificationLevel { get; }
|
||||||
|
public IUser Owner { get; }
|
||||||
|
public MfaLevel? MfaLevel { get; }
|
||||||
|
public int? ContentFilterLevel { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class GuildUpdateAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private GuildUpdateAuditLogData(GuildInfo before, GuildInfo after)
|
||||||
|
{
|
||||||
|
Before = before;
|
||||||
|
After = after;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static GuildUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var changes = entry.Changes;
|
||||||
|
|
||||||
|
var afkTimeoutModel = changes.FirstOrDefault(x => x.ChangedProperty == "afk_timeout");
|
||||||
|
var defaultMessageNotificationsModel = changes.FirstOrDefault(x => x.ChangedProperty == "afk_timeout");
|
||||||
|
var afkChannelModel = changes.FirstOrDefault(x => x.ChangedProperty == "afk_timeout");
|
||||||
|
var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "afk_timeout");
|
||||||
|
var regionIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "afk_timeout");
|
||||||
|
var iconHashModel = changes.FirstOrDefault(x => x.ChangedProperty == "afk_timeout");
|
||||||
|
var verificationLevelModel = changes.FirstOrDefault(x => x.ChangedProperty == "afk_timeout");
|
||||||
|
var ownerIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "afk_timeout");
|
||||||
|
var mfaLevelModel = changes.FirstOrDefault(x => x.ChangedProperty == "afk_timeout");
|
||||||
|
var contentFilterModel = changes.FirstOrDefault(x => x.ChangedProperty == "afk_timeout");
|
||||||
|
|
||||||
|
int? oldAfkTimeout = afkTimeoutModel?.OldValue?.ToObject<int>(),
|
||||||
|
newAfkTimeout = afkTimeoutModel?.NewValue?.ToObject<int>();
|
||||||
|
DefaultMessageNotifications? oldDefaultMessageNotifications = defaultMessageNotificationsModel?.OldValue?.ToObject<DefaultMessageNotifications>(),
|
||||||
|
newDefaultMessageNotifications = defaultMessageNotificationsModel?.NewValue?.ToObject<DefaultMessageNotifications>();
|
||||||
|
ulong? oldAfkChannelId = afkChannelModel?.OldValue?.ToObject<ulong>(),
|
||||||
|
newAfkChannelId = afkChannelModel?.NewValue?.ToObject<ulong>();
|
||||||
|
string oldName = nameModel?.OldValue?.ToObject<string>(),
|
||||||
|
newName = nameModel?.NewValue?.ToObject<string>();
|
||||||
|
string oldRegionId = regionIdModel?.OldValue?.ToObject<string>(),
|
||||||
|
newRegionId = regionIdModel?.NewValue?.ToObject<string>();
|
||||||
|
string oldIconHash = iconHashModel?.OldValue?.ToObject<string>(),
|
||||||
|
newIconHash = iconHashModel?.NewValue?.ToObject<string>();
|
||||||
|
VerificationLevel? oldVerificationLevel = verificationLevelModel?.OldValue?.ToObject<VerificationLevel>(),
|
||||||
|
newVerificationLevel = verificationLevelModel?.NewValue?.ToObject<VerificationLevel>();
|
||||||
|
ulong? oldOwnerId = ownerIdModel?.OldValue?.ToObject<ulong>(),
|
||||||
|
newOwnerId = ownerIdModel?.NewValue?.ToObject<ulong>();
|
||||||
|
MfaLevel? oldMfaLevel = mfaLevelModel?.OldValue?.ToObject<MfaLevel>(),
|
||||||
|
newMfaLevel = mfaLevelModel?.NewValue?.ToObject<MfaLevel>();
|
||||||
|
int? oldContentFilter = contentFilterModel?.OldValue?.ToObject<int>(),
|
||||||
|
newContentFilter = contentFilterModel?.NewValue?.ToObject<int>();
|
||||||
|
|
||||||
|
IUser oldOwner = null;
|
||||||
|
if (oldOwnerId != null)
|
||||||
|
{
|
||||||
|
var oldOwnerInfo = log.Users.FirstOrDefault(x => x.Id == oldOwnerId.Value);
|
||||||
|
oldOwner = RestUser.Create(discord, oldOwnerInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
IUser newOwner = null;
|
||||||
|
if (newOwnerId != null)
|
||||||
|
{
|
||||||
|
var newOwnerInfo = log.Users.FirstOrDefault(x => x.Id == newOwnerId.Value);
|
||||||
|
newOwner = RestUser.Create(discord, newOwnerInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
var before = new GuildInfo(oldAfkTimeout, oldDefaultMessageNotifications,
|
||||||
|
oldAfkChannelId, oldName, oldRegionId, oldIconHash, oldVerificationLevel, oldOwner,
|
||||||
|
oldMfaLevel, oldContentFilter);
|
||||||
|
var after = new GuildInfo(newAfkTimeout, newDefaultMessageNotifications,
|
||||||
|
newAfkChannelId, newName, newRegionId, newIconHash, newVerificationLevel, newOwner,
|
||||||
|
newMfaLevel, newContentFilter);
|
||||||
|
|
||||||
|
return new GuildUpdateAuditLogData(before, after);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GuildInfo Before { get; }
|
||||||
|
public GuildInfo After { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class InviteCreateAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private InviteCreateAuditLogData(int maxAge, string code, bool temporary, IUser inviter, ulong channelId, int uses, int maxUses)
|
||||||
|
{
|
||||||
|
MaxAge = maxAge;
|
||||||
|
Code = code;
|
||||||
|
Temporary = temporary;
|
||||||
|
Creator = inviter;
|
||||||
|
ChannelId = channelId;
|
||||||
|
Uses = uses;
|
||||||
|
MaxUses = maxUses;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static InviteCreateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var changes = entry.Changes;
|
||||||
|
|
||||||
|
var maxAgeModel = changes.FirstOrDefault(x => x.ChangedProperty == "max_age");
|
||||||
|
var codeModel = changes.FirstOrDefault(x => x.ChangedProperty == "code");
|
||||||
|
var temporaryModel = changes.FirstOrDefault(x => x.ChangedProperty == "temporary");
|
||||||
|
var inviterIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "inviter_id");
|
||||||
|
var channelIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "channel_id");
|
||||||
|
var usesModel = changes.FirstOrDefault(x => x.ChangedProperty == "uses");
|
||||||
|
var maxUsesModel = changes.FirstOrDefault(x => x.ChangedProperty == "max_uses");
|
||||||
|
|
||||||
|
var maxAge = maxAgeModel.NewValue.ToObject<int>();
|
||||||
|
var code = codeModel.NewValue.ToObject<string>();
|
||||||
|
var temporary = temporaryModel.NewValue.ToObject<bool>();
|
||||||
|
var inviterId = inviterIdModel.NewValue.ToObject<ulong>();
|
||||||
|
var channelId = channelIdModel.NewValue.ToObject<ulong>();
|
||||||
|
var uses = usesModel.NewValue.ToObject<int>();
|
||||||
|
var maxUses = maxUsesModel.NewValue.ToObject<int>();
|
||||||
|
|
||||||
|
var inviterInfo = log.Users.FirstOrDefault(x => x.Id == inviterId);
|
||||||
|
var inviter = RestUser.Create(discord, inviterInfo);
|
||||||
|
|
||||||
|
return new InviteCreateAuditLogData(maxAge, code, temporary, inviter, channelId, uses, maxUses);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int MaxAge { get; }
|
||||||
|
public string Code { get; }
|
||||||
|
public bool Temporary { get; }
|
||||||
|
public IUser Creator { get; }
|
||||||
|
public ulong ChannelId { get; }
|
||||||
|
public int Uses { get; }
|
||||||
|
public int MaxUses { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class InviteDeleteAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private InviteDeleteAuditLogData(int maxAge, string code, bool temporary, IUser inviter, ulong channelId, int uses, int maxUses)
|
||||||
|
{
|
||||||
|
MaxAge = maxAge;
|
||||||
|
Code = code;
|
||||||
|
Temporary = temporary;
|
||||||
|
Creator = inviter;
|
||||||
|
ChannelId = channelId;
|
||||||
|
Uses = uses;
|
||||||
|
MaxUses = maxUses;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static InviteDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var changes = entry.Changes;
|
||||||
|
|
||||||
|
var maxAgeModel = changes.FirstOrDefault(x => x.ChangedProperty == "max_age");
|
||||||
|
var codeModel = changes.FirstOrDefault(x => x.ChangedProperty == "code");
|
||||||
|
var temporaryModel = changes.FirstOrDefault(x => x.ChangedProperty == "temporary");
|
||||||
|
var inviterIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "inviter_id");
|
||||||
|
var channelIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "channel_id");
|
||||||
|
var usesModel = changes.FirstOrDefault(x => x.ChangedProperty == "uses");
|
||||||
|
var maxUsesModel = changes.FirstOrDefault(x => x.ChangedProperty == "max_uses");
|
||||||
|
|
||||||
|
var maxAge = maxAgeModel.OldValue.ToObject<int>();
|
||||||
|
var code = codeModel.OldValue.ToObject<string>();
|
||||||
|
var temporary = temporaryModel.OldValue.ToObject<bool>();
|
||||||
|
var inviterId = inviterIdModel.OldValue.ToObject<ulong>();
|
||||||
|
var channelId = channelIdModel.OldValue.ToObject<ulong>();
|
||||||
|
var uses = usesModel.OldValue.ToObject<int>();
|
||||||
|
var maxUses = maxUsesModel.OldValue.ToObject<int>();
|
||||||
|
|
||||||
|
var inviterInfo = log.Users.FirstOrDefault(x => x.Id == inviterId);
|
||||||
|
var inviter = RestUser.Create(discord, inviterInfo);
|
||||||
|
|
||||||
|
return new InviteDeleteAuditLogData(maxAge, code, temporary, inviter, channelId, uses, maxUses);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int MaxAge { get; }
|
||||||
|
public string Code { get; }
|
||||||
|
public bool Temporary { get; }
|
||||||
|
public IUser Creator { get; }
|
||||||
|
public ulong ChannelId { get; }
|
||||||
|
public int Uses { get; }
|
||||||
|
public int MaxUses { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public struct InviteInfo
|
||||||
|
{
|
||||||
|
internal InviteInfo(int? maxAge, string code, bool? temporary, ulong? channelId, int? maxUses)
|
||||||
|
{
|
||||||
|
MaxAge = maxAge;
|
||||||
|
Code = code;
|
||||||
|
Temporary = temporary;
|
||||||
|
ChannelId = channelId;
|
||||||
|
MaxUses = maxUses;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int? MaxAge { get; }
|
||||||
|
public string Code { get; }
|
||||||
|
public bool? Temporary { get; }
|
||||||
|
public ulong? ChannelId { get; }
|
||||||
|
public int? MaxUses { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class InviteUpdateAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private InviteUpdateAuditLogData(InviteInfo before, InviteInfo after)
|
||||||
|
{
|
||||||
|
Before = before;
|
||||||
|
After = after;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static InviteUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var changes = entry.Changes;
|
||||||
|
|
||||||
|
var maxAgeModel = changes.FirstOrDefault(x => x.ChangedProperty == "max_age");
|
||||||
|
var codeModel = changes.FirstOrDefault(x => x.ChangedProperty == "code");
|
||||||
|
var temporaryModel = changes.FirstOrDefault(x => x.ChangedProperty == "temporary");
|
||||||
|
var channelIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "channel_id");
|
||||||
|
var maxUsesModel = changes.FirstOrDefault(x => x.ChangedProperty == "max_uses");
|
||||||
|
|
||||||
|
int? oldMaxAge = maxAgeModel?.OldValue?.ToObject<int>(),
|
||||||
|
newMaxAge = maxAgeModel?.NewValue?.ToObject<int>();
|
||||||
|
string oldCode = codeModel?.OldValue?.ToObject<string>(),
|
||||||
|
newCode = codeModel?.NewValue?.ToObject<string>();
|
||||||
|
bool? oldTemporary = temporaryModel?.OldValue?.ToObject<bool>(),
|
||||||
|
newTemporary = temporaryModel?.NewValue?.ToObject<bool>();
|
||||||
|
ulong? oldChannelId = channelIdModel?.OldValue?.ToObject<ulong>(),
|
||||||
|
newChannelId = channelIdModel?.NewValue?.ToObject<ulong>();
|
||||||
|
int? oldMaxUses = maxUsesModel?.OldValue?.ToObject<int>(),
|
||||||
|
newMaxUses = maxUsesModel?.NewValue?.ToObject<int>();
|
||||||
|
|
||||||
|
var before = new InviteInfo(oldMaxAge, oldCode, oldTemporary, oldChannelId, oldMaxUses);
|
||||||
|
var after = new InviteInfo(newMaxAge, newCode, newTemporary, newChannelId, newMaxUses);
|
||||||
|
|
||||||
|
return new InviteUpdateAuditLogData(before, after);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InviteInfo Before { get; }
|
||||||
|
public InviteInfo After { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class KickAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private KickAuditLogData(RestUser user)
|
||||||
|
{
|
||||||
|
Target = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static KickAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId);
|
||||||
|
return new KickAuditLogData(RestUser.Create(discord, userInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
public IUser Target { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class MemberRoleAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private MemberRoleAuditLogData(IReadOnlyCollection<RoleInfo> roles, IUser target)
|
||||||
|
{
|
||||||
|
Roles = roles;
|
||||||
|
Target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static MemberRoleAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var changes = entry.Changes;
|
||||||
|
|
||||||
|
var roleInfos = changes.SelectMany(x => x.NewValue.ToObject<API.Role[]>(),
|
||||||
|
(model, role) => new { model.ChangedProperty, Role = role })
|
||||||
|
.Select(x => new RoleInfo(x.Role.Name, x.Role.Id, x.ChangedProperty == "$add"))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId);
|
||||||
|
var user = RestUser.Create(discord, userInfo);
|
||||||
|
|
||||||
|
return new MemberRoleAuditLogData(roleInfos.ToReadOnlyCollection(), user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IReadOnlyCollection<RoleInfo> Roles { get; }
|
||||||
|
public IUser Target { get; }
|
||||||
|
|
||||||
|
public struct RoleInfo
|
||||||
|
{
|
||||||
|
internal RoleInfo(string name, ulong roleId, bool added)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
RoleId = roleId;
|
||||||
|
Added = added;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name { get; }
|
||||||
|
public ulong RoleId { get; }
|
||||||
|
public bool Added { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
using ChangeModel = Discord.API.AuditLogChange;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class MemberUpdateAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private MemberUpdateAuditLogData(IUser target, string newNick, string oldNick)
|
||||||
|
{
|
||||||
|
Target = target;
|
||||||
|
NewNick = newNick;
|
||||||
|
OldNick = oldNick;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static MemberUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var changes = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "nick");
|
||||||
|
|
||||||
|
var newNick = changes.NewValue?.ToObject<string>();
|
||||||
|
var oldNick = changes.OldValue?.ToObject<string>();
|
||||||
|
|
||||||
|
var targetInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId);
|
||||||
|
var user = RestUser.Create(discord, targetInfo);
|
||||||
|
|
||||||
|
return new MemberUpdateAuditLogData(user, newNick, oldNick);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IUser Target { get; }
|
||||||
|
public string NewNick { get; }
|
||||||
|
public string OldNick { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class MessageDeleteAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private MessageDeleteAuditLogData(ulong channelId, int count)
|
||||||
|
{
|
||||||
|
ChannelId = channelId;
|
||||||
|
MessageCount = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static MessageDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
return new MessageDeleteAuditLogData(entry.Options.MessageDeleteChannelId.Value, entry.Options.MessageDeleteCount.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int MessageCount { get; }
|
||||||
|
public ulong ChannelId { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class OverwriteCreateAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private OverwriteCreateAuditLogData(Overwrite overwrite)
|
||||||
|
{
|
||||||
|
Overwrite = overwrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static OverwriteCreateAuditLogData Create(BaseDiscordClient discord, Model log, 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>();
|
||||||
|
var allow = allowModel.NewValue.ToObject<ulong>();
|
||||||
|
|
||||||
|
var permissions = new OverwritePermissions(allow, deny);
|
||||||
|
|
||||||
|
var id = entry.Options.OverwriteTargetId.Value;
|
||||||
|
var type = entry.Options.OverwriteType;
|
||||||
|
|
||||||
|
PermissionTarget target = type == "member" ? PermissionTarget.User : PermissionTarget.Role;
|
||||||
|
|
||||||
|
return new OverwriteCreateAuditLogData(new Overwrite(id, target, permissions));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Overwrite Overwrite { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
using ChangeModel = Discord.API.AuditLogChange;
|
||||||
|
using OptionModel = Discord.API.AuditLogOptions;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class OverwriteDeleteAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private OverwriteDeleteAuditLogData(Overwrite deletedOverwrite)
|
||||||
|
{
|
||||||
|
Overwrite = deletedOverwrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static OverwriteDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var changes = entry.Changes;
|
||||||
|
|
||||||
|
var denyModel = changes.FirstOrDefault(x => x.ChangedProperty == "deny");
|
||||||
|
var typeModel = changes.FirstOrDefault(x => x.ChangedProperty == "type");
|
||||||
|
var idModel = changes.FirstOrDefault(x => x.ChangedProperty == "id");
|
||||||
|
var allowModel = changes.FirstOrDefault(x => x.ChangedProperty == "allow");
|
||||||
|
|
||||||
|
var deny = denyModel.OldValue.ToObject<ulong>();
|
||||||
|
var type = typeModel.OldValue.ToObject<string>();
|
||||||
|
var id = idModel.OldValue.ToObject<ulong>();
|
||||||
|
var allow = allowModel.OldValue.ToObject<ulong>();
|
||||||
|
|
||||||
|
PermissionTarget target = type == "member" ? PermissionTarget.User : PermissionTarget.Role;
|
||||||
|
|
||||||
|
return new OverwriteDeleteAuditLogData(new Overwrite(id, target, new OverwritePermissions(allow, deny)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Overwrite Overwrite { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class OverwriteUpdateAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private OverwriteUpdateAuditLogData(OverwritePermissions before, OverwritePermissions after, ulong targetId, PermissionTarget targetType)
|
||||||
|
{
|
||||||
|
OldPermissions = before;
|
||||||
|
NewPermissions = after;
|
||||||
|
OverwriteTargetId = targetId;
|
||||||
|
OverwriteType = targetType;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static OverwriteUpdateAuditLogData Create(BaseDiscordClient discord, Model log, 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>();
|
||||||
|
var afterAllow = allowModel?.NewValue?.ToObject<ulong>();
|
||||||
|
var beforeDeny = denyModel?.OldValue?.ToObject<ulong>();
|
||||||
|
var afterDeny = denyModel?.OldValue?.ToObject<ulong>();
|
||||||
|
|
||||||
|
var beforePermissions = new OverwritePermissions(beforeAllow ?? 0, beforeDeny ?? 0);
|
||||||
|
var afterPermissions = new OverwritePermissions(afterAllow ?? 0, afterDeny ?? 0);
|
||||||
|
|
||||||
|
PermissionTarget target = entry.Options.OverwriteType == "member" ? PermissionTarget.User : PermissionTarget.Role;
|
||||||
|
|
||||||
|
return new OverwriteUpdateAuditLogData(beforePermissions, afterPermissions, entry.Options.OverwriteTargetId.Value, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OverwritePermissions OldPermissions { get; }
|
||||||
|
public OverwritePermissions NewPermissions { get; }
|
||||||
|
|
||||||
|
public ulong OverwriteTargetId { get; }
|
||||||
|
public PermissionTarget OverwriteType { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class PruneAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private PruneAuditLogData(int pruneDays, int membersRemoved)
|
||||||
|
{
|
||||||
|
PruneDays = pruneDays;
|
||||||
|
MembersRemoved = membersRemoved;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static PruneAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
return new PruneAuditLogData(entry.Options.PruneDeleteMemberDays.Value, entry.Options.PruneMembersRemoved.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int PruneDays { get; }
|
||||||
|
public int MembersRemoved { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class RoleCreateAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private RoleCreateAuditLogData(ulong id, RoleInfo props)
|
||||||
|
{
|
||||||
|
RoleId = id;
|
||||||
|
Properties = props;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static RoleCreateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var changes = entry.Changes;
|
||||||
|
|
||||||
|
var colorModel = changes.FirstOrDefault(x => x.ChangedProperty == "color");
|
||||||
|
var mentionableModel = changes.FirstOrDefault(x => x.ChangedProperty == "mentionable");
|
||||||
|
var hoistModel = changes.FirstOrDefault(x => x.ChangedProperty == "hoist");
|
||||||
|
var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name");
|
||||||
|
var permissionsModel = changes.FirstOrDefault(x => x.ChangedProperty == "permissions");
|
||||||
|
|
||||||
|
uint? colorRaw = colorModel?.NewValue?.ToObject<uint>();
|
||||||
|
bool? mentionable = mentionableModel?.NewValue?.ToObject<bool>();
|
||||||
|
bool? hoist = hoistModel?.NewValue?.ToObject<bool>();
|
||||||
|
string name = nameModel?.NewValue?.ToObject<string>();
|
||||||
|
ulong? permissionsRaw = permissionsModel?.NewValue?.ToObject<ulong>();
|
||||||
|
|
||||||
|
Color? color = null;
|
||||||
|
GuildPermissions? permissions = null;
|
||||||
|
|
||||||
|
if (colorRaw.HasValue)
|
||||||
|
color = new Color(colorRaw.Value);
|
||||||
|
if (permissionsRaw.HasValue)
|
||||||
|
permissions = new GuildPermissions(permissionsRaw.Value);
|
||||||
|
|
||||||
|
return new RoleCreateAuditLogData(entry.TargetId.Value,
|
||||||
|
new RoleInfo(color, mentionable, hoist, name, permissions));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong RoleId { get; }
|
||||||
|
public RoleInfo Properties { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class RoleDeleteAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private RoleDeleteAuditLogData(ulong id, RoleInfo props)
|
||||||
|
{
|
||||||
|
RoleId = id;
|
||||||
|
Properties = props;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static RoleDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var changes = entry.Changes;
|
||||||
|
|
||||||
|
var colorModel = changes.FirstOrDefault(x => x.ChangedProperty == "color");
|
||||||
|
var mentionableModel = changes.FirstOrDefault(x => x.ChangedProperty == "mentionable");
|
||||||
|
var hoistModel = changes.FirstOrDefault(x => x.ChangedProperty == "hoist");
|
||||||
|
var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name");
|
||||||
|
var permissionsModel = changes.FirstOrDefault(x => x.ChangedProperty == "permissions");
|
||||||
|
|
||||||
|
uint? colorRaw = colorModel?.OldValue?.ToObject<uint>();
|
||||||
|
bool? mentionable = mentionableModel?.OldValue?.ToObject<bool>();
|
||||||
|
bool? hoist = hoistModel?.OldValue?.ToObject<bool>();
|
||||||
|
string name = nameModel?.OldValue?.ToObject<string>();
|
||||||
|
ulong? permissionsRaw = permissionsModel?.OldValue?.ToObject<ulong>();
|
||||||
|
|
||||||
|
Color? color = null;
|
||||||
|
GuildPermissions? permissions = null;
|
||||||
|
|
||||||
|
if (colorRaw.HasValue)
|
||||||
|
color = new Color(colorRaw.Value);
|
||||||
|
if (permissionsRaw.HasValue)
|
||||||
|
permissions = new GuildPermissions(permissionsRaw.Value);
|
||||||
|
|
||||||
|
return new RoleDeleteAuditLogData(entry.TargetId.Value,
|
||||||
|
new RoleInfo(color, mentionable, hoist, name, permissions));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong RoleId { get; }
|
||||||
|
public RoleInfo Properties { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public struct RoleInfo
|
||||||
|
{
|
||||||
|
internal RoleInfo(Color? color, bool? mentionable, bool? hoist, string name,
|
||||||
|
GuildPermissions? permissions)
|
||||||
|
{
|
||||||
|
Color = color;
|
||||||
|
Mentionable = mentionable;
|
||||||
|
Hoist = hoist;
|
||||||
|
Name = name;
|
||||||
|
Permissions = permissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color? Color { get; }
|
||||||
|
public bool? Mentionable { get; }
|
||||||
|
public bool? Hoist { get; }
|
||||||
|
public string Name { get; }
|
||||||
|
public GuildPermissions? Permissions { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class RoleUpdateAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private RoleUpdateAuditLogData(ulong id, RoleInfo oldProps, RoleInfo newProps)
|
||||||
|
{
|
||||||
|
RoleId = id;
|
||||||
|
Before = oldProps;
|
||||||
|
After = newProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static RoleUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var changes = entry.Changes;
|
||||||
|
|
||||||
|
var colorModel = changes.FirstOrDefault(x => x.ChangedProperty == "color");
|
||||||
|
var mentionableModel = changes.FirstOrDefault(x => x.ChangedProperty == "mentionable");
|
||||||
|
var hoistModel = changes.FirstOrDefault(x => x.ChangedProperty == "hoist");
|
||||||
|
var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name");
|
||||||
|
var permissionsModel = changes.FirstOrDefault(x => x.ChangedProperty == "permissions");
|
||||||
|
|
||||||
|
uint? oldColorRaw = colorModel?.OldValue?.ToObject<uint>(),
|
||||||
|
newColorRaw = colorModel?.NewValue?.ToObject<uint>();
|
||||||
|
bool? oldMentionable = mentionableModel?.OldValue?.ToObject<bool>(),
|
||||||
|
newMentionable = mentionableModel?.NewValue?.ToObject<bool>();
|
||||||
|
bool? oldHoist = hoistModel?.OldValue?.ToObject<bool>(),
|
||||||
|
newHoist = hoistModel?.NewValue?.ToObject<bool>();
|
||||||
|
string oldName = nameModel?.OldValue?.ToObject<string>(),
|
||||||
|
newName = nameModel?.NewValue?.ToObject<string>();
|
||||||
|
ulong? oldPermissionsRaw = permissionsModel?.OldValue?.ToObject<ulong>(),
|
||||||
|
newPermissionsRaw = permissionsModel?.OldValue?.ToObject<ulong>();
|
||||||
|
|
||||||
|
Color? oldColor = null,
|
||||||
|
newColor = null;
|
||||||
|
GuildPermissions? oldPermissions = null,
|
||||||
|
newPermissions = null;
|
||||||
|
|
||||||
|
if (oldColorRaw.HasValue)
|
||||||
|
oldColor = new Color(oldColorRaw.Value);
|
||||||
|
if (newColorRaw.HasValue)
|
||||||
|
newColor = new Color(newColorRaw.Value);
|
||||||
|
if (oldPermissionsRaw.HasValue)
|
||||||
|
oldPermissions = new GuildPermissions(oldPermissionsRaw.Value);
|
||||||
|
if (newPermissionsRaw.HasValue)
|
||||||
|
newPermissions = new GuildPermissions(newPermissionsRaw.Value);
|
||||||
|
|
||||||
|
var oldProps = new RoleInfo(oldColor, oldMentionable, oldHoist, oldName, oldPermissions);
|
||||||
|
var newProps = new RoleInfo(newColor, newMentionable, newHoist, newName, newPermissions);
|
||||||
|
|
||||||
|
return new RoleUpdateAuditLogData(entry.TargetId.Value, oldProps, newProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong RoleId { get; }
|
||||||
|
public RoleInfo Before { get; }
|
||||||
|
public RoleInfo After { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class UnbanAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private UnbanAuditLogData(IUser user)
|
||||||
|
{
|
||||||
|
Target = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static UnbanAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var userInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId);
|
||||||
|
return new UnbanAuditLogData(RestUser.Create(discord, userInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
public IUser Target { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class WebhookCreateAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private WebhookCreateAuditLogData(IWebhook webhook, WebhookType type, string name, ulong channelId)
|
||||||
|
{
|
||||||
|
Webhook = webhook;
|
||||||
|
Name = name;
|
||||||
|
Type = type;
|
||||||
|
ChannelId = channelId;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static WebhookCreateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var changes = entry.Changes;
|
||||||
|
|
||||||
|
var channelIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "channel_id");
|
||||||
|
var typeModel = changes.FirstOrDefault(x => x.ChangedProperty == "type");
|
||||||
|
var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name");
|
||||||
|
|
||||||
|
var channelId = channelIdModel.NewValue.ToObject<ulong>();
|
||||||
|
var type = typeModel.NewValue.ToObject<WebhookType>();
|
||||||
|
var name = nameModel.NewValue.ToObject<string>();
|
||||||
|
|
||||||
|
var webhookInfo = log.Webhooks?.FirstOrDefault(x => x.Id == entry.TargetId);
|
||||||
|
var webhook = RestWebhook.Create(discord, (IGuild)null, webhookInfo);
|
||||||
|
|
||||||
|
return new WebhookCreateAuditLogData(webhook, type, name, channelId);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Corresponds to the *current* data
|
||||||
|
public IWebhook Webhook { get; }
|
||||||
|
|
||||||
|
//Corresponds to the *audit log* data
|
||||||
|
public WebhookType Type { get; }
|
||||||
|
public string Name { get; }
|
||||||
|
public ulong ChannelId { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class WebhookDeleteAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private WebhookDeleteAuditLogData(ulong id, ulong channel, WebhookType type, string name, string avatar)
|
||||||
|
{
|
||||||
|
WebhookId = id;
|
||||||
|
ChannelId = channel;
|
||||||
|
Name = name;
|
||||||
|
Type = type;
|
||||||
|
Avatar = avatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static WebhookDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var changes = entry.Changes;
|
||||||
|
|
||||||
|
var channelIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "channel_id");
|
||||||
|
var typeModel = changes.FirstOrDefault(x => x.ChangedProperty == "type");
|
||||||
|
var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name");
|
||||||
|
var avatarHashModel = changes.FirstOrDefault(x => x.ChangedProperty == "avatar_hash");
|
||||||
|
|
||||||
|
var channelId = channelIdModel.OldValue.ToObject<ulong>();
|
||||||
|
var type = typeModel.OldValue.ToObject<WebhookType>();
|
||||||
|
var name = nameModel.OldValue.ToObject<string>();
|
||||||
|
var avatarHash = avatarHashModel?.OldValue?.ToObject<string>();
|
||||||
|
|
||||||
|
return new WebhookDeleteAuditLogData(entry.TargetId.Value, channelId, type, name, avatarHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong WebhookId { get; }
|
||||||
|
public ulong ChannelId { get; }
|
||||||
|
public WebhookType Type { get; }
|
||||||
|
public string Name { get; }
|
||||||
|
public string Avatar { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public struct WebhookInfo
|
||||||
|
{
|
||||||
|
internal WebhookInfo(string name, ulong? channelId, string avatar)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
ChannelId = channelId;
|
||||||
|
Avatar = avatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name { get; }
|
||||||
|
public ulong? ChannelId { get; }
|
||||||
|
public string Avatar { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class WebhookUpdateAuditLogData : IAuditLogData
|
||||||
|
{
|
||||||
|
private WebhookUpdateAuditLogData(IWebhook webhook, WebhookInfo before, WebhookInfo after)
|
||||||
|
{
|
||||||
|
Webhook = webhook;
|
||||||
|
Before = before;
|
||||||
|
After = after;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static WebhookUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
|
||||||
|
{
|
||||||
|
var changes = entry.Changes;
|
||||||
|
|
||||||
|
var nameModel = changes.FirstOrDefault(x => x.ChangedProperty == "name");
|
||||||
|
var channelIdModel = changes.FirstOrDefault(x => x.ChangedProperty == "channel_id");
|
||||||
|
var avatarHashModel = changes.FirstOrDefault(x => x.ChangedProperty == "avatar_hash");
|
||||||
|
|
||||||
|
var oldName = nameModel?.OldValue?.ToObject<string>();
|
||||||
|
var oldChannelId = channelIdModel?.OldValue?.ToObject<ulong>();
|
||||||
|
var oldAvatar = avatarHashModel?.OldValue?.ToObject<string>();
|
||||||
|
var before = new WebhookInfo(oldName, oldChannelId, oldAvatar);
|
||||||
|
|
||||||
|
var newName = nameModel?.NewValue?.ToObject<string>();
|
||||||
|
var newChannelId = channelIdModel?.NewValue?.ToObject<ulong>();
|
||||||
|
var newAvatar = avatarHashModel?.NewValue?.ToObject<string>();
|
||||||
|
var after = new WebhookInfo(newName, newChannelId, newAvatar);
|
||||||
|
|
||||||
|
var webhookInfo = log.Webhooks?.FirstOrDefault(x => x.Id == entry.TargetId);
|
||||||
|
var webhook = RestWebhook.Create(discord, (IGuild)null, webhookInfo);
|
||||||
|
|
||||||
|
return new WebhookUpdateAuditLogData(webhook, before, after);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Again, the *current* data
|
||||||
|
public IWebhook Webhook { get; }
|
||||||
|
|
||||||
|
//And the *audit log* data
|
||||||
|
public WebhookInfo Before { get; }
|
||||||
|
public WebhookInfo After { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
38
src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs
Normal file
38
src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Model = Discord.API.AuditLog;
|
||||||
|
using EntryModel = Discord.API.AuditLogEntry;
|
||||||
|
|
||||||
|
namespace Discord.Rest
|
||||||
|
{
|
||||||
|
public class RestAuditLogEntry : RestEntity<ulong>, IAuditLogEntry
|
||||||
|
{
|
||||||
|
private RestAuditLogEntry(BaseDiscordClient discord, Model fullLog, EntryModel model, IUser user)
|
||||||
|
: base(discord, model.Id)
|
||||||
|
{
|
||||||
|
Action = model.Action;
|
||||||
|
Data = AuditLogHelper.CreateData(discord, fullLog, model);
|
||||||
|
User = user;
|
||||||
|
Reason = model.Reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static RestAuditLogEntry Create(BaseDiscordClient discord, Model fullLog, EntryModel model)
|
||||||
|
{
|
||||||
|
var userInfo = fullLog.Users.FirstOrDefault(x => x.Id == model.UserId);
|
||||||
|
IUser user = null;
|
||||||
|
if (userInfo != null)
|
||||||
|
user = RestUser.Create(discord, userInfo);
|
||||||
|
|
||||||
|
return new RestAuditLogEntry(discord, fullLog, model, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public ActionType Action { get; }
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IAuditLogData Data { get; }
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IUser User { get; }
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public string Reason { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -268,6 +268,35 @@ namespace Discord.Rest
|
|||||||
return model.Pruned;
|
return model.Pruned;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Audit logs
|
||||||
|
public static IAsyncEnumerable<IReadOnlyCollection<RestAuditLogEntry>> GetAuditLogsAsync(IGuild guild, BaseDiscordClient client,
|
||||||
|
ulong? from, int? limit, RequestOptions options)
|
||||||
|
{
|
||||||
|
return new PagedAsyncEnumerable<RestAuditLogEntry>(
|
||||||
|
DiscordConfig.MaxAuditLogEntriesPerBatch,
|
||||||
|
async (info, ct) =>
|
||||||
|
{
|
||||||
|
var args = new GetAuditLogsParams
|
||||||
|
{
|
||||||
|
Limit = info.PageSize
|
||||||
|
};
|
||||||
|
if (info.Position != null)
|
||||||
|
args.BeforeEntryId = info.Position.Value;
|
||||||
|
var model = await client.ApiClient.GetAuditLogsAsync(guild.Id, args, options);
|
||||||
|
return model.Entries.Select((x) => RestAuditLogEntry.Create(client, model, x)).ToImmutableArray();
|
||||||
|
},
|
||||||
|
nextPage: (info, lastPage) =>
|
||||||
|
{
|
||||||
|
if (lastPage.Count != DiscordConfig.MaxAuditLogEntriesPerBatch)
|
||||||
|
return false;
|
||||||
|
info.Position = lastPage.Min(x => x.Id);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
start: from,
|
||||||
|
count: limit
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
//Webhooks
|
//Webhooks
|
||||||
public static async Task<RestWebhook> GetWebhookAsync(IGuild guild, BaseDiscordClient client, ulong id, RequestOptions options)
|
public static async Task<RestWebhook> GetWebhookAsync(IGuild guild, BaseDiscordClient client, ulong id, RequestOptions options)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -268,6 +268,10 @@ namespace Discord.Rest
|
|||||||
public Task<int> PruneUsersAsync(int days = 30, bool simulate = false, RequestOptions options = null)
|
public Task<int> PruneUsersAsync(int days = 30, bool simulate = false, RequestOptions options = null)
|
||||||
=> GuildHelper.PruneUsersAsync(this, Discord, days, simulate, options);
|
=> GuildHelper.PruneUsersAsync(this, Discord, days, simulate, options);
|
||||||
|
|
||||||
|
//Audit logs
|
||||||
|
public IAsyncEnumerable<IReadOnlyCollection<RestAuditLogEntry>> GetAuditLogsAsync(int limit, RequestOptions options = null)
|
||||||
|
=> GuildHelper.GetAuditLogsAsync(this, Discord, null, limit, options);
|
||||||
|
|
||||||
//Webhooks
|
//Webhooks
|
||||||
public Task<RestWebhook> GetWebhookAsync(ulong id, RequestOptions options = null)
|
public Task<RestWebhook> GetWebhookAsync(ulong id, RequestOptions options = null)
|
||||||
=> GuildHelper.GetWebhookAsync(this, Discord, id, options);
|
=> GuildHelper.GetWebhookAsync(this, Discord, id, options);
|
||||||
@@ -429,6 +433,14 @@ namespace Discord.Rest
|
|||||||
}
|
}
|
||||||
Task IGuild.DownloadUsersAsync() { throw new NotSupportedException(); }
|
Task IGuild.DownloadUsersAsync() { throw new NotSupportedException(); }
|
||||||
|
|
||||||
|
async Task<IReadOnlyCollection<IAuditLogEntry>> IGuild.GetAuditLogAsync(int limit, CacheMode cacheMode, RequestOptions options)
|
||||||
|
{
|
||||||
|
if (cacheMode == CacheMode.AllowDownload)
|
||||||
|
return (await GetAuditLogsAsync(limit, options).FlattenAsync().ConfigureAwait(false)).ToImmutableArray();
|
||||||
|
else
|
||||||
|
return ImmutableArray.Create<IAuditLogEntry>();
|
||||||
|
}
|
||||||
|
|
||||||
async Task<IWebhook> IGuild.GetWebhookAsync(ulong id, RequestOptions options)
|
async Task<IWebhook> IGuild.GetWebhookAsync(ulong id, RequestOptions options)
|
||||||
=> await GetWebhookAsync(id, options);
|
=> await GetWebhookAsync(id, options);
|
||||||
async Task<IReadOnlyCollection<IWebhook>> IGuild.GetWebhooksAsync(RequestOptions options)
|
async Task<IReadOnlyCollection<IWebhook>> IGuild.GetWebhooksAsync(RequestOptions options)
|
||||||
|
|||||||
@@ -438,6 +438,10 @@ namespace Discord.WebSocket
|
|||||||
_downloaderPromise.TrySetResultAsync(true);
|
_downloaderPromise.TrySetResultAsync(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Audit logs
|
||||||
|
public IAsyncEnumerable<IReadOnlyCollection<RestAuditLogEntry>> GetAuditLogsAsync(int limit, RequestOptions options = null)
|
||||||
|
=> GuildHelper.GetAuditLogsAsync(this, Discord, null, limit, options);
|
||||||
|
|
||||||
//Webhooks
|
//Webhooks
|
||||||
public Task<RestWebhook> GetWebhookAsync(ulong id, RequestOptions options = null)
|
public Task<RestWebhook> GetWebhookAsync(ulong id, RequestOptions options = null)
|
||||||
=> GuildHelper.GetWebhookAsync(this, Discord, id, options);
|
=> GuildHelper.GetWebhookAsync(this, Discord, id, options);
|
||||||
@@ -703,6 +707,14 @@ namespace Discord.WebSocket
|
|||||||
Task<IGuildUser> IGuild.GetOwnerAsync(CacheMode mode, RequestOptions options)
|
Task<IGuildUser> IGuild.GetOwnerAsync(CacheMode mode, RequestOptions options)
|
||||||
=> Task.FromResult<IGuildUser>(Owner);
|
=> Task.FromResult<IGuildUser>(Owner);
|
||||||
|
|
||||||
|
async Task<IReadOnlyCollection<IAuditLogEntry>> IGuild.GetAuditLogAsync(int limit, CacheMode cacheMode, RequestOptions options)
|
||||||
|
{
|
||||||
|
if (cacheMode == CacheMode.AllowDownload)
|
||||||
|
return (await GetAuditLogsAsync(limit, options).FlattenAsync().ConfigureAwait(false)).ToImmutableArray();
|
||||||
|
else
|
||||||
|
return ImmutableArray.Create<IAuditLogEntry>();
|
||||||
|
}
|
||||||
|
|
||||||
async Task<IWebhook> IGuild.GetWebhookAsync(ulong id, RequestOptions options)
|
async Task<IWebhook> IGuild.GetWebhookAsync(ulong id, RequestOptions options)
|
||||||
=> await GetWebhookAsync(id, options);
|
=> await GetWebhookAsync(id, options);
|
||||||
async Task<IReadOnlyCollection<IWebhook>> IGuild.GetWebhooksAsync(RequestOptions options)
|
async Task<IReadOnlyCollection<IWebhook>> IGuild.GetWebhooksAsync(RequestOptions options)
|
||||||
|
|||||||
Reference in New Issue
Block a user