Add various optimizations and cleanups (#1114)
* Change all Select(... as ...) to OfType
* Add changes according to 194a8aa427
This commit is contained in:
@@ -7,13 +7,13 @@ namespace Discord.Commands
|
|||||||
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
|
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
|
||||||
public class OverrideTypeReaderAttribute : Attribute
|
public class OverrideTypeReaderAttribute : Attribute
|
||||||
{
|
{
|
||||||
private static readonly TypeInfo _typeReaderTypeInfo = typeof(TypeReader).GetTypeInfo();
|
private static readonly TypeInfo TypeReaderTypeInfo = typeof(TypeReader).GetTypeInfo();
|
||||||
|
|
||||||
public Type TypeReader { get; }
|
public Type TypeReader { get; }
|
||||||
|
|
||||||
public OverrideTypeReaderAttribute(Type overridenTypeReader)
|
public OverrideTypeReaderAttribute(Type overridenTypeReader)
|
||||||
{
|
{
|
||||||
if (!_typeReaderTypeInfo.IsAssignableFrom(overridenTypeReader.GetTypeInfo()))
|
if (!TypeReaderTypeInfo.IsAssignableFrom(overridenTypeReader.GetTypeInfo()))
|
||||||
throw new ArgumentException($"{nameof(overridenTypeReader)} must inherit from {nameof(TypeReader)}");
|
throw new ArgumentException($"{nameof(overridenTypeReader)} must inherit from {nameof(TypeReader)}");
|
||||||
|
|
||||||
TypeReader = overridenTypeReader;
|
TypeReader = overridenTypeReader;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace Discord.Commands
|
|||||||
{
|
{
|
||||||
internal static class ModuleClassBuilder
|
internal static class ModuleClassBuilder
|
||||||
{
|
{
|
||||||
private static readonly TypeInfo _moduleTypeInfo = typeof(IModuleBase).GetTypeInfo();
|
private static readonly TypeInfo ModuleTypeInfo = typeof(IModuleBase).GetTypeInfo();
|
||||||
|
|
||||||
public static async Task<IReadOnlyList<TypeInfo>> SearchAsync(Assembly assembly, CommandService service)
|
public static async Task<IReadOnlyList<TypeInfo>> SearchAsync(Assembly assembly, CommandService service)
|
||||||
{
|
{
|
||||||
@@ -135,7 +135,7 @@ namespace Discord.Commands
|
|||||||
if (builder.Name == null)
|
if (builder.Name == null)
|
||||||
builder.Name = typeInfo.Name;
|
builder.Name = typeInfo.Name;
|
||||||
|
|
||||||
var validCommands = typeInfo.DeclaredMethods.Where(x => IsValidCommandDefinition(x));
|
var validCommands = typeInfo.DeclaredMethods.Where(IsValidCommandDefinition);
|
||||||
|
|
||||||
foreach (var method in validCommands)
|
foreach (var method in validCommands)
|
||||||
{
|
{
|
||||||
@@ -299,7 +299,7 @@ namespace Discord.Commands
|
|||||||
|
|
||||||
private static bool IsValidModuleDefinition(TypeInfo typeInfo)
|
private static bool IsValidModuleDefinition(TypeInfo typeInfo)
|
||||||
{
|
{
|
||||||
return _moduleTypeInfo.IsAssignableFrom(typeInfo) &&
|
return ModuleTypeInfo.IsAssignableFrom(typeInfo) &&
|
||||||
!typeInfo.IsAbstract &&
|
!typeInfo.IsAbstract &&
|
||||||
!typeInfo.ContainsGenericParameters;
|
!typeInfo.ContainsGenericParameters;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ namespace Discord.Commands
|
|||||||
var typeInfo = type.GetTypeInfo();
|
var typeInfo = type.GetTypeInfo();
|
||||||
|
|
||||||
if (_typedModuleDefs.ContainsKey(type))
|
if (_typedModuleDefs.ContainsKey(type))
|
||||||
throw new ArgumentException($"This module has already been added.");
|
throw new ArgumentException("This module has already been added.");
|
||||||
|
|
||||||
var module = (await ModuleClassBuilder.BuildAsync(this, services, typeInfo).ConfigureAwait(false)).FirstOrDefault();
|
var module = (await ModuleClassBuilder.BuildAsync(this, services, typeInfo).ConfigureAwait(false)).FirstOrDefault();
|
||||||
|
|
||||||
@@ -241,7 +241,7 @@ namespace Discord.Commands
|
|||||||
{
|
{
|
||||||
if (_defaultTypeReaders.ContainsKey(type))
|
if (_defaultTypeReaders.ContainsKey(type))
|
||||||
_ = _cmdLogger.WarningAsync($"The default TypeReader for {type.FullName} was replaced by {reader.GetType().FullName}." +
|
_ = _cmdLogger.WarningAsync($"The default TypeReader for {type.FullName} was replaced by {reader.GetType().FullName}." +
|
||||||
$"To suppress this message, use AddTypeReader<T>(reader, true).");
|
"To suppress this message, use AddTypeReader<T>(reader, true).");
|
||||||
AddTypeReader(type, reader, true);
|
AddTypeReader(type, reader, true);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using Discord.Commands.Builders;
|
using Discord.Commands.Builders;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
@@ -63,7 +63,7 @@ namespace Discord.Commands
|
|||||||
Attributes = builder.Attributes.ToImmutableArray();
|
Attributes = builder.Attributes.ToImmutableArray();
|
||||||
|
|
||||||
Parameters = builder.Parameters.Select(x => x.Build(this)).ToImmutableArray();
|
Parameters = builder.Parameters.Select(x => x.Build(this)).ToImmutableArray();
|
||||||
HasVarArgs = builder.Parameters.Count > 0 ? builder.Parameters[builder.Parameters.Count - 1].IsMultiple : false;
|
HasVarArgs = builder.Parameters.Count > 0 && builder.Parameters[builder.Parameters.Count - 1].IsMultiple;
|
||||||
IgnoreExtraArgs = builder.IgnoreExtraArgs;
|
IgnoreExtraArgs = builder.IgnoreExtraArgs;
|
||||||
|
|
||||||
_action = builder.Callback;
|
_action = builder.Callback;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Discord.Commands
|
namespace Discord.Commands
|
||||||
{
|
{
|
||||||
@@ -6,7 +6,7 @@ namespace Discord.Commands
|
|||||||
{
|
{
|
||||||
private readonly CommandService _service;
|
private readonly CommandService _service;
|
||||||
private readonly CommandMapNode _root;
|
private readonly CommandMapNode _root;
|
||||||
private static readonly string[] _blankAliases = new[] { "" };
|
private static readonly string[] BlankAliases = { "" };
|
||||||
|
|
||||||
public CommandMap(CommandService service)
|
public CommandMap(CommandService service)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
@@ -7,7 +7,7 @@ namespace Discord.Commands
|
|||||||
{
|
{
|
||||||
internal class CommandMapNode
|
internal class CommandMapNode
|
||||||
{
|
{
|
||||||
private static readonly char[] _whitespaceChars = new[] { ' ', '\r', '\n' };
|
private static readonly char[] WhitespaceChars = { ' ', '\r', '\n' };
|
||||||
|
|
||||||
private readonly ConcurrentDictionary<string, CommandMapNode> _nodes;
|
private readonly ConcurrentDictionary<string, CommandMapNode> _nodes;
|
||||||
private readonly string _name;
|
private readonly string _name;
|
||||||
@@ -52,7 +52,6 @@ namespace Discord.Commands
|
|||||||
public void RemoveCommand(CommandService service, string text, int index, CommandInfo command)
|
public void RemoveCommand(CommandService service, string text, int index, CommandInfo command)
|
||||||
{
|
{
|
||||||
int nextSegment = NextSegment(text, index, service._separatorChar);
|
int nextSegment = NextSegment(text, index, service._separatorChar);
|
||||||
string name;
|
|
||||||
|
|
||||||
lock (_lockObj)
|
lock (_lockObj)
|
||||||
{
|
{
|
||||||
@@ -60,13 +59,13 @@ namespace Discord.Commands
|
|||||||
_commands = _commands.Remove(command);
|
_commands = _commands.Remove(command);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
string name;
|
||||||
if (nextSegment == -1)
|
if (nextSegment == -1)
|
||||||
name = text.Substring(index);
|
name = text.Substring(index);
|
||||||
else
|
else
|
||||||
name = text.Substring(index, nextSegment - index);
|
name = text.Substring(index, nextSegment - index);
|
||||||
|
|
||||||
CommandMapNode nextNode;
|
if (_nodes.TryGetValue(name, out var nextNode))
|
||||||
if (_nodes.TryGetValue(name, out nextNode))
|
|
||||||
{
|
{
|
||||||
nextNode.RemoveCommand(service, nextSegment == -1 ? "" : text, nextSegment + 1, command);
|
nextNode.RemoveCommand(service, nextSegment == -1 ? "" : text, nextSegment + 1, command);
|
||||||
if (nextNode.IsEmpty)
|
if (nextNode.IsEmpty)
|
||||||
@@ -100,7 +99,7 @@ namespace Discord.Commands
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Check if this is the last command segment before args
|
//Check if this is the last command segment before args
|
||||||
nextSegment = NextSegment(text, index, _whitespaceChars, service._separatorChar);
|
nextSegment = NextSegment(text, index, WhitespaceChars, service._separatorChar);
|
||||||
if (nextSegment != -1)
|
if (nextSegment != -1)
|
||||||
{
|
{
|
||||||
name = text.Substring(index, nextSegment - index);
|
name = text.Substring(index, nextSegment - index);
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ namespace Discord.Commands
|
|||||||
|
|
||||||
internal static class PrimitiveParsers
|
internal static class PrimitiveParsers
|
||||||
{
|
{
|
||||||
private static readonly Lazy<IReadOnlyDictionary<Type, Delegate>> _parsers = new Lazy<IReadOnlyDictionary<Type, Delegate>>(CreateParsers);
|
private static readonly Lazy<IReadOnlyDictionary<Type, Delegate>> Parsers = new Lazy<IReadOnlyDictionary<Type, Delegate>>(CreateParsers);
|
||||||
|
|
||||||
public static IEnumerable<Type> SupportedTypes = _parsers.Value.Keys;
|
public static IEnumerable<Type> SupportedTypes = Parsers.Value.Keys;
|
||||||
|
|
||||||
static IReadOnlyDictionary<Type, Delegate> CreateParsers()
|
static IReadOnlyDictionary<Type, Delegate> CreateParsers()
|
||||||
{
|
{
|
||||||
@@ -34,7 +34,7 @@ namespace Discord.Commands
|
|||||||
return parserBuilder.ToImmutable();
|
return parserBuilder.ToImmutable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TryParseDelegate<T> Get<T>() => (TryParseDelegate<T>)_parsers.Value[typeof(T)];
|
public static TryParseDelegate<T> Get<T>() => (TryParseDelegate<T>)Parsers.Value[typeof(T)];
|
||||||
public static Delegate Get(Type type) => _parsers.Value[type];
|
public static Delegate Get(Type type) => Parsers.Value[type];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ namespace Discord.Commands
|
|||||||
{
|
{
|
||||||
internal class TimeSpanTypeReader : TypeReader
|
internal class TimeSpanTypeReader : TypeReader
|
||||||
{
|
{
|
||||||
private static readonly string[] _formats = new[]
|
private static readonly string[] Formats = {
|
||||||
{
|
|
||||||
"%d'd'%h'h'%m'm'%s's'", //4d3h2m1s
|
"%d'd'%h'h'%m'm'%s's'", //4d3h2m1s
|
||||||
"%d'd'%h'h'%m'm'", //4d3h2m
|
"%d'd'%h'h'%m'm'", //4d3h2m
|
||||||
"%d'd'%h'h'%s's'", //4d3h 1s
|
"%d'd'%h'h'%s's'", //4d3h 1s
|
||||||
@@ -27,7 +26,7 @@ namespace Discord.Commands
|
|||||||
|
|
||||||
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
|
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
|
||||||
{
|
{
|
||||||
return (TimeSpan.TryParseExact(input.ToLowerInvariant(), _formats, CultureInfo.InvariantCulture, out var timeSpan))
|
return (TimeSpan.TryParseExact(input.ToLowerInvariant(), Formats, CultureInfo.InvariantCulture, out var timeSpan))
|
||||||
? Task.FromResult(TypeReaderResult.FromSuccess(timeSpan))
|
? Task.FromResult(TypeReaderResult.FromSuccess(timeSpan))
|
||||||
: Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Failed to parse TimeSpan"));
|
: Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Failed to parse TimeSpan"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ namespace Discord.Commands
|
|||||||
.Where(x => string.Equals(input, (x as IGuildUser)?.Nickname, StringComparison.OrdinalIgnoreCase))
|
.Where(x => string.Equals(input, (x as IGuildUser)?.Nickname, StringComparison.OrdinalIgnoreCase))
|
||||||
.ForEachAsync(channelUser => AddResult(results, channelUser as T, (channelUser as IGuildUser).Nickname == input ? 0.65f : 0.55f));
|
.ForEachAsync(channelUser => AddResult(results, channelUser as T, (channelUser as IGuildUser).Nickname == input ? 0.65f : 0.55f));
|
||||||
|
|
||||||
foreach (var guildUser in guildUsers.Where(x => string.Equals(input, (x as IGuildUser).Nickname, StringComparison.OrdinalIgnoreCase)))
|
foreach (var guildUser in guildUsers.Where(x => string.Equals(input, x.Nickname, StringComparison.OrdinalIgnoreCase)))
|
||||||
AddResult(results, guildUser as T, (guildUser as IGuildUser).Nickname == input ? 0.60f : 0.50f);
|
AddResult(results, guildUser as T, guildUser.Nickname == input ? 0.60f : 0.50f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results.Count > 0)
|
if (results.Count > 0)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace Discord.Commands
|
|||||||
{
|
{
|
||||||
internal static class ReflectionUtils
|
internal static class ReflectionUtils
|
||||||
{
|
{
|
||||||
private static readonly TypeInfo _objectTypeInfo = typeof(object).GetTypeInfo();
|
private static readonly TypeInfo ObjectTypeInfo = typeof(object).GetTypeInfo();
|
||||||
|
|
||||||
internal static T CreateObject<T>(TypeInfo typeInfo, CommandService commands, IServiceProvider services = null)
|
internal static T CreateObject<T>(TypeInfo typeInfo, CommandService commands, IServiceProvider services = null)
|
||||||
=> CreateBuilder<T>(typeInfo, commands)(services);
|
=> CreateBuilder<T>(typeInfo, commands)(services);
|
||||||
@@ -54,7 +54,7 @@ namespace Discord.Commands
|
|||||||
private static System.Reflection.PropertyInfo[] GetProperties(TypeInfo ownerType)
|
private static System.Reflection.PropertyInfo[] GetProperties(TypeInfo ownerType)
|
||||||
{
|
{
|
||||||
var result = new List<System.Reflection.PropertyInfo>();
|
var result = new List<System.Reflection.PropertyInfo>();
|
||||||
while (ownerType != _objectTypeInfo)
|
while (ownerType != ObjectTypeInfo)
|
||||||
{
|
{
|
||||||
foreach (var prop in ownerType.DeclaredProperties)
|
foreach (var prop in ownerType.DeclaredProperties)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ namespace Discord
|
|||||||
get => _name;
|
get => _name;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException($"Field name must not be null, empty or entirely whitespace.", nameof(Name));
|
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException("Field name must not be null, empty or entirely whitespace.", nameof(Name));
|
||||||
if (value.Length > MaxFieldNameLength) throw new ArgumentException($"Field name length must be less than or equal to {MaxFieldNameLength}.", nameof(Name));
|
if (value.Length > MaxFieldNameLength) throw new ArgumentException($"Field name length must be less than or equal to {MaxFieldNameLength}.", nameof(Name));
|
||||||
_name = value;
|
_name = value;
|
||||||
}
|
}
|
||||||
@@ -251,7 +251,7 @@ namespace Discord
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
var stringValue = value?.ToString();
|
var stringValue = value?.ToString();
|
||||||
if (string.IsNullOrEmpty(stringValue)) throw new ArgumentException($"Field value must not be null or empty.", nameof(Value));
|
if (string.IsNullOrEmpty(stringValue)) throw new ArgumentException("Field value must not be null or empty.", nameof(Value));
|
||||||
if (stringValue.Length > MaxFieldValueLength) throw new ArgumentException($"Field value length must be less than or equal to {MaxFieldValueLength}.", nameof(Value));
|
if (stringValue.Length > MaxFieldValueLength) throw new ArgumentException($"Field value length must be less than or equal to {MaxFieldValueLength}.", nameof(Value));
|
||||||
_value = stringValue;
|
_value = stringValue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace Discord
|
namespace Discord
|
||||||
@@ -20,6 +20,6 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
|
|
||||||
private string DebuggerDisplay => $"{Url} ({(Width != null && Height != null ? $"{Width}x{Height}" : "0x0")})";
|
private string DebuggerDisplay => $"{Url} ({(Width != null && Height != null ? $"{Width}x{Height}" : "0x0")})";
|
||||||
public override string ToString() => Url.ToString();
|
public override string ToString() => Url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace Discord
|
namespace Discord
|
||||||
@@ -20,6 +20,6 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
|
|
||||||
private string DebuggerDisplay => $"{Url} ({(Width != null && Height != null ? $"{Width}x{Height}" : "0x0")})";
|
private string DebuggerDisplay => $"{Url} ({(Width != null && Height != null ? $"{Width}x{Height}" : "0x0")})";
|
||||||
public override string ToString() => Url.ToString();
|
public override string ToString() => Url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace Discord
|
namespace Discord
|
||||||
@@ -18,6 +18,6 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
|
|
||||||
private string DebuggerDisplay => $"{Url} ({(Width != null && Height != null ? $"{Width}x{Height}" : "0x0")})";
|
private string DebuggerDisplay => $"{Url} ({(Width != null && Height != null ? $"{Width}x{Height}" : "0x0")})";
|
||||||
public override string ToString() => Url.ToString();
|
public override string ToString() => Url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ namespace Discord
|
|||||||
public static async Task<IDMChannel> GetDMChannelAsync(this IDiscordClient client, ulong id)
|
public static async Task<IDMChannel> GetDMChannelAsync(this IDiscordClient client, ulong id)
|
||||||
=> await client.GetPrivateChannelAsync(id).ConfigureAwait(false) as IDMChannel;
|
=> await client.GetPrivateChannelAsync(id).ConfigureAwait(false) as IDMChannel;
|
||||||
public static async Task<IEnumerable<IDMChannel>> GetDMChannelsAsync(this IDiscordClient client)
|
public static async Task<IEnumerable<IDMChannel>> GetDMChannelsAsync(this IDiscordClient client)
|
||||||
=> (await client.GetPrivateChannelsAsync().ConfigureAwait(false)).Select(x => x as IDMChannel).Where(x => x != null);
|
=> (await client.GetPrivateChannelsAsync().ConfigureAwait(false)).OfType<IDMChannel>();
|
||||||
|
|
||||||
public static async Task<IGroupChannel> GetGroupChannelAsync(this IDiscordClient client, ulong id)
|
public static async Task<IGroupChannel> GetGroupChannelAsync(this IDiscordClient client, ulong id)
|
||||||
=> await client.GetPrivateChannelAsync(id).ConfigureAwait(false) as IGroupChannel;
|
=> await client.GetPrivateChannelAsync(id).ConfigureAwait(false) as IGroupChannel;
|
||||||
public static async Task<IEnumerable<IGroupChannel>> GetGroupChannelsAsync(this IDiscordClient client)
|
public static async Task<IEnumerable<IGroupChannel>> GetGroupChannelsAsync(this IDiscordClient client)
|
||||||
=> (await client.GetPrivateChannelsAsync().ConfigureAwait(false)).Select(x => x as IGroupChannel).Where(x => x != null);
|
=> (await client.GetPrivateChannelsAsync().ConfigureAwait(false)).OfType<IGroupChannel>();
|
||||||
|
|
||||||
public static async Task<IVoiceRegion> GetOptimalVoiceRegionAsync(this IDiscordClient discord)
|
public static async Task<IVoiceRegion> GetOptimalVoiceRegionAsync(this IDiscordClient discord)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
namespace Discord
|
namespace Discord
|
||||||
{
|
{
|
||||||
public static class Format
|
public static class Format
|
||||||
{
|
{
|
||||||
// Characters which need escaping
|
// Characters which need escaping
|
||||||
private static string[] SensitiveCharacters = { "\\", "*", "_", "~", "`" };
|
private static readonly string[] SensitiveCharacters = { "\\", "*", "_", "~", "`" };
|
||||||
|
|
||||||
/// <summary> Returns a markdown-formatted string with bold formatting. </summary>
|
/// <summary> Returns a markdown-formatted string with bold formatting. </summary>
|
||||||
public static string Bold(string text) => $"**{text}**";
|
public static string Bold(string text) => $"**{text}**";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
@@ -139,22 +139,22 @@ namespace Discord
|
|||||||
if (user != null)
|
if (user != null)
|
||||||
return $"@{guildUser?.Nickname ?? user?.Username}";
|
return $"@{guildUser?.Nickname ?? user?.Username}";
|
||||||
else
|
else
|
||||||
return $"";
|
return "";
|
||||||
case TagHandling.NameNoPrefix:
|
case TagHandling.NameNoPrefix:
|
||||||
if (user != null)
|
if (user != null)
|
||||||
return $"{guildUser?.Nickname ?? user?.Username}";
|
return $"{guildUser?.Nickname ?? user?.Username}";
|
||||||
else
|
else
|
||||||
return $"";
|
return "";
|
||||||
case TagHandling.FullName:
|
case TagHandling.FullName:
|
||||||
if (user != null)
|
if (user != null)
|
||||||
return $"@{user.Username}#{user.Discriminator}";
|
return $"@{user.Username}#{user.Discriminator}";
|
||||||
else
|
else
|
||||||
return $"";
|
return "";
|
||||||
case TagHandling.FullNameNoPrefix:
|
case TagHandling.FullNameNoPrefix:
|
||||||
if (user != null)
|
if (user != null)
|
||||||
return $"{user.Username}#{user.Discriminator}";
|
return $"{user.Username}#{user.Discriminator}";
|
||||||
else
|
else
|
||||||
return $"";
|
return "";
|
||||||
case TagHandling.Sanitize:
|
case TagHandling.Sanitize:
|
||||||
if (guildUser != null && guildUser.Nickname == null)
|
if (guildUser != null && guildUser.Nickname == null)
|
||||||
return MentionUser($"{SanitizeChar}{tag.Key}", false);
|
return MentionUser($"{SanitizeChar}{tag.Key}", false);
|
||||||
@@ -176,13 +176,13 @@ namespace Discord
|
|||||||
if (channel != null)
|
if (channel != null)
|
||||||
return $"#{channel.Name}";
|
return $"#{channel.Name}";
|
||||||
else
|
else
|
||||||
return $"";
|
return "";
|
||||||
case TagHandling.NameNoPrefix:
|
case TagHandling.NameNoPrefix:
|
||||||
case TagHandling.FullNameNoPrefix:
|
case TagHandling.FullNameNoPrefix:
|
||||||
if (channel != null)
|
if (channel != null)
|
||||||
return $"{channel.Name}";
|
return $"{channel.Name}";
|
||||||
else
|
else
|
||||||
return $"";
|
return "";
|
||||||
case TagHandling.Sanitize:
|
case TagHandling.Sanitize:
|
||||||
return MentionChannel($"{SanitizeChar}{tag.Key}");
|
return MentionChannel($"{SanitizeChar}{tag.Key}");
|
||||||
}
|
}
|
||||||
@@ -201,13 +201,13 @@ namespace Discord
|
|||||||
if (role != null)
|
if (role != null)
|
||||||
return $"@{role.Name}";
|
return $"@{role.Name}";
|
||||||
else
|
else
|
||||||
return $"";
|
return "";
|
||||||
case TagHandling.NameNoPrefix:
|
case TagHandling.NameNoPrefix:
|
||||||
case TagHandling.FullNameNoPrefix:
|
case TagHandling.FullNameNoPrefix:
|
||||||
if (role != null)
|
if (role != null)
|
||||||
return $"{role.Name}";
|
return $"{role.Name}";
|
||||||
else
|
else
|
||||||
return $"";
|
return "";
|
||||||
case TagHandling.Sanitize:
|
case TagHandling.Sanitize:
|
||||||
return MentionRole($"{SanitizeChar}{tag.Key}");
|
return MentionRole($"{SanitizeChar}{tag.Key}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -60,7 +60,7 @@ namespace Discord
|
|||||||
if (Current.Count == 0)
|
if (Current.Count == 0)
|
||||||
_info.Remaining = 0;
|
_info.Remaining = 0;
|
||||||
}
|
}
|
||||||
_info.PageSize = _info.Remaining != null ? (int)Math.Min(_info.Remaining.Value, _source.PageSize) : _source.PageSize;
|
_info.PageSize = _info.Remaining != null ? Math.Min(_info.Remaining.Value, _source.PageSize) : _source.PageSize;
|
||||||
|
|
||||||
if (_info.Remaining != 0)
|
if (_info.Remaining != 0)
|
||||||
{
|
{
|
||||||
@@ -74,4 +74,4 @@ namespace Discord
|
|||||||
public void Dispose() { Current = null; }
|
public void Dispose() { Current = null; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Discord
|
namespace Discord
|
||||||
{
|
{
|
||||||
@@ -119,13 +119,11 @@ namespace Discord
|
|||||||
resolvedPermissions = mask; //Owners and administrators always have all permissions
|
resolvedPermissions = mask; //Owners and administrators always have all permissions
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OverwritePermissions? perms;
|
|
||||||
|
|
||||||
//Start with this user's guild permissions
|
//Start with this user's guild permissions
|
||||||
resolvedPermissions = guildPermissions;
|
resolvedPermissions = guildPermissions;
|
||||||
|
|
||||||
//Give/Take Everyone permissions
|
//Give/Take Everyone permissions
|
||||||
perms = channel.GetPermissionOverwrite(guild.EveryoneRole);
|
var perms = channel.GetPermissionOverwrite(guild.EveryoneRole);
|
||||||
if (perms != null)
|
if (perms != null)
|
||||||
resolvedPermissions = (resolvedPermissions & ~perms.Value.DenyValue) | perms.Value.AllowValue;
|
resolvedPermissions = (resolvedPermissions & ~perms.Value.DenyValue) | perms.Value.AllowValue;
|
||||||
|
|
||||||
@@ -133,7 +131,7 @@ namespace Discord
|
|||||||
ulong deniedPermissions = 0UL, allowedPermissions = 0UL;
|
ulong deniedPermissions = 0UL, allowedPermissions = 0UL;
|
||||||
foreach (var roleId in user.RoleIds)
|
foreach (var roleId in user.RoleIds)
|
||||||
{
|
{
|
||||||
IRole role = null;
|
IRole role;
|
||||||
if (roleId != guild.EveryoneRole.Id && (role = guild.GetRole(roleId)) != null)
|
if (roleId != guild.EveryoneRole.Id && (role = guild.GetRole(roleId)) != null)
|
||||||
{
|
{
|
||||||
perms = channel.GetPermissionOverwrite(role);
|
perms = channel.GetPermissionOverwrite(role);
|
||||||
@@ -151,7 +149,7 @@ namespace Discord
|
|||||||
if (perms != null)
|
if (perms != null)
|
||||||
resolvedPermissions = (resolvedPermissions & ~perms.Value.DenyValue) | perms.Value.AllowValue;
|
resolvedPermissions = (resolvedPermissions & ~perms.Value.DenyValue) | perms.Value.AllowValue;
|
||||||
|
|
||||||
if (channel is ITextChannel textChannel)
|
if (channel is ITextChannel)
|
||||||
{
|
{
|
||||||
if (!GetValue(resolvedPermissions, ChannelPermission.ViewChannel))
|
if (!GetValue(resolvedPermissions, ChannelPermission.ViewChannel))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Discord
|
namespace Discord
|
||||||
{
|
{
|
||||||
@@ -198,7 +198,7 @@ namespace Discord
|
|||||||
for (var i = 0; i < roles.Length; i++)
|
for (var i = 0; i < roles.Length; i++)
|
||||||
{
|
{
|
||||||
if (roles[i] == guildId)
|
if (roles[i] == guildId)
|
||||||
throw new ArgumentException($"The everyone role cannot be assigned to a user", name);
|
throw new ArgumentException("The everyone role cannot be assigned to a user", name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ namespace Discord.Rest
|
|||||||
await OnLoginAsync(tokenType, token).ConfigureAwait(false);
|
await OnLoginAsync(tokenType, token).ConfigureAwait(false);
|
||||||
LoginState = LoginState.LoggedIn;
|
LoginState = LoginState.LoggedIn;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch
|
||||||
{
|
{
|
||||||
await LogoutInternalAsync().ConfigureAwait(false);
|
await LogoutInternalAsync().ConfigureAwait(false);
|
||||||
throw;
|
throw;
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ namespace Discord.Rest
|
|||||||
public static async Task<IReadOnlyCollection<RestConnection>> GetConnectionsAsync(BaseDiscordClient client, RequestOptions options)
|
public static async Task<IReadOnlyCollection<RestConnection>> GetConnectionsAsync(BaseDiscordClient client, RequestOptions options)
|
||||||
{
|
{
|
||||||
var models = await client.ApiClient.GetMyConnectionsAsync(options).ConfigureAwait(false);
|
var models = await client.ApiClient.GetMyConnectionsAsync(options).ConfigureAwait(false);
|
||||||
return models.Select(x => RestConnection.Create(x)).ToImmutableArray();
|
return models.Select(RestConnection.Create).ToImmutableArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<RestInviteMetadata> GetInviteAsync(BaseDiscordClient client,
|
public static async Task<RestInviteMetadata> GetInviteAsync(BaseDiscordClient client,
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ namespace Discord.API
|
|||||||
|
|
||||||
LoginState = LoginState.LoggedIn;
|
LoginState = LoginState.LoggedIn;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch
|
||||||
{
|
{
|
||||||
await LogoutInternalAsync().ConfigureAwait(false);
|
await LogoutInternalAsync().ConfigureAwait(false);
|
||||||
throw;
|
throw;
|
||||||
@@ -1394,9 +1394,9 @@ namespace Discord.API
|
|||||||
|
|
||||||
int argId = int.Parse(format.Substring(leftIndex + 1, rightIndex - leftIndex - 1));
|
int argId = int.Parse(format.Substring(leftIndex + 1, rightIndex - leftIndex - 1));
|
||||||
string fieldName = GetFieldName(methodArgs[argId + 1]);
|
string fieldName = GetFieldName(methodArgs[argId + 1]);
|
||||||
int? mappedId;
|
|
||||||
|
|
||||||
mappedId = BucketIds.GetIndex(fieldName);
|
var mappedId = BucketIds.GetIndex(fieldName);
|
||||||
|
|
||||||
if(!mappedId.HasValue && rightIndex != endIndex && format.Length > rightIndex + 1 && format[rightIndex + 1] == '/') //Ignore the next slash
|
if(!mappedId.HasValue && rightIndex != endIndex && format.Length > rightIndex + 1 && format[rightIndex + 1] == '/') //Ignore the next slash
|
||||||
rightIndex++;
|
rightIndex++;
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ using Model = Discord.API.Channel;
|
|||||||
namespace Discord.Rest
|
namespace Discord.Rest
|
||||||
{
|
{
|
||||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
||||||
public class RestDMChannel : RestChannel, IDMChannel, IRestPrivateChannel, IRestMessageChannel, IUpdateable
|
public class RestDMChannel : RestChannel, IDMChannel, IRestPrivateChannel, IRestMessageChannel
|
||||||
{
|
{
|
||||||
public RestUser CurrentUser { get; private set; }
|
public RestUser CurrentUser { get; private set; }
|
||||||
public RestUser Recipient { get; private set; }
|
public RestUser Recipient { get; private set; }
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ using Model = Discord.API.Channel;
|
|||||||
namespace Discord.Rest
|
namespace Discord.Rest
|
||||||
{
|
{
|
||||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
||||||
public class RestGroupChannel : RestChannel, IGroupChannel, IRestPrivateChannel, IRestMessageChannel, IRestAudioChannel, IUpdateable
|
public class RestGroupChannel : RestChannel, IGroupChannel, IRestPrivateChannel, IRestMessageChannel, IRestAudioChannel
|
||||||
{
|
{
|
||||||
private string _iconId;
|
private string _iconId;
|
||||||
private ImmutableDictionary<ulong, RestGroupUser> _users;
|
private ImmutableDictionary<ulong, RestGroupUser> _users;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using Model = Discord.API.Channel;
|
|||||||
|
|
||||||
namespace Discord.Rest
|
namespace Discord.Rest
|
||||||
{
|
{
|
||||||
public class RestGuildChannel : RestChannel, IGuildChannel, IUpdateable
|
public class RestGuildChannel : RestChannel, IGuildChannel
|
||||||
{
|
{
|
||||||
private ImmutableArray<Overwrite> _overwrites;
|
private ImmutableArray<Overwrite> _overwrites;
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ namespace Discord.Rest
|
|||||||
public async Task<IReadOnlyCollection<RestTextChannel>> GetTextChannelsAsync(RequestOptions options = null)
|
public async Task<IReadOnlyCollection<RestTextChannel>> GetTextChannelsAsync(RequestOptions options = null)
|
||||||
{
|
{
|
||||||
var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false);
|
var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false);
|
||||||
return channels.Select(x => x as RestTextChannel).Where(x => x != null).ToImmutableArray();
|
return channels.OfType<RestTextChannel>().ToImmutableArray();
|
||||||
}
|
}
|
||||||
public async Task<RestVoiceChannel> GetVoiceChannelAsync(ulong id, RequestOptions options = null)
|
public async Task<RestVoiceChannel> GetVoiceChannelAsync(ulong id, RequestOptions options = null)
|
||||||
{
|
{
|
||||||
@@ -178,12 +178,12 @@ namespace Discord.Rest
|
|||||||
public async Task<IReadOnlyCollection<RestVoiceChannel>> GetVoiceChannelsAsync(RequestOptions options = null)
|
public async Task<IReadOnlyCollection<RestVoiceChannel>> GetVoiceChannelsAsync(RequestOptions options = null)
|
||||||
{
|
{
|
||||||
var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false);
|
var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false);
|
||||||
return channels.Select(x => x as RestVoiceChannel).Where(x => x != null).ToImmutableArray();
|
return channels.OfType<RestVoiceChannel>().ToImmutableArray();
|
||||||
}
|
}
|
||||||
public async Task<IReadOnlyCollection<RestCategoryChannel>> GetCategoryChannelsAsync(RequestOptions options = null)
|
public async Task<IReadOnlyCollection<RestCategoryChannel>> GetCategoryChannelsAsync(RequestOptions options = null)
|
||||||
{
|
{
|
||||||
var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false);
|
var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false);
|
||||||
return channels.Select(x => x as RestCategoryChannel).Where(x => x != null).ToImmutableArray();
|
return channels.OfType<RestCategoryChannel>().ToImmutableArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RestVoiceChannel> GetAFKChannelAsync(RequestOptions options = null)
|
public async Task<RestVoiceChannel> GetAFKChannelAsync(RequestOptions options = null)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Model = Discord.API.UserGuild;
|
using Model = Discord.API.UserGuild;
|
||||||
@@ -6,7 +6,7 @@ using Model = Discord.API.UserGuild;
|
|||||||
namespace Discord.Rest
|
namespace Discord.Rest
|
||||||
{
|
{
|
||||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
||||||
public class RestUserGuild : RestEntity<ulong>, ISnowflakeEntity, IUserGuild
|
public class RestUserGuild : RestEntity<ulong>, IUserGuild
|
||||||
{
|
{
|
||||||
private string _iconId;
|
private string _iconId;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -9,7 +9,7 @@ using Model = Discord.API.GuildMember;
|
|||||||
namespace Discord.Rest
|
namespace Discord.Rest
|
||||||
{
|
{
|
||||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
||||||
public class RestGuildUser : RestUser, IGuildUser, IUpdateable
|
public class RestGuildUser : RestUser, IGuildUser
|
||||||
{
|
{
|
||||||
private long? _joinedAtTicks;
|
private long? _joinedAtTicks;
|
||||||
private ImmutableArray<ulong> _roleIds;
|
private ImmutableArray<ulong> _roleIds;
|
||||||
|
|||||||
@@ -131,14 +131,14 @@ namespace Discord.Net.Rest
|
|||||||
return new RestResponse(response.StatusCode, headers, stream);
|
return new RestResponse(response.StatusCode, headers, stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly HttpMethod _patch = new HttpMethod("PATCH");
|
private static readonly HttpMethod Patch = new HttpMethod("PATCH");
|
||||||
private HttpMethod GetMethod(string method)
|
private HttpMethod GetMethod(string method)
|
||||||
{
|
{
|
||||||
switch (method)
|
switch (method)
|
||||||
{
|
{
|
||||||
case "DELETE": return HttpMethod.Delete;
|
case "DELETE": return HttpMethod.Delete;
|
||||||
case "GET": return HttpMethod.Get;
|
case "GET": return HttpMethod.Get;
|
||||||
case "PATCH": return _patch;
|
case "PATCH": return Patch;
|
||||||
case "POST": return HttpMethod.Post;
|
case "POST": return HttpMethod.Post;
|
||||||
case "PUT": return HttpMethod.Put;
|
case "PUT": return HttpMethod.Put;
|
||||||
default: throw new ArgumentOutOfRangeException(nameof(method), $"Unknown HttpMethod: {method}");
|
default: throw new ArgumentOutOfRangeException(nameof(method), $"Unknown HttpMethod: {method}");
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
|
|
||||||
namespace Discord.Net.Queue
|
namespace Discord.Net.Queue
|
||||||
{
|
{
|
||||||
@@ -9,8 +9,8 @@ namespace Discord.Net.Queue
|
|||||||
}
|
}
|
||||||
internal struct ClientBucket
|
internal struct ClientBucket
|
||||||
{
|
{
|
||||||
private static readonly ImmutableDictionary<ClientBucketType, ClientBucket> _defsByType;
|
private static readonly ImmutableDictionary<ClientBucketType, ClientBucket> DefsByType;
|
||||||
private static readonly ImmutableDictionary<string, ClientBucket> _defsById;
|
private static readonly ImmutableDictionary<string, ClientBucket> DefsById;
|
||||||
|
|
||||||
static ClientBucket()
|
static ClientBucket()
|
||||||
{
|
{
|
||||||
@@ -23,16 +23,16 @@ namespace Discord.Net.Queue
|
|||||||
var builder = ImmutableDictionary.CreateBuilder<ClientBucketType, ClientBucket>();
|
var builder = ImmutableDictionary.CreateBuilder<ClientBucketType, ClientBucket>();
|
||||||
foreach (var bucket in buckets)
|
foreach (var bucket in buckets)
|
||||||
builder.Add(bucket.Type, bucket);
|
builder.Add(bucket.Type, bucket);
|
||||||
_defsByType = builder.ToImmutable();
|
DefsByType = builder.ToImmutable();
|
||||||
|
|
||||||
var builder2 = ImmutableDictionary.CreateBuilder<string, ClientBucket>();
|
var builder2 = ImmutableDictionary.CreateBuilder<string, ClientBucket>();
|
||||||
foreach (var bucket in buckets)
|
foreach (var bucket in buckets)
|
||||||
builder2.Add(bucket.Id, bucket);
|
builder2.Add(bucket.Id, bucket);
|
||||||
_defsById = builder2.ToImmutable();
|
DefsById = builder2.ToImmutable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ClientBucket Get(ClientBucketType type) => _defsByType[type];
|
public static ClientBucket Get(ClientBucketType type) => DefsByType[type];
|
||||||
public static ClientBucket Get(string id) => _defsById[id];
|
public static ClientBucket Get(string id) => DefsById[id];
|
||||||
|
|
||||||
public ClientBucketType Type { get; }
|
public ClientBucketType Type { get; }
|
||||||
public string Id { get; }
|
public string Id { get; }
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
#if DEBUG_LIMITS
|
#if DEBUG_LIMITS
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -16,10 +16,10 @@ namespace Discord.Net.Queue
|
|||||||
|
|
||||||
private readonly ConcurrentDictionary<string, RequestBucket> _buckets;
|
private readonly ConcurrentDictionary<string, RequestBucket> _buckets;
|
||||||
private readonly SemaphoreSlim _tokenLock;
|
private readonly SemaphoreSlim _tokenLock;
|
||||||
|
private readonly CancellationTokenSource _cancelToken; //Dispose token
|
||||||
private CancellationTokenSource _clearToken;
|
private CancellationTokenSource _clearToken;
|
||||||
private CancellationToken _parentToken;
|
private CancellationToken _parentToken;
|
||||||
private CancellationToken _requestCancelToken; //Parent token + Clear token
|
private CancellationToken _requestCancelToken; //Parent token + Clear token
|
||||||
private CancellationTokenSource _cancelToken; //Dispose token
|
|
||||||
private DateTimeOffset _waitUntil;
|
private DateTimeOffset _waitUntil;
|
||||||
|
|
||||||
private Task _cleanupTask;
|
private Task _cleanupTask;
|
||||||
@@ -115,7 +115,7 @@ namespace Discord.Net.Queue
|
|||||||
foreach (var bucket in _buckets.Select(x => x.Value))
|
foreach (var bucket in _buckets.Select(x => x.Value))
|
||||||
{
|
{
|
||||||
if ((now - bucket.LastAttemptAt).TotalMinutes > 1.0)
|
if ((now - bucket.LastAttemptAt).TotalMinutes > 1.0)
|
||||||
_buckets.TryRemove(bucket.Id, out RequestBucket ignored);
|
_buckets.TryRemove(bucket.Id, out _);
|
||||||
}
|
}
|
||||||
await Task.Delay(60000, _cancelToken.Token); //Runs each minute
|
await Task.Delay(60000, _cancelToken.Token); //Runs each minute
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Discord.Net
|
|||||||
internal RateLimitInfo(Dictionary<string, string> headers)
|
internal RateLimitInfo(Dictionary<string, string> headers)
|
||||||
{
|
{
|
||||||
IsGlobal = headers.TryGetValue("X-RateLimit-Global", out string temp) &&
|
IsGlobal = headers.TryGetValue("X-RateLimit-Global", out string temp) &&
|
||||||
bool.TryParse(temp, out var isGlobal) ? isGlobal : false;
|
bool.TryParse(temp, out var isGlobal) && isGlobal;
|
||||||
Limit = headers.TryGetValue("X-RateLimit-Limit", out temp) &&
|
Limit = headers.TryGetValue("X-RateLimit-Limit", out temp) &&
|
||||||
int.TryParse(temp, out var limit) ? limit : (int?)null;
|
int.TryParse(temp, out var limit) ? limit : (int?)null;
|
||||||
Remaining = headers.TryGetValue("X-RateLimit-Remaining", out temp) &&
|
Remaining = headers.TryGetValue("X-RateLimit-Remaining", out temp) &&
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ using System.Collections.Generic;
|
|||||||
namespace Discord.Audio
|
namespace Discord.Audio
|
||||||
{
|
{
|
||||||
//TODO: Add audio reconnecting
|
//TODO: Add audio reconnecting
|
||||||
internal partial class AudioClient : IAudioClient, IDisposable
|
internal partial class AudioClient : IAudioClient
|
||||||
{
|
{
|
||||||
internal struct StreamPair
|
internal struct StreamPair
|
||||||
{
|
{
|
||||||
@@ -65,7 +65,7 @@ namespace Discord.Audio
|
|||||||
|
|
||||||
ApiClient = new DiscordVoiceAPIClient(guild.Id, Discord.WebSocketProvider, Discord.UdpSocketProvider);
|
ApiClient = new DiscordVoiceAPIClient(guild.Id, Discord.WebSocketProvider, Discord.UdpSocketProvider);
|
||||||
ApiClient.SentGatewayMessage += async opCode => await _audioLogger.DebugAsync($"Sent {opCode}").ConfigureAwait(false);
|
ApiClient.SentGatewayMessage += async opCode => await _audioLogger.DebugAsync($"Sent {opCode}").ConfigureAwait(false);
|
||||||
ApiClient.SentDiscovery += async () => await _audioLogger.DebugAsync($"Sent Discovery").ConfigureAwait(false);
|
ApiClient.SentDiscovery += async () => await _audioLogger.DebugAsync("Sent Discovery").ConfigureAwait(false);
|
||||||
//ApiClient.SentData += async bytes => await _audioLogger.DebugAsync($"Sent {bytes} Bytes").ConfigureAwait(false);
|
//ApiClient.SentData += async bytes => await _audioLogger.DebugAsync($"Sent {bytes} Bytes").ConfigureAwait(false);
|
||||||
ApiClient.ReceivedEvent += ProcessMessageAsync;
|
ApiClient.ReceivedEvent += ProcessMessageAsync;
|
||||||
ApiClient.ReceivedPacket += ProcessPacketAsync;
|
ApiClient.ReceivedPacket += ProcessPacketAsync;
|
||||||
@@ -131,7 +131,7 @@ namespace Discord.Audio
|
|||||||
await keepaliveTask.ConfigureAwait(false);
|
await keepaliveTask.ConfigureAwait(false);
|
||||||
_keepaliveTask = null;
|
_keepaliveTask = null;
|
||||||
|
|
||||||
while (_heartbeatTimes.TryDequeue(out long time)) { }
|
while (_heartbeatTimes.TryDequeue(out _)) { }
|
||||||
_lastMessageTime = 0;
|
_lastMessageTime = 0;
|
||||||
|
|
||||||
await ClearInputStreamsAsync().ConfigureAwait(false);
|
await ClearInputStreamsAsync().ConfigureAwait(false);
|
||||||
@@ -292,7 +292,7 @@ namespace Discord.Audio
|
|||||||
{
|
{
|
||||||
if (packet.Length != 70)
|
if (packet.Length != 70)
|
||||||
{
|
{
|
||||||
await _audioLogger.DebugAsync($"Malformed Packet").ConfigureAwait(false);
|
await _audioLogger.DebugAsync("Malformed Packet").ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
string ip;
|
string ip;
|
||||||
@@ -304,7 +304,7 @@ namespace Discord.Audio
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
await _audioLogger.DebugAsync($"Malformed Packet", ex).ConfigureAwait(false);
|
await _audioLogger.DebugAsync("Malformed Packet", ex).ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,7 +331,7 @@ namespace Discord.Audio
|
|||||||
{
|
{
|
||||||
if (pair.Key == value)
|
if (pair.Key == value)
|
||||||
{
|
{
|
||||||
int latency = (int)(Environment.TickCount - pair.Value);
|
int latency = Environment.TickCount - pair.Value;
|
||||||
int before = UdpLatency;
|
int before = UdpLatency;
|
||||||
UdpLatency = latency;
|
UdpLatency = latency;
|
||||||
|
|
||||||
@@ -344,7 +344,7 @@ namespace Discord.Audio
|
|||||||
{
|
{
|
||||||
if (!RTPReadStream.TryReadSsrc(packet, 0, out var ssrc))
|
if (!RTPReadStream.TryReadSsrc(packet, 0, out var ssrc))
|
||||||
{
|
{
|
||||||
await _audioLogger.DebugAsync($"Malformed Frame").ConfigureAwait(false);
|
await _audioLogger.DebugAsync("Malformed Frame").ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!_ssrcMap.TryGetValue(ssrc, out var userId))
|
if (!_ssrcMap.TryGetValue(ssrc, out var userId))
|
||||||
@@ -363,7 +363,7 @@ namespace Discord.Audio
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
await _audioLogger.DebugAsync($"Malformed Frame", ex).ConfigureAwait(false);
|
await _audioLogger.DebugAsync("Malformed Frame", ex).ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//await _audioLogger.DebugAsync($"Received {packet.Length} bytes from user {userId}").ConfigureAwait(false);
|
//await _audioLogger.DebugAsync($"Received {packet.Length} bytes from user {userId}").ConfigureAwait(false);
|
||||||
@@ -372,7 +372,7 @@ namespace Discord.Audio
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
await _audioLogger.WarningAsync($"Failed to process UDP packet", ex).ConfigureAwait(false);
|
await _audioLogger.WarningAsync("Failed to process UDP packet", ex).ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ namespace Discord.Audio.Streams
|
|||||||
timestamp += OpusEncoder.FrameSamplesPerChannel;
|
timestamp += OpusEncoder.FrameSamplesPerChannel;
|
||||||
}
|
}
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
var _ = _logger?.DebugAsync($"Buffer underrun");
|
var _ = _logger?.DebugAsync("Buffer underrun");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,7 +140,7 @@ namespace Discord.Audio.Streams
|
|||||||
if (!_bufferPool.TryDequeue(out byte[] buffer))
|
if (!_bufferPool.TryDequeue(out byte[] buffer))
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
var _ = _logger?.DebugAsync($"Buffer overflow"); //Should never happen because of the queueLock
|
var _ = _logger?.DebugAsync("Buffer overflow"); //Should never happen because of the queueLock
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -149,7 +149,7 @@ namespace Discord.Audio.Streams
|
|||||||
if (!_isPreloaded && _queuedFrames.Count == _queueLength)
|
if (!_isPreloaded && _queuedFrames.Count == _queueLength)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
var _ = _logger?.DebugAsync($"Preloaded");
|
var _ = _logger?.DebugAsync("Preloaded");
|
||||||
#endif
|
#endif
|
||||||
_isPreloaded = true;
|
_isPreloaded = true;
|
||||||
}
|
}
|
||||||
@@ -169,8 +169,8 @@ namespace Discord.Audio.Streams
|
|||||||
{
|
{
|
||||||
do
|
do
|
||||||
cancelToken.ThrowIfCancellationRequested();
|
cancelToken.ThrowIfCancellationRequested();
|
||||||
while (_queuedFrames.TryDequeue(out Frame ignored));
|
while (_queuedFrames.TryDequeue(out _));
|
||||||
return Task.Delay(0);
|
return Task.Delay(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -72,7 +72,7 @@ namespace Discord.WebSocket
|
|||||||
switch (channel)
|
switch (channel)
|
||||||
{
|
{
|
||||||
case SocketDMChannel dmChannel:
|
case SocketDMChannel dmChannel:
|
||||||
_dmChannels.TryRemove(dmChannel.Recipient.Id, out var ignored);
|
_dmChannels.TryRemove(dmChannel.Recipient.Id, out _);
|
||||||
break;
|
break;
|
||||||
case SocketGroupChannel groupChannel:
|
case SocketGroupChannel groupChannel:
|
||||||
_groupChannels.TryRemove(id);
|
_groupChannels.TryRemove(id);
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ namespace Discord.WebSocket
|
|||||||
{
|
{
|
||||||
private readonly DiscordSocketConfig _baseConfig;
|
private readonly DiscordSocketConfig _baseConfig;
|
||||||
private readonly SemaphoreSlim _connectionGroupLock;
|
private readonly SemaphoreSlim _connectionGroupLock;
|
||||||
|
private readonly Dictionary<int, int> _shardIdsToIndex;
|
||||||
|
private readonly bool _automaticShards;
|
||||||
private int[] _shardIds;
|
private int[] _shardIds;
|
||||||
private Dictionary<int, int> _shardIdsToIndex;
|
|
||||||
private DiscordSocketClient[] _shards;
|
private DiscordSocketClient[] _shards;
|
||||||
private int _totalShards;
|
private int _totalShards;
|
||||||
private bool _automaticShards;
|
|
||||||
|
|
||||||
/// <summary> Gets the estimated round-trip latency, in milliseconds, to the gateway server. </summary>
|
/// <summary> Gets the estimated round-trip latency, in milliseconds, to the gateway server. </summary>
|
||||||
public override int Latency { get => GetLatency(); protected set { } }
|
public override int Latency { get => GetLatency(); protected set { } }
|
||||||
@@ -25,8 +25,8 @@ namespace Discord.WebSocket
|
|||||||
public override IActivity Activity { get => _shards[0].Activity; protected set { } }
|
public override IActivity Activity { get => _shards[0].Activity; protected set { } }
|
||||||
|
|
||||||
internal new DiscordSocketApiClient ApiClient => base.ApiClient as DiscordSocketApiClient;
|
internal new DiscordSocketApiClient ApiClient => base.ApiClient as DiscordSocketApiClient;
|
||||||
public override IReadOnlyCollection<SocketGuild> Guilds => GetGuilds().ToReadOnlyCollection(() => GetGuildCount());
|
public override IReadOnlyCollection<SocketGuild> Guilds => GetGuilds().ToReadOnlyCollection(GetGuildCount);
|
||||||
public override IReadOnlyCollection<ISocketPrivateChannel> PrivateChannels => GetPrivateChannels().ToReadOnlyCollection(() => GetPrivateChannelCount());
|
public override IReadOnlyCollection<ISocketPrivateChannel> PrivateChannels => GetPrivateChannels().ToReadOnlyCollection(GetPrivateChannelCount);
|
||||||
public IReadOnlyCollection<DiscordSocketClient> Shards => _shards;
|
public IReadOnlyCollection<DiscordSocketClient> Shards => _shards;
|
||||||
public override IReadOnlyCollection<RestVoiceRegion> VoiceRegions => _shards[0].VoiceRegions;
|
public override IReadOnlyCollection<RestVoiceRegion> VoiceRegions => _shards[0].VoiceRegions;
|
||||||
|
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ namespace Discord.API
|
|||||||
public event Func<Exception, Task> Disconnected { add { _disconnectedEvent.Add(value); } remove { _disconnectedEvent.Remove(value); } }
|
public event Func<Exception, Task> Disconnected { add { _disconnectedEvent.Add(value); } remove { _disconnectedEvent.Remove(value); } }
|
||||||
private readonly AsyncEvent<Func<Exception, Task>> _disconnectedEvent = new AsyncEvent<Func<Exception, Task>>();
|
private readonly AsyncEvent<Func<Exception, Task>> _disconnectedEvent = new AsyncEvent<Func<Exception, Task>>();
|
||||||
|
|
||||||
|
private readonly bool _isExplicitUrl;
|
||||||
private CancellationTokenSource _connectCancelToken;
|
private CancellationTokenSource _connectCancelToken;
|
||||||
private string _gatewayUrl;
|
private string _gatewayUrl;
|
||||||
private bool _isExplicitUrl;
|
|
||||||
|
|
||||||
//Store our decompression streams for zlib shared state
|
//Store our decompression streams for zlib shared state
|
||||||
private MemoryStream _compressed;
|
private MemoryStream _compressed;
|
||||||
|
|||||||
@@ -63,9 +63,9 @@ namespace Discord.WebSocket
|
|||||||
public override IReadOnlyCollection<SocketGuild> Guilds => State.Guilds;
|
public override IReadOnlyCollection<SocketGuild> Guilds => State.Guilds;
|
||||||
public override IReadOnlyCollection<ISocketPrivateChannel> PrivateChannels => State.PrivateChannels;
|
public override IReadOnlyCollection<ISocketPrivateChannel> PrivateChannels => State.PrivateChannels;
|
||||||
public IReadOnlyCollection<SocketDMChannel> DMChannels
|
public IReadOnlyCollection<SocketDMChannel> DMChannels
|
||||||
=> State.PrivateChannels.Select(x => x as SocketDMChannel).Where(x => x != null).ToImmutableArray();
|
=> State.PrivateChannels.OfType<SocketDMChannel>().ToImmutableArray();
|
||||||
public IReadOnlyCollection<SocketGroupChannel> GroupChannels
|
public IReadOnlyCollection<SocketGroupChannel> GroupChannels
|
||||||
=> State.PrivateChannels.Select(x => x as SocketGroupChannel).Where(x => x != null).ToImmutableArray();
|
=> State.PrivateChannels.OfType<SocketGroupChannel>().ToImmutableArray();
|
||||||
public override IReadOnlyCollection<RestVoiceRegion> VoiceRegions => _voiceRegions.ToReadOnlyCollection();
|
public override IReadOnlyCollection<RestVoiceRegion> VoiceRegions => _voiceRegions.ToReadOnlyCollection();
|
||||||
|
|
||||||
/// <summary> Creates a new REST/WebSocket discord client. </summary>
|
/// <summary> Creates a new REST/WebSocket discord client. </summary>
|
||||||
@@ -207,7 +207,7 @@ namespace Discord.WebSocket
|
|||||||
await heartbeatTask.ConfigureAwait(false);
|
await heartbeatTask.ConfigureAwait(false);
|
||||||
_heartbeatTask = null;
|
_heartbeatTask = null;
|
||||||
|
|
||||||
while (_heartbeatTimes.TryDequeue(out long time)) { }
|
while (_heartbeatTimes.TryDequeue(out _)) { }
|
||||||
_lastMessageTime = 0;
|
_lastMessageTime = 0;
|
||||||
|
|
||||||
await _gatewayLogger.DebugAsync("Waiting for guild downloader").ConfigureAwait(false);
|
await _gatewayLogger.DebugAsync("Waiting for guild downloader").ConfigureAwait(false);
|
||||||
@@ -218,7 +218,7 @@ namespace Discord.WebSocket
|
|||||||
|
|
||||||
//Clear large guild queue
|
//Clear large guild queue
|
||||||
await _gatewayLogger.DebugAsync("Clearing large guild queue").ConfigureAwait(false);
|
await _gatewayLogger.DebugAsync("Clearing large guild queue").ConfigureAwait(false);
|
||||||
while (_largeGuilds.TryDequeue(out ulong guildId)) { }
|
while (_largeGuilds.TryDequeue(out _)) { }
|
||||||
|
|
||||||
//Raise virtual GUILD_UNAVAILABLEs
|
//Raise virtual GUILD_UNAVAILABLEs
|
||||||
await _gatewayLogger.DebugAsync("Raising virtual GuildUnavailables").ConfigureAwait(false);
|
await _gatewayLogger.DebugAsync("Raising virtual GuildUnavailables").ConfigureAwait(false);
|
||||||
@@ -351,7 +351,7 @@ namespace Discord.WebSocket
|
|||||||
|
|
||||||
var gameModel = new GameModel();
|
var gameModel = new GameModel();
|
||||||
// Discord only accepts rich presence over RPC, don't even bother building a payload
|
// Discord only accepts rich presence over RPC, don't even bother building a payload
|
||||||
if (Activity is RichGame game)
|
if (Activity is RichGame)
|
||||||
throw new NotSupportedException("Outgoing Rich Presences are not supported");
|
throw new NotSupportedException("Outgoing Rich Presences are not supported");
|
||||||
|
|
||||||
if (Activity != null)
|
if (Activity != null)
|
||||||
@@ -508,7 +508,7 @@ namespace Discord.WebSocket
|
|||||||
{
|
{
|
||||||
type = "GUILD_AVAILABLE";
|
type = "GUILD_AVAILABLE";
|
||||||
_lastGuildAvailableTime = Environment.TickCount;
|
_lastGuildAvailableTime = Environment.TickCount;
|
||||||
await _gatewayLogger.DebugAsync($"Received Dispatch (GUILD_AVAILABLE)").ConfigureAwait(false);
|
await _gatewayLogger.DebugAsync("Received Dispatch (GUILD_AVAILABLE)").ConfigureAwait(false);
|
||||||
|
|
||||||
var guild = State.GetGuild(data.Id);
|
var guild = State.GetGuild(data.Id);
|
||||||
if (guild != null)
|
if (guild != null)
|
||||||
@@ -533,7 +533,7 @@ namespace Discord.WebSocket
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await _gatewayLogger.DebugAsync($"Received Dispatch (GUILD_CREATE)").ConfigureAwait(false);
|
await _gatewayLogger.DebugAsync("Received Dispatch (GUILD_CREATE)").ConfigureAwait(false);
|
||||||
|
|
||||||
var guild = AddGuild(data, State);
|
var guild = AddGuild(data, State);
|
||||||
if (guild != null)
|
if (guild != null)
|
||||||
@@ -614,7 +614,7 @@ namespace Discord.WebSocket
|
|||||||
if (data.Unavailable == true)
|
if (data.Unavailable == true)
|
||||||
{
|
{
|
||||||
type = "GUILD_UNAVAILABLE";
|
type = "GUILD_UNAVAILABLE";
|
||||||
await _gatewayLogger.DebugAsync($"Received Dispatch (GUILD_UNAVAILABLE)").ConfigureAwait(false);
|
await _gatewayLogger.DebugAsync("Received Dispatch (GUILD_UNAVAILABLE)").ConfigureAwait(false);
|
||||||
|
|
||||||
var guild = State.GetGuild(data.Id);
|
var guild = State.GetGuild(data.Id);
|
||||||
if (guild != null)
|
if (guild != null)
|
||||||
@@ -630,7 +630,7 @@ namespace Discord.WebSocket
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await _gatewayLogger.DebugAsync($"Received Dispatch (GUILD_DELETE)").ConfigureAwait(false);
|
await _gatewayLogger.DebugAsync("Received Dispatch (GUILD_DELETE)").ConfigureAwait(false);
|
||||||
|
|
||||||
var guild = RemoveGuild(data.Id);
|
var guild = RemoveGuild(data.Id);
|
||||||
if (guild != null)
|
if (guild != null)
|
||||||
@@ -1626,7 +1626,7 @@ namespace Discord.WebSocket
|
|||||||
var guild = State.RemoveGuild(id);
|
var guild = State.RemoveGuild(id);
|
||||||
if (guild != null)
|
if (guild != null)
|
||||||
{
|
{
|
||||||
foreach (var channel in guild.Channels)
|
foreach (var _ in guild.Channels)
|
||||||
State.RemoveChannel(id);
|
State.RemoveChannel(id);
|
||||||
foreach (var user in guild.Users)
|
foreach (var user in guild.Users)
|
||||||
user.GlobalUser.RemoveRef(this);
|
user.GlobalUser.RemoveRef(this);
|
||||||
@@ -1679,7 +1679,7 @@ namespace Discord.WebSocket
|
|||||||
if (eventHandler.HasSubscribers)
|
if (eventHandler.HasSubscribers)
|
||||||
{
|
{
|
||||||
if (HandlerTimeout.HasValue)
|
if (HandlerTimeout.HasValue)
|
||||||
await TimeoutWrap(name, () => eventHandler.InvokeAsync()).ConfigureAwait(false);
|
await TimeoutWrap(name, eventHandler.InvokeAsync).ConfigureAwait(false);
|
||||||
else
|
else
|
||||||
await eventHandler.InvokeAsync().ConfigureAwait(false);
|
await eventHandler.InvokeAsync().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ namespace Discord.Audio
|
|||||||
|
|
||||||
private readonly JsonSerializer _serializer;
|
private readonly JsonSerializer _serializer;
|
||||||
private readonly SemaphoreSlim _connectionLock;
|
private readonly SemaphoreSlim _connectionLock;
|
||||||
|
private readonly IUdpSocket _udp;
|
||||||
private CancellationTokenSource _connectCancelToken;
|
private CancellationTokenSource _connectCancelToken;
|
||||||
private IUdpSocket _udp;
|
|
||||||
private bool _isDisposed;
|
private bool _isDisposed;
|
||||||
private ulong _nextKeepalive;
|
private ulong _nextKeepalive;
|
||||||
|
|
||||||
@@ -188,7 +188,7 @@ namespace Discord.Audio
|
|||||||
|
|
||||||
ConnectionState = ConnectionState.Connected;
|
ConnectionState = ConnectionState.Connected;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch
|
||||||
{
|
{
|
||||||
await DisconnectInternalAsync().ConfigureAwait(false);
|
await DisconnectInternalAsync().ConfigureAwait(false);
|
||||||
throw;
|
throw;
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ namespace Discord.WebSocket
|
|||||||
if (id == Recipient.Id)
|
if (id == Recipient.Id)
|
||||||
return Recipient;
|
return Recipient;
|
||||||
else if (id == Discord.CurrentUser.Id)
|
else if (id == Discord.CurrentUser.Id)
|
||||||
return Discord.CurrentUser as SocketSelfUser;
|
return Discord.CurrentUser;
|
||||||
else
|
else
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ namespace Discord.WebSocket
|
|||||||
public class SocketGroupChannel : SocketChannel, IGroupChannel, ISocketPrivateChannel, ISocketMessageChannel, ISocketAudioChannel
|
public class SocketGroupChannel : SocketChannel, IGroupChannel, ISocketPrivateChannel, ISocketMessageChannel, ISocketAudioChannel
|
||||||
{
|
{
|
||||||
private readonly MessageCache _messages;
|
private readonly MessageCache _messages;
|
||||||
|
private readonly ConcurrentDictionary<ulong, SocketVoiceState> _voiceStates;
|
||||||
|
|
||||||
private string _iconId;
|
private string _iconId;
|
||||||
private ConcurrentDictionary<ulong, SocketGroupUser> _users;
|
private ConcurrentDictionary<ulong, SocketGroupUser> _users;
|
||||||
private ConcurrentDictionary<ulong, SocketVoiceState> _voiceStates;
|
|
||||||
|
|
||||||
public string Name { get; private set; }
|
public string Name { get; private set; }
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ namespace Discord.WebSocket
|
|||||||
internal SocketGroupUser GetOrAddUser(UserModel model)
|
internal SocketGroupUser GetOrAddUser(UserModel model)
|
||||||
{
|
{
|
||||||
if (_users.TryGetValue(model.Id, out SocketGroupUser user))
|
if (_users.TryGetValue(model.Id, out SocketGroupUser user))
|
||||||
return user as SocketGroupUser;
|
return user;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var privateUser = SocketGroupUser.Create(this, Discord.State, model);
|
var privateUser = SocketGroupUser.Create(this, Discord.State, model);
|
||||||
@@ -143,7 +143,7 @@ namespace Discord.WebSocket
|
|||||||
if (_users.TryRemove(id, out SocketGroupUser user))
|
if (_users.TryRemove(id, out SocketGroupUser user))
|
||||||
{
|
{
|
||||||
user.GlobalUser.RemoveRef(Discord);
|
user.GlobalUser.RemoveRef(Discord);
|
||||||
return user as SocketGroupUser;
|
return user;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,11 +91,11 @@ namespace Discord.WebSocket
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public IReadOnlyCollection<SocketTextChannel> TextChannels
|
public IReadOnlyCollection<SocketTextChannel> TextChannels
|
||||||
=> Channels.Select(x => x as SocketTextChannel).Where(x => x != null).ToImmutableArray();
|
=> Channels.OfType<SocketTextChannel>().ToImmutableArray();
|
||||||
public IReadOnlyCollection<SocketVoiceChannel> VoiceChannels
|
public IReadOnlyCollection<SocketVoiceChannel> VoiceChannels
|
||||||
=> Channels.Select(x => x as SocketVoiceChannel).Where(x => x != null).ToImmutableArray();
|
=> Channels.OfType<SocketVoiceChannel>().ToImmutableArray();
|
||||||
public IReadOnlyCollection<SocketCategoryChannel> CategoryChannels
|
public IReadOnlyCollection<SocketCategoryChannel> CategoryChannels
|
||||||
=> Channels.Select(x => x as SocketCategoryChannel).Where(x => x != null).ToImmutableArray();
|
=> Channels.OfType<SocketCategoryChannel>().ToImmutableArray();
|
||||||
public SocketGuildUser CurrentUser => _members.TryGetValue(Discord.CurrentUser.Id, out SocketGuildUser member) ? member : null;
|
public SocketGuildUser CurrentUser => _members.TryGetValue(Discord.CurrentUser.Id, out SocketGuildUser member) ? member : null;
|
||||||
public SocketRole EveryoneRole => GetRole(Id);
|
public SocketRole EveryoneRole => GetRole(Id);
|
||||||
public IReadOnlyCollection<SocketGuildChannel> Channels
|
public IReadOnlyCollection<SocketGuildChannel> Channels
|
||||||
@@ -563,7 +563,7 @@ namespace Discord.WebSocket
|
|||||||
|
|
||||||
await Discord.ApiClient.SendVoiceStateUpdateAsync(Id, channelId, selfDeaf, selfMute).ConfigureAwait(false);
|
await Discord.ApiClient.SendVoiceStateUpdateAsync(Id, channelId, selfDeaf, selfMute).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch
|
||||||
{
|
{
|
||||||
await DisconnectAudioInternalAsync().ConfigureAwait(false);
|
await DisconnectAudioInternalAsync().ConfigureAwait(false);
|
||||||
throw;
|
throw;
|
||||||
@@ -580,7 +580,7 @@ namespace Discord.WebSocket
|
|||||||
throw new TimeoutException();
|
throw new TimeoutException();
|
||||||
return await promise.Task.ConfigureAwait(false);
|
return await promise.Task.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch
|
||||||
{
|
{
|
||||||
await DisconnectAudioAsync().ConfigureAwait(false);
|
await DisconnectAudioAsync().ConfigureAwait(false);
|
||||||
throw;
|
throw;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
@@ -28,7 +28,7 @@ namespace Discord.WebSocket
|
|||||||
_orderedMessages.Enqueue(message.Id);
|
_orderedMessages.Enqueue(message.Id);
|
||||||
|
|
||||||
while (_orderedMessages.Count > _size && _orderedMessages.TryDequeue(out ulong msgId))
|
while (_orderedMessages.Count > _size && _orderedMessages.TryDequeue(out ulong msgId))
|
||||||
_messages.TryRemove(msgId, out SocketMessage msg);
|
_messages.TryRemove(msgId, out _);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ namespace Discord.WebSocket
|
|||||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
||||||
public class SocketUserMessage : SocketMessage, IUserMessage
|
public class SocketUserMessage : SocketMessage, IUserMessage
|
||||||
{
|
{
|
||||||
|
private readonly List<SocketReaction> _reactions = new List<SocketReaction>();
|
||||||
private bool _isMentioningEveryone, _isTTS, _isPinned;
|
private bool _isMentioningEveryone, _isTTS, _isPinned;
|
||||||
private long? _editedTimestampTicks;
|
private long? _editedTimestampTicks;
|
||||||
private ImmutableArray<Attachment> _attachments;
|
private ImmutableArray<Attachment> _attachments;
|
||||||
private ImmutableArray<Embed> _embeds;
|
private ImmutableArray<Embed> _embeds;
|
||||||
private ImmutableArray<ITag> _tags;
|
private ImmutableArray<ITag> _tags;
|
||||||
private List<SocketReaction> _reactions = new List<SocketReaction>();
|
|
||||||
|
|
||||||
public override bool IsTTS => _isTTS;
|
public override bool IsTTS => _isTTS;
|
||||||
public override bool IsPinned => _isPinned;
|
public override bool IsPinned => _isPinned;
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ namespace Discord.Net.WebSockets
|
|||||||
|
|
||||||
private readonly SemaphoreSlim _lock;
|
private readonly SemaphoreSlim _lock;
|
||||||
private readonly Dictionary<string, string> _headers;
|
private readonly Dictionary<string, string> _headers;
|
||||||
|
private readonly IWebProxy _proxy;
|
||||||
private ClientWebSocket _client;
|
private ClientWebSocket _client;
|
||||||
private IWebProxy _proxy;
|
|
||||||
private Task _task;
|
private Task _task;
|
||||||
private CancellationTokenSource _cancelTokenSource;
|
private CancellationTokenSource _cancelTokenSource;
|
||||||
private CancellationToken _cancelToken, _parentToken;
|
private CancellationToken _cancelToken, _parentToken;
|
||||||
|
|||||||
Reference in New Issue
Block a user