@@ -1,5 +1,4 @@ | |||||
using Discord.Commands.Permissions; | |||||
using System; | |||||
using System; | |||||
namespace Discord.Commands | namespace Discord.Commands | ||||
{ | { | ||||
@@ -40,7 +39,7 @@ namespace Discord.Commands | |||||
protected void SetValue<T>(ref T storage, T value) | protected void SetValue<T>(ref T storage, T value) | ||||
{ | { | ||||
if (_isLocked) | if (_isLocked) | ||||
throw new InvalidOperationException("Unable to modify a discord client's configuration after it has been created."); | |||||
throw new InvalidOperationException("Unable to modify a service's configuration after it has been created."); | |||||
storage = value; | storage = value; | ||||
} | } | ||||
} | } | ||||
@@ -18,7 +18,5 @@ | |||||
"frameworks": { | "frameworks": { | ||||
"net45": { }, | "net45": { }, | ||||
"dotnet5.4": { } | "dotnet5.4": { } | ||||
}, | |||||
"configurations": { | |||||
} | } | ||||
} | } |
@@ -22,6 +22,7 @@ | |||||
<ErrorReport>prompt</ErrorReport> | <ErrorReport>prompt</ErrorReport> | ||||
<WarningLevel>4</WarningLevel> | <WarningLevel>4</WarningLevel> | ||||
<LangVersion>6</LangVersion> | <LangVersion>6</LangVersion> | ||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | ||||
<DebugType>pdbonly</DebugType> | <DebugType>pdbonly</DebugType> | ||||
@@ -32,6 +33,7 @@ | |||||
<WarningLevel>4</WarningLevel> | <WarningLevel>4</WarningLevel> | ||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> | <TreatWarningsAsErrors>true</TreatWarningsAsErrors> | ||||
<LangVersion>6</LangVersion> | <LangVersion>6</LangVersion> | ||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<Reference Include="System" /> | <Reference Include="System" /> | ||||
@@ -35,7 +35,6 @@ namespace Discord.Modules | |||||
public event EventHandler<UserEventArgs> UserPresenceUpdated; | public event EventHandler<UserEventArgs> UserPresenceUpdated; | ||||
public event EventHandler<UserEventArgs> UserVoiceStateUpdated; | public event EventHandler<UserEventArgs> UserVoiceStateUpdated; | ||||
public event EventHandler<UserChannelEventArgs> UserIsTypingUpdated; | public event EventHandler<UserChannelEventArgs> UserIsTypingUpdated; | ||||
public event EventHandler<UserIsSpeakingEventArgs> UserIsSpeakingUpdated; | |||||
public event EventHandler<MessageEventArgs> MessageReceived; | public event EventHandler<MessageEventArgs> MessageReceived; | ||||
public event EventHandler<MessageEventArgs> MessageSent; | public event EventHandler<MessageEventArgs> MessageSent; | ||||
@@ -77,9 +76,7 @@ namespace Discord.Modules | |||||
if (_allowAll || _useServerWhitelist) //Server-only events | if (_allowAll || _useServerWhitelist) //Server-only events | ||||
{ | { | ||||
client.ChannelCreated += (s, e) => { if (ChannelCreated != null && HasServer(e.Server)) ChannelCreated(s, e); }; | client.ChannelCreated += (s, e) => { if (ChannelCreated != null && HasServer(e.Server)) ChannelCreated(s, e); }; | ||||
client.UserVoiceStateUpdated += (s, e) => { if (UserVoiceStateUpdated != null && HasServer(e.Server)) UserVoiceStateUpdated(s, e); }; | client.UserVoiceStateUpdated += (s, e) => { if (UserVoiceStateUpdated != null && HasServer(e.Server)) UserVoiceStateUpdated(s, e); }; | ||||
client.UserIsSpeakingUpdated += (s, e) => { if (UserIsSpeakingUpdated != null && HasServer(e.Server)) UserIsSpeakingUpdated(s, e); }; | |||||
} | } | ||||
client.ChannelDestroyed += (s, e) => { if (ChannelDestroyed != null && HasChannel(e.Channel)) ChannelDestroyed(s, e); }; | client.ChannelDestroyed += (s, e) => { if (ChannelDestroyed != null && HasChannel(e.Channel)) ChannelDestroyed(s, e); }; | ||||
@@ -103,7 +100,7 @@ namespace Discord.Modules | |||||
client.UserJoined += (s, e) => { if (UserJoined != null && HasIndirectServer(e.Server)) UserJoined(s, e); }; | client.UserJoined += (s, e) => { if (UserJoined != null && HasIndirectServer(e.Server)) UserJoined(s, e); }; | ||||
client.UserLeft += (s, e) => { if (UserLeft != null && HasIndirectServer(e.Server)) UserLeft(s, e); }; | client.UserLeft += (s, e) => { if (UserLeft != null && HasIndirectServer(e.Server)) UserLeft(s, e); }; | ||||
client.UserUpdated += (s, e) => { if (UserUpdated != null && HasIndirectServer(e.Server)) UserUpdated(s, e); }; | client.UserUpdated += (s, e) => { if (UserUpdated != null && HasIndirectServer(e.Server)) UserUpdated(s, e); }; | ||||
client.UserIsTypingUpdated += (s, e) => { if (UserIsSpeakingUpdated != null && HasChannel(e.Channel)) UserIsTypingUpdated(s, e); }; | |||||
client.UserIsTypingUpdated += (s, e) => { if (UserIsTypingUpdated != null && HasChannel(e.Channel)) UserIsTypingUpdated(s, e); }; | |||||
//TODO: We aren't getting events from UserPresence if AllowPrivate is enabled, but the server we know that user through isn't on the whitelist | //TODO: We aren't getting events from UserPresence if AllowPrivate is enabled, but the server we know that user through isn't on the whitelist | ||||
client.UserPresenceUpdated += (s, e) => { if (UserPresenceUpdated != null && HasIndirectServer(e.Server)) UserPresenceUpdated(s, e); }; | client.UserPresenceUpdated += (s, e) => { if (UserPresenceUpdated != null && HasIndirectServer(e.Server)) UserPresenceUpdated(s, e); }; | ||||
client.UserBanned += (s, e) => { if (UserBanned != null && HasIndirectServer(e.Server)) UserBanned(s, e); }; | client.UserBanned += (s, e) => { if (UserBanned != null && HasIndirectServer(e.Server)) UserBanned(s, e); }; | ||||
@@ -19,7 +19,5 @@ | |||||
"frameworks": { | "frameworks": { | ||||
"net45": { }, | "net45": { }, | ||||
"dotnet5.4": { } | "dotnet5.4": { } | ||||
}, | |||||
"configurations": { | |||||
} | } | ||||
} | } |
@@ -134,27 +134,6 @@ | |||||
<Compile Include="..\Discord.Net\API\WebSockets.cs"> | <Compile Include="..\Discord.Net\API\WebSockets.cs"> | ||||
<Link>API\WebSockets.cs</Link> | <Link>API\WebSockets.cs</Link> | ||||
</Compile> | </Compile> | ||||
<Compile Include="..\Discord.Net\Audio\IDiscordVoiceBuffer.cs"> | |||||
<Link>Audio\IDiscordVoiceBuffer.cs</Link> | |||||
</Compile> | |||||
<Compile Include="..\Discord.Net\Audio\IDiscordVoiceClient.cs"> | |||||
<Link>Audio\IDiscordVoiceClient.cs</Link> | |||||
</Compile> | |||||
<Compile Include="..\Discord.Net\Audio\Opus.cs"> | |||||
<Link>Audio\Opus.cs</Link> | |||||
</Compile> | |||||
<Compile Include="..\Discord.Net\Audio\OpusDecoder.cs"> | |||||
<Link>Audio\OpusDecoder.cs</Link> | |||||
</Compile> | |||||
<Compile Include="..\Discord.Net\Audio\OpusEncoder.cs"> | |||||
<Link>Audio\OpusEncoder.cs</Link> | |||||
</Compile> | |||||
<Compile Include="..\Discord.Net\Audio\Sodium.cs"> | |||||
<Link>Audio\Sodium.cs</Link> | |||||
</Compile> | |||||
<Compile Include="..\Discord.Net\Audio\VoiceBuffer.cs"> | |||||
<Link>Audio\VoiceBuffer.cs</Link> | |||||
</Compile> | |||||
<Compile Include="..\Discord.Net\DiscordAPIClient.cs"> | <Compile Include="..\Discord.Net\DiscordAPIClient.cs"> | ||||
<Link>DiscordAPIClient.cs</Link> | <Link>DiscordAPIClient.cs</Link> | ||||
</Compile> | </Compile> | ||||
@@ -185,9 +164,6 @@ | |||||
<Compile Include="..\Discord.Net\DiscordClient.Users.cs"> | <Compile Include="..\Discord.Net\DiscordClient.Users.cs"> | ||||
<Link>DiscordClient.Users.cs</Link> | <Link>DiscordClient.Users.cs</Link> | ||||
</Compile> | </Compile> | ||||
<Compile Include="..\Discord.Net\DiscordClient.Voice.cs"> | |||||
<Link>DiscordClient.Voice.cs</Link> | |||||
</Compile> | |||||
<Compile Include="..\Discord.Net\DiscordClientConfig.cs"> | <Compile Include="..\Discord.Net\DiscordClientConfig.cs"> | ||||
<Link>DiscordClientConfig.cs</Link> | <Link>DiscordClientConfig.cs</Link> | ||||
</Compile> | </Compile> | ||||
@@ -197,9 +173,6 @@ | |||||
<Compile Include="..\Discord.Net\DiscordWSClient.Events.cs"> | <Compile Include="..\Discord.Net\DiscordWSClient.Events.cs"> | ||||
<Link>DiscordWSClient.Events.cs</Link> | <Link>DiscordWSClient.Events.cs</Link> | ||||
</Compile> | </Compile> | ||||
<Compile Include="..\Discord.Net\DiscordWSClient.Voice.cs"> | |||||
<Link>DiscordWSClient.Voice.cs</Link> | |||||
</Compile> | |||||
<Compile Include="..\Discord.Net\DiscordWSClientConfig.cs"> | <Compile Include="..\Discord.Net\DiscordWSClientConfig.cs"> | ||||
<Link>DiscordWSClientConfig.cs</Link> | <Link>DiscordWSClientConfig.cs</Link> | ||||
</Compile> | </Compile> | ||||
@@ -290,12 +263,6 @@ | |||||
<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\VoiceWebSocket.cs"> | |||||
<Link>Net\WebSockets\VoiceWebSocket.cs</Link> | |||||
</Compile> | |||||
<Compile Include="..\Discord.Net\Net\WebSockets\VoiceWebSocket.Events.cs"> | |||||
<Link>Net\WebSockets\VoiceWebSocket.Events.cs</Link> | |||||
</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> | ||||
@@ -1,18 +0,0 @@ | |||||
using System.Threading.Tasks; | |||||
namespace Discord.Audio | |||||
{ | |||||
public interface IDiscordVoiceClient | |||||
{ | |||||
long? ChannelId { get; } | |||||
long? ServerId { get; } | |||||
IDiscordVoiceBuffer OutputBuffer { get; } | |||||
Task JoinChannel(long channelId); | |||||
void SendVoicePCM(byte[] data, int count); | |||||
void ClearVoicePCM(); | |||||
Task WaitVoice(); | |||||
} | |||||
} |
@@ -105,12 +105,6 @@ namespace Discord | |||||
if (UserIsTypingUpdated != null) | if (UserIsTypingUpdated != null) | ||||
RaiseEvent(nameof(UserIsTypingUpdated), () => UserIsTypingUpdated(this, new UserChannelEventArgs(user, channel))); | RaiseEvent(nameof(UserIsTypingUpdated), () => UserIsTypingUpdated(this, new UserChannelEventArgs(user, channel))); | ||||
} | } | ||||
public event EventHandler<UserIsSpeakingEventArgs> UserIsSpeakingUpdated; | |||||
private void RaiseUserIsSpeaking(User user, Channel channel, bool isSpeaking) | |||||
{ | |||||
if (UserIsSpeakingUpdated != null) | |||||
RaiseEvent(nameof(UserIsSpeakingUpdated), () => UserIsSpeakingUpdated(this, new UserIsSpeakingEventArgs(user, channel, isSpeaking))); | |||||
} | |||||
public event EventHandler ProfileUpdated; | public event EventHandler ProfileUpdated; | ||||
private void RaiseProfileUpdated() | private void RaiseProfileUpdated() | ||||
{ | { | ||||
@@ -278,7 +272,7 @@ namespace Discord | |||||
{ | { | ||||
if (server == null) throw new ArgumentNullException(nameof(server)); | if (server == null) throw new ArgumentNullException(nameof(server)); | ||||
_dataSocket.SendGetUsers(server.Id); | |||||
_dataSocket.SendRequestUsers(server.Id); | |||||
} | } | ||||
public async Task EditProfile(string currentPassword = "", | public async Task EditProfile(string currentPassword = "", | ||||
@@ -19,10 +19,8 @@ namespace Discord | |||||
private readonly Random _rand; | private readonly Random _rand; | ||||
private readonly JsonSerializer _messageImporter; | private readonly JsonSerializer _messageImporter; | ||||
private readonly ConcurrentQueue<Message> _pendingMessages; | private readonly ConcurrentQueue<Message> _pendingMessages; | ||||
private readonly ConcurrentDictionary<long, DiscordWSClient> _voiceClients; | |||||
private readonly Dictionary<Type, object> _singletons; | private readonly Dictionary<Type, object> _singletons; | ||||
private bool _sentInitialLog; | private bool _sentInitialLog; | ||||
private uint _nextVoiceClientId; | |||||
private UserStatus _status; | private UserStatus _status; | ||||
private int? _gameId; | private int? _gameId; | ||||
@@ -40,8 +38,6 @@ namespace Discord | |||||
_api = new DiscordAPIClient(_config); | _api = new DiscordAPIClient(_config); | ||||
if (Config.UseMessageQueue) | if (Config.UseMessageQueue) | ||||
_pendingMessages = new ConcurrentQueue<Message>(); | _pendingMessages = new ConcurrentQueue<Message>(); | ||||
if (Config.EnableVoiceMultiserver) | |||||
_voiceClients = new ConcurrentDictionary<long, DiscordWSClient>(); | |||||
object cacheLock = new object(); | object cacheLock = new object(); | ||||
_channels = new Channels(this, cacheLock); | _channels = new Channels(this, cacheLock); | ||||
@@ -59,22 +55,6 @@ namespace Discord | |||||
_api.CancelToken = _cancelToken; | _api.CancelToken = _cancelToken; | ||||
await SendStatus().ConfigureAwait(false); | await SendStatus().ConfigureAwait(false); | ||||
}; | }; | ||||
VoiceDisconnected += (s, e) => | |||||
{ | |||||
var server = _servers[e.ServerId]; | |||||
if (server != null) | |||||
{ | |||||
foreach (var member in server.Members) | |||||
{ | |||||
if (member.IsSpeaking) | |||||
{ | |||||
member.IsSpeaking = false; | |||||
RaiseUserIsSpeaking(member, _channels[_voiceSocket.CurrentChannelId], false); | |||||
} | |||||
} | |||||
} | |||||
}; | |||||
if (_config.LogLevel >= LogMessageSeverity.Info) | if (_config.LogLevel >= LogMessageSeverity.Info) | ||||
{ | { | ||||
@@ -169,27 +149,6 @@ namespace Discord | |||||
_messageImporter = new JsonSerializer(); | _messageImporter = new JsonSerializer(); | ||||
_messageImporter.ContractResolver = new Message.ImportResolver(); | _messageImporter.ContractResolver = new Message.ImportResolver(); | ||||
} | } | ||||
internal override VoiceWebSocket CreateVoiceSocket() | |||||
{ | |||||
var socket = base.CreateVoiceSocket(); | |||||
socket.IsSpeaking += (s, e) => | |||||
{ | |||||
if (_voiceSocket.State == WebSocketState.Connected) | |||||
{ | |||||
var user = _users[e.UserId, socket.CurrentServerId]; | |||||
bool value = e.IsSpeaking; | |||||
if (user.IsSpeaking != value) | |||||
{ | |||||
user.IsSpeaking = value; | |||||
var channel = _channels[_voiceSocket.CurrentChannelId]; | |||||
RaiseUserIsSpeaking(user, channel, value); | |||||
if (Config.TrackActivity) | |||||
user.UpdateActivity(); | |||||
} | |||||
} | |||||
}; | |||||
return socket; | |||||
} | |||||
/// <summary> Connects to the Discord server with the provided email and password. </summary> | /// <summary> Connects to the Discord server with the provided email and password. </summary> | ||||
/// <returns> Returns a token for future connections. </returns> | /// <returns> Returns a token for future connections. </returns> | ||||
@@ -242,18 +201,6 @@ namespace Discord | |||||
{ | { | ||||
await base.Cleanup().ConfigureAwait(false); | await base.Cleanup().ConfigureAwait(false); | ||||
if (_config.VoiceMode != DiscordVoiceMode.Disabled) | |||||
{ | |||||
if (Config.EnableVoiceMultiserver) | |||||
{ | |||||
var tasks = _voiceClients | |||||
.Select(x => x.Value.Disconnect()) | |||||
.ToArray(); | |||||
_voiceClients.Clear(); | |||||
await Task.WhenAll(tasks).ConfigureAwait(false); | |||||
} | |||||
} | |||||
if (Config.UseMessageQueue) | if (Config.UseMessageQueue) | ||||
{ | { | ||||
Message ignored; | Message ignored; | ||||
@@ -309,7 +256,7 @@ namespace Discord | |||||
return base.GetTasks(); | return base.GetTasks(); | ||||
} | } | ||||
internal override async Task OnReceivedEvent(WebSocketEventEventArgs e) | |||||
protected override async Task OnReceivedEvent(WebSocketEventEventArgs e) | |||||
{ | { | ||||
try | try | ||||
{ | { | ||||
@@ -623,12 +570,12 @@ namespace Discord | |||||
var user = _users[data.UserId, data.GuildId]; | var user = _users[data.UserId, data.GuildId]; | ||||
if (user != null) | if (user != null) | ||||
{ | { | ||||
var voiceChannel = user.VoiceChannel; | |||||
/*var voiceChannel = user.VoiceChannel; | |||||
if (voiceChannel != null && data.ChannelId != voiceChannel.Id && user.IsSpeaking) | if (voiceChannel != null && data.ChannelId != voiceChannel.Id && user.IsSpeaking) | ||||
{ | { | ||||
user.IsSpeaking = false; | user.IsSpeaking = false; | ||||
RaiseUserIsSpeaking(user, _channels[voiceChannel.Id], false); | RaiseUserIsSpeaking(user, _channels[voiceChannel.Id], false); | ||||
} | |||||
}*/ | |||||
user.Update(data); | user.Update(data); | ||||
RaiseUserVoiceStateUpdated(user); | RaiseUserVoiceStateUpdated(user); | ||||
} | } | ||||
@@ -10,9 +10,6 @@ | |||||
private int _messageCacheLength = 100; | private int _messageCacheLength = 100; | ||||
//Experimental Features | //Experimental Features | ||||
/// <summary> (Experimental) Enables the client to be simultaneously connected to multiple channels at once (Discord still limits you to one channel per server). </summary> | |||||
public bool EnableVoiceMultiserver { get { return _enableVoiceMultiserver; } set { SetValue(ref _enableVoiceMultiserver, value); } } | |||||
private bool _enableVoiceMultiserver = false; | |||||
/// <summary> (Experimental) Enables or disables the internal message queue. This will allow SendMessage to return immediately and handle messages internally. Messages will set the IsQueued and HasFailed properties to show their progress. </summary> | /// <summary> (Experimental) Enables or disables the internal message queue. This will allow SendMessage to return immediately and handle messages internally. Messages will set the IsQueued and HasFailed properties to show their progress. </summary> | ||||
public bool UseMessageQueue { get { return _useMessageQueue; } set { SetValue(ref _useMessageQueue, value); } } | public bool UseMessageQueue { get { return _useMessageQueue; } set { SetValue(ref _useMessageQueue, value); } } | ||||
private bool _useMessageQueue = false; | private bool _useMessageQueue = false; | ||||
@@ -23,9 +20,6 @@ | |||||
public bool AckMessages { get { return _ackMessages; } set { SetValue(ref _ackMessages, value); } } | public bool AckMessages { get { return _ackMessages; } set { SetValue(ref _ackMessages, value); } } | ||||
private bool _ackMessages = false; | private bool _ackMessages = false; | ||||
//Internal | |||||
internal override bool EnableVoice => (base.EnableVoice && !EnableVoiceMultiserver) || base.VoiceOnly; | |||||
public new DiscordClientConfig Clone() | public new DiscordClientConfig Clone() | ||||
{ | { | ||||
var config = MemberwiseClone() as DiscordClientConfig; | var config = MemberwiseClone() as DiscordClientConfig; | ||||
@@ -26,22 +26,12 @@ namespace Discord | |||||
public readonly bool WasUnexpected; | public readonly bool WasUnexpected; | ||||
public readonly Exception Error; | public readonly Exception Error; | ||||
internal DisconnectedEventArgs(bool wasUnexpected, Exception error) | |||||
public DisconnectedEventArgs(bool wasUnexpected, Exception error) | |||||
{ | { | ||||
WasUnexpected = wasUnexpected; | WasUnexpected = wasUnexpected; | ||||
Error = error; | Error = error; | ||||
} | } | ||||
} | } | ||||
public class VoiceDisconnectedEventArgs : DisconnectedEventArgs | |||||
{ | |||||
public readonly long ServerId; | |||||
internal VoiceDisconnectedEventArgs(long serverId, DisconnectedEventArgs e) | |||||
: base(e.WasUnexpected, e.Error) | |||||
{ | |||||
ServerId = serverId; | |||||
} | |||||
} | |||||
public sealed class LogMessageEventArgs : EventArgs | public sealed class LogMessageEventArgs : EventArgs | ||||
{ | { | ||||
public LogMessageSeverity Severity { get; } | public LogMessageSeverity Severity { get; } | ||||
@@ -49,7 +39,7 @@ namespace Discord | |||||
public string Message { get; } | public string Message { get; } | ||||
public Exception Exception { get; } | public Exception Exception { get; } | ||||
internal LogMessageEventArgs(LogMessageSeverity severity, LogMessageSource source, string msg, Exception exception) | |||||
public LogMessageEventArgs(LogMessageSeverity severity, LogMessageSource source, string msg, Exception exception) | |||||
{ | { | ||||
Severity = severity; | Severity = severity; | ||||
Source = source; | Source = source; | ||||
@@ -66,7 +56,7 @@ namespace Discord | |||||
public int Offset { get; } | public int Offset { get; } | ||||
public int Count { get; } | public int Count { get; } | ||||
internal VoicePacketEventArgs(long userId, long channelId, byte[] buffer, int offset, int count) | |||||
public VoicePacketEventArgs(long userId, long channelId, byte[] buffer, int offset, int count) | |||||
{ | { | ||||
UserId = userId; | UserId = userId; | ||||
Buffer = buffer; | Buffer = buffer; | ||||
@@ -90,30 +80,10 @@ namespace Discord | |||||
RaiseEvent(nameof(Disconnected), () => Disconnected(this, e)); | RaiseEvent(nameof(Disconnected), () => Disconnected(this, e)); | ||||
} | } | ||||
public event EventHandler<LogMessageEventArgs> LogMessage; | public event EventHandler<LogMessageEventArgs> LogMessage; | ||||
internal void RaiseOnLog(LogMessageSeverity severity, LogMessageSource source, string message, Exception exception = null) | |||||
protected void RaiseOnLog(LogMessageSeverity severity, LogMessageSource source, string message, Exception exception = null) | |||||
{ | { | ||||
if (LogMessage != null) | if (LogMessage != null) | ||||
RaiseEvent(nameof(LogMessage), () => LogMessage(this, new LogMessageEventArgs(severity, source, message, exception))); | RaiseEvent(nameof(LogMessage), () => LogMessage(this, new LogMessageEventArgs(severity, source, message, exception))); | ||||
} | } | ||||
public event EventHandler VoiceConnected; | |||||
private void RaiseVoiceConnected() | |||||
{ | |||||
if (VoiceConnected != null) | |||||
RaiseEvent(nameof(VoiceConnected), () => VoiceConnected(this, EventArgs.Empty)); | |||||
} | |||||
public event EventHandler<VoiceDisconnectedEventArgs> VoiceDisconnected; | |||||
private void RaiseVoiceDisconnected(long serverId, DisconnectedEventArgs e) | |||||
{ | |||||
if (VoiceDisconnected != null) | |||||
RaiseEvent(nameof(VoiceDisconnected), () => VoiceDisconnected(this, new VoiceDisconnectedEventArgs(serverId, e))); | |||||
} | |||||
public event EventHandler<VoicePacketEventArgs> OnVoicePacket; | |||||
internal void RaiseOnVoicePacket(VoicePacketEventArgs e) | |||||
{ | |||||
if (OnVoicePacket != null) | |||||
OnVoicePacket(this, e); | |||||
} | |||||
} | } | ||||
} | } |
@@ -1,54 +0,0 @@ | |||||
using Discord.Audio; | |||||
using System; | |||||
using System.Threading.Tasks; | |||||
namespace Discord | |||||
{ | |||||
public partial class DiscordWSClient : IDiscordVoiceClient | |||||
{ | |||||
IDiscordVoiceBuffer IDiscordVoiceClient.OutputBuffer => _voiceSocket.OutputBuffer; | |||||
long? IDiscordVoiceClient.ServerId => _voiceSocket.CurrentServerId; | |||||
long? IDiscordVoiceClient.ChannelId => _voiceSocket.CurrentChannelId; | |||||
async Task IDiscordVoiceClient.JoinChannel(long channelId) | |||||
{ | |||||
CheckReady(checkVoice: true); | |||||
if (channelId <= 0) throw new ArgumentOutOfRangeException(nameof(channelId)); | |||||
await _voiceSocket.Disconnect().ConfigureAwait(false); | |||||
await _voiceSocket.SetChannel(_voiceServerId.Value, channelId).ConfigureAwait(false); | |||||
_dataSocket.SendJoinVoice(_voiceServerId.Value, channelId); | |||||
await _voiceSocket.WaitForConnection(_config.ConnectionTimeout).ConfigureAwait(false); | |||||
} | |||||
/// <summary> Sends a PCM frame to the voice server. Will block until space frees up in the outgoing buffer. </summary> | |||||
/// <param name="data">PCM frame to send. This must be a single or collection of uncompressed 48Kz monochannel 20ms PCM frames. </param> | |||||
/// <param name="count">Number of bytes in this frame. </param> | |||||
void IDiscordVoiceClient.SendVoicePCM(byte[] data, int count) | |||||
{ | |||||
if (data == null) throw new ArgumentException(nameof(data)); | |||||
if (count < 0) throw new ArgumentOutOfRangeException(nameof(count)); | |||||
CheckReady(checkVoice: true); | |||||
if (count != 0) | |||||
_voiceSocket.SendPCMFrames(data, count); | |||||
} | |||||
/// <summary> Clears the PCM buffer. </summary> | |||||
void IDiscordVoiceClient.ClearVoicePCM() | |||||
{ | |||||
CheckReady(checkVoice: true); | |||||
_voiceSocket.ClearPCMFrames(); | |||||
} | |||||
/// <summary> Returns a task that completes once the voice output buffer is empty. </summary> | |||||
async Task IDiscordVoiceClient.WaitVoice() | |||||
{ | |||||
CheckReady(checkVoice: true); | |||||
_voiceSocket.WaitForQueue(); | |||||
await TaskHelper.CompletedTask.ConfigureAwait(false); | |||||
} | |||||
} | |||||
} |
@@ -24,10 +24,9 @@ namespace Discord | |||||
protected readonly ManualResetEvent _disconnectedEvent; | protected readonly ManualResetEvent _disconnectedEvent; | ||||
protected readonly ManualResetEventSlim _connectedEvent; | protected readonly ManualResetEventSlim _connectedEvent; | ||||
protected ExceptionDispatchInfo _disconnectReason; | protected ExceptionDispatchInfo _disconnectReason; | ||||
internal readonly DataWebSocket _dataSocket; | |||||
internal readonly VoiceWebSocket _voiceSocket; | |||||
protected readonly DataWebSocket _dataSocket; | |||||
protected string _gateway, _token; | protected string _gateway, _token; | ||||
protected long? _userId, _voiceServerId; | |||||
protected long? _userId; | |||||
private Task _runTask; | private Task _runTask; | ||||
private bool _wasDisconnectUnexpected; | private bool _wasDisconnectUnexpected; | ||||
@@ -86,13 +85,6 @@ namespace Discord | |||||
#endif | #endif | ||||
_dataSocket = CreateDataSocket(); | _dataSocket = CreateDataSocket(); | ||||
if (_config.EnableVoice) | |||||
_voiceSocket = CreateVoiceSocket(); | |||||
} | |||||
internal DiscordWSClient(DiscordWSClientConfig config = null, long? voiceServerId = null) | |||||
: this(config) | |||||
{ | |||||
_voiceServerId = voiceServerId; | |||||
} | } | ||||
internal virtual DataWebSocket CreateDataSocket() | internal virtual DataWebSocket CreateDataSocket() | ||||
@@ -120,26 +112,6 @@ namespace Discord | |||||
socket.ReceivedEvent += async (s, e) => await OnReceivedEvent(e).ConfigureAwait(false); | socket.ReceivedEvent += async (s, e) => await OnReceivedEvent(e).ConfigureAwait(false); | ||||
return socket; | return socket; | ||||
} | } | ||||
internal virtual VoiceWebSocket CreateVoiceSocket() | |||||
{ | |||||
var socket = new VoiceWebSocket(this); | |||||
socket.Connected += (s, e) => RaiseVoiceConnected(); | |||||
socket.Disconnected += async (s, e) => | |||||
{ | |||||
RaiseVoiceDisconnected(socket.CurrentServerId.Value, e); | |||||
if (e.WasUnexpected) | |||||
await socket.Reconnect().ConfigureAwait(false); | |||||
}; | |||||
socket.LogMessage += (s, e) => RaiseOnLog(e.Severity, LogMessageSource.VoiceWebSocket, e.Message, e.Exception); | |||||
if (_config.LogLevel >= LogMessageSeverity.Info) | |||||
{ | |||||
socket.Connected += (s, e) => RaiseOnLog(LogMessageSeverity.Info, LogMessageSource.VoiceWebSocket, "Connected"); | |||||
socket.Disconnected += (s, e) => RaiseOnLog(LogMessageSeverity.Info, LogMessageSource.VoiceWebSocket, "Disconnected"); | |||||
} | |||||
return socket; | |||||
} | |||||
//Connection | //Connection | ||||
public async Task<string> Connect(string gateway, string token) | public async Task<string> Connect(string gateway, string token) | ||||
@@ -160,8 +132,6 @@ namespace Discord | |||||
_dataSocket.Host = gateway; | _dataSocket.Host = gateway; | ||||
_dataSocket.ParentCancelToken = _cancelToken; | _dataSocket.ParentCancelToken = _cancelToken; | ||||
if (_config.EnableVoice) | |||||
_voiceSocket.ParentCancelToken = _cancelToken; | |||||
await _dataSocket.Login(token).ConfigureAwait(false); | await _dataSocket.Login(token).ConfigureAwait(false); | ||||
_runTask = RunTasks(); | _runTask = RunTasks(); | ||||
@@ -268,13 +238,6 @@ namespace Discord | |||||
protected virtual async Task Cleanup() | protected virtual async Task Cleanup() | ||||
{ | { | ||||
if (_config.EnableVoice) | |||||
{ | |||||
var voiceServerId = _voiceSocket.CurrentServerId; | |||||
if (voiceServerId != null) | |||||
_dataSocket.SendLeaveVoice(voiceServerId.Value); | |||||
await _voiceSocket.Disconnect().ConfigureAwait(false); | |||||
} | |||||
await _dataSocket.Disconnect().ConfigureAwait(false); | await _dataSocket.Disconnect().ConfigureAwait(false); | ||||
_userId = null; | _userId = null; | ||||
@@ -310,9 +273,6 @@ namespace Discord | |||||
case (int)DiscordClientState.Connecting: | case (int)DiscordClientState.Connecting: | ||||
throw new InvalidOperationException("The client is connecting."); | throw new InvalidOperationException("The client is connecting."); | ||||
} | } | ||||
if (checkVoice && _config.VoiceMode == DiscordVoiceMode.Disabled) | |||||
throw new InvalidOperationException("Voice is not enabled for this client."); | |||||
} | } | ||||
protected void RaiseEvent(string name, Action action) | protected void RaiseEvent(string name, Action action) | ||||
{ | { | ||||
@@ -325,7 +285,7 @@ namespace Discord | |||||
} | } | ||||
} | } | ||||
internal virtual async Task OnReceivedEvent(WebSocketEventEventArgs e) | |||||
protected virtual Task OnReceivedEvent(WebSocketEventEventArgs e) | |||||
{ | { | ||||
try | try | ||||
{ | { | ||||
@@ -334,24 +294,13 @@ namespace Discord | |||||
case "READY": | case "READY": | ||||
_userId = IdConvert.ToLong(e.Payload["user"].Value<string>("id")); | _userId = IdConvert.ToLong(e.Payload["user"].Value<string>("id")); | ||||
break; | break; | ||||
case "VOICE_SERVER_UPDATE": | |||||
{ | |||||
long guildId = IdConvert.ToLong(e.Payload.Value<string>("guild_id")); | |||||
if (_config.EnableVoice && guildId == _voiceSocket.CurrentServerId) | |||||
{ | |||||
string token = e.Payload.Value<string>("token"); | |||||
_voiceSocket.Host = "wss://" + e.Payload.Value<string>("endpoint").Split(':')[0]; | |||||
await _voiceSocket.Login(_userId.Value, _dataSocket.SessionId, token, _cancelToken).ConfigureAwait(false); | |||||
} | |||||
} | |||||
break; | |||||
} | } | ||||
} | } | ||||
catch (Exception ex) | catch (Exception ex) | ||||
{ | { | ||||
RaiseOnLog(LogMessageSeverity.Error, LogMessageSource.Client, $"Error handling {e.Type} event: {ex.GetBaseException().Message}"); | RaiseOnLog(LogMessageSeverity.Error, LogMessageSource.Client, $"Error handling {e.Type} event: {ex.GetBaseException().Message}"); | ||||
} | } | ||||
return TaskHelper.CompletedTask; | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -3,15 +3,6 @@ using System.Reflection; | |||||
namespace Discord | namespace Discord | ||||
{ | { | ||||
[Flags] | |||||
public enum DiscordVoiceMode | |||||
{ | |||||
Disabled = 0x00, | |||||
Incoming = 0x01, | |||||
Outgoing = 0x02, | |||||
Both = Outgoing | Incoming | |||||
} | |||||
public class DiscordWSClientConfig : DiscordAPIClientConfig | public class DiscordWSClientConfig : DiscordAPIClientConfig | ||||
{ | { | ||||
/// <summary> Max time in milliseconds to wait for DiscordClient to connect and initialize. </summary> | /// <summary> Max time in milliseconds to wait for DiscordClient to connect and initialize. </summary> | ||||
@@ -23,36 +14,15 @@ namespace Discord | |||||
/// <summary> Gets or sets the time (in milliseconds) to wait after an reconnect fails before retrying. </summary> | /// <summary> Gets or sets the time (in milliseconds) to wait after an reconnect fails before retrying. </summary> | ||||
public int FailedReconnectDelay { get { return _failedReconnectDelay; } set { SetValue(ref _failedReconnectDelay, value); } } | public int FailedReconnectDelay { get { return _failedReconnectDelay; } set { SetValue(ref _failedReconnectDelay, value); } } | ||||
private int _failedReconnectDelay = 10000; | private int _failedReconnectDelay = 10000; | ||||
/// <summary> Gets or sets the time (in milliseconds) to wait when the websocket's message queue is empty before checking again. </summary> | /// <summary> Gets or sets the time (in milliseconds) to wait when the websocket's message queue is empty before checking again. </summary> | ||||
public int WebSocketInterval { get { return _webSocketInterval; } set { SetValue(ref _webSocketInterval, value); } } | public int WebSocketInterval { get { return _webSocketInterval; } set { SetValue(ref _webSocketInterval, value); } } | ||||
private int _webSocketInterval = 100; | private int _webSocketInterval = 100; | ||||
/// <summary> Gets or sets the max buffer length (in milliseconds) for outgoing voice packets. This value is the target maximum but is not guaranteed, the buffer will often go slightly above this value. </summary> | |||||
public int VoiceBufferLength { get { return _voiceBufferLength; } set { SetValue(ref _voiceBufferLength, value); } } | |||||
private int _voiceBufferLength = 1000; | |||||
/// <summary> Gets or sets the bitrate used (in kbit/s, between 1 and 512 inclusively) for outgoing voice packets. A null value will use default Opus settings. </summary> | |||||
public int? VoiceBitrate { get { return _voiceBitrate; } set { SetValue(ref _voiceBitrate, value); } } | |||||
private int? _voiceBitrate = null; | |||||
//Experimental Features | //Experimental Features | ||||
/// <summary> (Experimental) Enables the voice websocket and UDP client and specifies how it will be used. Any option other than Disabled requires the opus .dll or .so be in the local or system folder. </summary> | |||||
public DiscordVoiceMode VoiceMode { get { return _voiceMode; } set { SetValue(ref _voiceMode, value); } } | |||||
private DiscordVoiceMode _voiceMode = DiscordVoiceMode.Disabled; | |||||
/// <summary> (Experimental) Enables the voice websocket and UDP client. This option requires the libsodium .dll or .so be in the local or system folder. </summary> | |||||
public bool EnableVoiceEncryption { get { return _enableVoiceEncryption; } set { SetValue(ref _enableVoiceEncryption, value); } } | |||||
private bool _enableVoiceEncryption = true; | |||||
/// <summary> (Experimental) Instructs Discord to not send send information about offline users, for servers with more than 50 users. </summary> | /// <summary> (Experimental) Instructs Discord to not send send information about offline users, for servers with more than 50 users. </summary> | ||||
public bool UseLargeThreshold { get { return _useLargeThreshold; } set { SetValue(ref _useLargeThreshold, value); } } | public bool UseLargeThreshold { get { return _useLargeThreshold; } set { SetValue(ref _useLargeThreshold, value); } } | ||||
private bool _useLargeThreshold = false; | private bool _useLargeThreshold = false; | ||||
//Internals | |||||
internal bool VoiceOnly { get { return _voiceOnly; } set { SetValue(ref _voiceOnly, value); } } | |||||
private bool _voiceOnly; | |||||
internal uint VoiceClientId { get { return _voiceClientId; } set { SetValue(ref _voiceClientId, value); } } | |||||
private uint _voiceClientId; | |||||
internal virtual bool EnableVoice => _voiceMode != DiscordVoiceMode.Disabled; | |||||
public new DiscordWSClientConfig Clone() | public new DiscordWSClientConfig Clone() | ||||
{ | { | ||||
var config = MemberwiseClone() as DiscordWSClientConfig; | var config = MemberwiseClone() as DiscordWSClientConfig; | ||||
@@ -1,10 +1,4 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace Discord | |||||
namespace Discord | |||||
{ | { | ||||
internal static class BitHelper | internal static class BitHelper | ||||
{ | { | ||||
@@ -0,0 +1,33 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading; | |||||
using System.Threading.Tasks; | |||||
namespace Discord | |||||
{ | |||||
public enum EditMode : byte | |||||
{ | |||||
Set, | |||||
Add, | |||||
Remove | |||||
} | |||||
internal static class Extensions | |||||
{ | |||||
public static IEnumerable<T> Modify<T>(this IEnumerable<T> original, IEnumerable<T> modified, EditMode mode) | |||||
{ | |||||
if (original == null) return null; | |||||
switch (mode) | |||||
{ | |||||
case EditMode.Set: | |||||
default: | |||||
return modified; | |||||
case EditMode.Add: | |||||
return original.Concat(modified); | |||||
case EditMode.Remove: | |||||
return original.Except(modified); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -1,6 +1,5 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Linq; | |||||
using System.Text.RegularExpressions; | using System.Text.RegularExpressions; | ||||
namespace Discord | namespace Discord | ||||
@@ -10,17 +9,21 @@ namespace Discord | |||||
private static readonly Regex _userRegex = new Regex(@"<@([0-9]+?)>", RegexOptions.Compiled); | private static readonly Regex _userRegex = new Regex(@"<@([0-9]+?)>", RegexOptions.Compiled); | ||||
private static readonly Regex _channelRegex = new Regex(@"<#([0-9]+?)>", RegexOptions.Compiled); | private static readonly Regex _channelRegex = new Regex(@"<#([0-9]+?)>", RegexOptions.Compiled); | ||||
private static readonly Regex _roleRegex = new Regex(@"@everyone", RegexOptions.Compiled); | private static readonly Regex _roleRegex = new Regex(@"@everyone", RegexOptions.Compiled); | ||||
/// <summary> Returns the string used to create a user mention. </summary> | /// <summary> Returns the string used to create a user mention. </summary> | ||||
[Obsolete("Use User.Mention instead")] | |||||
public static string User(User user) | public static string User(User user) | ||||
=> $"<@{user.Id}>"; | => $"<@{user.Id}>"; | ||||
/// <summary> Returns the string used to create a user mention. </summary> | /// <summary> Returns the string used to create a user mention. </summary> | ||||
[Obsolete("Use GlobalUser.Mention instead")] | |||||
public static string User(GlobalUser user) | public static string User(GlobalUser user) | ||||
=> $"<@{user.Id}>"; | => $"<@{user.Id}>"; | ||||
/// <summary> Returns the string used to create a channel mention. </summary> | /// <summary> Returns the string used to create a channel mention. </summary> | ||||
[Obsolete("Use Channel.Mention instead")] | |||||
public static string Channel(Channel channel) | public static string Channel(Channel channel) | ||||
=> $"<#{channel.Id}>"; | => $"<#{channel.Id}>"; | ||||
/// <summary> Returns the string used to create a mention to everyone in a channel. </summary> | /// <summary> Returns the string used to create a mention to everyone in a channel. </summary> | ||||
[Obsolete("Use Role.Mention instead")] | |||||
public static string Everyone() | public static string Everyone() | ||||
=> $"@everyone"; | => $"@everyone"; | ||||
@@ -72,7 +75,7 @@ namespace Discord | |||||
if (source == null) throw new ArgumentNullException(nameof(source)); | if (source == null) throw new ArgumentNullException(nameof(source)); | ||||
if (text == null) throw new ArgumentNullException(nameof(text)); | if (text == null) throw new ArgumentNullException(nameof(text)); | ||||
return Resolve(source?.Server, text); | |||||
return Resolve(source.Server, text); | |||||
} | } | ||||
/// <summary>Resolves all mentions in a provided string to those users, channels or roles' names.</summary> | /// <summary>Resolves all mentions in a provided string to those users, channels or roles' names.</summary> | ||||
@@ -80,12 +83,12 @@ namespace Discord | |||||
{ | { | ||||
if (text == null) throw new ArgumentNullException(nameof(text)); | if (text == null) throw new ArgumentNullException(nameof(text)); | ||||
var client = server.Client; | |||||
text = Mention.CleanUserMentions(client, server, text); | |||||
var client = server?.Client; | |||||
text = CleanUserMentions(client, server, text); | |||||
if (server != null) | if (server != null) | ||||
{ | { | ||||
text = Mention.CleanChannelMentions(client, server, text); | |||||
//text = Mention.CleanRoleMentions(_client, User, channel, text); | |||||
text = CleanChannelMentions(client, server, text); | |||||
//text = CleanRoleMentions(_client, User, channel, text); | |||||
} | } | ||||
return text; | return text; | ||||
} | } | ||||
@@ -1,19 +1,10 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Threading; | using System.Threading; | ||||
using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
namespace Discord | namespace Discord | ||||
{ | { | ||||
public enum EditMode : byte | |||||
{ | |||||
Set, | |||||
Add, | |||||
Remove | |||||
} | |||||
internal static class Extensions | |||||
public static class TaskExtensions | |||||
{ | { | ||||
public static async Task Timeout(this Task task, int milliseconds) | public static async Task Timeout(this Task task, int milliseconds) | ||||
{ | { | ||||
@@ -73,20 +64,5 @@ namespace Discord | |||||
try { await Task.Delay(-1, token).ConfigureAwait(false); } | try { await Task.Delay(-1, token).ConfigureAwait(false); } | ||||
catch (OperationCanceledException) { } //Expected | catch (OperationCanceledException) { } //Expected | ||||
} | } | ||||
public static IEnumerable<T> Modify<T>(this IEnumerable<T> original, IEnumerable<T> modified, EditMode mode) | |||||
{ | |||||
if (original == null) return null; | |||||
switch (mode) | |||||
{ | |||||
case EditMode.Set: | |||||
default: | |||||
return modified; | |||||
case EditMode.Add: | |||||
return original.Concat(modified); | |||||
case EditMode.Remove: | |||||
return original.Except(modified); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | } |
@@ -2,6 +2,7 @@ | |||||
{ | { | ||||
public interface IService | public interface IService | ||||
{ | { | ||||
void Install(DiscordClient client); | void Install(DiscordClient client); | ||||
} | } | ||||
} | } |
@@ -6,9 +6,9 @@ using System.Threading.Tasks; | |||||
namespace Discord.Net.WebSockets | namespace Discord.Net.WebSockets | ||||
{ | { | ||||
internal partial class DataWebSocket : WebSocket | |||||
public partial class DataWebSocket : WebSocket | |||||
{ | { | ||||
public enum OpCodes : byte | |||||
internal enum OpCodes : byte | |||||
{ | { | ||||
Dispatch = 0, | Dispatch = 0, | ||||
Heartbeat = 1, | Heartbeat = 1, | ||||
@@ -155,7 +155,7 @@ namespace Discord.Net.WebSockets | |||||
leaveVoice.Payload.ServerId = serverId; | leaveVoice.Payload.ServerId = serverId; | ||||
QueueMessage(leaveVoice); | QueueMessage(leaveVoice); | ||||
} | } | ||||
public void SendGetUsers(long serverId, string query = "", int limit = 0) | |||||
public void SendRequestUsers(long serverId, string query = "", int limit = 0) | |||||
{ | { | ||||
var getOfflineUsers = new GetUsersCommand(); | var getOfflineUsers = new GetUsersCommand(); | ||||
getOfflineUsers.Payload.ServerId = serverId; | getOfflineUsers.Payload.ServerId = serverId; | ||||
@@ -3,7 +3,7 @@ using System; | |||||
namespace Discord.Net.WebSockets | namespace Discord.Net.WebSockets | ||||
{ | { | ||||
internal sealed class WebSocketEventEventArgs : EventArgs | |||||
public sealed class WebSocketEventEventArgs : EventArgs | |||||
{ | { | ||||
public readonly string Type; | public readonly string Type; | ||||
public readonly JToken Payload; | public readonly JToken Payload; | ||||
@@ -14,7 +14,7 @@ namespace Discord.Net.WebSockets | |||||
} | } | ||||
} | } | ||||
internal partial class DataWebSocket | |||||
public partial class DataWebSocket | |||||
{ | { | ||||
internal event EventHandler<WebSocketEventEventArgs> ReceivedEvent; | internal event EventHandler<WebSocketEventEventArgs> ReceivedEvent; | ||||
private void RaiseReceivedEvent(string type, JToken payload) | private void RaiseReceivedEvent(string type, JToken payload) | ||||
@@ -5,18 +5,18 @@ using System.Threading.Tasks; | |||||
namespace Discord.Net.WebSockets | namespace Discord.Net.WebSockets | ||||
{ | { | ||||
internal class WebSocketBinaryMessageEventArgs : EventArgs | |||||
public class WebSocketBinaryMessageEventArgs : EventArgs | |||||
{ | { | ||||
public readonly byte[] Data; | public readonly byte[] Data; | ||||
public WebSocketBinaryMessageEventArgs(byte[] data) { Data = data; } | public WebSocketBinaryMessageEventArgs(byte[] data) { Data = data; } | ||||
} | } | ||||
internal class WebSocketTextMessageEventArgs : EventArgs | |||||
public class WebSocketTextMessageEventArgs : EventArgs | |||||
{ | { | ||||
public readonly string Message; | public readonly string Message; | ||||
public WebSocketTextMessageEventArgs(string msg) { Message = msg; } | public WebSocketTextMessageEventArgs(string msg) { Message = msg; } | ||||
} | } | ||||
internal interface IWebSocketEngine | |||||
public interface IWebSocketEngine | |||||
{ | { | ||||
event EventHandler<WebSocketBinaryMessageEventArgs> BinaryMessage; | event EventHandler<WebSocketBinaryMessageEventArgs> BinaryMessage; | ||||
event EventHandler<WebSocketTextMessageEventArgs> TextMessage; | event EventHandler<WebSocketTextMessageEventArgs> TextMessage; | ||||
@@ -2,7 +2,7 @@ | |||||
namespace Discord.Net.WebSockets | namespace Discord.Net.WebSockets | ||||
{ | { | ||||
internal abstract partial class WebSocket | |||||
public abstract partial class WebSocket | |||||
{ | { | ||||
public event EventHandler Connected; | public event EventHandler Connected; | ||||
private void RaiseConnected() | private void RaiseConnected() | ||||
@@ -10,7 +10,7 @@ using System.Threading.Tasks; | |||||
namespace Discord.Net.WebSockets | namespace Discord.Net.WebSockets | ||||
{ | { | ||||
internal enum WebSocketState : byte | |||||
public enum WebSocketState : byte | |||||
{ | { | ||||
Disconnected, | Disconnected, | ||||
Connecting, | Connecting, | ||||
@@ -18,7 +18,7 @@ namespace Discord.Net.WebSockets | |||||
Disconnecting | Disconnecting | ||||
} | } | ||||
internal abstract partial class WebSocket | |||||
public abstract partial class WebSocket | |||||
{ | { | ||||
protected readonly IWebSocketEngine _engine; | protected readonly IWebSocketEngine _engine; | ||||
protected readonly DiscordWSClient _client; | protected readonly DiscordWSClient _client; | ||||
@@ -4,7 +4,7 @@ using System.Collections.Concurrent; | |||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Threading; | using System.Threading; | ||||
using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
using WSSharpNWebSocket = WebSocketSharp.WebSocket; | |||||
using WSSharpWebSocket = WebSocketSharp.WebSocket; | |||||
namespace Discord.Net.WebSockets | namespace Discord.Net.WebSockets | ||||
{ | { | ||||
@@ -13,7 +13,7 @@ namespace Discord.Net.WebSockets | |||||
private readonly DiscordWSClientConfig _config; | private readonly DiscordWSClientConfig _config; | ||||
private readonly ConcurrentQueue<string> _sendQueue; | private readonly ConcurrentQueue<string> _sendQueue; | ||||
private readonly WebSocket _parent; | private readonly WebSocket _parent; | ||||
private WSSharpNWebSocket _webSocket; | |||||
private WSSharpWebSocket _webSocket; | |||||
public event EventHandler<WebSocketBinaryMessageEventArgs> BinaryMessage; | public event EventHandler<WebSocketBinaryMessageEventArgs> BinaryMessage; | ||||
public event EventHandler<WebSocketTextMessageEventArgs> TextMessage; | public event EventHandler<WebSocketTextMessageEventArgs> TextMessage; | ||||
@@ -37,7 +37,7 @@ namespace Discord.Net.WebSockets | |||||
public Task Connect(string host, CancellationToken cancelToken) | public Task Connect(string host, CancellationToken cancelToken) | ||||
{ | { | ||||
_webSocket = new WSSharpNWebSocket(host); | |||||
_webSocket = new WSSharpWebSocket(host); | |||||
_webSocket.EmitOnPing = false; | _webSocket.EmitOnPing = false; | ||||
_webSocket.EnableRedirection = true; | _webSocket.EnableRedirection = true; | ||||
_webSocket.Compression = WebSocketSharp.CompressionMethod.Deflate; | _webSocket.Compression = WebSocketSharp.CompressionMethod.Deflate; | ||||
@@ -1,32 +1,30 @@ | |||||
{ | { | ||||
"version": "0.8.1-beta2", | |||||
"description": "An unofficial .Net API wrapper for the Discord client.", | |||||
"authors": [ | |||||
"RogueException" | |||||
], | |||||
"version": "0.8.1-beta2", | |||||
"description": "An unofficial .Net API wrapper for the Discord client.", | |||||
"authors": [ | |||||
"RogueException" | |||||
], | |||||
"tags": [ | "tags": [ | ||||
"discord", | "discord", | ||||
"discordapp" | "discordapp" | ||||
], | ], | ||||
"projectUrl": "https://github.com/RogueException/Discord.Net", | |||||
"licenseUrl": "http://opensource.org/licenses/MIT", | |||||
"repository": { | |||||
"type": "git", | |||||
"url": "git://github.com/RogueException/Discord.Net" | |||||
}, | |||||
"compilationOptions": { | |||||
"allowUnsafe": true | |||||
}, | |||||
"projectUrl": "https://github.com/RogueException/Discord.Net", | |||||
"licenseUrl": "http://opensource.org/licenses/MIT", | |||||
"repository": { | |||||
"type": "git", | |||||
"url": "git://github.com/RogueException/Discord.Net" | |||||
}, | |||||
"configurations": { | "configurations": { | ||||
"TestResponses": { | |||||
"compilationOptions": { | |||||
"define": [ | |||||
"DEBUG", | |||||
"TRACE", | |||||
"TEST_RESPONSES" | |||||
] | |||||
} | |||||
} | |||||
"TestResponses": { | |||||
"compilationOptions": { | |||||
"define": [ | |||||
"DEBUG", | |||||
"TRACE", | |||||
"TEST_RESPONSES" | |||||
] | |||||
} | |||||
} | |||||
}, | }, | ||||
"dependencies": { | "dependencies": { | ||||