Browse Source

Cleaned up several classes

tags/docs-0.9
RogueException 9 years ago
parent
commit
c1bee10523
60 changed files with 411 additions and 722 deletions
  1. +9
    -0
      src/Discord.Net.Audio.Net45/Discord.Net.Audio.csproj
  2. +21
    -73
      src/Discord.Net.Audio/AudioService.cs
  3. +13
    -0
      src/Discord.Net.Audio/UserIsTalkingEventArgs.cs
  4. +15
    -0
      src/Discord.Net.Audio/VoiceDisconnectedEventArgs.cs
  5. +22
    -0
      src/Discord.Net.Audio/VoicePacketEventArgs.cs
  6. +9
    -3
      src/Discord.Net.Commands.Net45/Discord.Net.Commands.csproj
  7. +10
    -35
      src/Discord.Net.Commands/Command.cs
  8. +18
    -0
      src/Discord.Net.Commands/CommandErrorEventArgs.cs
  9. +27
    -0
      src/Discord.Net.Commands/CommandEventArgs.cs
  10. +26
    -0
      src/Discord.Net.Commands/CommandParameter.cs
  11. +0
    -57
      src/Discord.Net.Commands/CommandService.Events.cs
  12. +36
    -33
      src/Discord.Net.Commands/CommandService.cs
  13. +1
    -1
      src/Discord.Net.Modules/ModuleManager.cs
  14. +9
    -9
      src/Discord.Net.Modules/ModuleService.cs
  15. +42
    -36
      src/Discord.Net.Net45/Discord.Net.csproj
  16. +1
    -1
      src/Discord.Net/API/Client/GatewaySocket/Commands/Identify.cs
  17. +1
    -1
      src/Discord.Net/API/Client/GatewaySocket/Commands/RequestMembers.cs
  18. +2
    -7
      src/Discord.Net/API/Client/GatewaySocket/Events/GuildBanAdd.cs
  19. +2
    -7
      src/Discord.Net/API/Client/GatewaySocket/Events/GuildBanRemove.cs
  20. +1
    -1
      src/Discord.Net/API/Client/GatewaySocket/Events/GuildEmojisUpdate.cs
  21. +1
    -1
      src/Discord.Net/API/Client/GatewaySocket/Events/GuildMembersChunk.cs
  22. +1
    -1
      src/Discord.Net/API/Client/IWebSocketMessage.cs
  23. +4
    -4
      src/Discord.Net/API/Converters.cs
  24. +1
    -0
      src/Discord.Net/ChannelEventArgs.cs
  25. +0
    -0
      src/Discord.Net/ChannelUserEventArgs.cs
  26. +24
    -0
      src/Discord.Net/Config.cs
  27. +0
    -0
      src/Discord.Net/DisconnectedEventArgs.cs
  28. +0
    -20
      src/Discord.Net/DiscordConfig.cs
  29. +1
    -1
      src/Discord.Net/Enums/ChannelType.cs
  30. +1
    -1
      src/Discord.Net/Enums/PermissionTarget.cs
  31. +1
    -1
      src/Discord.Net/Enums/UserStatus.cs
  32. +22
    -22
      src/Discord.Net/Legacy.cs
  33. +1
    -1
      src/Discord.Net/LogMessageEventArgs.cs
  34. +1
    -1
      src/Discord.Net/Logging/LogManager.cs
  35. +1
    -1
      src/Discord.Net/Logging/Logger.cs
  36. +1
    -0
      src/Discord.Net/MessageEventArgs.cs
  37. +2
    -2
      src/Discord.Net/MessageQueue.cs
  38. +3
    -3
      src/Discord.Net/Models/Color.cs
  39. +1
    -1
      src/Discord.Net/Models/User.cs
  40. +1
    -1
      src/Discord.Net/Net/HttpException.cs
  41. +20
    -0
      src/Discord.Net/Net/Rest/RequestEventArgs.cs
  42. +0
    -15
      src/Discord.Net/Net/Rest/RestClient.cs
  43. +1
    -1
      src/Discord.Net/Net/WebSocketException.cs
  44. +11
    -0
      src/Discord.Net/Net/WebSockets/BinaryMessageEventArgs.cs
  45. +5
    -5
      src/Discord.Net/Net/WebSockets/BuiltInEngine.cs
  46. +1
    -12
      src/Discord.Net/Net/WebSockets/GatewaySocket.cs
  47. +2
    -13
      src/Discord.Net/Net/WebSockets/IWebSocketEngine.cs
  48. +11
    -0
      src/Discord.Net/Net/WebSockets/TextMessageEventArgs.cs
  49. +5
    -5
      src/Discord.Net/Net/WebSockets/WS4NetEngine.cs
  50. +0
    -152
      src/Discord.Net/Net/WebSockets/WebSocket.BuiltIn.cs
  51. +17
    -0
      src/Discord.Net/Net/WebSockets/WebSocketEventEventArgs.cs
  52. +0
    -118
      src/Discord.Net/Net/WebSockets/WebSocketSharpEngine.cs
  53. +0
    -0
      src/Discord.Net/ProfileEventArgs.cs
  54. +0
    -71
      src/Discord.Net/Reference.cs
  55. +1
    -0
      src/Discord.Net/RoleEventArgs.cs
  56. +0
    -0
      src/Discord.Net/ServerEventArgs.cs
  57. +1
    -1
      src/Discord.Net/ServiceManager.cs
  58. +2
    -2
      src/Discord.Net/TaskManager.cs
  59. +1
    -0
      src/Discord.Net/UserEventArgs.cs
  60. +1
    -2
      test/Discord.Net.Tests/Tests.cs

