diff --git a/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogChange.cs b/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogChanges.cs
similarity index 83%
rename from src/Discord.Net.Core/Entities/AuditLogs/IAuditLogChange.cs
rename to src/Discord.Net.Core/Entities/AuditLogs/IAuditLogChanges.cs
index 0c36b53b2..2be25a13e 100644
--- a/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogChange.cs
+++ b/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogChanges.cs
@@ -9,8 +9,6 @@ namespace Discord
///
/// Represents changes which may occur within a
///
- public interface IAuditLogChange
- {
-
- }
+ public interface IAuditLogChanges
+ { }
}
diff --git a/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogEntry.cs b/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogEntry.cs
index 0569f5fff..b3cf6d4af 100644
--- a/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogEntry.cs
+++ b/src/Discord.Net.Core/Entities/AuditLogs/IAuditLogEntry.cs
@@ -19,7 +19,7 @@ namespace Discord
///
/// The changes which occured within this entry. May be empty if no changes occured.
///
- IReadOnlyCollection Changes { get; }
+ IAuditLogChanges Changes { get; }
///
/// Any options which apply to this entry. If no options were provided, this may be .
@@ -27,9 +27,9 @@ namespace Discord
IAuditLogOptions Options { get; }
///
- /// The id which the target applies to
+ /// The id which the target applies to, or null if it does not apply to anything specific.
///
- ulong TargetId { get; }
+ ulong? TargetId { get; }
///
/// The user responsible for causing the changes
diff --git a/src/Discord.Net.Rest/API/Common/AuditLogEntry.cs b/src/Discord.Net.Rest/API/Common/AuditLogEntry.cs
index ecdb12650..80d9a9e97 100644
--- a/src/Discord.Net.Rest/API/Common/AuditLogEntry.cs
+++ b/src/Discord.Net.Rest/API/Common/AuditLogEntry.cs
@@ -5,7 +5,7 @@ namespace Discord.API
internal class AuditLogEntry
{
[JsonProperty("target_id")]
- public ulong TargetId { get; set; }
+ public ulong? TargetId { get; set; }
[JsonProperty("user_id")]
public ulong UserId { get; set; }
diff --git a/src/Discord.Net.Rest/API/Rest/GetAuditLogsParams.cs b/src/Discord.Net.Rest/API/Rest/GetAuditLogsParams.cs
index fc3e0d9f3..ceabccbc8 100644
--- a/src/Discord.Net.Rest/API/Rest/GetAuditLogsParams.cs
+++ b/src/Discord.Net.Rest/API/Rest/GetAuditLogsParams.cs
@@ -3,6 +3,6 @@
class GetAuditLogsParams
{
public Optional Limit { get; set; }
- public Optional AfterEntryId { get; set; }
+ public Optional BeforeEntryId { get; set; }
}
}
diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs
index c7b1b23c5..6ab6bd334 100644
--- a/src/Discord.Net.Rest/DiscordRestApiClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs
@@ -1067,10 +1067,15 @@ namespace Discord.API
options = RequestOptions.CreateOrClone(options);
int limit = args.Limit.GetValueOrDefault(int.MaxValue);
- ulong afterEntryId = args.AfterEntryId.GetValueOrDefault(0);
var ids = new BucketIds(guildId: guildId);
- Expression> endpoint = () => $"guilds/{guildId}/audit-logs?limit={limit}&after={afterEntryId}";
+ Expression> 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("GET", endpoint, ids, options: options).ConfigureAwait(false);
}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/AuditLogHelper.cs b/src/Discord.Net.Rest/Entities/AuditLogs/AuditLogHelper.cs
index 7e349e110..01855267a 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/AuditLogHelper.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/AuditLogHelper.cs
@@ -1,9 +1,7 @@
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;
@@ -12,25 +10,76 @@ namespace Discord.Rest
{
internal static class AuditLogHelper
{
- public static IAuditLogChange CreateChange(BaseDiscordClient discord, EntryModel entryModel, ChangeModel model)
+ public static IAuditLogChanges CreateChange(BaseDiscordClient discord, Model log, EntryModel entry, ChangeModel[] models)
{
- switch (entryModel.Action)
+ switch (entry.Action)
{
+ case ActionType.GuildUpdated:
+ break;
+ case ActionType.ChannelCreated:
+ break;
+ case ActionType.ChannelUpdated:
+ break;
+ case ActionType.ChannelDeleted:
+ return ChannelDeleteChanges.Create(discord, models);
+ case ActionType.OverwriteCreated:
+ break;
+ case ActionType.OverwriteUpdated:
+ break;
+ case ActionType.OverwriteDeleted:
+ return OverwriteDeleteChanges.Create(discord, log, entry, models);
+ case ActionType.Prune:
+ break;
+ case ActionType.Ban:
+ break;
+ case ActionType.Unban:
+ break;
+ case ActionType.MemberUpdated:
+ return MemberUpdateChanges.Create(discord, log, entry, models.FirstOrDefault());
case ActionType.MemberRoleUpdated:
- return new MemberRoleAuditLogChange(discord, model);
+ return MemberRoleChanges.Create(discord, log, entry, models);
+ case ActionType.RoleCreated:
+ break;
+ case ActionType.RoleUpdated:
+ break;
+ case ActionType.RoleDeleted:
+ break;
+ case ActionType.InviteCreated:
+ return InviteCreateChanges.Create(discord, log, models);
+ case ActionType.InviteUpdated:
+ break;
+ case ActionType.InviteDeleted:
+ break;
+ case ActionType.WebhookCreated:
+ break;
+ case ActionType.WebhookUpdated:
+ break;
+ case ActionType.WebhookDeleted:
+ break;
+ case ActionType.EmojiCreated:
+ return EmoteCreateChanges.Create(discord, entry, models.FirstOrDefault());
+ case ActionType.EmojiUpdated:
+ return EmoteUpdateChanges.Create(discord, entry, models.FirstOrDefault());
+ case ActionType.EmojiDeleted:
+ return EmoteDeleteChanges.Create(discord, entry, models.FirstOrDefault());
+ case ActionType.MessageDeleted:
+ case ActionType.Kick:
default:
- throw new NotImplementedException($"{nameof(AuditLogHelper)} does not implement the {entryModel.Action} audit log action.");
+ return null;
}
+ return null;
+ //throw new NotImplementedException($"{nameof(AuditLogHelper)} does not implement the {entry.Action} audit log changeset.");
}
- public static IAuditLogOptions CreateOptions(BaseDiscordClient discord, EntryModel entryModel, OptionModel model)
+ public static IAuditLogOptions CreateOptions(BaseDiscordClient discord, Model fullModel, EntryModel entryModel, OptionModel model)
{
switch (entryModel.Action)
{
case ActionType.MessageDeleted:
return new MessageDeleteAuditLogOptions(discord, model);
default:
- throw new NotImplementedException($"{nameof(AuditLogHelper)} does not implement the {entryModel.Action} audit log action.");
+ return null;
+ //throw new NotImplementedException($"{nameof(AuditLogHelper)} does not implement the {entryModel.Action} audit log action.");
}
}
}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/Changes/ChannelDeleteChanges.cs b/src/Discord.Net.Rest/Entities/AuditLogs/Changes/ChannelDeleteChanges.cs
new file mode 100644
index 000000000..ad2a2cd67
--- /dev/null
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/Changes/ChannelDeleteChanges.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using ChangeModel = Discord.API.AuditLogChange;
+
+namespace Discord.Rest
+{
+ public class ChannelDeleteChanges : IAuditLogChanges
+ {
+ private ChannelDeleteChanges(string name, ChannelType type, IReadOnlyCollection overwrites)
+ {
+ ChannelName = name;
+ ChannelType = type;
+ Overwrites = overwrites;
+ }
+
+ internal static ChannelDeleteChanges Create(BaseDiscordClient discord, ChangeModel[] models)
+ {
+ //Use FirstOrDefault here in case the order ever changes
+ var overwritesModel = models.FirstOrDefault(x => x.ChangedProperty == "permission_overwrites");
+ var typeModel = models.FirstOrDefault(x => x.ChangedProperty == "type");
+ var nameModel = models.FirstOrDefault(x => x.ChangedProperty == "name");
+
+ var overwrites = overwritesModel.OldValue.ToObject()
+ .Select(x => new Overwrite(x.TargetId, x.TargetType, new OverwritePermissions(x.Allow, x.Deny)))
+ .ToList();
+ var type = typeModel.OldValue.ToObject();
+ var name = nameModel.OldValue.ToObject();
+
+ return new ChannelDeleteChanges(name, type, overwrites.ToReadOnlyCollection());
+ }
+
+ public string ChannelName { get; }
+ public ChannelType ChannelType { get; }
+ public IReadOnlyCollection Overwrites { get; }
+ }
+}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/Changes/EmoteCreateChanges.cs b/src/Discord.Net.Rest/Entities/AuditLogs/Changes/EmoteCreateChanges.cs
new file mode 100644
index 000000000..e6e7e3b64
--- /dev/null
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/Changes/EmoteCreateChanges.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using EntryModel = Discord.API.AuditLogEntry;
+using ChangeModel = Discord.API.AuditLogChange;
+
+namespace Discord.Rest
+{
+ public class EmoteCreateChanges : IAuditLogChanges
+ {
+ private EmoteCreateChanges(Emote emote)
+ {
+ Emote = emote;
+ }
+
+ internal static EmoteCreateChanges Create(BaseDiscordClient discord, EntryModel entry, ChangeModel model)
+ {
+ var emoteName = model.NewValue.ToObject();
+ var emote = new Emote(entry.TargetId.Value, emoteName);
+
+ return new EmoteCreateChanges(emote);
+ }
+
+ public Emote Emote { get; }
+ }
+}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/Changes/EmoteDeleteChanges.cs b/src/Discord.Net.Rest/Entities/AuditLogs/Changes/EmoteDeleteChanges.cs
new file mode 100644
index 000000000..7e876eff7
--- /dev/null
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/Changes/EmoteDeleteChanges.cs
@@ -0,0 +1,23 @@
+using EntryModel = Discord.API.AuditLogEntry;
+using ChangeModel = Discord.API.AuditLogChange;
+
+namespace Discord.Rest
+{
+ public class EmoteDeleteChanges : IAuditLogChanges
+ {
+ private EmoteDeleteChanges(Emote emote)
+ {
+ Emote = emote;
+ }
+
+ internal static EmoteDeleteChanges Create(BaseDiscordClient discord, EntryModel entry, ChangeModel model)
+ {
+ var emoteName = model.OldValue.ToObject();
+ var emote = new Emote(entry.TargetId.Value, emoteName);
+
+ return new EmoteDeleteChanges(emote);
+ }
+
+ public Emote Emote { get; }
+ }
+}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/Changes/EmoteUpdateChanges.cs b/src/Discord.Net.Rest/Entities/AuditLogs/Changes/EmoteUpdateChanges.cs
new file mode 100644
index 000000000..73b174f8b
--- /dev/null
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/Changes/EmoteUpdateChanges.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using EntryModel = Discord.API.AuditLogEntry;
+using ChangeModel = Discord.API.AuditLogChange;
+
+namespace Discord.Rest
+{
+ public class EmoteUpdateChanges : IAuditLogChanges
+ {
+ private EmoteUpdateChanges(Emote emote, string oldName)
+ {
+ Emote = emote;
+ PreviousName = oldName;
+ }
+
+ internal static EmoteUpdateChanges Create(BaseDiscordClient discord, EntryModel entry, ChangeModel model)
+ {
+ var emoteName = model.NewValue.ToObject();
+ var emote = new Emote(entry.TargetId.Value, emoteName);
+
+ var oldName = model.OldValue.ToObject();
+
+ return new EmoteUpdateChanges(emote, oldName);
+ }
+
+ public Emote Emote { get; }
+ public string PreviousName { get; }
+ }
+}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/Changes/InviteCreateChanges.cs b/src/Discord.Net.Rest/Entities/AuditLogs/Changes/InviteCreateChanges.cs
new file mode 100644
index 000000000..9d0e4419d
--- /dev/null
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/Changes/InviteCreateChanges.cs
@@ -0,0 +1,54 @@
+using System.Linq;
+
+using Model = Discord.API.AuditLog;
+using ChangeModel = Discord.API.AuditLogChange;
+
+namespace Discord.Rest
+{
+ public class InviteCreateChanges : IAuditLogChanges
+ {
+ private InviteCreateChanges(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 InviteCreateChanges Create(BaseDiscordClient discord, Model log, ChangeModel[] models)
+ {
+ //Again, FirstOrDefault to protect against ordering changes
+ var maxAgeModel = models.FirstOrDefault(x => x.ChangedProperty == "max_age");
+ var codeModel = models.FirstOrDefault(x => x.ChangedProperty == "code");
+ var temporaryModel = models.FirstOrDefault(x => x.ChangedProperty == "temporary");
+ var inviterIdModel = models.FirstOrDefault(x => x.ChangedProperty == "inviter_id");
+ var channelIdModel = models.FirstOrDefault(x => x.ChangedProperty == "channel_id");
+ var usesModel = models.FirstOrDefault(x => x.ChangedProperty == "uses");
+ var maxUsesModel = models.FirstOrDefault(x => x.ChangedProperty == "max_uses");
+
+ var maxAge = maxAgeModel.NewValue.ToObject();
+ var code = codeModel.NewValue.ToObject();
+ var temporary = temporaryModel.NewValue.ToObject();
+ var inviterId = inviterIdModel.NewValue.ToObject();
+ var channelId = channelIdModel.NewValue.ToObject();
+ var uses = usesModel.NewValue.ToObject();
+ var maxUses = maxUsesModel.NewValue.ToObject();
+
+ var inviterInfo = log.Users.FirstOrDefault(x => x.Id == inviterId);
+ var inviter = RestUser.Create(discord, inviterInfo);
+
+ return new InviteCreateChanges(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; } //TODO: IChannel-ify
+ public int Uses { get; }
+ public int MaxUses { get; }
+ }
+}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/Changes/MemberRoleAuditLogChange.cs b/src/Discord.Net.Rest/Entities/AuditLogs/Changes/MemberRoleAuditLogChange.cs
deleted file mode 100644
index c5f167d6f..000000000
--- a/src/Discord.Net.Rest/Entities/AuditLogs/Changes/MemberRoleAuditLogChange.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using Newtonsoft.Json;
-
-using Model = Discord.API.AuditLogChange;
-
-namespace Discord.Rest
-{
- public class MemberRoleAuditLogChange : IAuditLogChange
- {
- internal MemberRoleAuditLogChange(BaseDiscordClient discord, Model model)
- {
- RoleAdded = model.ChangedProperty == "$add";
- RoleId = model.NewValue.Value("id");
- }
-
- public bool RoleAdded { get; set; }
- //TODO: convert to IRole
- public ulong RoleId { get; set; }
- }
-}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/Changes/MemberRoleChanges.cs b/src/Discord.Net.Rest/Entities/AuditLogs/Changes/MemberRoleChanges.cs
new file mode 100644
index 000000000..9abf5be79
--- /dev/null
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/Changes/MemberRoleChanges.cs
@@ -0,0 +1,51 @@
+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;
+
+namespace Discord.Rest
+{
+ public class MemberRoleChanges : IAuditLogChanges
+ {
+ private MemberRoleChanges(IReadOnlyCollection roles, IUser target)
+ {
+ Roles = roles;
+ TargetUser = target;
+ }
+
+ internal static MemberRoleChanges Create(BaseDiscordClient discord, Model log, EntryModel entry, ChangeModel[] models)
+ {
+ var roleInfos = models.SelectMany(x => x.NewValue.ToObject(),
+ (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 MemberRoleChanges(roleInfos.ToReadOnlyCollection(), user);
+ }
+
+ public IReadOnlyCollection Roles { get; }
+ public IUser TargetUser { get; }
+
+ public struct RoleInfo
+ {
+ internal RoleInfo(string name, ulong roleId, bool added)
+ {
+ Name = name;
+ RoleId = roleId;
+ Added = added;
+ }
+
+ string Name { get; }
+ ulong RoleId { get; }
+ bool Added { get; }
+ }
+ }
+}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/Changes/MemberUpdateChanges.cs b/src/Discord.Net.Rest/Entities/AuditLogs/Changes/MemberUpdateChanges.cs
new file mode 100644
index 000000000..4097a6d9b
--- /dev/null
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/Changes/MemberUpdateChanges.cs
@@ -0,0 +1,33 @@
+using System.Linq;
+
+using Model = Discord.API.AuditLog;
+using EntryModel = Discord.API.AuditLogEntry;
+using ChangeModel = Discord.API.AuditLogChange;
+
+namespace Discord.Rest
+{
+ public class MemberUpdateChanges : IAuditLogChanges
+ {
+ private MemberUpdateChanges(IUser user, string newNick, string oldNick)
+ {
+ User = user;
+ NewNick = newNick;
+ OldNick = oldNick;
+ }
+
+ internal static MemberUpdateChanges Create(BaseDiscordClient discord, Model log, EntryModel entry, ChangeModel model)
+ {
+ var newNick = model.NewValue?.ToObject();
+ var oldNick = model.OldValue?.ToObject();
+
+ var targetInfo = log.Users.FirstOrDefault(x => x.Id == entry.TargetId);
+ var user = RestUser.Create(discord, targetInfo);
+
+ return new MemberUpdateChanges(user, newNick, oldNick);
+ }
+
+ public IUser User { get; }
+ public string NewNick { get; }
+ public string OldNick { get; }
+ }
+}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/Changes/OverwriteDeleteChanges.cs b/src/Discord.Net.Rest/Entities/AuditLogs/Changes/OverwriteDeleteChanges.cs
new file mode 100644
index 000000000..7fe4ca475
--- /dev/null
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/Changes/OverwriteDeleteChanges.cs
@@ -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;
+using ChangeModel = Discord.API.AuditLogChange;
+using OptionModel = Discord.API.AuditLogOptions;
+
+namespace Discord.Rest
+{
+ public class OverwriteDeleteChanges : IAuditLogChanges
+ {
+ private OverwriteDeleteChanges(Overwrite deletedOverwrite)
+ {
+ Overwrite = deletedOverwrite;
+ }
+
+ internal static OverwriteDeleteChanges Create(BaseDiscordClient discord, Model log, EntryModel entry, ChangeModel[] models)
+ {
+ var denyModel = models.FirstOrDefault(x => x.ChangedProperty == "deny");
+ var typeModel = models.FirstOrDefault(x => x.ChangedProperty == "type");
+ var idModel = models.FirstOrDefault(x => x.ChangedProperty == "id");
+ var allowModel = models.FirstOrDefault(x => x.ChangedProperty == "allow");
+
+ var deny = denyModel.OldValue.ToObject();
+ var type = typeModel.OldValue.ToObject(); //'role' or 'member', can't use PermissionsTarget :(
+ var id = idModel.OldValue.ToObject();
+ var allow = allowModel.OldValue.ToObject();
+
+ PermissionTarget target;
+
+ if (type == "member")
+ target = PermissionTarget.User;
+ else
+ target = PermissionTarget.Role;
+
+ return new OverwriteDeleteChanges(new Overwrite(id, target, new OverwritePermissions(allow, deny)));
+ }
+
+ public Overwrite Overwrite { get; }
+ }
+}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs b/src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs
index 6efe4e88e..6f4de2e82 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/RestAuditLogEntry.cs
@@ -1,47 +1,46 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Linq;
+using System.Linq;
-using FullModel = Discord.API.AuditLog;
-using Model = Discord.API.AuditLogEntry;
+using Model = Discord.API.AuditLog;
+using EntryModel = Discord.API.AuditLogEntry;
namespace Discord.Rest
{
public class RestAuditLogEntry : RestEntity, IAuditLogEntry
{
- internal RestAuditLogEntry(BaseDiscordClient discord, Model model, API.User user)
+ private RestAuditLogEntry(BaseDiscordClient discord, Model fullLog, EntryModel model, IUser user)
: base(discord, model.Id)
{
Action = model.Action;
- if (model.Changes != null)
- Changes = model.Changes
- .Select(x => AuditLogHelper.CreateChange(discord, model, x))
- .ToReadOnlyCollection(() => model.Changes.Length);
- else
- Changes = ImmutableArray.Create();
+ if (model.Changes != null)
+ Changes = AuditLogHelper.CreateChange(discord, fullLog, model, model.Changes);
if (model.Options != null)
- Options = AuditLogHelper.CreateOptions(discord, model, model.Options);
+ Options = AuditLogHelper.CreateOptions(discord, fullLog, model, model.Options);
TargetId = model.TargetId;
- User = RestUser.Create(discord, user);
+ User = user;
Reason = model.Reason;
}
- internal static RestAuditLogEntry Create(BaseDiscordClient discord, FullModel fullLog, Model model)
+ internal static RestAuditLogEntry Create(BaseDiscordClient discord, Model fullLog, EntryModel model)
{
- var user = fullLog.Users.FirstOrDefault(x => x.Id == model.UserId);
+ 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, model, user);
+ return new RestAuditLogEntry(discord, fullLog, model, user);
}
public ActionType Action { get; }
- public IReadOnlyCollection Changes { get; }
+
+ public IAuditLogChanges Changes { get; }
public IAuditLogOptions Options { get; }
- public ulong TargetId { get; }
+
+ public ulong? TargetId { get; } //TODO: if we're exposing this on the changes instead, do we need this?
public IUser User { get; }
+
public string Reason { get; }
}
}
diff --git a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
index e568bf402..de7512fa3 100644
--- a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
+++ b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
@@ -260,7 +260,7 @@ namespace Discord.Rest
Limit = info.PageSize
};
if (info.Position != null)
- args.AfterEntryId = info.Position.Value;
+ 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();
},
@@ -268,7 +268,7 @@ namespace Discord.Rest
{
if (lastPage.Count != DiscordConfig.MaxAuditLogEntriesPerBatch)
return false;
- info.Position = lastPage.Max(x => x.Id);
+ info.Position = lastPage.Min(x => x.Id);
return true;
},
start: from,