@@ -70,7 +70,9 @@ namespace Discord.Commands | |||
else | |||
perms = ChannelPermissions.All(context.Channel); | |||
return !perms.Has(ChannelPermission.Value) ? PreconditionResult.FromError($"Bot requires channel permission {ChannelPermission.Value}") : PreconditionResult.FromSuccess(); | |||
return !perms.Has(ChannelPermission.Value) | |||
? PreconditionResult.FromError($"Bot requires channel permission {ChannelPermission.Value}") | |||
: PreconditionResult.FromSuccess(); | |||
} | |||
} | |||
} |
@@ -52,7 +52,9 @@ namespace Discord.Commands | |||
if ((Contexts & ContextType.Group) != 0) | |||
isValid = isValid || context.Channel is IGroupChannel; | |||
return Task.FromResult(isValid ? PreconditionResult.FromSuccess() : PreconditionResult.FromError($"Invalid context for command; accepted contexts: {Contexts}")); | |||
return Task.FromResult(isValid | |||
? PreconditionResult.FromSuccess() | |||
: PreconditionResult.FromError($"Invalid context for command; accepted contexts: {Contexts}")); | |||
} | |||
} | |||
} |
@@ -70,7 +70,9 @@ namespace Discord.Commands | |||
else | |||
perms = ChannelPermissions.All(context.Channel); | |||
return Task.FromResult(!perms.Has(ChannelPermission.Value) ? PreconditionResult.FromError($"User requires channel permission {ChannelPermission.Value}") : PreconditionResult.FromSuccess()); | |||
return Task.FromResult(!perms.Has(ChannelPermission.Value) | |||
? PreconditionResult.FromError($"User requires channel permission {ChannelPermission.Value}") | |||
: PreconditionResult.FromSuccess()); | |||
} | |||
} | |||
} |
@@ -9,9 +9,8 @@ namespace Discord.Commands | |||
public static IEnumerable<TResult> Permutate<TFirst, TSecond, TResult>( | |||
this IEnumerable<TFirst> set, | |||
IEnumerable<TSecond> others, | |||
Func<TFirst, TSecond, TResult> func) | |||
{ | |||
return from elem in set from elem2 in others select func(elem, elem2); | |||
} | |||
Func<TFirst, TSecond, TResult> func) => from elem in set | |||
from elem2 in others | |||
select func(elem, elem2); | |||
} | |||
} |
@@ -10,7 +10,6 @@ namespace Discord.Commands | |||
if (text.Length <= 0 || text[0] != c) return false; | |||
argPos = 1; | |||
return true; | |||
} | |||
public static bool HasStringPrefix(this IUserMessage msg, string str, ref int argPos, | |||
@@ -20,7 +19,6 @@ namespace Discord.Commands | |||
if (!text.StartsWith(str, comparisonType)) return false; | |||
argPos = str.Length; | |||
return true; | |||
} | |||
public static bool HasMentionPrefix(this IUserMessage msg, IUser user, ref int argPos) | |||
@@ -37,7 +35,6 @@ namespace Discord.Commands | |||
if (userId != user.Id) return false; | |||
argPos = endPos + 2; | |||
return true; | |||
} | |||
} | |||
} |
@@ -202,7 +202,8 @@ namespace Discord.Commands | |||
case Task<IResult> resultTask: | |||
{ | |||
var result = await resultTask.ConfigureAwait(false); | |||
await Module.Service._commandExecutedEvent.InvokeAsync(this, context, result).ConfigureAwait(false); | |||
await Module.Service._commandExecutedEvent.InvokeAsync(this, context, result) | |||
.ConfigureAwait(false); | |||
if (result is RuntimeResult execResult) | |||
return execResult; | |||
break; | |||
@@ -210,14 +211,16 @@ namespace Discord.Commands | |||
case Task<ExecuteResult> execTask: | |||
{ | |||
var result = await execTask.ConfigureAwait(false); | |||
await Module.Service._commandExecutedEvent.InvokeAsync(this, context, result).ConfigureAwait(false); | |||
await Module.Service._commandExecutedEvent.InvokeAsync(this, context, result) | |||
.ConfigureAwait(false); | |||
return result; | |||
} | |||
default: | |||
{ | |||
await task.ConfigureAwait(false); | |||
var result = ExecuteResult.FromSuccess(); | |||
await Module.Service._commandExecutedEvent.InvokeAsync(this, context, result).ConfigureAwait(false); | |||
await Module.Service._commandExecutedEvent.InvokeAsync(this, context, result) | |||
.ConfigureAwait(false); | |||
break; | |||
} | |||
} | |||
@@ -280,9 +283,8 @@ namespace Discord.Commands | |||
private static T[] ConvertParamsList<T>(IEnumerable<object> paramsList) | |||
=> paramsList.Cast<T>().ToArray(); | |||
internal string GetLogText(ICommandContext context) | |||
{ | |||
return context.Guild != null ? $"\"{Name}\" for {context.User} in {context.Guild}/{context.Channel}" : $"\"{Name}\" for {context.User} in {context.Channel}"; | |||
} | |||
internal string GetLogText(ICommandContext context) => context.Guild != null | |||
? $"\"{Name}\" for {context.User} in {context.Guild}/{context.Channel}" | |||
: $"\"{Name}\" for {context.User} in {context.Channel}"; | |||
} | |||
} |
@@ -68,10 +68,8 @@ namespace Discord.Commands | |||
} | |||
private IEnumerable<ModuleInfo> BuildSubmodules(ModuleBuilder parent, CommandService service, | |||
IServiceProvider services) | |||
{ | |||
return parent.Modules.Select(submodule => submodule.Build(service, services, this)).ToList(); | |||
} | |||
IServiceProvider services) => | |||
parent.Modules.Select(submodule => submodule.Build(service, services, this)).ToList(); | |||
private static IEnumerable<PreconditionAttribute> BuildPreconditions(ModuleBuilder builder) | |||
{ | |||
@@ -36,7 +36,9 @@ namespace Discord.Commands | |||
_commands = _commands.Add(command); | |||
break; | |||
default: | |||
var name = nextSegment == -1 ? text.Substring(index) : text.Substring(index, nextSegment - index); | |||
var name = nextSegment == -1 | |||
? text.Substring(index) | |||
: text.Substring(index, nextSegment - index); | |||
var fullName = _name == "" ? name : _name + service._separatorChar + name; | |||
var nextNode = _nodes.GetOrAdd(name, x => new CommandMapNode(fullName)); | |||
@@ -29,7 +29,9 @@ namespace Discord.Commands | |||
foreach (var role in roles.Where(x => string.Equals(input, x.Name, StringComparison.OrdinalIgnoreCase))) | |||
AddResult(results, role as T, role.Name == input ? 0.80f : 0.70f); | |||
return Task.FromResult(results.Count > 0 ? TypeReaderResult.FromSuccess(results.Values.ToReadOnlyCollection()) : TypeReaderResult.FromError(CommandError.ObjectNotFound, "Role not found.")); | |||
return Task.FromResult(results.Count > 0 | |||
? TypeReaderResult.FromSuccess(results.Values.ToReadOnlyCollection()) | |||
: TypeReaderResult.FromError(CommandError.ObjectNotFound, "Role not found.")); | |||
} | |||
private void AddResult(Dictionary<ulong, TypeReaderValue> results, T role, float score) | |||
@@ -29,15 +29,11 @@ namespace Discord.Commands | |||
IReadOnlyList<TypeReaderResult> paramValues) | |||
{ | |||
if (argValues.Any(t => t.Values.Count > 1)) | |||
{ | |||
return new ParseResult(argValues, paramValues, CommandError.MultipleMatches, | |||
"Multiple matches found."); | |||
} | |||
if (paramValues.Any(t => t.Values.Count > 1)) | |||
{ | |||
return new ParseResult(argValues, paramValues, CommandError.MultipleMatches, | |||
"Multiple matches found."); | |||
} | |||
return new ParseResult(argValues, paramValues, null, null); | |||
} | |||
@@ -58,7 +58,9 @@ namespace Discord.Commands | |||
var result = new List<PropertyInfo>(); | |||
while (ownerType != _objectTypeInfo) | |||
{ | |||
result.AddRange(ownerType.DeclaredProperties.Where(prop => prop.SetMethod?.IsStatic == false && prop.SetMethod?.IsPublic == true && prop.GetCustomAttribute<DontInjectAttribute>() == null)); | |||
result.AddRange(ownerType.DeclaredProperties.Where(prop => | |||
prop.SetMethod?.IsStatic == false && prop.SetMethod?.IsPublic == true && | |||
prop.GetCustomAttribute<DontInjectAttribute>() == null)); | |||
ownerType = ownerType.BaseType.GetTypeInfo(); | |||
} | |||
@@ -86,7 +86,6 @@ namespace Discord | |||
var name = text.Substring(startIndex, splitIndex - startIndex); | |||
result = new Emote(id, name, animated); | |||
return true; | |||
} | |||
public override string ToString() => $"<{(Animated ? "a" : "")}:{Name}:{Id}>"; | |||
@@ -46,7 +46,8 @@ namespace Discord | |||
/// <remarks> | |||
/// To add a role to a user: | |||
/// <see cref="IGuildUser.AddRolesAsync(System.Collections.Generic.IEnumerable{Discord.IRole}, RequestOptions)" /> | |||
/// To remove a role from a user: <see cref="IGuildUser.RemoveRolesAsync(System.Collections.Generic.IEnumerable{Discord.IRole}, RequestOptions)" /> | |||
/// To remove a role from a user: | |||
/// <see cref="IGuildUser.RemoveRolesAsync(System.Collections.Generic.IEnumerable{Discord.IRole}, RequestOptions)" /> | |||
/// </remarks> | |||
public Optional<IEnumerable<IRole>> Roles { get; set; } | |||
@@ -28,9 +28,7 @@ namespace Discord | |||
} | |||
/// <summary> Sanitizes the string, safely escaping any Markdown sequences. </summary> | |||
public static string Sanitize(string text) | |||
{ | |||
return SensitiveCharacters.Aggregate(text, (current, unsafeChar) => current.Replace(unsafeChar, $"\\{unsafeChar}")); | |||
} | |||
public static string Sanitize(string text) => SensitiveCharacters.Aggregate(text, | |||
(current, unsafeChar) => current.Replace(unsafeChar, $"\\{unsafeChar}")); | |||
} | |||
} |
@@ -23,13 +23,13 @@ namespace Discord.Net | |||
{ | |||
string msg; | |||
if (discordCode != null && discordCode != 0) | |||
{ | |||
msg = reason != null ? $"The server responded with error {(int)discordCode}: {reason}" : $"The server responded with error {(int)discordCode}: {httpCode}"; | |||
} | |||
msg = reason != null | |||
? $"The server responded with error {(int)discordCode}: {reason}" | |||
: $"The server responded with error {(int)discordCode}: {httpCode}"; | |||
else | |||
{ | |||
msg = reason != null ? $"The server responded with error {(int)httpCode}: {reason}" : $"The server responded with error {(int)httpCode}: {httpCode}"; | |||
} | |||
msg = reason != null | |||
? $"The server responded with error {(int)httpCode}: {reason}" | |||
: $"The server responded with error {(int)httpCode}: {httpCode}"; | |||
return msg; | |||
} | |||
@@ -214,6 +214,7 @@ namespace Discord | |||
case TagHandling.Sanitize: | |||
return $"@{SanitizeChar}everyone"; | |||
} | |||
return ""; | |||
} | |||
@@ -230,6 +231,7 @@ namespace Discord | |||
case TagHandling.Sanitize: | |||
return $"@{SanitizeChar}here"; | |||
} | |||
return ""; | |||
} | |||
@@ -239,10 +241,7 @@ namespace Discord | |||
var emoji = (Emote)tag.Value; | |||
//Remove if its name contains any bad chars (prevents a few tag exploits) | |||
if (emoji.Name.Any(c => !char.IsLetterOrDigit(c) && c != '_' && c != '-')) | |||
{ | |||
return ""; | |||
} | |||
if (emoji.Name.Any(c => !char.IsLetterOrDigit(c) && c != '_' && c != '-')) return ""; | |||
switch (mode) | |||
{ | |||
@@ -111,7 +111,8 @@ namespace Discord | |||
resolvedPermissions = GuildPermissions.Webhook.RawValue; | |||
else | |||
{ | |||
resolvedPermissions = user.RoleIds.Aggregate(resolvedPermissions, (current, roleId) => current | (guild.GetRole(roleId)?.Permissions.RawValue ?? 0)); | |||
resolvedPermissions = user.RoleIds.Aggregate(resolvedPermissions, | |||
(current, roleId) => current | (guild.GetRole(roleId)?.Permissions.RawValue ?? 0)); | |||
if (GetValue(resolvedPermissions, GuildPermission.Administrator)) | |||
resolvedPermissions = GuildPermissions.All.RawValue; //Administrators always have all permissions | |||
} | |||
@@ -16,11 +16,11 @@ namespace Discord.Net.Providers.WS4Net | |||
private readonly Dictionary<string, string> _headers; | |||
private readonly SemaphoreSlim _lock; | |||
private readonly ManualResetEventSlim _waitUntilConnect; | |||
private CancellationToken _cancelToken, _parentToken; | |||
private CancellationTokenSource _cancelTokenSource; | |||
private WS4NetSocket _client; | |||
private bool _isDisposed; | |||
private readonly ManualResetEventSlim _waitUntilConnect; | |||
public WS4NetClient() | |||
{ | |||
@@ -47,9 +47,7 @@ namespace Discord.Rest | |||
[ActionType.MessageDeleted] = MessageDeleteAuditLogData.Create | |||
}; | |||
public static IAuditLogData CreateData(BaseDiscordClient discord, Model log, EntryModel entry) | |||
{ | |||
return CreateMapping.TryGetValue(entry.Action, out var func) ? func(discord, log, entry) : null; | |||
} | |||
public static IAuditLogData CreateData(BaseDiscordClient discord, Model log, EntryModel entry) => | |||
CreateMapping.TryGetValue(entry.Action, out var func) ? func(discord, log, entry) : null; | |||
} | |||
} |
@@ -52,22 +52,19 @@ namespace Discord.Rest | |||
} | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(int limit, CacheMode mode, | |||
RequestOptions options) | |||
{ | |||
return mode == CacheMode.AllowDownload ? GetMessagesAsync(limit, options) : AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
} | |||
RequestOptions options) => mode == CacheMode.AllowDownload | |||
? GetMessagesAsync(limit, options) | |||
: AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(ulong fromMessageId, | |||
Direction dir, int limit, CacheMode mode, RequestOptions options) | |||
{ | |||
return mode == CacheMode.AllowDownload ? GetMessagesAsync(fromMessageId, dir, limit, options) : AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
} | |||
Direction dir, int limit, CacheMode mode, RequestOptions options) => mode == CacheMode.AllowDownload | |||
? GetMessagesAsync(fromMessageId, dir, limit, options) | |||
: AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(IMessage fromMessage, | |||
Direction dir, int limit, CacheMode mode, RequestOptions options) | |||
{ | |||
return mode == CacheMode.AllowDownload ? GetMessagesAsync(fromMessage, dir, limit, options) : AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
} | |||
Direction dir, int limit, CacheMode mode, RequestOptions options) => mode == CacheMode.AllowDownload | |||
? GetMessagesAsync(fromMessage, dir, limit, options) | |||
: AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options) | |||
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false); | |||
@@ -57,22 +57,19 @@ namespace Discord.Rest | |||
} | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(int limit, CacheMode mode, | |||
RequestOptions options) | |||
{ | |||
return mode == CacheMode.AllowDownload ? GetMessagesAsync(limit, options) : AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
} | |||
RequestOptions options) => mode == CacheMode.AllowDownload | |||
? GetMessagesAsync(limit, options) | |||
: AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(ulong fromMessageId, | |||
Direction dir, int limit, CacheMode mode, RequestOptions options) | |||
{ | |||
return mode == CacheMode.AllowDownload ? GetMessagesAsync(fromMessageId, dir, limit, options) : AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
} | |||
Direction dir, int limit, CacheMode mode, RequestOptions options) => mode == CacheMode.AllowDownload | |||
? GetMessagesAsync(fromMessageId, dir, limit, options) | |||
: AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(IMessage fromMessage, | |||
Direction dir, int limit, CacheMode mode, RequestOptions options) | |||
{ | |||
return mode == CacheMode.AllowDownload ? GetMessagesAsync(fromMessage, dir, limit, options) : AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
} | |||
Direction dir, int limit, CacheMode mode, RequestOptions options) => mode == CacheMode.AllowDownload | |||
? GetMessagesAsync(fromMessage, dir, limit, options) | |||
: AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options) | |||
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false); | |||
@@ -170,10 +167,7 @@ namespace Discord.Rest | |||
_users = users.ToImmutable(); | |||
} | |||
public RestUser GetUser(ulong id) | |||
{ | |||
return _users.TryGetValue(id, out var user) ? user : null; | |||
} | |||
public RestUser GetUser(ulong id) => _users.TryGetValue(id, out var user) ? user : null; | |||
public IDisposable EnterTypingState(RequestOptions options = null) | |||
=> ChannelHelper.EnterTypingState(this, Discord, options); | |||
@@ -66,24 +66,19 @@ namespace Discord.Rest | |||
} | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(int limit, CacheMode mode, | |||
RequestOptions options) | |||
{ | |||
return mode == CacheMode.AllowDownload | |||
? GetMessagesAsync(limit, options) | |||
: AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
} | |||
RequestOptions options) => mode == CacheMode.AllowDownload | |||
? GetMessagesAsync(limit, options) | |||
: AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(ulong fromMessageId, | |||
Direction dir, int limit, CacheMode mode, RequestOptions options) | |||
{ | |||
return mode == CacheMode.AllowDownload ? GetMessagesAsync(fromMessageId, dir, limit, options) : AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
} | |||
Direction dir, int limit, CacheMode mode, RequestOptions options) => mode == CacheMode.AllowDownload | |||
? GetMessagesAsync(fromMessageId, dir, limit, options) | |||
: AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(IMessage fromMessage, | |||
Direction dir, int limit, CacheMode mode, RequestOptions options) | |||
{ | |||
return mode == CacheMode.AllowDownload ? GetMessagesAsync(fromMessage, dir, limit, options) : AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
} | |||
Direction dir, int limit, CacheMode mode, RequestOptions options) => mode == CacheMode.AllowDownload | |||
? GetMessagesAsync(fromMessage, dir, limit, options) | |||
: AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options) | |||
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false); | |||
@@ -111,10 +106,10 @@ namespace Discord.Rest | |||
return null; | |||
} | |||
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) | |||
{ | |||
return mode == CacheMode.AllowDownload ? GetUsersAsync(options) : AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>(); | |||
} | |||
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) => | |||
mode == CacheMode.AllowDownload | |||
? GetUsersAsync(options) | |||
: AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>(); | |||
public string Topic { get; private set; } | |||
public ulong? CategoryId { get; private set; } | |||
@@ -153,10 +148,9 @@ namespace Discord.Rest | |||
} | |||
IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode, | |||
RequestOptions options) | |||
{ | |||
return mode == CacheMode.AllowDownload ? GetUsersAsync(options) : AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>(); | |||
} | |||
RequestOptions options) => mode == CacheMode.AllowDownload | |||
? GetUsersAsync(options) | |||
: AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>(); | |||
// INestedChannel | |||
async Task<ICategoryChannel> INestedChannel.GetCategoryAsync(CacheMode mode, RequestOptions options) | |||
@@ -38,22 +38,19 @@ namespace Discord.Rest | |||
} | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(int limit, CacheMode mode, | |||
RequestOptions options) | |||
{ | |||
return mode == CacheMode.AllowDownload ? GetMessagesAsync(limit, options) : AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
} | |||
RequestOptions options) => mode == CacheMode.AllowDownload | |||
? GetMessagesAsync(limit, options) | |||
: AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(ulong fromMessageId, | |||
Direction dir, int limit, CacheMode mode, RequestOptions options) | |||
{ | |||
return mode == CacheMode.AllowDownload ? GetMessagesAsync(fromMessageId, dir, limit, options) : AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
} | |||
Direction dir, int limit, CacheMode mode, RequestOptions options) => mode == CacheMode.AllowDownload | |||
? GetMessagesAsync(fromMessageId, dir, limit, options) | |||
: AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(IMessage fromMessage, | |||
Direction dir, int limit, CacheMode mode, RequestOptions options) | |||
{ | |||
return mode == CacheMode.AllowDownload ? GetMessagesAsync(fromMessage, dir, limit, options) : AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
} | |||
Direction dir, int limit, CacheMode mode, RequestOptions options) => mode == CacheMode.AllowDownload | |||
? GetMessagesAsync(fromMessage, dir, limit, options) | |||
: AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>(); | |||
async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options) | |||
=> await GetPinnedMessagesAsync(options); | |||
@@ -4,7 +4,6 @@ using System.Collections.Immutable; | |||
using System.Diagnostics; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
using Discord.API; | |||
using Discord.Audio; | |||
using EmbedModel = Discord.API.GuildEmbed; | |||
using Model = Discord.API.Guild; | |||
@@ -473,10 +472,7 @@ namespace Discord.Rest | |||
=> GuildHelper.GetVanityInviteAsync(this, Discord, options); | |||
//Roles | |||
public RestRole GetRole(ulong id) | |||
{ | |||
return _roles.TryGetValue(id, out var value) ? value : null; | |||
} | |||
public RestRole GetRole(ulong id) => _roles.TryGetValue(id, out var value) ? value : null; | |||
public async Task<RestRole> CreateRoleAsync(string name, | |||
GuildPermissions? permissions = default(GuildPermissions?), Color? color = default(Color?), | |||
@@ -204,7 +204,9 @@ namespace Discord.Rest | |||
return MessageSource.System; | |||
if (msg.WebhookId.IsSpecified) | |||
return MessageSource.Webhook; | |||
return msg.Author.GetValueOrDefault()?.Bot.GetValueOrDefault(false) == true ? MessageSource.Bot : MessageSource.User; | |||
return msg.Author.GetValueOrDefault()?.Bot.GetValueOrDefault(false) == true | |||
? MessageSource.Bot | |||
: MessageSource.User; | |||
} | |||
} | |||
} |
@@ -49,7 +49,9 @@ namespace Discord.Rest | |||
internal static RestUser Create(BaseDiscordClient discord, IGuild guild, Model model, ulong? webhookId) | |||
{ | |||
RestUser entity; | |||
entity = webhookId.HasValue ? new RestWebhookUser(discord, guild, model.Id, webhookId.Value) : new RestUser(discord, model.Id); | |||
entity = webhookId.HasValue | |||
? new RestWebhookUser(discord, guild, model.Id, webhookId.Value) | |||
: new RestUser(discord, model.Id); | |||
entity.Update(model); | |||
return entity; | |||
} | |||
@@ -89,7 +89,9 @@ namespace Discord.Net.Converters | |||
var typeInfo = type.GetTypeInfo(); | |||
if (typeInfo.ImplementedInterfaces.Any(x => x == typeof(IEntity<ulong>))) | |||
return UInt64EntityConverter.Instance; | |||
return typeInfo.ImplementedInterfaces.Any(x => x == typeof(IEntity<string>)) ? StringEntityConverter.Instance : null; | |||
return typeInfo.ImplementedInterfaces.Any(x => x == typeof(IEntity<string>)) | |||
? StringEntityConverter.Instance | |||
: null; | |||
} | |||
private static bool ShouldSerialize<TOwner, TValue>(object owner, Delegate getter) => | |||
@@ -14,8 +14,8 @@ namespace Discord.Net.Queue | |||
internal class RequestQueue : IDisposable | |||
{ | |||
private readonly ConcurrentDictionary<string, RequestBucket> _buckets; | |||
private readonly SemaphoreSlim _tokenLock; | |||
private readonly CancellationTokenSource _cancelToken; //Dispose token | |||
private readonly SemaphoreSlim _tokenLock; | |||
private Task _cleanupTask; | |||
private CancellationTokenSource _clearToken; | |||
@@ -198,10 +198,8 @@ namespace Discord.Audio | |||
} | |||
} | |||
internal AudioInStream GetInputStream(ulong id) | |||
{ | |||
return _streams.TryGetValue(id, out var streamPair) ? streamPair.Reader : null; | |||
} | |||
internal AudioInStream GetInputStream(ulong id) => | |||
_streams.TryGetValue(id, out var streamPair) ? streamPair.Reader : null; | |||
internal async Task RemoveInputStreamAsync(ulong userId) | |||
{ | |||
@@ -133,7 +133,9 @@ namespace Discord.Audio.Streams | |||
public override async Task WriteAsync(byte[] data, int offset, int count, CancellationToken cancelToken) | |||
{ | |||
cancelToken = cancelToken.CanBeCanceled ? CancellationTokenSource.CreateLinkedTokenSource(cancelToken, _cancelToken).Token : _cancelToken; | |||
cancelToken = cancelToken.CanBeCanceled | |||
? CancellationTokenSource.CreateLinkedTokenSource(cancelToken, _cancelToken).Token | |||
: _cancelToken; | |||
await _queueLock.WaitAsync(-1, cancelToken).ConfigureAwait(false); | |||
if (!_bufferPool.TryDequeue(out var buffer)) | |||
@@ -11,12 +11,12 @@ namespace Discord.Audio.Streams | |||
private const int MaxFrames = 100; //1-2 Seconds | |||
private readonly ConcurrentQueue<RTPFrame> _frames; | |||
private readonly SemaphoreSlim _signal; | |||
private bool _hasHeader; | |||
private bool _isDisposed; | |||
private bool _nextMissed; | |||
private ushort _nextSeq; | |||
private uint _nextTimestamp; | |||
private readonly SemaphoreSlim _signal; | |||
public InputStream() | |||
{ | |||
@@ -246,3 +246,4 @@ namespace Discord.Audio.Streams | |||
}*/ | |||
@@ -10,10 +10,10 @@ namespace Discord.Audio.Streams | |||
protected readonly byte[] _buffer; | |||
private readonly byte[] _header; | |||
private readonly AudioStream _next; | |||
private readonly uint _ssrc; | |||
private bool _hasHeader; | |||
private ushort _nextSeq; | |||
private uint _nextTimestamp; | |||
private readonly uint _ssrc; | |||
public RTPWriteStream(AudioStream next, uint ssrc, int bufferSize = 4000) | |||
{ | |||
@@ -47,15 +47,10 @@ namespace Discord.WebSocket | |||
_groupChannels.Select(x => GetChannel(x) as ISocketPrivateChannel)) | |||
.ToReadOnlyCollection(() => _dmChannels.Count + _groupChannels.Count); | |||
internal SocketChannel GetChannel(ulong id) | |||
{ | |||
return _channels.TryGetValue(id, out var channel) ? channel : null; | |||
} | |||
internal SocketChannel GetChannel(ulong id) => _channels.TryGetValue(id, out var channel) ? channel : null; | |||
internal SocketDMChannel GetDMChannel(ulong userId) | |||
{ | |||
return _dmChannels.TryGetValue(userId, out var channel) ? channel : null; | |||
} | |||
internal SocketDMChannel GetDMChannel(ulong userId) => | |||
_dmChannels.TryGetValue(userId, out var channel) ? channel : null; | |||
internal void AddChannel(SocketChannel channel) | |||
{ | |||
@@ -86,32 +81,19 @@ namespace Discord.WebSocket | |||
} | |||
return channel; | |||
} | |||
internal SocketGuild GetGuild(ulong id) | |||
{ | |||
return _guilds.TryGetValue(id, out var guild) ? guild : null; | |||
} | |||
internal SocketGuild GetGuild(ulong id) => _guilds.TryGetValue(id, out var guild) ? guild : null; | |||
internal void AddGuild(SocketGuild guild) => _guilds[guild.Id] = guild; | |||
internal SocketGuild RemoveGuild(ulong id) | |||
{ | |||
return _guilds.TryRemove(id, out var guild) ? guild : null; | |||
} | |||
internal SocketGuild RemoveGuild(ulong id) => _guilds.TryRemove(id, out var guild) ? guild : null; | |||
internal SocketGlobalUser GetUser(ulong id) | |||
{ | |||
return _users.TryGetValue(id, out var user) ? user : null; | |||
} | |||
internal SocketGlobalUser GetUser(ulong id) => _users.TryGetValue(id, out var user) ? user : null; | |||
internal SocketGlobalUser GetOrAddUser(ulong id, Func<ulong, SocketGlobalUser> userFactory) => | |||
_users.GetOrAdd(id, userFactory); | |||
internal SocketGlobalUser RemoveUser(ulong id) | |||
{ | |||
return _users.TryRemove(id, out var user) ? user : null; | |||
} | |||
internal SocketGlobalUser RemoveUser(ulong id) => _users.TryRemove(id, out var user) ? user : null; | |||
} | |||
} |
@@ -11,11 +11,11 @@ namespace Discord.WebSocket | |||
{ | |||
public partial class DiscordShardedClient : BaseSocketClient, IDiscordClient | |||
{ | |||
private readonly bool _automaticShards; | |||
private readonly DiscordSocketConfig _baseConfig; | |||
private readonly SemaphoreSlim _connectionGroupLock; | |||
private readonly bool _automaticShards; | |||
private int[] _shardIds; | |||
private readonly Dictionary<int, int> _shardIdsToIndex; | |||
private int[] _shardIds; | |||
private DiscordSocketClient[] _shards; | |||
private int _totalShards; | |||
@@ -192,10 +192,7 @@ namespace Discord.WebSocket | |||
} | |||
} | |||
public DiscordSocketClient GetShard(int id) | |||
{ | |||
return _shardIdsToIndex.TryGetValue(id, out id) ? _shards[id] : null; | |||
} | |||
public DiscordSocketClient GetShard(int id) => _shardIdsToIndex.TryGetValue(id, out id) ? _shards[id] : null; | |||
private int GetShardIdFor(ulong guildId) | |||
=> (int)((guildId >> 22) % (uint)_totalShards); | |||
@@ -218,42 +215,24 @@ namespace Discord.WebSocket | |||
=> GetShardFor(id).GetGuild(id); | |||
/// <inheritdoc /> | |||
public override SocketChannel GetChannel(ulong id) | |||
{ | |||
return _shards.Select(t => t.GetChannel(id)).FirstOrDefault(channel => channel != null); | |||
} | |||
public override SocketChannel GetChannel(ulong id) => | |||
_shards.Select(t => t.GetChannel(id)).FirstOrDefault(channel => channel != null); | |||
private IEnumerable<ISocketPrivateChannel> GetPrivateChannels() | |||
{ | |||
return _shards.SelectMany(t => t.PrivateChannels); | |||
} | |||
private IEnumerable<ISocketPrivateChannel> GetPrivateChannels() => _shards.SelectMany(t => t.PrivateChannels); | |||
private int GetPrivateChannelCount() | |||
{ | |||
return _shards.Sum(t => t.PrivateChannels.Count); | |||
} | |||
private int GetPrivateChannelCount() => _shards.Sum(t => t.PrivateChannels.Count); | |||
private IEnumerable<SocketGuild> GetGuilds() | |||
{ | |||
return _shards.SelectMany(t => t.Guilds); | |||
} | |||
private IEnumerable<SocketGuild> GetGuilds() => _shards.SelectMany(t => t.Guilds); | |||
private int GetGuildCount() | |||
{ | |||
return _shards.Sum(t => t.Guilds.Count); | |||
} | |||
private int GetGuildCount() => _shards.Sum(t => t.Guilds.Count); | |||
/// <inheritdoc /> | |||
public override SocketUser GetUser(ulong id) | |||
{ | |||
return _shards.Select(t => t.GetUser(id)).FirstOrDefault(user => user != null); | |||
} | |||
public override SocketUser GetUser(ulong id) => | |||
_shards.Select(t => t.GetUser(id)).FirstOrDefault(user => user != null); | |||
/// <inheritdoc /> | |||
public override SocketUser GetUser(string username, string discriminator) | |||
{ | |||
return _shards.Select(t => t.GetUser(username, discriminator)).FirstOrDefault(user => user != null); | |||
} | |||
public override SocketUser GetUser(string username, string discriminator) => _shards | |||
.Select(t => t.GetUser(username, discriminator)).FirstOrDefault(user => user != null); | |||
/// <inheritdoc /> | |||
public override RestVoiceRegion GetVoiceRegion(string id) | |||
@@ -18,6 +18,7 @@ namespace Discord.API | |||
internal class DiscordSocketApiClient : DiscordRestApiClient | |||
{ | |||
private readonly AsyncEvent<Func<Exception, Task>> _disconnectedEvent = new AsyncEvent<Func<Exception, Task>>(); | |||
private readonly bool _isExplicitUrl; | |||
private readonly AsyncEvent<Func<GatewayOpCode, int?, string, object, Task>> _receivedGatewayEvent = | |||
new AsyncEvent<Func<GatewayOpCode, int?, string, object, Task>>(); | |||
@@ -31,7 +32,6 @@ namespace Discord.API | |||
private CancellationTokenSource _connectCancelToken; | |||
private DeflateStream _decompressor; | |||
private string _gatewayUrl; | |||
private readonly bool _isExplicitUrl; | |||
public DiscordSocketApiClient(RestClientProvider restClientProvider, WebSocketProvider webSocketProvider, | |||
string userAgent, | |||
@@ -357,10 +357,8 @@ namespace Discord.WebSocket | |||
=> State.RemoveUser(id); | |||
/// <inheritdoc /> | |||
public override RestVoiceRegion GetVoiceRegion(string id) | |||
{ | |||
return _voiceRegions.TryGetValue(id, out var region) ? region : null; | |||
} | |||
public override RestVoiceRegion GetVoiceRegion(string id) => | |||
_voiceRegions.TryGetValue(id, out var region) ? region : null; | |||
/// <summary> Downloads the users list for the provided guilds, if they don't have a complete list. </summary> | |||
public override async Task DownloadUsersAsync(IEnumerable<IGuild> guilds) | |||
@@ -1152,7 +1150,7 @@ namespace Discord.WebSocket | |||
author = guild.GetUser(data.Author.Value.Id); | |||
} | |||
else | |||
author = ((SocketChannel) channel).GetUser(data.Author.Value.Id); | |||
author = ((SocketChannel)channel).GetUser(data.Author.Value.Id); | |||
if (author == null) | |||
{ | |||
@@ -1205,8 +1203,11 @@ namespace Discord.WebSocket | |||
else if (data.Author.IsSpecified) | |||
{ | |||
//Edited message isnt in cache, create a detached one | |||
var author = (guild != null ? guild.GetUser(data.Author.Value.Id) : ((SocketChannel) channel).GetUser(data.Author.Value.Id)) ?? | |||
SocketUnknownUser.Create(this, State, data.Author.Value); | |||
var author = | |||
(guild != null | |||
? guild.GetUser(data.Author.Value.Id) | |||
: ((SocketChannel)channel).GetUser(data.Author.Value.Id)) ?? | |||
SocketUnknownUser.Create(this, State, data.Author.Value); | |||
after = SocketMessage.Create(this, State, author, channel, data); | |||
} | |||
@@ -37,10 +37,10 @@ namespace Discord.Audio | |||
new AsyncEvent<Func<string, string, double, Task>>(); | |||
private readonly JsonSerializer _serializer; | |||
private readonly IUdpSocket _udp; | |||
private CancellationTokenSource _connectCancelToken; | |||
private bool _isDisposed; | |||
private ulong _nextKeepalive; | |||
private readonly IUdpSocket _udp; | |||
internal DiscordVoiceAPIClient(ulong guildId, WebSocketProvider webSocketProvider, | |||
UdpSocketProvider udpSocketProvider, JsonSerializer serializer = null) | |||
@@ -23,7 +23,9 @@ namespace Discord.WebSocket | |||
if (dir == Direction.Before || mode == CacheMode.CacheOnly) | |||
{ | |||
cachedMessages = messages != null ? messages.GetMany(fromMessageId, dir, limit) : ImmutableArray.Create<SocketMessage>(); | |||
cachedMessages = messages != null | |||
? messages.GetMany(fromMessageId, dir, limit) | |||
: ImmutableArray.Create<SocketMessage>(); | |||
result = ImmutableArray.Create(cachedMessages).ToAsyncEnumerable<IReadOnlyCollection<IMessage>>(); | |||
} | |||
@@ -45,10 +47,9 @@ namespace Discord.WebSocket | |||
public static IReadOnlyCollection<SocketMessage> GetCachedMessages(SocketChannel channel, | |||
DiscordSocketClient discord, MessageCache messages, | |||
ulong? fromMessageId, Direction dir, int limit) | |||
{ | |||
return messages != null ? messages.GetMany(fromMessageId, dir, limit) : ImmutableArray.Create<SocketMessage>(); | |||
} | |||
ulong? fromMessageId, Direction dir, int limit) => messages != null | |||
? messages.GetMany(fromMessageId, dir, limit) | |||
: ImmutableArray.Create<SocketMessage>(); | |||
public static void AddMessage(ISocketMessageChannel channel, DiscordSocketClient discord, | |||
SocketMessage msg) | |||
@@ -19,10 +19,10 @@ namespace Discord.WebSocket | |||
ISocketAudioChannel | |||
{ | |||
private readonly MessageCache _messages; | |||
private readonly ConcurrentDictionary<ulong, SocketVoiceState> _voiceStates; | |||
private string _iconId; | |||
private ConcurrentDictionary<ulong, SocketGroupUser> _users; | |||
private readonly ConcurrentDictionary<ulong, SocketVoiceState> _voiceStates; | |||
internal SocketGroupChannel(DiscordSocketClient discord, ulong id) | |||
: base(discord, id) | |||
@@ -211,10 +211,7 @@ namespace Discord.WebSocket | |||
=> _messages?.Remove(id); | |||
//Users | |||
public new SocketGroupUser GetUser(ulong id) | |||
{ | |||
return _users.TryGetValue(id, out var user) ? user : null; | |||
} | |||
public new SocketGroupUser GetUser(ulong id) => _users.TryGetValue(id, out var user) ? user : null; | |||
internal SocketGroupUser GetOrAddUser(UserModel model) | |||
{ | |||
@@ -231,7 +228,6 @@ namespace Discord.WebSocket | |||
if (!_users.TryRemove(id, out var user)) return null; | |||
user.GlobalUser.RemoveRef(Discord); | |||
return user; | |||
} | |||
//Voice States | |||
@@ -523,10 +523,7 @@ namespace Discord.WebSocket | |||
=> GuildHelper.GetVanityInviteAsync(this, Discord, options); | |||
//Roles | |||
public SocketRole GetRole(ulong id) | |||
{ | |||
return _roles.TryGetValue(id, out var value) ? value : null; | |||
} | |||
public SocketRole GetRole(ulong id) => _roles.TryGetValue(id, out var value) ? value : null; | |||
public Task<RestRole> CreateRoleAsync(string name, GuildPermissions? permissions = default(GuildPermissions?), | |||
Color? color = default(Color?), | |||
@@ -540,16 +537,10 @@ namespace Discord.WebSocket | |||
return role; | |||
} | |||
internal SocketRole RemoveRole(ulong id) | |||
{ | |||
return _roles.TryRemove(id, out var role) ? role : null; | |||
} | |||
internal SocketRole RemoveRole(ulong id) => _roles.TryRemove(id, out var role) ? role : null; | |||
//Users | |||
public SocketGuildUser GetUser(ulong id) | |||
{ | |||
return _members.TryGetValue(id, out var member) ? member : null; | |||
} | |||
public SocketGuildUser GetUser(ulong id) => _members.TryGetValue(id, out var member) ? member : null; | |||
internal SocketGuildUser AddOrUpdateUser(UserModel model) | |||
{ | |||
@@ -602,7 +593,6 @@ namespace Discord.WebSocket | |||
DownloadedMemberCount--; | |||
member.GlobalUser.RemoveRef(Discord); | |||
return member; | |||
} | |||
internal void CompleteDownloadUsers() => _downloaderPromise.TrySetResultAsync(true); | |||
@@ -37,10 +37,7 @@ namespace Discord.WebSocket | |||
return msg; | |||
} | |||
public SocketMessage Get(ulong id) | |||
{ | |||
return _messages.TryGetValue(id, out var result) ? result : null; | |||
} | |||
public SocketMessage Get(ulong id) => _messages.TryGetValue(id, out var result) ? result : null; | |||
public IReadOnlyCollection<SocketMessage> GetMany(ulong? fromMessageId, Direction dir, | |||
int limit = DiscordConfig.MaxMessagesPerBatch) | |||
@@ -60,10 +57,7 @@ namespace Discord.WebSocket | |||
cachedMessageIds = cachedMessageIds.Reverse(); | |||
return cachedMessageIds | |||
.Select(x => | |||
{ | |||
return _messages.TryGetValue(x, out var msg) ? msg : null; | |||
}) | |||
.Select(x => { return _messages.TryGetValue(x, out var msg) ? msg : null; }) | |||
.Where(x => x != null) | |||
.Take(limit) | |||
.ToImmutableArray(); | |||
@@ -12,11 +12,11 @@ namespace Discord.WebSocket | |||
[DebuggerDisplay(@"{" + nameof(DebuggerDisplay) + @",nq}")] | |||
public class SocketUserMessage : SocketMessage, IUserMessage | |||
{ | |||
private readonly List<SocketReaction> _reactions = new List<SocketReaction>(); | |||
private ImmutableArray<Attachment> _attachments; | |||
private long? _editedTimestampTicks; | |||
private ImmutableArray<Embed> _embeds; | |||
private bool _isMentioningEveryone, _isTTS, _isPinned; | |||
private readonly List<SocketReaction> _reactions = new List<SocketReaction>(); | |||
private ImmutableArray<ITag> _tags; | |||
internal SocketUserMessage(DiscordSocketClient discord, ulong id, ISocketMessageChannel channel, | |||
@@ -142,10 +142,8 @@ namespace Discord.WebSocket | |||
{ | |||
var newMentions = ImmutableArray.CreateBuilder<SocketUnknownUser>(value.Length); | |||
foreach (var val in value) | |||
{ | |||
if (val.Object != null) | |||
newMentions.Add(SocketUnknownUser.Create(Discord, state, val.Object)); | |||
} | |||
mentions = newMentions.ToImmutable(); | |||
} | |||
@@ -18,11 +18,11 @@ namespace Discord.Net.WebSockets | |||
private readonly Dictionary<string, string> _headers; | |||
private readonly SemaphoreSlim _lock; | |||
private readonly IWebProxy _proxy; | |||
private CancellationToken _cancelToken, _parentToken; | |||
private CancellationTokenSource _cancelTokenSource; | |||
private ClientWebSocket _client; | |||
private bool _isDisposed, _isDisconnecting; | |||
private readonly IWebProxy _proxy; | |||
private Task _task; | |||
public DefaultWebSocketClient(IWebProxy proxy = null) | |||
@@ -15,11 +15,11 @@ namespace Discord.Net | |||
{ | |||
internal class CachedRestClient : IRestClient | |||
{ | |||
private readonly IBlobCache _blobCache; | |||
private readonly CancellationTokenSource _cancelTokenSource; | |||
private readonly Dictionary<string, string> _headers; | |||
private string _baseUrl; | |||
private readonly IBlobCache _blobCache; | |||
private CancellationToken _cancelToken, _parentToken; | |||
private readonly CancellationTokenSource _cancelTokenSource; | |||
private bool _isDisposed; | |||
public CachedRestClient() | |||
@@ -44,7 +44,8 @@ namespace Discord | |||
.Distinct() | |||
.ToArray(); | |||
// test GuildPermissions.All | |||
var sumOfAllGuildPermissions = enumValues.Aggregate<GuildPermission, ulong>(0, (current, v) => current | (ulong)v); | |||
var sumOfAllGuildPermissions = | |||
enumValues.Aggregate<GuildPermission, ulong>(0, (current, v) => current | (ulong)v); | |||
// assert that the raw values match | |||
Assert.Equal(sumOfAllGuildPermissions, GuildPermissions.All.RawValue); | |||
@@ -41,8 +41,8 @@ namespace Discord | |||
public partial class Tests : IClassFixture<TestsFixture> | |||
{ | |||
private DiscordRestClient _client; | |||
private readonly RestGuild _guild; | |||
private DiscordRestClient _client; | |||
public Tests(TestsFixture fixture) | |||
{ | |||