+ 9
- 0
src/Discord.Net.Audio.Net45/Discord.Net.Audio.csproj View File

@@ -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>


+ 21
- 73
src/Discord.Net.Audio/AudioService.cs View File

@@ -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
- 0
src/Discord.Net.Audio/UserIsTalkingEventArgs.cs View 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
- 0
src/Discord.Net.Audio/VoiceDisconnectedEventArgs.cs View 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
- 0
src/Discord.Net.Audio/VoicePacketEventArgs.cs View 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;
}
}
}

+ 9
- 3
src/Discord.Net.Commands.Net45/Discord.Net.Commands.csproj View File

@@ -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>


+ 10
- 35
src/Discord.Net.Commands/Command.cs View File

@@ -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
- 0
src/Discord.Net.Commands/CommandErrorEventArgs.cs View 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
- 0
src/Discord.Net.Commands/CommandEventArgs.cs View 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
- 0
src/Discord.Net.Commands/CommandParameter.cs View 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;
}
}
}

+ 0
- 57
src/Discord.Net.Commands/CommandService.Events.cs View File

@@ -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));
}
}
}

+ 36
- 33
src/Discord.Net.Commands/CommandService.cs View File

@@ -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)
{


+ 1
- 1
src/Discord.Net.Modules/ModuleManager.cs View File

@@ -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 { };


+ 9
- 9
src/Discord.Net.Modules/ModuleService.cs View File

@@ -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);
}


+ 42
- 36
src/Discord.Net.Net45/Discord.Net.csproj View File

@@ -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>


+ 1
- 1
src/Discord.Net/API/Client/GatewaySocket/Commands/Identify.cs View File

@@ -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;


+ 1
- 1
src/Discord.Net/API/Client/GatewaySocket/Commands/RequestMembers.cs View File

@@ -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;


+ 2
- 7
src/Discord.Net/API/Client/GatewaySocket/Events/GuildBanAdd.cs View File

@@ -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 { }
}

+ 2
- 7
src/Discord.Net/API/Client/GatewaySocket/Events/GuildBanRemove.cs View File

@@ -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
- 1
src/Discord.Net/API/Client/GatewaySocket/Events/GuildEmojisUpdate.cs View File

@@ -1,4 +1,4 @@
namespace Discord.API.Client.GatewaySocket.Events
{
//public sealed class GuildEmojisUpdate { }
//public sealed class GuildEmojisUpdateEvent { }
}

+ 1
- 1
src/Discord.Net/API/Client/GatewaySocket/Events/GuildMembersChunk.cs View File

@@ -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; }
}
}

+ 1
- 1
src/Discord.Net/API/Client/IWebSocketMessage.cs View File

@@ -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
- 4
src/Discord.Net/API/Converters.cs View File

@@ -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)


src/Discord.Net/Events/ChannelEventArgs.cs → src/Discord.Net/ChannelEventArgs.cs View File

@@ -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; }

src/Discord.Net/Events/ChannelUserEventArgs.cs → src/Discord.Net/ChannelUserEventArgs.cs View File


+ 24
- 0
src/Discord.Net/Config.cs View 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;
}
}
}

