| @@ -535,7 +535,7 @@ namespace Discord.API | |||
| Preconditions.NotEqual(args.AFKChannelId, 0, nameof(args.AFKChannelId)); | |||
| Preconditions.AtLeast(args.AFKTimeout, 0, nameof(args.AFKTimeout)); | |||
| 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.AtLeast(args.VerificationLevel, 0, nameof(args.VerificationLevel)); | |||
| @@ -831,7 +831,21 @@ namespace Discord.API | |||
| int limit = args.Limit; | |||
| 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 lastRunCount = limit - (runs - 1) * DiscordConfig.MaxMessagesPerBatch; | |||
| @@ -1079,7 +1093,7 @@ namespace Discord.API | |||
| public async Task<Channel> CreateDMChannelAsync(CreateDMChannelParams args, RequestOptions options = null) | |||
| { | |||
| 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); | |||
| } | |||
| @@ -6,5 +6,7 @@ namespace Discord.API.Rest | |||
| { | |||
| [JsonProperty("recipient_id")] | |||
| public ulong RecipientId { get; set; } | |||
| [JsonIgnore] | |||
| public IUser Recipient { set { RecipientId = value.Id; } } | |||
| } | |||
| } | |||
| @@ -1,5 +1,6 @@ | |||
| using Newtonsoft.Json; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| namespace Discord.API.Rest | |||
| { | |||
| @@ -7,5 +8,7 @@ namespace Discord.API.Rest | |||
| { | |||
| [JsonProperty("messages")] | |||
| 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 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 | |||
| { | |||
| @@ -7,7 +6,10 @@ namespace Discord.API.Rest | |||
| { | |||
| [JsonProperty("enabled")] | |||
| public Optional<bool> Enabled { get; set; } | |||
| [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 System.Collections.Generic; | |||
| using System.Linq; | |||
| namespace Discord.API.Rest | |||
| { | |||
| public class ModifyGuildMemberParams | |||
| { | |||
| [JsonProperty("roles")] | |||
| public Optional<ulong[]> Roles { get; set; } | |||
| [JsonProperty("mute")] | |||
| public Optional<bool> Mute { get; set; } | |||
| [JsonProperty("deaf")] | |||
| public Optional<bool> Deaf { get; set; } | |||
| [JsonProperty("nick")] | |||
| 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")] | |||
| 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; | |||
| namespace Discord.API.Rest | |||
| @@ -12,15 +11,21 @@ namespace Discord.API.Rest | |||
| public Optional<IVoiceRegion> Region { get; set; } | |||
| [JsonProperty("verification_level")] | |||
| public Optional<int> VerificationLevel { get; set; } | |||
| [JsonProperty("afk_channel_id")] | |||
| public Optional<ulong?> AFKChannelId { get; set; } | |||
| [JsonProperty("afk_timeout")] | |||
| public Optional<int> AFKTimeout { get; set; } | |||
| [JsonProperty("icon"), Image] | |||
| public Optional<Stream> Icon { get; set; } | |||
| [JsonProperty("owner_id")] | |||
| public Optional<GuildMember> Owner { get; set; } | |||
| [JsonProperty("splash"), Image] | |||
| 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 | |||
| } | |||
| 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); | |||
| if (args.Deaf.IsSpecified) | |||
| @@ -133,8 +133,8 @@ namespace Discord | |||
| IsMute = args.Mute.Value; | |||
| if (args.Nickname.IsSpecified) | |||
| 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() | |||
| @@ -153,7 +153,7 @@ namespace Discord | |||
| 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); | |||
| 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; | |||
| if (type == typeof(UserStatus)) | |||
| return UserStatusConverter.Instance; | |||
| if (type == typeof(Direction)) | |||
| return DirectionConverter.Instance; | |||
| //Special | |||
| if (type == typeof(Stream) && propInfo.GetCustomAttribute<ImageAttribute>() != null) | |||
| @@ -7,6 +7,7 @@ namespace Discord | |||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
| public struct Optional<T> | |||
| { | |||
| public static Optional<T> Unspecified => default(Optional<T>); | |||
| private readonly T _value; | |||
| /// <summary> Gets the value for this paramter. </summary> | |||
| @@ -28,7 +29,7 @@ namespace Discord | |||
| _value = value; | |||
| IsSpecified = true; | |||
| } | |||
| public T GetValueOrDefault() => _value; | |||
| 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 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); | |||
| } | |||
| } | |||