Cleaned up several classes
This commit is contained in:
@@ -84,9 +84,18 @@
|
||||
<Compile Include="..\Discord.Net.Audio\Sodium\SecretBox.cs">
|
||||
<Link>Sodium\SecretBox.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net.Audio\UserIsTalkingEventArgs.cs">
|
||||
<Link>UserIsTalkingEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net.Audio\VoiceBuffer.cs">
|
||||
<Link>VoiceBuffer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net.Audio\VoiceDisconnectedEventArgs.cs">
|
||||
<Link>VoiceDisconnectedEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net.Audio\VoicePacketEventArgs.cs">
|
||||
<Link>VoicePacketEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,49 +1,10 @@
|
||||
using Discord.Net.WebSockets;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Audio
|
||||
{
|
||||
public class VoiceDisconnectedEventArgs : DisconnectedEventArgs
|
||||
{
|
||||
public readonly ulong ServerId;
|
||||
|
||||
public VoiceDisconnectedEventArgs(ulong serverId, DisconnectedEventArgs e)
|
||||
: base(e.WasUnexpected, e.Exception)
|
||||
{
|
||||
ServerId = serverId;
|
||||
}
|
||||
}
|
||||
public class UserIsSpeakingEventArgs : UserEventArgs
|
||||
{
|
||||
public readonly bool IsSpeaking;
|
||||
|
||||
public UserIsSpeakingEventArgs(User user, bool isSpeaking)
|
||||
: base(user)
|
||||
{
|
||||
IsSpeaking = isSpeaking;
|
||||
}
|
||||
}
|
||||
public class VoicePacketEventArgs : EventArgs
|
||||
{
|
||||
public readonly ulong UserId;
|
||||
public readonly ulong ChannelId;
|
||||
public readonly byte[] Buffer;
|
||||
public readonly int Offset;
|
||||
public readonly int Count;
|
||||
|
||||
public VoicePacketEventArgs(ulong userId, ulong channelId, byte[] buffer, int offset, int count)
|
||||
{
|
||||
UserId = userId;
|
||||
ChannelId = channelId;
|
||||
Buffer = buffer;
|
||||
Offset = offset;
|
||||
Count = count;
|
||||
}
|
||||
}
|
||||
|
||||
public class AudioService : IService
|
||||
{
|
||||
private AudioClient _defaultClient;
|
||||
@@ -51,46 +12,33 @@ namespace Discord.Audio
|
||||
private ConcurrentDictionary<User, bool> _talkingUsers;
|
||||
//private int _nextClientId;
|
||||
|
||||
internal DiscordClient Client => _client;
|
||||
private DiscordClient _client;
|
||||
internal DiscordClient Client { get; private set; }
|
||||
public AudioServiceConfig Config { get; }
|
||||
|
||||
public AudioServiceConfig Config => _config;
|
||||
private readonly AudioServiceConfig _config;
|
||||
public event EventHandler Connected = delegate { };
|
||||
public event EventHandler<VoiceDisconnectedEventArgs> Disconnected = delegate { };
|
||||
public event EventHandler<VoicePacketEventArgs> PacketReceived = delegate { };
|
||||
public event EventHandler<UserIsSpeakingEventArgs> UserIsSpeakingUpdated = delegate { };
|
||||
|
||||
public event EventHandler Connected;
|
||||
private void RaiseConnected()
|
||||
{
|
||||
if (Connected != null)
|
||||
Connected(this, EventArgs.Empty);
|
||||
}
|
||||
public event EventHandler<VoiceDisconnectedEventArgs> Disconnected;
|
||||
private void RaiseDisconnected(ulong serverId, DisconnectedEventArgs e)
|
||||
{
|
||||
if (Disconnected != null)
|
||||
Disconnected(this, new VoiceDisconnectedEventArgs(serverId, e));
|
||||
}
|
||||
public event EventHandler<VoicePacketEventArgs> OnPacket;
|
||||
internal void RaiseOnPacket(VoicePacketEventArgs e)
|
||||
{
|
||||
if (OnPacket != null)
|
||||
OnPacket(this, e);
|
||||
}
|
||||
public event EventHandler<UserIsSpeakingEventArgs> UserIsSpeakingUpdated;
|
||||
private void RaiseUserIsSpeakingUpdated(User user, bool isSpeaking)
|
||||
{
|
||||
if (UserIsSpeakingUpdated != null)
|
||||
UserIsSpeakingUpdated(this, new UserIsSpeakingEventArgs(user, isSpeaking));
|
||||
}
|
||||
private void OnConnected()
|
||||
=> Connected(this, EventArgs.Empty);
|
||||
private void OnDisconnected(ulong serverId, bool wasUnexpected, Exception ex)
|
||||
=> Disconnected(this, new VoiceDisconnectedEventArgs(serverId, wasUnexpected, ex));
|
||||
internal void OnPacketReceived(VoicePacketEventArgs e)
|
||||
=> PacketReceived(this, e);
|
||||
private void OnUserIsSpeakingUpdated(User user, bool isSpeaking)
|
||||
=> UserIsSpeakingUpdated(this, new UserIsSpeakingEventArgs(user, isSpeaking));
|
||||
|
||||
public AudioService(AudioServiceConfig config)
|
||||
{
|
||||
_config = config;
|
||||
_config.Lock();
|
||||
Config = config;
|
||||
}
|
||||
public void Install(DiscordClient client)
|
||||
{
|
||||
_client = client;
|
||||
if (Config.EnableMultiserver)
|
||||
Client = client;
|
||||
Config.Lock();
|
||||
|
||||
if (Config.EnableMultiserver)
|
||||
_voiceClients = new ConcurrentDictionary<ulong, IAudioClient>();
|
||||
else
|
||||
{
|
||||
@@ -113,7 +61,7 @@ namespace Discord.Audio
|
||||
{
|
||||
bool ignored;
|
||||
if (_talkingUsers.TryRemove(member.Key, out ignored))
|
||||
RaiseUserIsSpeakingUpdated(member.Key, false);
|
||||
OnUserIsSpeakingUpdated(member.Key, false);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
13
src/Discord.Net.Audio/UserIsTalkingEventArgs.cs
Normal file
13
src/Discord.Net.Audio/UserIsTalkingEventArgs.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace Discord
|
||||
{
|
||||
public class UserIsSpeakingEventArgs : UserEventArgs
|
||||
{
|
||||
public bool IsSpeaking { get; }
|
||||
|
||||
public UserIsSpeakingEventArgs(User user, bool isSpeaking)
|
||||
: base(user)
|
||||
{
|
||||
IsSpeaking = isSpeaking;
|
||||
}
|
||||
}
|
||||
}
|
||||
15
src/Discord.Net.Audio/VoiceDisconnectedEventArgs.cs
Normal file
15
src/Discord.Net.Audio/VoiceDisconnectedEventArgs.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
public class VoiceDisconnectedEventArgs : DisconnectedEventArgs
|
||||
{
|
||||
public ulong ServerId { get; }
|
||||
|
||||
public VoiceDisconnectedEventArgs(ulong serverId, bool wasUnexpected, Exception ex)
|
||||
: base(wasUnexpected, ex)
|
||||
{
|
||||
ServerId = serverId;
|
||||
}
|
||||
}
|
||||
}
|
||||
22
src/Discord.Net.Audio/VoicePacketEventArgs.cs
Normal file
22
src/Discord.Net.Audio/VoicePacketEventArgs.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
public class VoicePacketEventArgs : EventArgs
|
||||
{
|
||||
public ulong UserId { get; }
|
||||
public ulong ChannelId { get; }
|
||||
public byte[] Buffer { get; }
|
||||
public int Offset { get; }
|
||||
public int Count { get; }
|
||||
|
||||
public VoicePacketEventArgs(ulong userId, ulong channelId, byte[] buffer, int offset, int count)
|
||||
{
|
||||
UserId = userId;
|
||||
ChannelId = channelId;
|
||||
Buffer = buffer;
|
||||
Offset = offset;
|
||||
Count = count;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,21 +45,27 @@
|
||||
<Compile Include="..\Discord.Net.Commands\CommandBuilder.cs">
|
||||
<Link>CommandBuilder.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net.Commands\CommandErrorEventArgs.cs">
|
||||
<Link>CommandErrorEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net.Commands\CommandEventArgs.cs">
|
||||
<Link>CommandEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net.Commands\CommandExtensions.cs">
|
||||
<Link>CommandExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net.Commands\CommandMap.cs">
|
||||
<Link>CommandMap.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net.Commands\CommandParameter.cs">
|
||||
<Link>CommandParameter.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net.Commands\CommandParser.cs">
|
||||
<Link>CommandParser.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net.Commands\CommandService.cs">
|
||||
<Link>CommandService.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net.Commands\CommandService.Events.cs">
|
||||
<Link>CommandService.Events.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net.Commands\CommandServiceConfig.cs">
|
||||
<Link>CommandServiceConfig.cs</Link>
|
||||
</Compile>
|
||||
|
||||
@@ -5,48 +5,24 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Commands
|
||||
{
|
||||
public enum ParameterType
|
||||
{
|
||||
/// <summary> Catches a single required parameter. </summary>
|
||||
Required,
|
||||
/// <summary> Catches a single optional parameter. </summary>
|
||||
Optional,
|
||||
/// <summary> Catches a zero or more optional parameters. </summary>
|
||||
Multiple,
|
||||
/// <summary> Catches all remaining text as a single optional parameter. </summary>
|
||||
Unparsed
|
||||
}
|
||||
public sealed class CommandParameter
|
||||
{
|
||||
public string Name { get; }
|
||||
public int Id { get; internal set; }
|
||||
public ParameterType Type { get; }
|
||||
|
||||
public CommandParameter(string name, ParameterType type)
|
||||
{
|
||||
Name = name;
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class Command
|
||||
{
|
||||
public string Text { get; }
|
||||
{
|
||||
private string[] _aliases;
|
||||
internal CommandParameter[] _parameters;
|
||||
private IPermissionChecker[] _checks;
|
||||
private Func<CommandEventArgs, Task> _runFunc;
|
||||
internal readonly Dictionary<string, CommandParameter> _parametersByName;
|
||||
|
||||
public string Text { get; }
|
||||
public string Category { get; internal set; }
|
||||
public bool IsHidden { get; internal set; }
|
||||
public string Description { get; internal set; }
|
||||
|
||||
public IEnumerable<string> Aliases => _aliases;
|
||||
private string[] _aliases;
|
||||
|
||||
public IEnumerable<CommandParameter> Parameters => _parameters;
|
||||
internal CommandParameter[] _parameters;
|
||||
|
||||
private IPermissionChecker[] _checks;
|
||||
private Func<CommandEventArgs, Task> _runFunc;
|
||||
internal readonly Dictionary<string, CommandParameter> _parametersByName;
|
||||
public CommandParameter this[string name] => _parametersByName[name];
|
||||
|
||||
internal Command(string text)
|
||||
internal Command(string text)
|
||||
{
|
||||
Text = text;
|
||||
IsHidden = false;
|
||||
@@ -55,7 +31,6 @@ namespace Discord.Commands
|
||||
_parametersByName = new Dictionary<string, CommandParameter>();
|
||||
}
|
||||
|
||||
public CommandParameter this[string name] => _parametersByName[name];
|
||||
|
||||
internal void SetAliases(string[] aliases)
|
||||
{
|
||||
|
||||
18
src/Discord.Net.Commands/CommandErrorEventArgs.cs
Normal file
18
src/Discord.Net.Commands/CommandErrorEventArgs.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
|
||||
namespace Discord.Commands
|
||||
{
|
||||
public enum CommandErrorType { Exception, UnknownCommand, BadPermissions, BadArgCount, InvalidInput }
|
||||
public class CommandErrorEventArgs : CommandEventArgs
|
||||
{
|
||||
public CommandErrorType ErrorType { get; }
|
||||
public Exception Exception { get; }
|
||||
|
||||
public CommandErrorEventArgs(CommandErrorType errorType, CommandEventArgs baseArgs, Exception ex)
|
||||
: base(baseArgs.Message, baseArgs.Command, baseArgs.Args)
|
||||
{
|
||||
Exception = ex;
|
||||
ErrorType = errorType;
|
||||
}
|
||||
}
|
||||
}
|
||||
27
src/Discord.Net.Commands/CommandEventArgs.cs
Normal file
27
src/Discord.Net.Commands/CommandEventArgs.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
|
||||
namespace Discord.Commands
|
||||
{
|
||||
public class CommandEventArgs : EventArgs
|
||||
{
|
||||
private readonly string[] _args;
|
||||
|
||||
public Message Message { get; }
|
||||
public Command Command { get; }
|
||||
|
||||
public User User => Message.User;
|
||||
public Channel Channel => Message.Channel;
|
||||
public Server Server => Message.Channel.Server;
|
||||
|
||||
public CommandEventArgs(Message message, Command command, string[] args)
|
||||
{
|
||||
Message = message;
|
||||
Command = command;
|
||||
_args = args;
|
||||
}
|
||||
|
||||
public string[] Args => _args;
|
||||
public string GetArg(int index) => _args[index];
|
||||
public string GetArg(string name) => _args[Command[name].Id];
|
||||
}
|
||||
}
|
||||
26
src/Discord.Net.Commands/CommandParameter.cs
Normal file
26
src/Discord.Net.Commands/CommandParameter.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
namespace Discord.Commands
|
||||
{
|
||||
public enum ParameterType
|
||||
{
|
||||
/// <summary> Catches a single required parameter. </summary>
|
||||
Required,
|
||||
/// <summary> Catches a single optional parameter. </summary>
|
||||
Optional,
|
||||
/// <summary> Catches a zero or more optional parameters. </summary>
|
||||
Multiple,
|
||||
/// <summary> Catches all remaining text as a single optional parameter. </summary>
|
||||
Unparsed
|
||||
}
|
||||
public sealed class CommandParameter
|
||||
{
|
||||
public string Name { get; }
|
||||
public int Id { get; internal set; }
|
||||
public ParameterType Type { get; }
|
||||
|
||||
public CommandParameter(string name, ParameterType type)
|
||||
{
|
||||
Name = name;
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Discord.Commands
|
||||
{
|
||||
public class CommandEventArgs : EventArgs
|
||||
{
|
||||
private readonly string[] _args;
|
||||
|
||||
public Message Message { get; }
|
||||
public Command Command { get; }
|
||||
|
||||
public User User => Message.User;
|
||||
public Channel Channel => Message.Channel;
|
||||
public Server Server => Message.Channel.Server;
|
||||
|
||||
public CommandEventArgs(Message message, Command command, string[] args)
|
||||
{
|
||||
Message = message;
|
||||
Command = command;
|
||||
_args = args;
|
||||
}
|
||||
|
||||
public string[] Args => _args;
|
||||
public string GetArg(int index) => _args[index];
|
||||
public string GetArg(string name) => _args[Command[name].Id];
|
||||
}
|
||||
|
||||
public enum CommandErrorType { Exception, UnknownCommand, BadPermissions, BadArgCount, InvalidInput }
|
||||
public class CommandErrorEventArgs : CommandEventArgs
|
||||
{
|
||||
public CommandErrorType ErrorType { get; }
|
||||
public Exception Exception { get; }
|
||||
|
||||
public CommandErrorEventArgs(CommandErrorType errorType, CommandEventArgs baseArgs, Exception ex)
|
||||
: base(baseArgs.Message, baseArgs.Command, baseArgs.Args)
|
||||
{
|
||||
Exception = ex;
|
||||
ErrorType = errorType;
|
||||
}
|
||||
}
|
||||
|
||||
public partial class CommandService
|
||||
{
|
||||
public event EventHandler<CommandEventArgs> RanCommand;
|
||||
private void RaiseRanCommand(CommandEventArgs args)
|
||||
{
|
||||
if (RanCommand != null)
|
||||
RanCommand(this, args);
|
||||
}
|
||||
public event EventHandler<CommandErrorEventArgs> CommandError;
|
||||
private void RaiseCommandError(CommandErrorType errorType, CommandEventArgs args, Exception ex = null)
|
||||
{
|
||||
if (CommandError != null)
|
||||
CommandError(this, new CommandErrorEventArgs(errorType, args, ex));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,42 +6,45 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Commands
|
||||
{
|
||||
/// <summary> A Discord.Net client with extensions for handling common bot operations like text commands. </summary>
|
||||
public sealed partial class CommandService : IService
|
||||
public partial class CommandService : IService
|
||||
{
|
||||
private readonly CommandServiceConfig _config;
|
||||
private readonly CommandGroupBuilder _root;
|
||||
private DiscordClient _client;
|
||||
|
||||
public DiscordClient Client => _client;
|
||||
public CommandGroupBuilder Root => _root;
|
||||
private readonly List<Command> _allCommands;
|
||||
private readonly Dictionary<string, CommandMap> _categories;
|
||||
private readonly CommandMap _map; //Command map stores all commands by their input text, used for fast resolving and parsing
|
||||
|
||||
public CommandServiceConfig Config { get; }
|
||||
public CommandGroupBuilder Root { get; }
|
||||
public DiscordClient Client { get; private set; }
|
||||
|
||||
//AllCommands store a flattened collection of all commands
|
||||
public IEnumerable<Command> AllCommands => _allCommands;
|
||||
private readonly List<Command> _allCommands;
|
||||
|
||||
//Command map stores all commands by their input text, used for fast resolving and parsing
|
||||
private readonly CommandMap _map;
|
||||
|
||||
public IEnumerable<Command> AllCommands => _allCommands;
|
||||
//Groups store all commands by their module, used for more informative help
|
||||
internal IEnumerable<CommandMap> Categories => _categories.Values;
|
||||
private readonly Dictionary<string, CommandMap> _categories;
|
||||
|
||||
public CommandService(CommandServiceConfig config)
|
||||
public event EventHandler<CommandEventArgs> Command = delegate { };
|
||||
public event EventHandler<CommandErrorEventArgs> CommandError = delegate { };
|
||||
|
||||
private void OnCommand(CommandEventArgs args)
|
||||
=> Command(this, args);
|
||||
private void OnCommandError(CommandErrorType errorType, CommandEventArgs args, Exception ex = null)
|
||||
=> CommandError(this, new CommandErrorEventArgs(errorType, args, ex));
|
||||
|
||||
public CommandService(CommandServiceConfig config)
|
||||
{
|
||||
_config = config;
|
||||
Config = config;
|
||||
|
||||
_allCommands = new List<Command>();
|
||||
_map = new CommandMap(null, "", "");
|
||||
_categories = new Dictionary<string, CommandMap>();
|
||||
_root = new CommandGroupBuilder(this, "", null);
|
||||
Root = new CommandGroupBuilder(this, "", null);
|
||||
}
|
||||
|
||||
void IService.Install(DiscordClient client)
|
||||
{
|
||||
_client = client;
|
||||
_config.Lock();
|
||||
Client = client;
|
||||
Config.Lock();
|
||||
|
||||
if (_config.HelpMode != HelpMode.Disable)
|
||||
if (Config.HelpMode != HelpMode.Disable)
|
||||
{
|
||||
CreateCommand("help")
|
||||
.Parameter("command", ParameterType.Multiple)
|
||||
@@ -49,7 +52,7 @@ namespace Discord.Commands
|
||||
.Description("Returns information about commands.")
|
||||
.Do(async e =>
|
||||
{
|
||||
Channel replyChannel = _config.HelpMode == HelpMode.Public ? e.Channel : await e.User.CreatePMChannel().ConfigureAwait(false);
|
||||
Channel replyChannel = Config.HelpMode == HelpMode.Public ? e.Channel : await e.User.CreatePMChannel().ConfigureAwait(false);
|
||||
if (e.Args.Length > 0) //Show command help
|
||||
{
|
||||
var map = _map.GetItem(string.Join(" ", e.Args));
|
||||
@@ -66,13 +69,13 @@ namespace Discord.Commands
|
||||
client.MessageReceived += async (s, e) =>
|
||||
{
|
||||
if (_allCommands.Count == 0) return;
|
||||
if (e.Message.User == null || e.Message.User.Id == _client.CurrentUser.Id) return;
|
||||
if (e.Message.User == null || e.Message.User.Id == Client.CurrentUser.Id) return;
|
||||
|
||||
string msg = e.Message.RawText;
|
||||
if (msg.Length == 0) return;
|
||||
|
||||
//Check for command char if one is provided
|
||||
var chars = _config.CommandChars;
|
||||
var chars = Config.CommandChars;
|
||||
if (chars.Length > 0)
|
||||
{
|
||||
if (!chars.Contains(msg[0]))
|
||||
@@ -87,7 +90,7 @@ namespace Discord.Commands
|
||||
if (commands == null)
|
||||
{
|
||||
CommandEventArgs errorArgs = new CommandEventArgs(e.Message, null, null);
|
||||
RaiseCommandError(CommandErrorType.UnknownCommand, errorArgs);
|
||||
OnCommandError(CommandErrorType.UnknownCommand, errorArgs);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -104,7 +107,7 @@ namespace Discord.Commands
|
||||
else
|
||||
{
|
||||
var errorArgs = new CommandEventArgs(e.Message, command, null);
|
||||
RaiseCommandError(error.Value, errorArgs);
|
||||
OnCommandError(error.Value, errorArgs);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -115,24 +118,24 @@ namespace Discord.Commands
|
||||
string errorText;
|
||||
if (!command.CanRun(eventArgs.User, eventArgs.Channel, out errorText))
|
||||
{
|
||||
RaiseCommandError(CommandErrorType.BadPermissions, eventArgs, errorText != null ? new Exception(errorText) : null);
|
||||
OnCommandError(CommandErrorType.BadPermissions, eventArgs, errorText != null ? new Exception(errorText) : null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Run the command
|
||||
try
|
||||
{
|
||||
RaiseRanCommand(eventArgs);
|
||||
OnCommand(eventArgs);
|
||||
await command.Run(eventArgs).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
RaiseCommandError(CommandErrorType.Exception, eventArgs, ex);
|
||||
OnCommandError(CommandErrorType.Exception, eventArgs, ex);
|
||||
}
|
||||
return;
|
||||
}
|
||||
var errorArgs2 = new CommandEventArgs(e.Message, null, null);
|
||||
RaiseCommandError(CommandErrorType.BadArgCount, errorArgs2);
|
||||
OnCommandError(CommandErrorType.BadArgCount, errorArgs2);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -184,7 +187,7 @@ namespace Discord.Commands
|
||||
{
|
||||
output.Append("\n\n");
|
||||
|
||||
var chars = _config.CommandChars;
|
||||
var chars = Config.CommandChars;
|
||||
if (chars.Length > 0)
|
||||
{
|
||||
if (chars.Length == 1)
|
||||
@@ -294,8 +297,8 @@ namespace Discord.Commands
|
||||
output.AppendLine($"Aliases: `" + string.Join("`, `", command.Aliases) + '`');
|
||||
}
|
||||
|
||||
public void CreateGroup(string cmd, Action<CommandGroupBuilder> config = null) => _root.CreateGroup(cmd, config);
|
||||
public CommandBuilder CreateCommand(string cmd) => _root.CreateCommand(cmd);
|
||||
public void CreateGroup(string cmd, Action<CommandGroupBuilder> config = null) => Root.CreateGroup(cmd, config);
|
||||
public CommandBuilder CreateCommand(string cmd) => Root.CreateCommand(cmd);
|
||||
|
||||
internal void AddCommand(Command command)
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@ using System.Linq;
|
||||
|
||||
namespace Discord.Modules
|
||||
{
|
||||
public class ModuleManager
|
||||
public sealed class ModuleManager
|
||||
{
|
||||
public event EventHandler<ServerEventArgs> ServerEnabled = delegate { };
|
||||
public event EventHandler<ServerEventArgs> ServerDisabled = delegate { };
|
||||
|
||||
@@ -5,21 +5,19 @@ namespace Discord.Modules
|
||||
{
|
||||
public class ModuleService : IService
|
||||
{
|
||||
private DiscordClient _client;
|
||||
|
||||
//ModuleServiceConfig Config { get; }
|
||||
public DiscordClient Client { get; private set; }
|
||||
|
||||
public IEnumerable<ModuleManager> Modules => _modules.Values;
|
||||
private readonly Dictionary<IModule, ModuleManager> _modules;
|
||||
|
||||
public ModuleService(/*ModuleServiceConfig config*/)
|
||||
public ModuleService()
|
||||
{
|
||||
//Config = config;
|
||||
_modules = new Dictionary<IModule, ModuleManager>();
|
||||
}
|
||||
|
||||
void IService.Install(DiscordClient client)
|
||||
{
|
||||
_client = client;
|
||||
Client = client;
|
||||
}
|
||||
|
||||
public void Install<T>(T module, string name, FilterType type)
|
||||
@@ -27,10 +25,12 @@ namespace Discord.Modules
|
||||
{
|
||||
if (module == null) throw new ArgumentNullException(nameof(module));
|
||||
if (name == null) throw new ArgumentNullException(nameof(name));
|
||||
if (_client == null) throw new InvalidOperationException("Service needs to be added to a DiscordClient before modules can be installed.");
|
||||
if (_modules.ContainsKey(module)) throw new InvalidOperationException("This module has already been added.");
|
||||
if (Client == null)
|
||||
throw new InvalidOperationException("Service needs to be added to a DiscordClient before modules can be installed.");
|
||||
if (_modules.ContainsKey(module))
|
||||
throw new InvalidOperationException("This module has already been added.");
|
||||
|
||||
var manager = new ModuleManager(_client, name, type);
|
||||
var manager = new ModuleManager(Client, name, type);
|
||||
_modules.Add(module, manager);
|
||||
module.Install(manager);
|
||||
}
|
||||
|
||||
@@ -391,15 +391,24 @@
|
||||
<Compile Include="..\Discord.Net\API\Status\Rest\Upcoming.cs">
|
||||
<Link>API\Status\Rest\Upcoming.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\ChannelEventArgs.cs">
|
||||
<Link>ChannelEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\ChannelUserEventArgs.cs">
|
||||
<Link>ChannelUserEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Config.cs">
|
||||
<Link>Config.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\DisconnectedEventArgs.cs">
|
||||
<Link>DisconnectedEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\DiscordClient.cs">
|
||||
<Link>DiscordClient.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\DiscordClient.Events.cs">
|
||||
<Link>DiscordClient.Events.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\DiscordClient.Obsolete.cs">
|
||||
<Link>DiscordClient.Obsolete.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\DiscordConfig.cs">
|
||||
<Link>DiscordConfig.cs</Link>
|
||||
</Compile>
|
||||
@@ -421,33 +430,6 @@
|
||||
<Compile Include="..\Discord.Net\Enums\UserStatus.cs">
|
||||
<Link>Enums\UserStatus.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Events\ChannelEventArgs.cs">
|
||||
<Link>Events\ChannelEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Events\ChannelUserEventArgs.cs">
|
||||
<Link>Events\ChannelUserEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Events\DisconnectedEventArgs.cs">
|
||||
<Link>Events\DisconnectedEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Events\LogMessageEventArgs.cs">
|
||||
<Link>Events\LogMessageEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Events\MessageEventArgs.cs">
|
||||
<Link>Events\MessageEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Events\ProfileEventArgs.cs">
|
||||
<Link>Events\ProfileEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Events\RoleEventArgs.cs">
|
||||
<Link>Events\RoleEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Events\ServerEventArgs.cs">
|
||||
<Link>Events\ServerEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Events\UserEventArgs.cs">
|
||||
<Link>Events\UserEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Extensions.cs">
|
||||
<Link>Extensions.cs</Link>
|
||||
</Compile>
|
||||
@@ -457,12 +439,21 @@
|
||||
<Compile Include="..\Discord.Net\IService.cs">
|
||||
<Link>IService.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Legacy.cs">
|
||||
<Link>Legacy.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Logging\Logger.cs">
|
||||
<Link>Logging\Logger.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Logging\LogManager.cs">
|
||||
<Link>Logging\LogManager.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\LogMessageEventArgs.cs">
|
||||
<Link>LogMessageEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\MessageEventArgs.cs">
|
||||
<Link>MessageEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\MessageQueue.cs">
|
||||
<Link>MessageQueue.cs</Link>
|
||||
</Compile>
|
||||
@@ -502,6 +493,9 @@
|
||||
<Compile Include="..\Discord.Net\Net\Rest\IRestEngine.cs">
|
||||
<Link>Net\Rest\IRestEngine.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Net\Rest\RequestEventArgs.cs">
|
||||
<Link>Net\Rest\RequestEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Net\Rest\RestClient.cs">
|
||||
<Link>Net\Rest\RestClient.cs</Link>
|
||||
</Compile>
|
||||
@@ -514,6 +508,9 @@
|
||||
<Compile Include="..\Discord.Net\Net\WebSocketException.cs">
|
||||
<Link>Net\WebSockets\WebSocketException.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\BinaryMessageEventArgs.cs">
|
||||
<Link>Net\WebSockets\BinaryMessageEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\BuiltInEngine.cs">
|
||||
<Link>Net\WebSockets\BuiltInEngine.cs</Link>
|
||||
</Compile>
|
||||
@@ -523,30 +520,39 @@
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\IWebSocketEngine.cs">
|
||||
<Link>Net\WebSockets\IWebSocketEngine.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\WebSocket.BuiltIn.cs">
|
||||
<Link>Net\WebSockets\WebSocket.BuiltIn.cs</Link>
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\TextMessageEventArgs.cs">
|
||||
<Link>Net\WebSockets\TextMessageEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\WebSocket.cs">
|
||||
<Link>Net\WebSockets\WebSocket.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\WebSocketSharpEngine.cs">
|
||||
<Link>Net\WebSockets\WebSocketSharpEngine.cs</Link>
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\WebSocketEventEventArgs.cs">
|
||||
<Link>Net\WebSockets\WebSocketEventEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\WS4NetEngine.cs">
|
||||
<Link>Net\WebSockets\WS4NetEngine.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Reference.cs">
|
||||
<Link>Reference.cs</Link>
|
||||
<Compile Include="..\Discord.Net\ProfileEventArgs.cs">
|
||||
<Link>ProfileEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\RelativeDirection.cs">
|
||||
<Link>RelativeDirection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\RoleEventArgs.cs">
|
||||
<Link>RoleEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\ServerEventArgs.cs">
|
||||
<Link>ServerEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\ServiceManager.cs">
|
||||
<Link>ServiceManager.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\TaskManager.cs">
|
||||
<Link>TaskManager.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\UserEventArgs.cs">
|
||||
<Link>UserEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Collections.Generic;
|
||||
namespace Discord.API.Client.GatewaySocket
|
||||
{
|
||||
[JsonObject(MemberSerialization.OptIn)]
|
||||
internal sealed class IdentifyCommand : IWebSocketMessage
|
||||
public sealed class IdentifyCommand : IWebSocketMessage
|
||||
{
|
||||
int IWebSocketMessage.OpCode => (int)OpCodes.Identify;
|
||||
object IWebSocketMessage.Payload => this;
|
||||
|
||||
@@ -4,7 +4,7 @@ using Newtonsoft.Json;
|
||||
namespace Discord.API.Client.GatewaySocket
|
||||
{
|
||||
[JsonObject(MemberSerialization.OptIn)]
|
||||
internal sealed class RequestMembersCommand : IWebSocketMessage
|
||||
public sealed class RequestMembersCommand : IWebSocketMessage
|
||||
{
|
||||
int IWebSocketMessage.OpCode => (int)OpCodes.RequestGuildMembers;
|
||||
object IWebSocketMessage.Payload => this;
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
using Discord.API.Converters;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Discord.API.Client.GatewaySocket
|
||||
namespace Discord.API.Client.GatewaySocket
|
||||
{
|
||||
public sealed class GuildBanAddEvent : MemberReference
|
||||
{
|
||||
}
|
||||
public sealed class GuildBanAddEvent : MemberReference { }
|
||||
}
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
using Discord.API.Converters;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Discord.API.Client.GatewaySocket
|
||||
namespace Discord.API.Client.GatewaySocket
|
||||
{
|
||||
public sealed class GuildBanRemoveEvent : MemberReference
|
||||
{
|
||||
}
|
||||
public sealed class GuildBanRemoveEvent : MemberReference { }
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Discord.API.Client.GatewaySocket.Events
|
||||
{
|
||||
//public sealed class GuildEmojisUpdate { }
|
||||
//public sealed class GuildEmojisUpdateEvent { }
|
||||
}
|
||||
|
||||
@@ -8,6 +8,6 @@ namespace Discord.API.Client.GatewaySocket
|
||||
[JsonProperty("guild_id"), JsonConverter(typeof(LongStringConverter))]
|
||||
public ulong GuildId { get; set; }
|
||||
[JsonProperty("members")]
|
||||
public Member[] Members;
|
||||
public Member[] Members { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Discord.API.Client
|
||||
object Payload { get; }
|
||||
bool IsPrivate { get; }
|
||||
}
|
||||
public class WebSocketMessage
|
||||
public sealed class WebSocketMessage
|
||||
{
|
||||
[JsonProperty("op")]
|
||||
public int? Operation { get; set; }
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Collections.Generic;
|
||||
|
||||
namespace Discord.API.Converters
|
||||
{
|
||||
public class LongStringConverter : JsonConverter
|
||||
public sealed class LongStringConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType)
|
||||
=> objectType == typeof(ulong);
|
||||
@@ -14,7 +14,7 @@ namespace Discord.API.Converters
|
||||
=> writer.WriteValue(((ulong)value).ToIdString());
|
||||
}
|
||||
|
||||
public class NullableLongStringConverter : JsonConverter
|
||||
public sealed class NullableLongStringConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType)
|
||||
=> objectType == typeof(ulong?);
|
||||
@@ -24,7 +24,7 @@ namespace Discord.API.Converters
|
||||
=> writer.WriteValue(((ulong?)value).ToIdString());
|
||||
}
|
||||
|
||||
/*public class LongStringEnumerableConverter : JsonConverter
|
||||
/*public sealed class LongStringEnumerableConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType) => objectType == typeof(IEnumerable<ulong>);
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
@@ -55,7 +55,7 @@ namespace Discord.API.Converters
|
||||
}
|
||||
}*/
|
||||
|
||||
internal class LongStringArrayConverter : JsonConverter
|
||||
internal sealed class LongStringArrayConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType) => objectType == typeof(IEnumerable<ulong[]>);
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Discord
|
||||
public class ChannelEventArgs : EventArgs
|
||||
{
|
||||
public Channel Channel { get; }
|
||||
|
||||
public Server Server => Channel.Server;
|
||||
|
||||
public ChannelEventArgs(Channel channel) { Channel = channel; }
|
||||
24
src/Discord.Net/Config.cs
Normal file
24
src/Discord.Net/Config.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
public abstract class Config<T>
|
||||
where T : Config<T>
|
||||
{
|
||||
protected bool _isLocked;
|
||||
protected internal void Lock() { _isLocked = true; }
|
||||
protected void SetValue<U>(ref U storage, U value)
|
||||
{
|
||||
if (_isLocked)
|
||||
throw new InvalidOperationException("Unable to modify a discord client's configuration after it has been created.");
|
||||
storage = value;
|
||||
}
|
||||
|
||||
public T Clone()
|
||||
{
|
||||
var config = MemberwiseClone() as T;
|
||||
config._isLocked = false;
|
||||
return config;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,26 +13,6 @@ namespace Discord
|
||||
Verbose = 4,
|
||||
Debug = 5
|
||||
}
|
||||
|
||||
public abstract class Config<T>
|
||||
where T : Config<T>
|
||||
{
|
||||
protected bool _isLocked;
|
||||
protected internal void Lock() { _isLocked = true; }
|
||||
protected void SetValue<U>(ref U storage, U value)
|
||||
{
|
||||
if (_isLocked)
|
||||
throw new InvalidOperationException("Unable to modify a discord client's configuration after it has been created.");
|
||||
storage = value;
|
||||
}
|
||||
|
||||
public T Clone()
|
||||
{
|
||||
var config = MemberwiseClone() as T;
|
||||
config._isLocked = false;
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
public class DiscordConfig : Config<DiscordConfig>
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace Discord
|
||||
{
|
||||
public class ChannelType : StringEnum
|
||||
public sealed class ChannelType : StringEnum
|
||||
{
|
||||
/// <summary> A text-only channel. </summary>
|
||||
public static ChannelType Text { get; } = new ChannelType("text");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace Discord
|
||||
{
|
||||
public class PermissionTarget : StringEnum
|
||||
public sealed class PermissionTarget : StringEnum
|
||||
{
|
||||
/// <summary> A text-only channel. </summary>
|
||||
public static PermissionTarget Role { get; } = new PermissionTarget("role");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace Discord
|
||||
{
|
||||
public class UserStatus : StringEnum
|
||||
public sealed class UserStatus : StringEnum
|
||||
{
|
||||
/// <summary> User is currently online and active. </summary>
|
||||
public static UserStatus Online { get; } = new UserStatus("online");
|
||||
|
||||
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Legacy
|
||||
namespace Discord
|
||||
{
|
||||
public static class Mention
|
||||
{
|
||||
@@ -31,19 +31,19 @@ namespace Discord.Legacy
|
||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||
return server.FindChannels(name, type, exactMatch);
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("Use Server.CreateChannel")]
|
||||
public static Task<Channel> CreateChannel(this DiscordClient client, Server server, string name, ChannelType type)
|
||||
{
|
||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||
return server.CreateChannel(name, type);
|
||||
}
|
||||
}
|
||||
[Obsolete("Use User.CreateChannel")]
|
||||
public static Task<Channel> CreatePMChannel(this DiscordClient client, User user)
|
||||
{
|
||||
if (user == null) throw new ArgumentNullException(nameof(user));
|
||||
return user.CreatePMChannel();
|
||||
}
|
||||
}
|
||||
[Obsolete("Use Channel.Edit")]
|
||||
public static Task EditChannel(this DiscordClient client, Channel channel, string name = null, string topic = null, int? position = null)
|
||||
{
|
||||
@@ -62,15 +62,15 @@ namespace Discord.Legacy
|
||||
{
|
||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||
return server.ReorderChannels(channels, after);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Obsolete("Use Server.GetInvites")]
|
||||
public static Task<IEnumerable<Invite>> GetInvites(this DiscordClient client, Server server)
|
||||
{
|
||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||
return server.GetInvites();
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("Use Server.CreateInvite")]
|
||||
public static Task<Invite> CreateInvite(this DiscordClient client, Server server, int? maxAge = 1800, int? maxUses = null, bool tempMembership = false, bool withXkcd = false)
|
||||
{
|
||||
@@ -83,20 +83,20 @@ namespace Discord.Legacy
|
||||
if (channel == null) throw new ArgumentNullException(nameof(channel));
|
||||
return channel.CreateInvite(maxAge, maxUses, tempMembership, withXkcd);
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("Use Invite.Delete")]
|
||||
public static Task DeleteInvite(this DiscordClient client, Invite invite)
|
||||
{
|
||||
if (invite == null) throw new ArgumentNullException(nameof(invite));
|
||||
return invite.Delete();
|
||||
}
|
||||
}
|
||||
[Obsolete("Use Invite.Accept")]
|
||||
public static Task AcceptInvite(this DiscordClient client, Invite invite)
|
||||
{
|
||||
if (invite == null) throw new ArgumentNullException(nameof(invite));
|
||||
return invite.Accept();
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("Use Channel.SendMessage")]
|
||||
public static Task<Message> SendMessage(this DiscordClient client, Channel channel, string text)
|
||||
{
|
||||
@@ -139,14 +139,14 @@ namespace Discord.Legacy
|
||||
if (user == null) throw new ArgumentNullException(nameof(user));
|
||||
return user.SendFile(filename, stream);
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("Use Message.Edit")]
|
||||
public static Task EditMessage(this DiscordClient client, Message message, string text)
|
||||
{
|
||||
if (message == null) throw new ArgumentNullException(nameof(message));
|
||||
return message.Edit(text);
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("Use Message.Delete")]
|
||||
public static Task DeleteMessage(this DiscordClient client, Message message)
|
||||
{
|
||||
@@ -161,14 +161,14 @@ namespace Discord.Legacy
|
||||
foreach (var message in messages)
|
||||
await message.Delete().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("Use Channel.DownloadMessages")]
|
||||
public static Task<Message[]> DownloadMessages(this DiscordClient client, Channel channel, int limit = 100, ulong? relativeMessageId = null, RelativeDirection relativeDir = RelativeDirection.Before, bool useCache = true)
|
||||
{
|
||||
if (channel == null) throw new ArgumentNullException(nameof(channel));
|
||||
return channel.DownloadMessages(limit, relativeMessageId, relativeDir, useCache);
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("Use Message.Acknowledge")]
|
||||
public static Task AckMessage(this DiscordClient client, Message message)
|
||||
{
|
||||
@@ -212,7 +212,7 @@ namespace Discord.Legacy
|
||||
|
||||
return JsonConvert.SerializeObject(channel.Messages);
|
||||
}*/
|
||||
|
||||
|
||||
[Obsolete("Use Server.GetUser")]
|
||||
public static User GetUser(this DiscordClient client, Server server, ulong userId)
|
||||
{
|
||||
@@ -225,7 +225,7 @@ namespace Discord.Legacy
|
||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||
return server.GetUser(username, discriminator);
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("Use Server.FindUsers")]
|
||||
public static IEnumerable<User> FindUsers(this DiscordClient client, Server server, string name, bool exactMatch = false)
|
||||
{
|
||||
@@ -287,20 +287,20 @@ namespace Discord.Legacy
|
||||
string username = null, string email = null, string password = null,
|
||||
Stream avatar = null, ImageType avatarType = ImageType.Png)
|
||||
=> client.CurrentUser.Edit(currentPassword, username, email, password, avatar, avatarType);
|
||||
|
||||
|
||||
[Obsolete("Use Server.GetRole")]
|
||||
public static Role GetRole(this DiscordClient client, Server server, ulong id)
|
||||
{
|
||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||
return server.GetRole(id);
|
||||
}
|
||||
}
|
||||
[Obsolete("Use Server.FindRoles")]
|
||||
public static IEnumerable<Role> FindRoles(this DiscordClient client, Server server, string name)
|
||||
{
|
||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||
return server.FindRoles(name);
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("Use Server.CreateRole")]
|
||||
public static Task<Role> CreateRole(this DiscordClient client, Server server, string name, ServerPermissions permissions = null, Color color = null, bool isHoisted = false)
|
||||
{
|
||||
@@ -320,21 +320,21 @@ namespace Discord.Legacy
|
||||
if (role == null) throw new ArgumentNullException(nameof(role));
|
||||
return role.Delete();
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("Use Server.ReorderRoles")]
|
||||
public static Task ReorderRoles(this DiscordClient client, Server server, IEnumerable<Role> roles, Role after = null)
|
||||
{
|
||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||
return server.ReorderRoles(roles, after);
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("Use Server.Edit")]
|
||||
public static Task EditServer(this DiscordClient client, Server server, string name = null, string region = null, Stream icon = null, ImageType iconType = ImageType.Png)
|
||||
{
|
||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||
return server.Edit(name, region, icon, iconType);
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("Use Server.Leave")]
|
||||
public static Task LeaveServer(this DiscordClient client, Server server)
|
||||
{
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
public sealed class LogMessageEventArgs : EventArgs
|
||||
public class LogMessageEventArgs : EventArgs
|
||||
{
|
||||
public LogSeverity Severity { get; }
|
||||
public string Source { get; }
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Discord.Logging
|
||||
{
|
||||
public class LogManager
|
||||
public sealed class LogManager
|
||||
{
|
||||
private readonly DiscordClient _client;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Discord.Logging
|
||||
{
|
||||
public class Logger
|
||||
public sealed class Logger
|
||||
{
|
||||
private readonly LogManager _manager;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Discord
|
||||
public class MessageEventArgs : EventArgs
|
||||
{
|
||||
public Message Message { get; }
|
||||
|
||||
public User User => Message.User;
|
||||
public Channel Channel => Message.Channel;
|
||||
public Server Server => Message.Server;
|
||||
@@ -9,9 +9,9 @@ using System.Threading.Tasks;
|
||||
namespace Discord.Net
|
||||
{
|
||||
/// <summary> Manages an outgoing message queue for DiscordClient. </summary>
|
||||
public class MessageQueue
|
||||
public sealed class MessageQueue
|
||||
{
|
||||
private class MessageQueueItem
|
||||
private struct MessageQueueItem
|
||||
{
|
||||
public readonly ulong Id, ChannelId;
|
||||
public readonly string Text;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
public class Color
|
||||
public sealed class Color
|
||||
{
|
||||
public static readonly Color Default = PresetColor(0);
|
||||
|
||||
@@ -65,8 +65,8 @@ namespace Discord
|
||||
//Bypasses isLocked for API changes.
|
||||
_rawValue = rawValue;
|
||||
}
|
||||
protected byte GetByte(int pos) => (byte)((_rawValue >> (8 * (pos - 1))) & 0xFF);
|
||||
protected void SetByte(int pos, byte value)
|
||||
private byte GetByte(int pos) => (byte)((_rawValue >> (8 * (pos - 1))) & 0xFF);
|
||||
private void SetByte(int pos, byte value)
|
||||
{
|
||||
if (_isLocked)
|
||||
throw new InvalidOperationException("Unable to edit cached colors directly, use Copy() to make an editable copy.");
|
||||
|
||||
@@ -9,7 +9,7 @@ using APIMember = Discord.API.Client.Member;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
public class User
|
||||
public sealed class User
|
||||
{
|
||||
internal static string GetAvatarUrl(ulong userId, string avatarId)
|
||||
=> avatarId != null ? $"{DiscordConfig.CDNUrl}avatars/{userId}/{avatarId}.jpg" : null;
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Discord.Net
|
||||
#if NET46
|
||||
[Serializable]
|
||||
#endif
|
||||
public class HttpException : Exception
|
||||
public sealed class HttpException : Exception
|
||||
{
|
||||
public HttpStatusCode StatusCode { get; }
|
||||
|
||||
|
||||
20
src/Discord.Net/Net/Rest/RequestEventArgs.cs
Normal file
20
src/Discord.Net/Net/Rest/RequestEventArgs.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
|
||||
namespace Discord.Net.Rest
|
||||
{
|
||||
public class RequestEventArgs : EventArgs
|
||||
{
|
||||
public string Method { get; }
|
||||
public string Path { get; }
|
||||
public string Payload { get; }
|
||||
public double ElapsedMilliseconds { get; }
|
||||
|
||||
public RequestEventArgs(string method, string path, string payload, double milliseconds)
|
||||
{
|
||||
Method = method;
|
||||
Path = path;
|
||||
Payload = payload;
|
||||
ElapsedMilliseconds = milliseconds;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,21 +8,6 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Net.Rest
|
||||
{
|
||||
public class RequestEventArgs : EventArgs
|
||||
{
|
||||
public string Method { get; }
|
||||
public string Path { get; }
|
||||
public string Payload { get; }
|
||||
public double ElapsedMilliseconds { get; }
|
||||
public RequestEventArgs(string method, string path, string payload, double milliseconds)
|
||||
{
|
||||
Method = method;
|
||||
Path = path;
|
||||
Payload = payload;
|
||||
ElapsedMilliseconds = milliseconds;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed partial class RestClient
|
||||
{
|
||||
private readonly DiscordConfig _config;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Discord.Net
|
||||
{
|
||||
public class WebSocketException : Exception
|
||||
public sealed class WebSocketException : Exception
|
||||
{
|
||||
public int Code { get; }
|
||||
public string Reason { get; }
|
||||
|
||||
11
src/Discord.Net/Net/WebSockets/BinaryMessageEventArgs.cs
Normal file
11
src/Discord.Net/Net/WebSockets/BinaryMessageEventArgs.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace Discord.Net.WebSockets
|
||||
{
|
||||
public class BinaryMessageEventArgs : EventArgs
|
||||
{
|
||||
public byte[] Data { get; }
|
||||
|
||||
public BinaryMessageEventArgs(byte[] data) { Data = data; }
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ using WebSocketClient = System.Net.WebSockets.ClientWebSocket;
|
||||
|
||||
namespace Discord.Net.WebSockets
|
||||
{
|
||||
internal class BuiltInEngine : IWebSocketEngine
|
||||
internal sealed class BuiltInEngine : IWebSocketEngine
|
||||
{
|
||||
private const int ReceiveChunkSize = 12 * 1024; //12KB
|
||||
private const int SendChunkSize = 4 * 1024; //4KB
|
||||
@@ -23,12 +23,12 @@ namespace Discord.Net.WebSockets
|
||||
private WebSocketClient _webSocket;
|
||||
private Task _tempTask;
|
||||
|
||||
public event EventHandler<WebSocketBinaryMessageEventArgs> BinaryMessage = delegate { };
|
||||
public event EventHandler<WebSocketTextMessageEventArgs> TextMessage = delegate { };
|
||||
public event EventHandler<BinaryMessageEventArgs> BinaryMessage = delegate { };
|
||||
public event EventHandler<TextMessageEventArgs> TextMessage = delegate { };
|
||||
private void OnBinaryMessage(byte[] data)
|
||||
=> BinaryMessage(this, new WebSocketBinaryMessageEventArgs(data));
|
||||
=> BinaryMessage(this, new BinaryMessageEventArgs(data));
|
||||
private void OnTextMessage(string msg)
|
||||
=> TextMessage(this, new WebSocketTextMessageEventArgs(msg));
|
||||
=> TextMessage(this, new TextMessageEventArgs(msg));
|
||||
|
||||
internal BuiltInEngine(DiscordConfig config)
|
||||
{
|
||||
|
||||
@@ -10,18 +10,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Net.WebSockets
|
||||
{
|
||||
public sealed class WebSocketEventEventArgs : EventArgs
|
||||
{
|
||||
public readonly string Type;
|
||||
public readonly JToken Payload;
|
||||
internal WebSocketEventEventArgs(string type, JToken data)
|
||||
{
|
||||
Type = type;
|
||||
Payload = data;
|
||||
}
|
||||
}
|
||||
|
||||
public partial class GatewaySocket : WebSocket
|
||||
public sealed class GatewaySocket : WebSocket
|
||||
{
|
||||
private uint _lastSequence;
|
||||
private string _sessionId;
|
||||
|
||||
@@ -5,21 +5,10 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Net.WebSockets
|
||||
{
|
||||
public class WebSocketBinaryMessageEventArgs : EventArgs
|
||||
{
|
||||
public readonly byte[] Data;
|
||||
public WebSocketBinaryMessageEventArgs(byte[] data) { Data = data; }
|
||||
}
|
||||
public class WebSocketTextMessageEventArgs : EventArgs
|
||||
{
|
||||
public readonly string Message;
|
||||
public WebSocketTextMessageEventArgs(string msg) { Message = msg; }
|
||||
}
|
||||
|
||||
public interface IWebSocketEngine
|
||||
{
|
||||
event EventHandler<WebSocketBinaryMessageEventArgs> BinaryMessage;
|
||||
event EventHandler<WebSocketTextMessageEventArgs> TextMessage;
|
||||
event EventHandler<BinaryMessageEventArgs> BinaryMessage;
|
||||
event EventHandler<TextMessageEventArgs> TextMessage;
|
||||
|
||||
Task Connect(string host, CancellationToken cancelToken);
|
||||
Task Disconnect();
|
||||
|
||||
11
src/Discord.Net/Net/WebSockets/TextMessageEventArgs.cs
Normal file
11
src/Discord.Net/Net/WebSockets/TextMessageEventArgs.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace Discord.Net.WebSockets
|
||||
{
|
||||
public class TextMessageEventArgs : EventArgs
|
||||
{
|
||||
public string Message { get; }
|
||||
|
||||
public TextMessageEventArgs(string msg) { Message = msg; }
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ using WebSocketClient = WebSocket4Net.WebSocket;
|
||||
|
||||
namespace Discord.Net.WebSockets
|
||||
{
|
||||
internal class WS4NetEngine : IWebSocketEngine
|
||||
internal sealed class WS4NetEngine : IWebSocketEngine
|
||||
{
|
||||
private readonly DiscordConfig _config;
|
||||
private readonly ConcurrentQueue<string> _sendQueue;
|
||||
@@ -18,12 +18,12 @@ namespace Discord.Net.WebSockets
|
||||
private WebSocketClient _webSocket;
|
||||
private ManualResetEventSlim _waitUntilConnect, _waitUntilDisconnect;
|
||||
|
||||
public event EventHandler<WebSocketBinaryMessageEventArgs> BinaryMessage = delegate { };
|
||||
public event EventHandler<WebSocketTextMessageEventArgs> TextMessage = delegate { };
|
||||
public event EventHandler<BinaryMessageEventArgs> BinaryMessage = delegate { };
|
||||
public event EventHandler<TextMessageEventArgs> TextMessage = delegate { };
|
||||
private void OnBinaryMessage(byte[] data)
|
||||
=> BinaryMessage(this, new WebSocketBinaryMessageEventArgs(data));
|
||||
=> BinaryMessage(this, new BinaryMessageEventArgs(data));
|
||||
private void OnTextMessage(string msg)
|
||||
=> TextMessage(this, new WebSocketTextMessageEventArgs(msg));
|
||||
=> TextMessage(this, new TextMessageEventArgs(msg));
|
||||
|
||||
internal WS4NetEngine(DiscordConfig config, TaskManager taskManager)
|
||||
{
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
#if DOTNET5_4
|
||||
/*using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using State = System.Net.WebSockets.WebSocketState;
|
||||
|
||||
namespace Discord.Net.WebSockets
|
||||
{
|
||||
internal class BuiltInWebSocketEngine : IWebSocketEngine
|
||||
{
|
||||
private const int ReceiveChunkSize = 4096;
|
||||
private const int SendChunkSize = 4096;
|
||||
private const int HR_TIMEOUT = -2147012894;
|
||||
|
||||
private readonly ConcurrentQueue<string> _sendQueue;
|
||||
private readonly int _sendInterval;
|
||||
private ClientWebSocket _webSocket;
|
||||
|
||||
public event EventHandler<WebSocketMessageEventArgs> ProcessMessage;
|
||||
private void RaiseProcessMessage(string msg)
|
||||
{
|
||||
if (ProcessMessage != null)
|
||||
ProcessMessage(this, new WebSocketMessageEventArgs(msg));
|
||||
}
|
||||
|
||||
public BuiltInWebSocketEngine(int sendInterval)
|
||||
{
|
||||
_sendInterval = sendInterval;
|
||||
_sendQueue = new ConcurrentQueue<string>();
|
||||
}
|
||||
|
||||
public Task Connect(string host, CancellationToken cancelToken)
|
||||
{
|
||||
_webSocket = new ClientWebSocket();
|
||||
return _webSocket.ConnectAsync(new Uri(host), cancelToken);
|
||||
}
|
||||
|
||||
public Task Disconnect()
|
||||
{
|
||||
string ignored;
|
||||
while (_sendQueue.TryDequeue(out ignored)) { }
|
||||
_webSocket.Dispose();
|
||||
_webSocket = new ClientWebSocket();
|
||||
return TaskHelper.CompletedTask;
|
||||
}
|
||||
|
||||
public IEnumerable<Task> GetTasks(CancellationToken cancelToken)
|
||||
{
|
||||
return new Task[]
|
||||
{
|
||||
ReceiveAsync(cancelToken),
|
||||
SendAsync(cancelToken)
|
||||
};
|
||||
}
|
||||
|
||||
private Task ReceiveAsync(CancellationToken cancelToken)
|
||||
{
|
||||
return Task.Run(async () =>
|
||||
{
|
||||
var buffer = new ArraySegment<byte>(new byte[ReceiveChunkSize]);
|
||||
var builder = new StringBuilder();
|
||||
|
||||
try
|
||||
{
|
||||
while (_webSocket.State == State.Open && !cancelToken.IsCancellationRequested)
|
||||
{
|
||||
WebSocketReceiveResult result = null;
|
||||
do
|
||||
{
|
||||
if (_webSocket.State != State.Open || cancelToken.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
result = await _webSocket.ReceiveAsync(buffer, cancelToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Win32Exception ex) when (ex.HResult == HR_TIMEOUT)
|
||||
{
|
||||
throw new Exception($"Connection timed out.");
|
||||
}
|
||||
|
||||
if (result.MessageType == WebSocketMessageType.Close)
|
||||
throw new Exception($"Got Close Message ({result.CloseStatus?.ToString() ?? "Unexpected"}): " +
|
||||
result.CloseStatusDescription != "" ? result.CloseStatusDescription : "No Reason");
|
||||
else
|
||||
builder.Append(Encoding.UTF8.GetString(buffer.Array, buffer.Offset, result.Count));
|
||||
|
||||
}
|
||||
while (result == null || !result.EndOfMessage);
|
||||
|
||||
RaiseProcessMessage(builder.ToString());
|
||||
|
||||
builder.Clear();
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
});
|
||||
}
|
||||
private Task SendAsync(CancellationToken cancelToken)
|
||||
{
|
||||
return Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
while (_webSocket.State == State.Open && !cancelToken.IsCancellationRequested)
|
||||
{
|
||||
string json;
|
||||
while (_sendQueue.TryDequeue(out json))
|
||||
{
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(json);
|
||||
int frameCount = (int)Math.Ceiling((double)bytes.Length / SendChunkSize);
|
||||
|
||||
int offset = 0;
|
||||
for (var i = 0; i < frameCount; i++, offset += SendChunkSize)
|
||||
{
|
||||
bool isLast = i == (frameCount - 1);
|
||||
|
||||
int count;
|
||||
if (isLast)
|
||||
count = bytes.Length - (i * SendChunkSize);
|
||||
else
|
||||
count = SendChunkSize;
|
||||
|
||||
try
|
||||
{
|
||||
await _webSocket.SendAsync(new ArraySegment<byte>(bytes, offset, count), WebSocketMessageType.Text, isLast, cancelToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Win32Exception ex) when (ex.HResult == HR_TIMEOUT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
await Task.Delay(_sendInterval, cancelToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
});
|
||||
}
|
||||
|
||||
public void QueueMessage(string message)
|
||||
{
|
||||
_sendQueue.Enqueue(message);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
#endif
|
||||
17
src/Discord.Net/Net/WebSockets/WebSocketEventEventArgs.cs
Normal file
17
src/Discord.Net/Net/WebSockets/WebSocketEventEventArgs.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
|
||||
namespace Discord.Net.WebSockets
|
||||
{
|
||||
public class WebSocketEventEventArgs : EventArgs
|
||||
{
|
||||
public string Type { get; }
|
||||
public JToken Payload { get; }
|
||||
|
||||
internal WebSocketEventEventArgs(string type, JToken data)
|
||||
{
|
||||
Type = type;
|
||||
Payload = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
/*#if !DOTNET5_4
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using WSSharpWebSocket = WebSocketSharp.WebSocket;
|
||||
|
||||
namespace Discord.Net.WebSockets
|
||||
{
|
||||
internal class WebSocketSharpEngine : IWebSocketEngine
|
||||
{
|
||||
private readonly DiscordConfig _config;
|
||||
private readonly Logger _logger;
|
||||
private readonly ConcurrentQueue<string> _sendQueue;
|
||||
private readonly WebSocket _parent;
|
||||
private WSSharpWebSocket _webSocket;
|
||||
|
||||
public event EventHandler<WebSocketBinaryMessageEventArgs> BinaryMessage;
|
||||
public event EventHandler<WebSocketTextMessageEventArgs> TextMessage;
|
||||
private void RaiseBinaryMessage(byte[] data)
|
||||
{
|
||||
if (BinaryMessage != null)
|
||||
BinaryMessage(this, new WebSocketBinaryMessageEventArgs(data));
|
||||
}
|
||||
private void RaiseTextMessage(string msg)
|
||||
{
|
||||
if (TextMessage != null)
|
||||
TextMessage(this, new WebSocketTextMessageEventArgs(msg));
|
||||
}
|
||||
|
||||
internal WebSocketSharpEngine(WebSocket parent, DiscordConfig config, Logger logger)
|
||||
{
|
||||
_parent = parent;
|
||||
_config = config;
|
||||
_logger = logger;
|
||||
_sendQueue = new ConcurrentQueue<string>();
|
||||
}
|
||||
|
||||
public Task Connect(string host, CancellationToken cancelToken)
|
||||
{
|
||||
_webSocket = new WSSharpWebSocket(host);
|
||||
_webSocket.EmitOnPing = false;
|
||||
_webSocket.EnableRedirection = true;
|
||||
//_webSocket.Compression = WebSocketSharp.CompressionMethod.Deflate;
|
||||
_webSocket.SetProxy(null, null, null); //Disable
|
||||
//_webSocket.SetProxy(_config.ProxyUrl, _config.ProxyCredentials?.UserName, _config.ProxyCredentials?.Password);
|
||||
_webSocket.OnMessage += (s, e) =>
|
||||
{
|
||||
if (e.IsBinary)
|
||||
RaiseBinaryMessage(e.RawData);
|
||||
else if (e.IsText)
|
||||
RaiseTextMessage(e.Data);
|
||||
};
|
||||
_webSocket.OnError += async (s, e) =>
|
||||
{
|
||||
_logger.Log(LogSeverity.Error, "WebSocket Error", e.Exception);
|
||||
await _parent.SignalDisconnect(e.Exception, isUnexpected: true).ConfigureAwait(false);
|
||||
};
|
||||
_webSocket.OnClose += async (s, e) =>
|
||||
{
|
||||
string code = e.WasClean ? e.Code.ToString() : "Unexpected";
|
||||
string reason = e.Reason != "" ? e.Reason : "No Reason";
|
||||
var ex = new Exception($"Got Close Message ({code}): {reason}");
|
||||
await _parent.SignalDisconnect(ex, isUnexpected: true).ConfigureAwait(false);
|
||||
};
|
||||
_webSocket.Log.Output = (e, m) => { }; //Dont let websocket-sharp print to console directly
|
||||
_webSocket.Connect();
|
||||
return TaskHelper.CompletedTask;
|
||||
}
|
||||
|
||||
public Task Disconnect()
|
||||
{
|
||||
string ignored;
|
||||
while (_sendQueue.TryDequeue(out ignored)) { }
|
||||
|
||||
var socket = _webSocket;
|
||||
_webSocket = null;
|
||||
if (socket != null)
|
||||
socket.Close();
|
||||
|
||||
return TaskHelper.CompletedTask;
|
||||
}
|
||||
|
||||
public IEnumerable<Task> GetTasks(CancellationToken cancelToken)
|
||||
{
|
||||
return new Task[]
|
||||
{
|
||||
SendAsync(cancelToken)
|
||||
};
|
||||
}
|
||||
|
||||
private Task SendAsync(CancellationToken cancelToken)
|
||||
{
|
||||
var sendInterval = _config.WebSocketInterval;
|
||||
return Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
while (!cancelToken.IsCancellationRequested)
|
||||
{
|
||||
string json;
|
||||
while (_sendQueue.TryDequeue(out json))
|
||||
_webSocket.Send(json);
|
||||
await Task.Delay(sendInterval, cancelToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
});
|
||||
}
|
||||
|
||||
public void QueueMessage(string message)
|
||||
{
|
||||
_sendQueue.Enqueue(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif*/
|
||||
@@ -1,71 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
/*internal class Reference<T>
|
||||
where T : CachedObject<ulong>
|
||||
{
|
||||
private Action<T> _onCache, _onUncache;
|
||||
private Func<ulong, T> _getItem;
|
||||
private ulong? _id;
|
||||
public ulong? Id
|
||||
{
|
||||
get { return _id; }
|
||||
set
|
||||
{
|
||||
_id = value;
|
||||
_value = null;
|
||||
}
|
||||
}
|
||||
|
||||
private T _value;
|
||||
public T Value
|
||||
{
|
||||
get
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public T Load()
|
||||
{
|
||||
var v = _value; //A little trickery to make this threadsafe
|
||||
var id = _id;
|
||||
if (v != null && !_value.IsCached)
|
||||
{
|
||||
v = null;
|
||||
_value = null;
|
||||
}
|
||||
if (v == null && id != null)
|
||||
{
|
||||
v = _getItem(id.Value);
|
||||
if (v != null && _onCache != null)
|
||||
_onCache(v);
|
||||
_value = v;
|
||||
}
|
||||
return v;
|
||||
return Value != null; //Used for precaching
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
if (_onUncache != null)
|
||||
{
|
||||
var v = _value;
|
||||
if (v != null && _onUncache != null)
|
||||
_onUncache(v);
|
||||
}
|
||||
}
|
||||
|
||||
public Reference(Func<ulong, T> onUpdate, Action<T> onCache = null, Action<T> onUncache = null)
|
||||
: this(null, onUpdate, onCache, onUncache)
|
||||
{ }
|
||||
public Reference(ulong? id, Func<ulong, T> getItem, Action<T> onCache = null, Action<T> onUncache = null)
|
||||
{
|
||||
_id = id;
|
||||
_getItem = getItem;
|
||||
_onCache = onCache;
|
||||
_onUncache = onUncache;
|
||||
_value = null;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
@@ -5,6 +5,7 @@ namespace Discord
|
||||
public class RoleEventArgs : EventArgs
|
||||
{
|
||||
public Role Role { get; }
|
||||
|
||||
public Server Server => Role.Server;
|
||||
|
||||
public RoleEventArgs(Role role) { Role = role; }
|
||||
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
public class ServiceManager
|
||||
public sealed class ServiceManager
|
||||
{
|
||||
private readonly Dictionary<Type, IService> _services;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ using System.Threading.Tasks;
|
||||
namespace Discord
|
||||
{
|
||||
/// <summary> Helper class used to manage several tasks and keep them in sync. If any single task errors or stops, all other tasks will also be stopped. </summary>
|
||||
public class TaskManager
|
||||
public sealed class TaskManager
|
||||
{
|
||||
private readonly object _lock;
|
||||
private readonly Func<Task> _stopAction;
|
||||
@@ -22,7 +22,7 @@ namespace Discord
|
||||
public Exception Exception => _stopReason?.SourceException;
|
||||
private ExceptionDispatchInfo _stopReason;
|
||||
|
||||
public TaskManager()
|
||||
internal TaskManager()
|
||||
{
|
||||
_lock = new object();
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Discord
|
||||
public class UserEventArgs : EventArgs
|
||||
{
|
||||
public User User { get; }
|
||||
|
||||
public Server Server => User.Server;
|
||||
|
||||
public UserEventArgs(User user) { User = user; }
|
||||
@@ -1,5 +1,4 @@
|
||||
using Discord.Legacy;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
Reference in New Issue
Block a user