src/Discord.Net/Events/DisconnectedEventArgs.cs → src/Discord.Net/DisconnectedEventArgs.cs View File


+ 0
- 20
src/Discord.Net/DiscordConfig.cs View File

@@ -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
- 1
src/Discord.Net/Enums/ChannelType.cs View File

@@ -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
- 1
src/Discord.Net/Enums/PermissionTarget.cs View File

@@ -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
- 1
src/Discord.Net/Enums/UserStatus.cs View File

@@ -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");


src/Discord.Net/DiscordClient.Obsolete.cs → src/Discord.Net/Legacy.cs View File

@@ -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)
{

src/Discord.Net/Events/LogMessageEventArgs.cs → src/Discord.Net/LogMessageEventArgs.cs View File

@@ -2,7 +2,7 @@

namespace Discord
{
public sealed class LogMessageEventArgs : EventArgs
public class LogMessageEventArgs : EventArgs
{
public LogSeverity Severity { get; }
public string Source { get; }

+ 1
- 1
src/Discord.Net/Logging/LogManager.cs View File

@@ -2,7 +2,7 @@

namespace Discord.Logging
{
public class LogManager
public sealed class LogManager
{
private readonly DiscordClient _client;



+ 1
- 1
src/Discord.Net/Logging/Logger.cs View File

@@ -2,7 +2,7 @@

namespace Discord.Logging
{
public class Logger
public sealed class Logger
{
private readonly LogManager _manager;



src/Discord.Net/Events/MessageEventArgs.cs → src/Discord.Net/MessageEventArgs.cs View File

@@ -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;

+ 2
- 2
src/Discord.Net/MessageQueue.cs View File

@@ -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;


+ 3
- 3
src/Discord.Net/Models/Color.cs View File

@@ -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.");


+ 1
- 1
src/Discord.Net/Models/User.cs View File

@@ -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;


+ 1
- 1
src/Discord.Net/Net/HttpException.cs View File

@@ -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
- 0
src/Discord.Net/Net/Rest/RequestEventArgs.cs View 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;
}
}
}

+ 0
- 15
src/Discord.Net/Net/Rest/RestClient.cs View File

@@ -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;


+ 1
- 1
src/Discord.Net/Net/WebSocketException.cs View File

@@ -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
- 0
src/Discord.Net/Net/WebSockets/BinaryMessageEventArgs.cs View 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; }
}
}

+ 5
- 5
src/Discord.Net/Net/WebSockets/BuiltInEngine.cs View File

@@ -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)
{


+ 1
- 12
src/Discord.Net/Net/WebSockets/GatewaySocket.cs View File

@@ -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;


+ 2
- 13
src/Discord.Net/Net/WebSockets/IWebSocketEngine.cs View File

@@ -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
- 0
src/Discord.Net/Net/WebSockets/TextMessageEventArgs.cs View 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; }
}
}

+ 5
- 5
src/Discord.Net/Net/WebSockets/WS4NetEngine.cs View File

@@ -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)
{


+ 0
- 152
src/Discord.Net/Net/WebSockets/WebSocket.BuiltIn.cs View File

@@ -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
- 0
src/Discord.Net/Net/WebSockets/WebSocketEventEventArgs.cs View 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;
}
}
}

+ 0
- 118
src/Discord.Net/Net/WebSockets/WebSocketSharpEngine.cs View File

@@ -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*/

src/Discord.Net/Events/ProfileEventArgs.cs → src/Discord.Net/ProfileEventArgs.cs View File


+ 0
- 71
src/Discord.Net/Reference.cs View File

@@ -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;
}
}*/
}

src/Discord.Net/Events/RoleEventArgs.cs → src/Discord.Net/RoleEventArgs.cs View File

@@ -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; }

src/Discord.Net/Events/ServerEventArgs.cs → src/Discord.Net/ServerEventArgs.cs View File


+ 1
- 1
src/Discord.Net/ServiceManager.cs View File

@@ -3,7 +3,7 @@ using System.Collections.Generic;

namespace Discord
{
public class ServiceManager
public sealed class ServiceManager
{
private readonly Dictionary<Type, IService> _services;



+ 2
- 2
src/Discord.Net/TaskManager.cs View File

@@ -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();
}


src/Discord.Net/Events/UserEventArgs.cs → src/Discord.Net/UserEventArgs.cs View File

@@ -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
- 2
test/Discord.Net.Tests/Tests.cs View File

@@ -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;


Loading…
Cancel
Save