Cleaned up several classes
This commit is contained in:
@@ -84,9 +84,18 @@
|
|||||||
<Compile Include="..\Discord.Net.Audio\Sodium\SecretBox.cs">
|
<Compile Include="..\Discord.Net.Audio\Sodium\SecretBox.cs">
|
||||||
<Link>Sodium\SecretBox.cs</Link>
|
<Link>Sodium\SecretBox.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\Discord.Net.Audio\UserIsTalkingEventArgs.cs">
|
||||||
|
<Link>UserIsTalkingEventArgs.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net.Audio\VoiceBuffer.cs">
|
<Compile Include="..\Discord.Net.Audio\VoiceBuffer.cs">
|
||||||
<Link>VoiceBuffer.cs</Link>
|
<Link>VoiceBuffer.cs</Link>
|
||||||
</Compile>
|
</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" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,49 +1,10 @@
|
|||||||
using Discord.Net.WebSockets;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Discord.Audio
|
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
|
public class AudioService : IService
|
||||||
{
|
{
|
||||||
private AudioClient _defaultClient;
|
private AudioClient _defaultClient;
|
||||||
@@ -51,46 +12,33 @@ namespace Discord.Audio
|
|||||||
private ConcurrentDictionary<User, bool> _talkingUsers;
|
private ConcurrentDictionary<User, bool> _talkingUsers;
|
||||||
//private int _nextClientId;
|
//private int _nextClientId;
|
||||||
|
|
||||||
internal DiscordClient Client => _client;
|
internal DiscordClient Client { get; private set; }
|
||||||
private DiscordClient _client;
|
public AudioServiceConfig Config { get; }
|
||||||
|
|
||||||
public AudioServiceConfig Config => _config;
|
public event EventHandler Connected = delegate { };
|
||||||
private readonly AudioServiceConfig _config;
|
public event EventHandler<VoiceDisconnectedEventArgs> Disconnected = delegate { };
|
||||||
|
public event EventHandler<VoicePacketEventArgs> PacketReceived = delegate { };
|
||||||
|
public event EventHandler<UserIsSpeakingEventArgs> UserIsSpeakingUpdated = delegate { };
|
||||||
|
|
||||||
public event EventHandler Connected;
|
private void OnConnected()
|
||||||
private void RaiseConnected()
|
=> Connected(this, EventArgs.Empty);
|
||||||
{
|
private void OnDisconnected(ulong serverId, bool wasUnexpected, Exception ex)
|
||||||
if (Connected != null)
|
=> Disconnected(this, new VoiceDisconnectedEventArgs(serverId, wasUnexpected, ex));
|
||||||
Connected(this, EventArgs.Empty);
|
internal void OnPacketReceived(VoicePacketEventArgs e)
|
||||||
}
|
=> PacketReceived(this, e);
|
||||||
public event EventHandler<VoiceDisconnectedEventArgs> Disconnected;
|
private void OnUserIsSpeakingUpdated(User user, bool isSpeaking)
|
||||||
private void RaiseDisconnected(ulong serverId, DisconnectedEventArgs e)
|
=> UserIsSpeakingUpdated(this, new UserIsSpeakingEventArgs(user, isSpeaking));
|
||||||
{
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
public AudioService(AudioServiceConfig config)
|
public AudioService(AudioServiceConfig config)
|
||||||
{
|
{
|
||||||
_config = config;
|
Config = config;
|
||||||
_config.Lock();
|
|
||||||
}
|
}
|
||||||
public void Install(DiscordClient client)
|
public void Install(DiscordClient client)
|
||||||
{
|
{
|
||||||
_client = client;
|
Client = client;
|
||||||
if (Config.EnableMultiserver)
|
Config.Lock();
|
||||||
|
|
||||||
|
if (Config.EnableMultiserver)
|
||||||
_voiceClients = new ConcurrentDictionary<ulong, IAudioClient>();
|
_voiceClients = new ConcurrentDictionary<ulong, IAudioClient>();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -113,7 +61,7 @@ namespace Discord.Audio
|
|||||||
{
|
{
|
||||||
bool ignored;
|
bool ignored;
|
||||||
if (_talkingUsers.TryRemove(member.Key, out 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">
|
<Compile Include="..\Discord.Net.Commands\CommandBuilder.cs">
|
||||||
<Link>CommandBuilder.cs</Link>
|
<Link>CommandBuilder.cs</Link>
|
||||||
</Compile>
|
</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">
|
<Compile Include="..\Discord.Net.Commands\CommandExtensions.cs">
|
||||||
<Link>CommandExtensions.cs</Link>
|
<Link>CommandExtensions.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net.Commands\CommandMap.cs">
|
<Compile Include="..\Discord.Net.Commands\CommandMap.cs">
|
||||||
<Link>CommandMap.cs</Link>
|
<Link>CommandMap.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\Discord.Net.Commands\CommandParameter.cs">
|
||||||
|
<Link>CommandParameter.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net.Commands\CommandParser.cs">
|
<Compile Include="..\Discord.Net.Commands\CommandParser.cs">
|
||||||
<Link>CommandParser.cs</Link>
|
<Link>CommandParser.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net.Commands\CommandService.cs">
|
<Compile Include="..\Discord.Net.Commands\CommandService.cs">
|
||||||
<Link>CommandService.cs</Link>
|
<Link>CommandService.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net.Commands\CommandService.Events.cs">
|
|
||||||
<Link>CommandService.Events.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\Discord.Net.Commands\CommandServiceConfig.cs">
|
<Compile Include="..\Discord.Net.Commands\CommandServiceConfig.cs">
|
||||||
<Link>CommandServiceConfig.cs</Link>
|
<Link>CommandServiceConfig.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|||||||
@@ -5,48 +5,24 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Discord.Commands
|
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 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 string Category { get; internal set; }
|
||||||
public bool IsHidden { get; internal set; }
|
public bool IsHidden { get; internal set; }
|
||||||
public string Description { get; internal set; }
|
public string Description { get; internal set; }
|
||||||
|
|
||||||
public IEnumerable<string> Aliases => _aliases;
|
public IEnumerable<string> Aliases => _aliases;
|
||||||
private string[] _aliases;
|
|
||||||
|
|
||||||
public IEnumerable<CommandParameter> Parameters => _parameters;
|
public IEnumerable<CommandParameter> Parameters => _parameters;
|
||||||
internal CommandParameter[] _parameters;
|
public CommandParameter this[string name] => _parametersByName[name];
|
||||||
|
|
||||||
private IPermissionChecker[] _checks;
|
|
||||||
private Func<CommandEventArgs, Task> _runFunc;
|
|
||||||
internal readonly Dictionary<string, CommandParameter> _parametersByName;
|
|
||||||
|
|
||||||
internal Command(string text)
|
internal Command(string text)
|
||||||
{
|
{
|
||||||
Text = text;
|
Text = text;
|
||||||
IsHidden = false;
|
IsHidden = false;
|
||||||
@@ -55,7 +31,6 @@ namespace Discord.Commands
|
|||||||
_parametersByName = new Dictionary<string, CommandParameter>();
|
_parametersByName = new Dictionary<string, CommandParameter>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandParameter this[string name] => _parametersByName[name];
|
|
||||||
|
|
||||||
internal void SetAliases(string[] aliases)
|
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
|
namespace Discord.Commands
|
||||||
{
|
{
|
||||||
/// <summary> A Discord.Net client with extensions for handling common bot operations like text commands. </summary>
|
public partial class CommandService : IService
|
||||||
public sealed partial class CommandService : IService
|
|
||||||
{
|
{
|
||||||
private readonly CommandServiceConfig _config;
|
private readonly List<Command> _allCommands;
|
||||||
private readonly CommandGroupBuilder _root;
|
private readonly Dictionary<string, CommandMap> _categories;
|
||||||
private DiscordClient _client;
|
private readonly CommandMap _map; //Command map stores all commands by their input text, used for fast resolving and parsing
|
||||||
|
|
||||||
public DiscordClient Client => _client;
|
public CommandServiceConfig Config { get; }
|
||||||
public CommandGroupBuilder Root => _root;
|
public CommandGroupBuilder Root { get; }
|
||||||
|
public DiscordClient Client { get; private set; }
|
||||||
|
|
||||||
//AllCommands store a flattened collection of all commands
|
//AllCommands store a flattened collection of all commands
|
||||||
public IEnumerable<Command> AllCommands => _allCommands;
|
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;
|
|
||||||
|
|
||||||
//Groups store all commands by their module, used for more informative help
|
//Groups store all commands by their module, used for more informative help
|
||||||
internal IEnumerable<CommandMap> Categories => _categories.Values;
|
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>();
|
_allCommands = new List<Command>();
|
||||||
_map = new CommandMap(null, "", "");
|
_map = new CommandMap(null, "", "");
|
||||||
_categories = new Dictionary<string, CommandMap>();
|
_categories = new Dictionary<string, CommandMap>();
|
||||||
_root = new CommandGroupBuilder(this, "", null);
|
Root = new CommandGroupBuilder(this, "", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IService.Install(DiscordClient client)
|
void IService.Install(DiscordClient client)
|
||||||
{
|
{
|
||||||
_client = client;
|
Client = client;
|
||||||
_config.Lock();
|
Config.Lock();
|
||||||
|
|
||||||
if (_config.HelpMode != HelpMode.Disable)
|
if (Config.HelpMode != HelpMode.Disable)
|
||||||
{
|
{
|
||||||
CreateCommand("help")
|
CreateCommand("help")
|
||||||
.Parameter("command", ParameterType.Multiple)
|
.Parameter("command", ParameterType.Multiple)
|
||||||
@@ -49,7 +52,7 @@ namespace Discord.Commands
|
|||||||
.Description("Returns information about commands.")
|
.Description("Returns information about commands.")
|
||||||
.Do(async e =>
|
.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
|
if (e.Args.Length > 0) //Show command help
|
||||||
{
|
{
|
||||||
var map = _map.GetItem(string.Join(" ", e.Args));
|
var map = _map.GetItem(string.Join(" ", e.Args));
|
||||||
@@ -66,13 +69,13 @@ namespace Discord.Commands
|
|||||||
client.MessageReceived += async (s, e) =>
|
client.MessageReceived += async (s, e) =>
|
||||||
{
|
{
|
||||||
if (_allCommands.Count == 0) return;
|
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;
|
string msg = e.Message.RawText;
|
||||||
if (msg.Length == 0) return;
|
if (msg.Length == 0) return;
|
||||||
|
|
||||||
//Check for command char if one is provided
|
//Check for command char if one is provided
|
||||||
var chars = _config.CommandChars;
|
var chars = Config.CommandChars;
|
||||||
if (chars.Length > 0)
|
if (chars.Length > 0)
|
||||||
{
|
{
|
||||||
if (!chars.Contains(msg[0]))
|
if (!chars.Contains(msg[0]))
|
||||||
@@ -87,7 +90,7 @@ namespace Discord.Commands
|
|||||||
if (commands == null)
|
if (commands == null)
|
||||||
{
|
{
|
||||||
CommandEventArgs errorArgs = new CommandEventArgs(e.Message, null, null);
|
CommandEventArgs errorArgs = new CommandEventArgs(e.Message, null, null);
|
||||||
RaiseCommandError(CommandErrorType.UnknownCommand, errorArgs);
|
OnCommandError(CommandErrorType.UnknownCommand, errorArgs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -104,7 +107,7 @@ namespace Discord.Commands
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var errorArgs = new CommandEventArgs(e.Message, command, null);
|
var errorArgs = new CommandEventArgs(e.Message, command, null);
|
||||||
RaiseCommandError(error.Value, errorArgs);
|
OnCommandError(error.Value, errorArgs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,24 +118,24 @@ namespace Discord.Commands
|
|||||||
string errorText;
|
string errorText;
|
||||||
if (!command.CanRun(eventArgs.User, eventArgs.Channel, out 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the command
|
// Run the command
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RaiseRanCommand(eventArgs);
|
OnCommand(eventArgs);
|
||||||
await command.Run(eventArgs).ConfigureAwait(false);
|
await command.Run(eventArgs).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
RaiseCommandError(CommandErrorType.Exception, eventArgs, ex);
|
OnCommandError(CommandErrorType.Exception, eventArgs, ex);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var errorArgs2 = new CommandEventArgs(e.Message, null, null);
|
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");
|
output.Append("\n\n");
|
||||||
|
|
||||||
var chars = _config.CommandChars;
|
var chars = Config.CommandChars;
|
||||||
if (chars.Length > 0)
|
if (chars.Length > 0)
|
||||||
{
|
{
|
||||||
if (chars.Length == 1)
|
if (chars.Length == 1)
|
||||||
@@ -294,8 +297,8 @@ namespace Discord.Commands
|
|||||||
output.AppendLine($"Aliases: `" + string.Join("`, `", command.Aliases) + '`');
|
output.AppendLine($"Aliases: `" + string.Join("`, `", command.Aliases) + '`');
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CreateGroup(string cmd, Action<CommandGroupBuilder> config = null) => _root.CreateGroup(cmd, config);
|
public void CreateGroup(string cmd, Action<CommandGroupBuilder> config = null) => Root.CreateGroup(cmd, config);
|
||||||
public CommandBuilder CreateCommand(string cmd) => _root.CreateCommand(cmd);
|
public CommandBuilder CreateCommand(string cmd) => Root.CreateCommand(cmd);
|
||||||
|
|
||||||
internal void AddCommand(Command command)
|
internal void AddCommand(Command command)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace Discord.Modules
|
namespace Discord.Modules
|
||||||
{
|
{
|
||||||
public class ModuleManager
|
public sealed class ModuleManager
|
||||||
{
|
{
|
||||||
public event EventHandler<ServerEventArgs> ServerEnabled = delegate { };
|
public event EventHandler<ServerEventArgs> ServerEnabled = delegate { };
|
||||||
public event EventHandler<ServerEventArgs> ServerDisabled = delegate { };
|
public event EventHandler<ServerEventArgs> ServerDisabled = delegate { };
|
||||||
|
|||||||
@@ -5,21 +5,19 @@ namespace Discord.Modules
|
|||||||
{
|
{
|
||||||
public class ModuleService : IService
|
public class ModuleService : IService
|
||||||
{
|
{
|
||||||
private DiscordClient _client;
|
public DiscordClient Client { get; private set; }
|
||||||
|
|
||||||
//ModuleServiceConfig Config { get; }
|
|
||||||
public IEnumerable<ModuleManager> Modules => _modules.Values;
|
public IEnumerable<ModuleManager> Modules => _modules.Values;
|
||||||
private readonly Dictionary<IModule, ModuleManager> _modules;
|
private readonly Dictionary<IModule, ModuleManager> _modules;
|
||||||
|
|
||||||
public ModuleService(/*ModuleServiceConfig config*/)
|
public ModuleService()
|
||||||
{
|
{
|
||||||
//Config = config;
|
|
||||||
_modules = new Dictionary<IModule, ModuleManager>();
|
_modules = new Dictionary<IModule, ModuleManager>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IService.Install(DiscordClient client)
|
void IService.Install(DiscordClient client)
|
||||||
{
|
{
|
||||||
_client = client;
|
Client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Install<T>(T module, string name, FilterType type)
|
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 (module == null) throw new ArgumentNullException(nameof(module));
|
||||||
if (name == null) throw new ArgumentNullException(nameof(name));
|
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 (Client == null)
|
||||||
if (_modules.ContainsKey(module)) throw new InvalidOperationException("This module has already been added.");
|
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);
|
_modules.Add(module, manager);
|
||||||
module.Install(manager);
|
module.Install(manager);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -391,15 +391,24 @@
|
|||||||
<Compile Include="..\Discord.Net\API\Status\Rest\Upcoming.cs">
|
<Compile Include="..\Discord.Net\API\Status\Rest\Upcoming.cs">
|
||||||
<Link>API\Status\Rest\Upcoming.cs</Link>
|
<Link>API\Status\Rest\Upcoming.cs</Link>
|
||||||
</Compile>
|
</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">
|
<Compile Include="..\Discord.Net\DiscordClient.cs">
|
||||||
<Link>DiscordClient.cs</Link>
|
<Link>DiscordClient.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\DiscordClient.Events.cs">
|
<Compile Include="..\Discord.Net\DiscordClient.Events.cs">
|
||||||
<Link>DiscordClient.Events.cs</Link>
|
<Link>DiscordClient.Events.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\DiscordClient.Obsolete.cs">
|
|
||||||
<Link>DiscordClient.Obsolete.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\Discord.Net\DiscordConfig.cs">
|
<Compile Include="..\Discord.Net\DiscordConfig.cs">
|
||||||
<Link>DiscordConfig.cs</Link>
|
<Link>DiscordConfig.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -421,33 +430,6 @@
|
|||||||
<Compile Include="..\Discord.Net\Enums\UserStatus.cs">
|
<Compile Include="..\Discord.Net\Enums\UserStatus.cs">
|
||||||
<Link>Enums\UserStatus.cs</Link>
|
<Link>Enums\UserStatus.cs</Link>
|
||||||
</Compile>
|
</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">
|
<Compile Include="..\Discord.Net\Extensions.cs">
|
||||||
<Link>Extensions.cs</Link>
|
<Link>Extensions.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -457,12 +439,21 @@
|
|||||||
<Compile Include="..\Discord.Net\IService.cs">
|
<Compile Include="..\Discord.Net\IService.cs">
|
||||||
<Link>IService.cs</Link>
|
<Link>IService.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\Discord.Net\Legacy.cs">
|
||||||
|
<Link>Legacy.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\Logging\Logger.cs">
|
<Compile Include="..\Discord.Net\Logging\Logger.cs">
|
||||||
<Link>Logging\Logger.cs</Link>
|
<Link>Logging\Logger.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\Logging\LogManager.cs">
|
<Compile Include="..\Discord.Net\Logging\LogManager.cs">
|
||||||
<Link>Logging\LogManager.cs</Link>
|
<Link>Logging\LogManager.cs</Link>
|
||||||
</Compile>
|
</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">
|
<Compile Include="..\Discord.Net\MessageQueue.cs">
|
||||||
<Link>MessageQueue.cs</Link>
|
<Link>MessageQueue.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -502,6 +493,9 @@
|
|||||||
<Compile Include="..\Discord.Net\Net\Rest\IRestEngine.cs">
|
<Compile Include="..\Discord.Net\Net\Rest\IRestEngine.cs">
|
||||||
<Link>Net\Rest\IRestEngine.cs</Link>
|
<Link>Net\Rest\IRestEngine.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\Discord.Net\Net\Rest\RequestEventArgs.cs">
|
||||||
|
<Link>Net\Rest\RequestEventArgs.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\Net\Rest\RestClient.cs">
|
<Compile Include="..\Discord.Net\Net\Rest\RestClient.cs">
|
||||||
<Link>Net\Rest\RestClient.cs</Link>
|
<Link>Net\Rest\RestClient.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -514,6 +508,9 @@
|
|||||||
<Compile Include="..\Discord.Net\Net\WebSocketException.cs">
|
<Compile Include="..\Discord.Net\Net\WebSocketException.cs">
|
||||||
<Link>Net\WebSockets\WebSocketException.cs</Link>
|
<Link>Net\WebSockets\WebSocketException.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\Discord.Net\Net\WebSockets\BinaryMessageEventArgs.cs">
|
||||||
|
<Link>Net\WebSockets\BinaryMessageEventArgs.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\Net\WebSockets\BuiltInEngine.cs">
|
<Compile Include="..\Discord.Net\Net\WebSockets\BuiltInEngine.cs">
|
||||||
<Link>Net\WebSockets\BuiltInEngine.cs</Link>
|
<Link>Net\WebSockets\BuiltInEngine.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -523,30 +520,39 @@
|
|||||||
<Compile Include="..\Discord.Net\Net\WebSockets\IWebSocketEngine.cs">
|
<Compile Include="..\Discord.Net\Net\WebSockets\IWebSocketEngine.cs">
|
||||||
<Link>Net\WebSockets\IWebSocketEngine.cs</Link>
|
<Link>Net\WebSockets\IWebSocketEngine.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\Net\WebSockets\WebSocket.BuiltIn.cs">
|
<Compile Include="..\Discord.Net\Net\WebSockets\TextMessageEventArgs.cs">
|
||||||
<Link>Net\WebSockets\WebSocket.BuiltIn.cs</Link>
|
<Link>Net\WebSockets\TextMessageEventArgs.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\Net\WebSockets\WebSocket.cs">
|
<Compile Include="..\Discord.Net\Net\WebSockets\WebSocket.cs">
|
||||||
<Link>Net\WebSockets\WebSocket.cs</Link>
|
<Link>Net\WebSockets\WebSocket.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\Net\WebSockets\WebSocketSharpEngine.cs">
|
<Compile Include="..\Discord.Net\Net\WebSockets\WebSocketEventEventArgs.cs">
|
||||||
<Link>Net\WebSockets\WebSocketSharpEngine.cs</Link>
|
<Link>Net\WebSockets\WebSocketEventEventArgs.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\Net\WebSockets\WS4NetEngine.cs">
|
<Compile Include="..\Discord.Net\Net\WebSockets\WS4NetEngine.cs">
|
||||||
<Link>Net\WebSockets\WS4NetEngine.cs</Link>
|
<Link>Net\WebSockets\WS4NetEngine.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\Reference.cs">
|
<Compile Include="..\Discord.Net\ProfileEventArgs.cs">
|
||||||
<Link>Reference.cs</Link>
|
<Link>ProfileEventArgs.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\RelativeDirection.cs">
|
<Compile Include="..\Discord.Net\RelativeDirection.cs">
|
||||||
<Link>RelativeDirection.cs</Link>
|
<Link>RelativeDirection.cs</Link>
|
||||||
</Compile>
|
</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">
|
<Compile Include="..\Discord.Net\ServiceManager.cs">
|
||||||
<Link>ServiceManager.cs</Link>
|
<Link>ServiceManager.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\TaskManager.cs">
|
<Compile Include="..\Discord.Net\TaskManager.cs">
|
||||||
<Link>TaskManager.cs</Link>
|
<Link>TaskManager.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\Discord.Net\UserEventArgs.cs">
|
||||||
|
<Link>UserEventArgs.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using System.Collections.Generic;
|
|||||||
namespace Discord.API.Client.GatewaySocket
|
namespace Discord.API.Client.GatewaySocket
|
||||||
{
|
{
|
||||||
[JsonObject(MemberSerialization.OptIn)]
|
[JsonObject(MemberSerialization.OptIn)]
|
||||||
internal sealed class IdentifyCommand : IWebSocketMessage
|
public sealed class IdentifyCommand : IWebSocketMessage
|
||||||
{
|
{
|
||||||
int IWebSocketMessage.OpCode => (int)OpCodes.Identify;
|
int IWebSocketMessage.OpCode => (int)OpCodes.Identify;
|
||||||
object IWebSocketMessage.Payload => this;
|
object IWebSocketMessage.Payload => this;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using Newtonsoft.Json;
|
|||||||
namespace Discord.API.Client.GatewaySocket
|
namespace Discord.API.Client.GatewaySocket
|
||||||
{
|
{
|
||||||
[JsonObject(MemberSerialization.OptIn)]
|
[JsonObject(MemberSerialization.OptIn)]
|
||||||
internal sealed class RequestMembersCommand : IWebSocketMessage
|
public sealed class RequestMembersCommand : IWebSocketMessage
|
||||||
{
|
{
|
||||||
int IWebSocketMessage.OpCode => (int)OpCodes.RequestGuildMembers;
|
int IWebSocketMessage.OpCode => (int)OpCodes.RequestGuildMembers;
|
||||||
object IWebSocketMessage.Payload => this;
|
object IWebSocketMessage.Payload => this;
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using Discord.API.Converters;
|
namespace Discord.API.Client.GatewaySocket
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Discord.API.Client.GatewaySocket
|
|
||||||
{
|
{
|
||||||
public sealed class GuildBanAddEvent : MemberReference
|
public sealed class GuildBanAddEvent : MemberReference { }
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using Discord.API.Converters;
|
namespace Discord.API.Client.GatewaySocket
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
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
|
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))]
|
[JsonProperty("guild_id"), JsonConverter(typeof(LongStringConverter))]
|
||||||
public ulong GuildId { get; set; }
|
public ulong GuildId { get; set; }
|
||||||
[JsonProperty("members")]
|
[JsonProperty("members")]
|
||||||
public Member[] Members;
|
public Member[] Members { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace Discord.API.Client
|
|||||||
object Payload { get; }
|
object Payload { get; }
|
||||||
bool IsPrivate { get; }
|
bool IsPrivate { get; }
|
||||||
}
|
}
|
||||||
public class WebSocketMessage
|
public sealed class WebSocketMessage
|
||||||
{
|
{
|
||||||
[JsonProperty("op")]
|
[JsonProperty("op")]
|
||||||
public int? Operation { get; set; }
|
public int? Operation { get; set; }
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace Discord.API.Converters
|
namespace Discord.API.Converters
|
||||||
{
|
{
|
||||||
public class LongStringConverter : JsonConverter
|
public sealed class LongStringConverter : JsonConverter
|
||||||
{
|
{
|
||||||
public override bool CanConvert(Type objectType)
|
public override bool CanConvert(Type objectType)
|
||||||
=> objectType == typeof(ulong);
|
=> objectType == typeof(ulong);
|
||||||
@@ -14,7 +14,7 @@ namespace Discord.API.Converters
|
|||||||
=> writer.WriteValue(((ulong)value).ToIdString());
|
=> writer.WriteValue(((ulong)value).ToIdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NullableLongStringConverter : JsonConverter
|
public sealed class NullableLongStringConverter : JsonConverter
|
||||||
{
|
{
|
||||||
public override bool CanConvert(Type objectType)
|
public override bool CanConvert(Type objectType)
|
||||||
=> objectType == typeof(ulong?);
|
=> objectType == typeof(ulong?);
|
||||||
@@ -24,7 +24,7 @@ namespace Discord.API.Converters
|
|||||||
=> writer.WriteValue(((ulong?)value).ToIdString());
|
=> 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 bool CanConvert(Type objectType) => objectType == typeof(IEnumerable<ulong>);
|
||||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
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 bool CanConvert(Type objectType) => objectType == typeof(IEnumerable<ulong[]>);
|
||||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace Discord
|
|||||||
public class ChannelEventArgs : EventArgs
|
public class ChannelEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public Channel Channel { get; }
|
public Channel Channel { get; }
|
||||||
|
|
||||||
public Server Server => Channel.Server;
|
public Server Server => Channel.Server;
|
||||||
|
|
||||||
public ChannelEventArgs(Channel channel) { Channel = channel; }
|
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,
|
Verbose = 4,
|
||||||
Debug = 5
|
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>
|
public class DiscordConfig : Config<DiscordConfig>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace Discord
|
namespace Discord
|
||||||
{
|
{
|
||||||
public class ChannelType : StringEnum
|
public sealed class ChannelType : StringEnum
|
||||||
{
|
{
|
||||||
/// <summary> A text-only channel. </summary>
|
/// <summary> A text-only channel. </summary>
|
||||||
public static ChannelType Text { get; } = new ChannelType("text");
|
public static ChannelType Text { get; } = new ChannelType("text");
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace Discord
|
namespace Discord
|
||||||
{
|
{
|
||||||
public class PermissionTarget : StringEnum
|
public sealed class PermissionTarget : StringEnum
|
||||||
{
|
{
|
||||||
/// <summary> A text-only channel. </summary>
|
/// <summary> A text-only channel. </summary>
|
||||||
public static PermissionTarget Role { get; } = new PermissionTarget("role");
|
public static PermissionTarget Role { get; } = new PermissionTarget("role");
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace Discord
|
namespace Discord
|
||||||
{
|
{
|
||||||
public class UserStatus : StringEnum
|
public sealed class UserStatus : StringEnum
|
||||||
{
|
{
|
||||||
/// <summary> User is currently online and active. </summary>
|
/// <summary> User is currently online and active. </summary>
|
||||||
public static UserStatus Online { get; } = new UserStatus("online");
|
public static UserStatus Online { get; } = new UserStatus("online");
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Discord.Legacy
|
namespace Discord
|
||||||
{
|
{
|
||||||
public static class Mention
|
public static class Mention
|
||||||
{
|
{
|
||||||
@@ -31,19 +31,19 @@ namespace Discord.Legacy
|
|||||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||||
return server.FindChannels(name, type, exactMatch);
|
return server.FindChannels(name, type, exactMatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Use Server.CreateChannel")]
|
[Obsolete("Use Server.CreateChannel")]
|
||||||
public static Task<Channel> CreateChannel(this DiscordClient client, Server server, string name, ChannelType type)
|
public static Task<Channel> CreateChannel(this DiscordClient client, Server server, string name, ChannelType type)
|
||||||
{
|
{
|
||||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||||
return server.CreateChannel(name, type);
|
return server.CreateChannel(name, type);
|
||||||
}
|
}
|
||||||
[Obsolete("Use User.CreateChannel")]
|
[Obsolete("Use User.CreateChannel")]
|
||||||
public static Task<Channel> CreatePMChannel(this DiscordClient client, User user)
|
public static Task<Channel> CreatePMChannel(this DiscordClient client, User user)
|
||||||
{
|
{
|
||||||
if (user == null) throw new ArgumentNullException(nameof(user));
|
if (user == null) throw new ArgumentNullException(nameof(user));
|
||||||
return user.CreatePMChannel();
|
return user.CreatePMChannel();
|
||||||
}
|
}
|
||||||
[Obsolete("Use Channel.Edit")]
|
[Obsolete("Use Channel.Edit")]
|
||||||
public static Task EditChannel(this DiscordClient client, Channel channel, string name = null, string topic = null, int? position = null)
|
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));
|
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||||
return server.ReorderChannels(channels, after);
|
return server.ReorderChannels(channels, after);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Use Server.GetInvites")]
|
[Obsolete("Use Server.GetInvites")]
|
||||||
public static Task<IEnumerable<Invite>> GetInvites(this DiscordClient client, Server server)
|
public static Task<IEnumerable<Invite>> GetInvites(this DiscordClient client, Server server)
|
||||||
{
|
{
|
||||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||||
return server.GetInvites();
|
return server.GetInvites();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Use Server.CreateInvite")]
|
[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)
|
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));
|
if (channel == null) throw new ArgumentNullException(nameof(channel));
|
||||||
return channel.CreateInvite(maxAge, maxUses, tempMembership, withXkcd);
|
return channel.CreateInvite(maxAge, maxUses, tempMembership, withXkcd);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Use Invite.Delete")]
|
[Obsolete("Use Invite.Delete")]
|
||||||
public static Task DeleteInvite(this DiscordClient client, Invite invite)
|
public static Task DeleteInvite(this DiscordClient client, Invite invite)
|
||||||
{
|
{
|
||||||
if (invite == null) throw new ArgumentNullException(nameof(invite));
|
if (invite == null) throw new ArgumentNullException(nameof(invite));
|
||||||
return invite.Delete();
|
return invite.Delete();
|
||||||
}
|
}
|
||||||
[Obsolete("Use Invite.Accept")]
|
[Obsolete("Use Invite.Accept")]
|
||||||
public static Task AcceptInvite(this DiscordClient client, Invite invite)
|
public static Task AcceptInvite(this DiscordClient client, Invite invite)
|
||||||
{
|
{
|
||||||
if (invite == null) throw new ArgumentNullException(nameof(invite));
|
if (invite == null) throw new ArgumentNullException(nameof(invite));
|
||||||
return invite.Accept();
|
return invite.Accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Use Channel.SendMessage")]
|
[Obsolete("Use Channel.SendMessage")]
|
||||||
public static Task<Message> SendMessage(this DiscordClient client, Channel channel, string text)
|
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));
|
if (user == null) throw new ArgumentNullException(nameof(user));
|
||||||
return user.SendFile(filename, stream);
|
return user.SendFile(filename, stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Use Message.Edit")]
|
[Obsolete("Use Message.Edit")]
|
||||||
public static Task EditMessage(this DiscordClient client, Message message, string text)
|
public static Task EditMessage(this DiscordClient client, Message message, string text)
|
||||||
{
|
{
|
||||||
if (message == null) throw new ArgumentNullException(nameof(message));
|
if (message == null) throw new ArgumentNullException(nameof(message));
|
||||||
return message.Edit(text);
|
return message.Edit(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Use Message.Delete")]
|
[Obsolete("Use Message.Delete")]
|
||||||
public static Task DeleteMessage(this DiscordClient client, Message message)
|
public static Task DeleteMessage(this DiscordClient client, Message message)
|
||||||
{
|
{
|
||||||
@@ -161,14 +161,14 @@ namespace Discord.Legacy
|
|||||||
foreach (var message in messages)
|
foreach (var message in messages)
|
||||||
await message.Delete().ConfigureAwait(false);
|
await message.Delete().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Use Channel.DownloadMessages")]
|
[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)
|
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));
|
if (channel == null) throw new ArgumentNullException(nameof(channel));
|
||||||
return channel.DownloadMessages(limit, relativeMessageId, relativeDir, useCache);
|
return channel.DownloadMessages(limit, relativeMessageId, relativeDir, useCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Use Message.Acknowledge")]
|
[Obsolete("Use Message.Acknowledge")]
|
||||||
public static Task AckMessage(this DiscordClient client, Message message)
|
public static Task AckMessage(this DiscordClient client, Message message)
|
||||||
{
|
{
|
||||||
@@ -212,7 +212,7 @@ namespace Discord.Legacy
|
|||||||
|
|
||||||
return JsonConvert.SerializeObject(channel.Messages);
|
return JsonConvert.SerializeObject(channel.Messages);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
[Obsolete("Use Server.GetUser")]
|
[Obsolete("Use Server.GetUser")]
|
||||||
public static User GetUser(this DiscordClient client, Server server, ulong userId)
|
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));
|
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||||
return server.GetUser(username, discriminator);
|
return server.GetUser(username, discriminator);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Use Server.FindUsers")]
|
[Obsolete("Use Server.FindUsers")]
|
||||||
public static IEnumerable<User> FindUsers(this DiscordClient client, Server server, string name, bool exactMatch = false)
|
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,
|
string username = null, string email = null, string password = null,
|
||||||
Stream avatar = null, ImageType avatarType = ImageType.Png)
|
Stream avatar = null, ImageType avatarType = ImageType.Png)
|
||||||
=> client.CurrentUser.Edit(currentPassword, username, email, password, avatar, avatarType);
|
=> client.CurrentUser.Edit(currentPassword, username, email, password, avatar, avatarType);
|
||||||
|
|
||||||
[Obsolete("Use Server.GetRole")]
|
[Obsolete("Use Server.GetRole")]
|
||||||
public static Role GetRole(this DiscordClient client, Server server, ulong id)
|
public static Role GetRole(this DiscordClient client, Server server, ulong id)
|
||||||
{
|
{
|
||||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||||
return server.GetRole(id);
|
return server.GetRole(id);
|
||||||
}
|
}
|
||||||
[Obsolete("Use Server.FindRoles")]
|
[Obsolete("Use Server.FindRoles")]
|
||||||
public static IEnumerable<Role> FindRoles(this DiscordClient client, Server server, string name)
|
public static IEnumerable<Role> FindRoles(this DiscordClient client, Server server, string name)
|
||||||
{
|
{
|
||||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||||
return server.FindRoles(name);
|
return server.FindRoles(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Use Server.CreateRole")]
|
[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)
|
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));
|
if (role == null) throw new ArgumentNullException(nameof(role));
|
||||||
return role.Delete();
|
return role.Delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Use Server.ReorderRoles")]
|
[Obsolete("Use Server.ReorderRoles")]
|
||||||
public static Task ReorderRoles(this DiscordClient client, Server server, IEnumerable<Role> roles, Role after = null)
|
public static Task ReorderRoles(this DiscordClient client, Server server, IEnumerable<Role> roles, Role after = null)
|
||||||
{
|
{
|
||||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||||
return server.ReorderRoles(roles, after);
|
return server.ReorderRoles(roles, after);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Use Server.Edit")]
|
[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)
|
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));
|
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||||
return server.Edit(name, region, icon, iconType);
|
return server.Edit(name, region, icon, iconType);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Use Server.Leave")]
|
[Obsolete("Use Server.Leave")]
|
||||||
public static Task LeaveServer(this DiscordClient client, Server server)
|
public static Task LeaveServer(this DiscordClient client, Server server)
|
||||||
{
|
{
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Discord
|
namespace Discord
|
||||||
{
|
{
|
||||||
public sealed class LogMessageEventArgs : EventArgs
|
public class LogMessageEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public LogSeverity Severity { get; }
|
public LogSeverity Severity { get; }
|
||||||
public string Source { get; }
|
public string Source { get; }
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Discord.Logging
|
namespace Discord.Logging
|
||||||
{
|
{
|
||||||
public class LogManager
|
public sealed class LogManager
|
||||||
{
|
{
|
||||||
private readonly DiscordClient _client;
|
private readonly DiscordClient _client;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Discord.Logging
|
namespace Discord.Logging
|
||||||
{
|
{
|
||||||
public class Logger
|
public sealed class Logger
|
||||||
{
|
{
|
||||||
private readonly LogManager _manager;
|
private readonly LogManager _manager;
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace Discord
|
|||||||
public class MessageEventArgs : EventArgs
|
public class MessageEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public Message Message { get; }
|
public Message Message { get; }
|
||||||
|
|
||||||
public User User => Message.User;
|
public User User => Message.User;
|
||||||
public Channel Channel => Message.Channel;
|
public Channel Channel => Message.Channel;
|
||||||
public Server Server => Message.Server;
|
public Server Server => Message.Server;
|
||||||
@@ -9,9 +9,9 @@ using System.Threading.Tasks;
|
|||||||
namespace Discord.Net
|
namespace Discord.Net
|
||||||
{
|
{
|
||||||
/// <summary> Manages an outgoing message queue for DiscordClient. </summary>
|
/// <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 ulong Id, ChannelId;
|
||||||
public readonly string Text;
|
public readonly string Text;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Discord
|
namespace Discord
|
||||||
{
|
{
|
||||||
public class Color
|
public sealed class Color
|
||||||
{
|
{
|
||||||
public static readonly Color Default = PresetColor(0);
|
public static readonly Color Default = PresetColor(0);
|
||||||
|
|
||||||
@@ -65,8 +65,8 @@ namespace Discord
|
|||||||
//Bypasses isLocked for API changes.
|
//Bypasses isLocked for API changes.
|
||||||
_rawValue = rawValue;
|
_rawValue = rawValue;
|
||||||
}
|
}
|
||||||
protected byte GetByte(int pos) => (byte)((_rawValue >> (8 * (pos - 1))) & 0xFF);
|
private byte GetByte(int pos) => (byte)((_rawValue >> (8 * (pos - 1))) & 0xFF);
|
||||||
protected void SetByte(int pos, byte value)
|
private void SetByte(int pos, byte value)
|
||||||
{
|
{
|
||||||
if (_isLocked)
|
if (_isLocked)
|
||||||
throw new InvalidOperationException("Unable to edit cached colors directly, use Copy() to make an editable copy.");
|
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
|
namespace Discord
|
||||||
{
|
{
|
||||||
public class User
|
public sealed class User
|
||||||
{
|
{
|
||||||
internal static string GetAvatarUrl(ulong userId, string avatarId)
|
internal static string GetAvatarUrl(ulong userId, string avatarId)
|
||||||
=> avatarId != null ? $"{DiscordConfig.CDNUrl}avatars/{userId}/{avatarId}.jpg" : null;
|
=> avatarId != null ? $"{DiscordConfig.CDNUrl}avatars/{userId}/{avatarId}.jpg" : null;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace Discord.Net
|
|||||||
#if NET46
|
#if NET46
|
||||||
[Serializable]
|
[Serializable]
|
||||||
#endif
|
#endif
|
||||||
public class HttpException : Exception
|
public sealed class HttpException : Exception
|
||||||
{
|
{
|
||||||
public HttpStatusCode StatusCode { get; }
|
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
|
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
|
public sealed partial class RestClient
|
||||||
{
|
{
|
||||||
private readonly DiscordConfig _config;
|
private readonly DiscordConfig _config;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Discord.Net
|
namespace Discord.Net
|
||||||
{
|
{
|
||||||
public class WebSocketException : Exception
|
public sealed class WebSocketException : Exception
|
||||||
{
|
{
|
||||||
public int Code { get; }
|
public int Code { get; }
|
||||||
public string Reason { 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
|
namespace Discord.Net.WebSockets
|
||||||
{
|
{
|
||||||
internal class BuiltInEngine : IWebSocketEngine
|
internal sealed class BuiltInEngine : IWebSocketEngine
|
||||||
{
|
{
|
||||||
private const int ReceiveChunkSize = 12 * 1024; //12KB
|
private const int ReceiveChunkSize = 12 * 1024; //12KB
|
||||||
private const int SendChunkSize = 4 * 1024; //4KB
|
private const int SendChunkSize = 4 * 1024; //4KB
|
||||||
@@ -23,12 +23,12 @@ namespace Discord.Net.WebSockets
|
|||||||
private WebSocketClient _webSocket;
|
private WebSocketClient _webSocket;
|
||||||
private Task _tempTask;
|
private Task _tempTask;
|
||||||
|
|
||||||
public event EventHandler<WebSocketBinaryMessageEventArgs> BinaryMessage = delegate { };
|
public event EventHandler<BinaryMessageEventArgs> BinaryMessage = delegate { };
|
||||||
public event EventHandler<WebSocketTextMessageEventArgs> TextMessage = delegate { };
|
public event EventHandler<TextMessageEventArgs> TextMessage = delegate { };
|
||||||
private void OnBinaryMessage(byte[] data)
|
private void OnBinaryMessage(byte[] data)
|
||||||
=> BinaryMessage(this, new WebSocketBinaryMessageEventArgs(data));
|
=> BinaryMessage(this, new BinaryMessageEventArgs(data));
|
||||||
private void OnTextMessage(string msg)
|
private void OnTextMessage(string msg)
|
||||||
=> TextMessage(this, new WebSocketTextMessageEventArgs(msg));
|
=> TextMessage(this, new TextMessageEventArgs(msg));
|
||||||
|
|
||||||
internal BuiltInEngine(DiscordConfig config)
|
internal BuiltInEngine(DiscordConfig config)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,18 +10,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Discord.Net.WebSockets
|
namespace Discord.Net.WebSockets
|
||||||
{
|
{
|
||||||
public sealed class WebSocketEventEventArgs : EventArgs
|
public sealed class GatewaySocket : WebSocket
|
||||||
{
|
|
||||||
public readonly string Type;
|
|
||||||
public readonly JToken Payload;
|
|
||||||
internal WebSocketEventEventArgs(string type, JToken data)
|
|
||||||
{
|
|
||||||
Type = type;
|
|
||||||
Payload = data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public partial class GatewaySocket : WebSocket
|
|
||||||
{
|
{
|
||||||
private uint _lastSequence;
|
private uint _lastSequence;
|
||||||
private string _sessionId;
|
private string _sessionId;
|
||||||
|
|||||||
@@ -5,21 +5,10 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Discord.Net.WebSockets
|
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
|
public interface IWebSocketEngine
|
||||||
{
|
{
|
||||||
event EventHandler<WebSocketBinaryMessageEventArgs> BinaryMessage;
|
event EventHandler<BinaryMessageEventArgs> BinaryMessage;
|
||||||
event EventHandler<WebSocketTextMessageEventArgs> TextMessage;
|
event EventHandler<TextMessageEventArgs> TextMessage;
|
||||||
|
|
||||||
Task Connect(string host, CancellationToken cancelToken);
|
Task Connect(string host, CancellationToken cancelToken);
|
||||||
Task Disconnect();
|
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
|
namespace Discord.Net.WebSockets
|
||||||
{
|
{
|
||||||
internal class WS4NetEngine : IWebSocketEngine
|
internal sealed class WS4NetEngine : IWebSocketEngine
|
||||||
{
|
{
|
||||||
private readonly DiscordConfig _config;
|
private readonly DiscordConfig _config;
|
||||||
private readonly ConcurrentQueue<string> _sendQueue;
|
private readonly ConcurrentQueue<string> _sendQueue;
|
||||||
@@ -18,12 +18,12 @@ namespace Discord.Net.WebSockets
|
|||||||
private WebSocketClient _webSocket;
|
private WebSocketClient _webSocket;
|
||||||
private ManualResetEventSlim _waitUntilConnect, _waitUntilDisconnect;
|
private ManualResetEventSlim _waitUntilConnect, _waitUntilDisconnect;
|
||||||
|
|
||||||
public event EventHandler<WebSocketBinaryMessageEventArgs> BinaryMessage = delegate { };
|
public event EventHandler<BinaryMessageEventArgs> BinaryMessage = delegate { };
|
||||||
public event EventHandler<WebSocketTextMessageEventArgs> TextMessage = delegate { };
|
public event EventHandler<TextMessageEventArgs> TextMessage = delegate { };
|
||||||
private void OnBinaryMessage(byte[] data)
|
private void OnBinaryMessage(byte[] data)
|
||||||
=> BinaryMessage(this, new WebSocketBinaryMessageEventArgs(data));
|
=> BinaryMessage(this, new BinaryMessageEventArgs(data));
|
||||||
private void OnTextMessage(string msg)
|
private void OnTextMessage(string msg)
|
||||||
=> TextMessage(this, new WebSocketTextMessageEventArgs(msg));
|
=> TextMessage(this, new TextMessageEventArgs(msg));
|
||||||
|
|
||||||
internal WS4NetEngine(DiscordConfig config, TaskManager taskManager)
|
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 class RoleEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public Role Role { get; }
|
public Role Role { get; }
|
||||||
|
|
||||||
public Server Server => Role.Server;
|
public Server Server => Role.Server;
|
||||||
|
|
||||||
public RoleEventArgs(Role role) { Role = role; }
|
public RoleEventArgs(Role role) { Role = role; }
|
||||||
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace Discord
|
namespace Discord
|
||||||
{
|
{
|
||||||
public class ServiceManager
|
public sealed class ServiceManager
|
||||||
{
|
{
|
||||||
private readonly Dictionary<Type, IService> _services;
|
private readonly Dictionary<Type, IService> _services;
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using System.Threading.Tasks;
|
|||||||
namespace Discord
|
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>
|
/// <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 object _lock;
|
||||||
private readonly Func<Task> _stopAction;
|
private readonly Func<Task> _stopAction;
|
||||||
@@ -22,7 +22,7 @@ namespace Discord
|
|||||||
public Exception Exception => _stopReason?.SourceException;
|
public Exception Exception => _stopReason?.SourceException;
|
||||||
private ExceptionDispatchInfo _stopReason;
|
private ExceptionDispatchInfo _stopReason;
|
||||||
|
|
||||||
public TaskManager()
|
internal TaskManager()
|
||||||
{
|
{
|
||||||
_lock = new object();
|
_lock = new object();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace Discord
|
|||||||
public class UserEventArgs : EventArgs
|
public class UserEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public User User { get; }
|
public User User { get; }
|
||||||
|
|
||||||
public Server Server => User.Server;
|
public Server Server => User.Server;
|
||||||
|
|
||||||
public UserEventArgs(User user) { User = user; }
|
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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|||||||
Reference in New Issue
Block a user