@@ -535,7 +535,7 @@ namespace Discord.API | |||||
Preconditions.NotEqual(args.AFKChannelId, 0, nameof(args.AFKChannelId)); | Preconditions.NotEqual(args.AFKChannelId, 0, nameof(args.AFKChannelId)); | ||||
Preconditions.AtLeast(args.AFKTimeout, 0, nameof(args.AFKTimeout)); | Preconditions.AtLeast(args.AFKTimeout, 0, nameof(args.AFKTimeout)); | ||||
Preconditions.NotNullOrEmpty(args.Name, nameof(args.Name)); | Preconditions.NotNullOrEmpty(args.Name, nameof(args.Name)); | ||||
Preconditions.NotNull(args.Owner, nameof(args.Owner)); | |||||
Preconditions.GreaterThan(args.OwnerId, 0, nameof(args.OwnerId)); | |||||
Preconditions.NotNull(args.Region, nameof(args.Region)); | Preconditions.NotNull(args.Region, nameof(args.Region)); | ||||
Preconditions.AtLeast(args.VerificationLevel, 0, nameof(args.VerificationLevel)); | Preconditions.AtLeast(args.VerificationLevel, 0, nameof(args.VerificationLevel)); | ||||
@@ -831,7 +831,21 @@ namespace Discord.API | |||||
int limit = args.Limit; | int limit = args.Limit; | ||||
ulong? relativeId = args.RelativeMessageId.IsSpecified ? args.RelativeMessageId.Value : (ulong?)null; | ulong? relativeId = args.RelativeMessageId.IsSpecified ? args.RelativeMessageId.Value : (ulong?)null; | ||||
string relativeDir = args.RelativeDirection == Direction.After ? "after" : "before"; | |||||
string relativeDir; | |||||
switch (args.RelativeDirection) | |||||
{ | |||||
case Direction.Before: | |||||
default: | |||||
relativeDir = "before"; | |||||
break; | |||||
case Direction.After: | |||||
relativeDir = "after"; | |||||
break; | |||||
case Direction.Around: | |||||
relativeDir = "around"; | |||||
break; | |||||
} | |||||
int runs = (limit + DiscordConfig.MaxMessagesPerBatch - 1) / DiscordConfig.MaxMessagesPerBatch; | int runs = (limit + DiscordConfig.MaxMessagesPerBatch - 1) / DiscordConfig.MaxMessagesPerBatch; | ||||
int lastRunCount = limit - (runs - 1) * DiscordConfig.MaxMessagesPerBatch; | int lastRunCount = limit - (runs - 1) * DiscordConfig.MaxMessagesPerBatch; | ||||
@@ -1079,7 +1093,7 @@ namespace Discord.API | |||||
public async Task<Channel> CreateDMChannelAsync(CreateDMChannelParams args, RequestOptions options = null) | public async Task<Channel> CreateDMChannelAsync(CreateDMChannelParams args, RequestOptions options = null) | ||||
{ | { | ||||
Preconditions.NotNull(args, nameof(args)); | Preconditions.NotNull(args, nameof(args)); | ||||
Preconditions.NotEqual(args.RecipientId, 0, nameof(args.RecipientId)); | |||||
Preconditions.GreaterThan(args.RecipientId, 0, nameof(args.Recipient)); | |||||
return await SendAsync<Channel>("POST", $"users/@me/channels", args, options: options).ConfigureAwait(false); | return await SendAsync<Channel>("POST", $"users/@me/channels", args, options: options).ConfigureAwait(false); | ||||
} | } | ||||
@@ -6,5 +6,7 @@ namespace Discord.API.Rest | |||||
{ | { | ||||
[JsonProperty("recipient_id")] | [JsonProperty("recipient_id")] | ||||
public ulong RecipientId { get; set; } | public ulong RecipientId { get; set; } | ||||
[JsonIgnore] | |||||
public IUser Recipient { set { RecipientId = value.Id; } } | |||||
} | } | ||||
} | } |
@@ -1,5 +1,6 @@ | |||||
using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Linq; | |||||
namespace Discord.API.Rest | namespace Discord.API.Rest | ||||
{ | { | ||||
@@ -7,5 +8,7 @@ namespace Discord.API.Rest | |||||
{ | { | ||||
[JsonProperty("messages")] | [JsonProperty("messages")] | ||||
public IEnumerable<ulong> MessageIds { get; set; } | public IEnumerable<ulong> MessageIds { get; set; } | ||||
[JsonIgnore] | |||||
public IEnumerable<IMessage> Messages { set { MessageIds = value.Select(x => x.Id); } } | |||||
} | } | ||||
} | } |
@@ -6,5 +6,6 @@ | |||||
public Direction RelativeDirection { get; set; } = Direction.Before; | public Direction RelativeDirection { get; set; } = Direction.Before; | ||||
public Optional<ulong> RelativeMessageId { get; set; } | public Optional<ulong> RelativeMessageId { get; set; } | ||||
public Optional<IMessage> RelativeMessage { set { RelativeMessageId = value.IsSpecified ? value.Value.Id : Optional.Create<ulong>(); } } | |||||
} | } | ||||
} | } |
@@ -1,5 +1,4 @@ | |||||
using Discord.Net.Converters; | |||||
using Newtonsoft.Json; | |||||
using Newtonsoft.Json; | |||||
namespace Discord.API.Rest | namespace Discord.API.Rest | ||||
{ | { | ||||
@@ -7,7 +6,10 @@ namespace Discord.API.Rest | |||||
{ | { | ||||
[JsonProperty("enabled")] | [JsonProperty("enabled")] | ||||
public Optional<bool> Enabled { get; set; } | public Optional<bool> Enabled { get; set; } | ||||
[JsonProperty("channel")] | [JsonProperty("channel")] | ||||
public Optional<IVoiceChannel> Channel { get; set; } | |||||
public Optional<ulong> ChannelId { get; set; } | |||||
[JsonIgnore] | |||||
public Optional<IVoiceChannel> Channel { set { ChannelId = value.IsSpecified ? value.Value.Id : Optional.Create<ulong>(); } } | |||||
} | } | ||||
} | } |
@@ -1,18 +1,26 @@ | |||||
using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
namespace Discord.API.Rest | namespace Discord.API.Rest | ||||
{ | { | ||||
public class ModifyGuildMemberParams | public class ModifyGuildMemberParams | ||||
{ | { | ||||
[JsonProperty("roles")] | |||||
public Optional<ulong[]> Roles { get; set; } | |||||
[JsonProperty("mute")] | [JsonProperty("mute")] | ||||
public Optional<bool> Mute { get; set; } | public Optional<bool> Mute { get; set; } | ||||
[JsonProperty("deaf")] | [JsonProperty("deaf")] | ||||
public Optional<bool> Deaf { get; set; } | public Optional<bool> Deaf { get; set; } | ||||
[JsonProperty("nick")] | [JsonProperty("nick")] | ||||
public Optional<string> Nickname { get; set; } | public Optional<string> Nickname { get; set; } | ||||
[JsonProperty("roles")] | |||||
public Optional<IEnumerable<ulong>> RoleIds { get; set; } | |||||
[JsonIgnore] | |||||
public Optional<IEnumerable<IRole>> Roles { set { RoleIds = value.IsSpecified ? Optional.Create(value.Value.Select(x => x.Id)) : Optional.Create<IEnumerable<ulong>>(); } } | |||||
[JsonProperty("channel_id")] | [JsonProperty("channel_id")] | ||||
public Optional<IVoiceChannel> VoiceChannel { get; set; } | |||||
public Optional<ulong> VoiceChannelId { get; set; } | |||||
[JsonIgnore] | |||||
public Optional<IVoiceChannel> VoiceChannel { set { VoiceChannelId = value.IsSpecified ? value.Value.Id : Optional.Create<ulong>(); } } | |||||
} | } | ||||
} | } |
@@ -1,5 +1,4 @@ | |||||
using Discord.Net.Converters; | |||||
using Newtonsoft.Json; | |||||
using Newtonsoft.Json; | |||||
using System.IO; | using System.IO; | ||||
namespace Discord.API.Rest | namespace Discord.API.Rest | ||||
@@ -12,15 +11,21 @@ namespace Discord.API.Rest | |||||
public Optional<IVoiceRegion> Region { get; set; } | public Optional<IVoiceRegion> Region { get; set; } | ||||
[JsonProperty("verification_level")] | [JsonProperty("verification_level")] | ||||
public Optional<int> VerificationLevel { get; set; } | public Optional<int> VerificationLevel { get; set; } | ||||
[JsonProperty("afk_channel_id")] | |||||
public Optional<ulong?> AFKChannelId { get; set; } | |||||
[JsonProperty("afk_timeout")] | [JsonProperty("afk_timeout")] | ||||
public Optional<int> AFKTimeout { get; set; } | public Optional<int> AFKTimeout { get; set; } | ||||
[JsonProperty("icon"), Image] | [JsonProperty("icon"), Image] | ||||
public Optional<Stream> Icon { get; set; } | public Optional<Stream> Icon { get; set; } | ||||
[JsonProperty("owner_id")] | |||||
public Optional<GuildMember> Owner { get; set; } | |||||
[JsonProperty("splash"), Image] | [JsonProperty("splash"), Image] | ||||
public Optional<Stream> Splash { get; set; } | public Optional<Stream> Splash { get; set; } | ||||
[JsonProperty("afk_channel_id")] | |||||
public Optional<ulong?> AFKChannelId { get; set; } | |||||
[JsonIgnore] | |||||
public Optional<IVoiceChannel> AFKChannel { set { OwnerId = value.IsSpecified ? value.Value.Id : Optional.Create<ulong>(); } } | |||||
[JsonProperty("owner_id")] | |||||
public Optional<ulong> OwnerId { get; set; } | |||||
[JsonIgnore] | |||||
public Optional<IGuildUser> Owner { set { OwnerId = value.IsSpecified ? value.Value.Id : Optional.Create<ulong>(); } } | |||||
} | } | ||||
} | } |
@@ -124,7 +124,7 @@ namespace Discord | |||||
args.Nickname = new Optional<string>(); //Remove | args.Nickname = new Optional<string>(); //Remove | ||||
} | } | ||||
if (!isCurrentUser || args.Deaf.IsSpecified || args.Mute.IsSpecified || args.Roles.IsSpecified) | |||||
if (!isCurrentUser || args.Deaf.IsSpecified || args.Mute.IsSpecified || args.RoleIds.IsSpecified) | |||||
{ | { | ||||
await Discord.ApiClient.ModifyGuildMemberAsync(Guild.Id, Id, args).ConfigureAwait(false); | await Discord.ApiClient.ModifyGuildMemberAsync(Guild.Id, Id, args).ConfigureAwait(false); | ||||
if (args.Deaf.IsSpecified) | if (args.Deaf.IsSpecified) | ||||
@@ -133,8 +133,8 @@ namespace Discord | |||||
IsMute = args.Mute.Value; | IsMute = args.Mute.Value; | ||||
if (args.Nickname.IsSpecified) | if (args.Nickname.IsSpecified) | ||||
Nickname = args.Nickname.Value ?? ""; | Nickname = args.Nickname.Value ?? ""; | ||||
if (args.Roles.IsSpecified) | |||||
Roles = args.Roles.Value.Select(x => Guild.GetRole(x)).Where(x => x != null).ToImmutableArray(); | |||||
if (args.RoleIds.IsSpecified) | |||||
Roles = args.RoleIds.Value.Select(x => Guild.GetRole(x)).Where(x => x != null).ToImmutableArray(); | |||||
} | } | ||||
} | } | ||||
public async Task KickAsync() | public async Task KickAsync() | ||||
@@ -153,7 +153,7 @@ namespace Discord | |||||
public async Task<IDMChannel> CreateDMChannelAsync() | public async Task<IDMChannel> CreateDMChannelAsync() | ||||
{ | { | ||||
var args = new CreateDMChannelParams { RecipientId = Id }; | |||||
var args = new CreateDMChannelParams { Recipient = this }; | |||||
var model = await Discord.ApiClient.CreateDMChannelAsync(args).ConfigureAwait(false); | var model = await Discord.ApiClient.CreateDMChannelAsync(args).ConfigureAwait(false); | ||||
return new DMChannel(Discord, User, model); | return new DMChannel(Discord, User, model); | ||||
@@ -1,47 +0,0 @@ | |||||
using Newtonsoft.Json; | |||||
using System; | |||||
namespace Discord.Net.Converters | |||||
{ | |||||
public class DirectionConverter : JsonConverter | |||||
{ | |||||
public static readonly DirectionConverter Instance = new DirectionConverter(); | |||||
public override bool CanConvert(Type objectType) => true; | |||||
public override bool CanRead => true; | |||||
public override bool CanWrite => true; | |||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) | |||||
{ | |||||
switch ((string)reader.Value) | |||||
{ | |||||
case "before": | |||||
return Direction.Before; | |||||
case "after": | |||||
return Direction.After; | |||||
case "around": | |||||
return Direction.Around; | |||||
default: | |||||
throw new JsonSerializationException("Unknown direction"); | |||||
} | |||||
} | |||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) | |||||
{ | |||||
switch ((Direction)value) | |||||
{ | |||||
case Direction.Before: | |||||
writer.WriteValue("before"); | |||||
break; | |||||
case Direction.After: | |||||
writer.WriteValue("after"); | |||||
break; | |||||
case Direction.Around: | |||||
writer.WriteValue("around"); | |||||
break; | |||||
default: | |||||
throw new JsonSerializationException("Invalid direction"); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -77,8 +77,6 @@ namespace Discord.Net.Converters | |||||
return PermissionTargetConverter.Instance; | return PermissionTargetConverter.Instance; | ||||
if (type == typeof(UserStatus)) | if (type == typeof(UserStatus)) | ||||
return UserStatusConverter.Instance; | return UserStatusConverter.Instance; | ||||
if (type == typeof(Direction)) | |||||
return DirectionConverter.Instance; | |||||
//Special | //Special | ||||
if (type == typeof(Stream) && propInfo.GetCustomAttribute<ImageAttribute>() != null) | if (type == typeof(Stream) && propInfo.GetCustomAttribute<ImageAttribute>() != null) | ||||
@@ -7,6 +7,7 @@ namespace Discord | |||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
public struct Optional<T> | public struct Optional<T> | ||||
{ | { | ||||
public static Optional<T> Unspecified => default(Optional<T>); | |||||
private readonly T _value; | private readonly T _value; | ||||
/// <summary> Gets the value for this paramter. </summary> | /// <summary> Gets the value for this paramter. </summary> | ||||
@@ -28,7 +29,7 @@ namespace Discord | |||||
_value = value; | _value = value; | ||||
IsSpecified = true; | IsSpecified = true; | ||||
} | } | ||||
public T GetValueOrDefault() => _value; | public T GetValueOrDefault() => _value; | ||||
public T GetValueOrDefault(T defaultValue) => IsSpecified ? _value : defaultValue; | public T GetValueOrDefault(T defaultValue) => IsSpecified ? _value : defaultValue; | ||||
@@ -46,4 +47,9 @@ namespace Discord | |||||
public static implicit operator Optional<T>(T value) => new Optional<T>(value); | public static implicit operator Optional<T>(T value) => new Optional<T>(value); | ||||
public static explicit operator T(Optional<T> value) => value.Value; | public static explicit operator T(Optional<T> value) => value.Value; | ||||
} | } | ||||
public static class Optional | |||||
{ | |||||
public static Optional<T> Create<T>() => Optional<T>.Unspecified; | |||||
public static Optional<T> Create<T>(T value) => new Optional<T>(value); | |||||
} | |||||
} | } |