Browse Source

Added XHRRawOutput, XHRTiming and VoiceInput debug types

tags/docs-0.9
RogueException 9 years ago
parent
commit
cb88b69a7f
8 changed files with 103 additions and 52 deletions
  1. +3
    -0
      src/Discord.Net.Net45/Discord.Net.csproj
  2. +4
    -1
      src/Discord.Net/DiscordClient.Events.cs
  3. +7
    -4
      src/Discord.Net/DiscordClient.cs
  4. +4
    -4
      src/Discord.Net/DiscordDataSocket.cs
  5. +33
    -13
      src/Discord.Net/DiscordVoiceSocket.cs
  6. +7
    -5
      src/Discord.Net/DiscordWebSocket.cs
  7. +14
    -0
      src/Discord.Net/Helpers/JsonHttpClient.Events.cs
  8. +31
    -25
      src/Discord.Net/Helpers/JsonHttpClient.cs

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

@@ -110,6 +110,9 @@
<Compile Include="..\Discord.Net\Helpers\JsonHttpClient.cs"> <Compile Include="..\Discord.Net\Helpers\JsonHttpClient.cs">
<Link>Helpers\JsonHttpClient.cs</Link> <Link>Helpers\JsonHttpClient.cs</Link>
</Compile> </Compile>
<Compile Include="..\Discord.Net\Helpers\JsonHttpClient.Events.cs">
<Link>Helpers\JsonHttpClient.Events.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\HttpException.cs"> <Compile Include="..\Discord.Net\HttpException.cs">
<Link>HttpException.cs</Link> <Link>HttpException.cs</Link>
</Compile> </Compile>


+ 4
- 1
src/Discord.Net/DiscordClient.Events.cs View File

@@ -10,7 +10,10 @@ namespace Discord
WebSocketRawInput, //TODO: Make Http instanced and add a rawoutput event WebSocketRawInput, //TODO: Make Http instanced and add a rawoutput event
WebSocketUnknownOpCode, WebSocketUnknownOpCode,
WebSocketUnknownEvent, WebSocketUnknownEvent,
VoiceOutput
XHRRawOutput,
XHRTiming,
VoiceInput,
VoiceOutput,
} }
public sealed class LogMessageEventArgs : EventArgs public sealed class LogMessageEventArgs : EventArgs
{ {


+ 7
- 4
src/Discord.Net/DiscordClient.cs View File

@@ -90,8 +90,6 @@ namespace Discord
_blockEvent = new ManualResetEventSlim(true); _blockEvent = new ManualResetEventSlim(true);
_config = config ?? new DiscordClientConfig(); _config = config ?? new DiscordClientConfig();
_rand = new Random(); _rand = new Random();
_http = new JsonHttpClient();
_api = new DiscordAPI(_http);


_serializer = new JsonSerializer(); _serializer = new JsonSerializer();
#if TEST_RESPONSES #if TEST_RESPONSES
@@ -367,7 +365,12 @@ namespace Discord
} }
); );


_webSocket = new DiscordDataSocket(this, _config.ConnectionTimeout, _config.WebSocketInterval);
_http = new JsonHttpClient(config.EnableDebug);
_api = new DiscordAPI(_http);
if (_config.EnableDebug)
_http.OnDebugMessage += (s, e) => RaiseOnDebugMessage(e.Type, e.Message);

_webSocket = new DiscordDataSocket(this, config.ConnectionTimeout, config.WebSocketInterval, config.EnableDebug);
_webSocket.Connected += (s, e) => RaiseConnected(); _webSocket.Connected += (s, e) => RaiseConnected();
_webSocket.Disconnected += async (s, e) => _webSocket.Disconnected += async (s, e) =>
{ {
@@ -406,7 +409,7 @@ namespace Discord
#if !DNXCORE50 #if !DNXCORE50
if (_config.EnableVoice) if (_config.EnableVoice)
{ {
_voiceWebSocket = new DiscordVoiceSocket(this, _config.VoiceConnectionTimeout, _config.WebSocketInterval);
_voiceWebSocket = new DiscordVoiceSocket(this, _config.VoiceConnectionTimeout, _config.WebSocketInterval, config.EnableDebug);
_voiceWebSocket.Connected += (s, e) => RaiseVoiceConnected(); _voiceWebSocket.Connected += (s, e) => RaiseVoiceConnected();
_voiceWebSocket.Disconnected += async (s, e) => _voiceWebSocket.Disconnected += async (s, e) =>
{ {


+ 4
- 4
src/Discord.Net/DiscordDataSocket.cs View File

@@ -1,5 +1,4 @@
using Discord.API.Models; using Discord.API.Models;
using Discord.Helpers;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System; using System;
@@ -13,8 +12,8 @@ namespace Discord
{ {
private readonly ManualResetEventSlim _connectWaitOnLogin, _connectWaitOnLogin2; private readonly ManualResetEventSlim _connectWaitOnLogin, _connectWaitOnLogin2;


public DiscordDataSocket(DiscordClient client, int timeout, int interval)
: base(client, timeout, interval)
public DiscordDataSocket(DiscordClient client, int timeout, int interval, bool isDebug)
: base(client, timeout, interval, isDebug)
{ {
_connectWaitOnLogin = new ManualResetEventSlim(false); _connectWaitOnLogin = new ManualResetEventSlim(false);
_connectWaitOnLogin2 = new ManualResetEventSlim(false); _connectWaitOnLogin2 = new ManualResetEventSlim(false);
@@ -72,7 +71,8 @@ namespace Discord
} }
break; break;
default: default:
RaiseOnDebugMessage(DebugMessageType.WebSocketUnknownOpCode, "Unknown DataSocket op: " + msg.Operation);
if (_isDebug)
RaiseOnDebugMessage(DebugMessageType.WebSocketUnknownOpCode, "Unknown DataSocket op: " + msg.Operation);
break; break;
} }
#if DNXCORE #if DNXCORE


+ 33
- 13
src/Discord.Net/DiscordVoiceSocket.cs View File

@@ -49,8 +49,8 @@ namespace Discord
#endif #endif
#endif #endif


public DiscordVoiceSocket(DiscordClient client, int timeout, int interval)
: base(client, timeout, interval)
public DiscordVoiceSocket(DiscordClient client, int timeout, int interval, bool isDebug)
: base(client, timeout, interval, isDebug)
{ {
_connectWaitOnLogin = new ManualResetEventSlim(false); _connectWaitOnLogin = new ManualResetEventSlim(false);
#if !DNXCORE50 #if !DNXCORE50
@@ -287,7 +287,8 @@ namespace Discord
break; break;
#endif #endif
default: default:
RaiseOnDebugMessage(DebugMessageType.WebSocketUnknownOpCode, "Unknown VoiceSocket op: " + msg.Operation);
if (_isDebug)
RaiseOnDebugMessage(DebugMessageType.WebSocketUnknownOpCode, "Unknown VoiceSocket op: " + msg.Operation);
break; break;
} }
#if DNXCORE50 #if DNXCORE50
@@ -322,25 +323,42 @@ namespace Discord
else else
{ {
//Parse RTP Data //Parse RTP Data
/*if (length < 12)
throw new Exception($"Unexpected message length. Expected >= 12, got {length}.");
if (length < 12)
{
if (_isDebug)
RaiseOnDebugMessage(DebugMessageType.VoiceInput, $"Unexpected message length. Expected >= 12, got {length}.");
return;
}


byte flags = buffer[0]; byte flags = buffer[0];
if (flags != 0x80) if (flags != 0x80)
throw new Exception("Unexpected Flags");
{
if (_isDebug)
RaiseOnDebugMessage(DebugMessageType.VoiceInput, $"Unexpected Flags: {flags}");
return;
}


byte payloadType = buffer[1]; byte payloadType = buffer[1];
if (payloadType != 0x78) if (payloadType != 0x78)
throw new Exception("Unexpected Payload Type");
{
if (_isDebug)
RaiseOnDebugMessage(DebugMessageType.VoiceInput, $"Unexpected Payload Type: {flags}");
return;
}


ushort sequenceNumber = (ushort)((buffer[2] << 8) | buffer[3]);
uint timestamp = (uint)((buffer[4] << 24) | (buffer[5] << 16) |
(buffer[6] << 8) | (buffer[7] << 0));
uint ssrc = (uint)((buffer[8] << 24) | (buffer[9] << 16) |
(buffer[10] << 8) | (buffer[11] << 0));
ushort sequenceNumber = (ushort)((buffer[2] << 8) |
buffer[3] << 0);
uint timestamp = (uint)((buffer[4] << 24) |
(buffer[5] << 16) |
(buffer[6] << 8) |
(buffer[7] << 0));
uint ssrc = (uint)((buffer[8] << 24) |
(buffer[9] << 16) |
(buffer[10] << 8) |
(buffer[11] << 0));


//Decrypt //Decrypt
if (_mode == "xsalsa20_poly1305")
/*if (_mode == "xsalsa20_poly1305")
{ {
if (length < 36) //12 + 24 if (length < 36) //12 + 24
throw new Exception($"Unexpected message length. Expected >= 36, got {length}."); throw new Exception($"Unexpected message length. Expected >= 36, got {length}.");
@@ -362,6 +380,8 @@ namespace Discord
buffer = newBuffer; buffer = newBuffer;
}*/ }*/


if (_isDebug)
RaiseOnDebugMessage(DebugMessageType.VoiceInput, $"Received {buffer.Length - 12} bytes.");
//TODO: Use Voice Data //TODO: Use Voice Data
} }
} }


+ 7
- 5
src/Discord.Net/DiscordWebSocket.cs View File

@@ -14,22 +14,24 @@ namespace Discord
private const int SendChunkSize = 4096; private const int SendChunkSize = 4096;


protected readonly DiscordClient _client; protected readonly DiscordClient _client;
protected volatile CancellationTokenSource _disconnectToken;
protected int _timeout, _heartbeatInterval;
protected readonly int _sendInterval; protected readonly int _sendInterval;
protected string _host;
protected readonly bool _isDebug;
private readonly ConcurrentQueue<byte[]> _sendQueue;


protected volatile CancellationTokenSource _disconnectToken;
private volatile ClientWebSocket _webSocket; private volatile ClientWebSocket _webSocket;
private volatile Task _tasks; private volatile Task _tasks;
private ConcurrentQueue<byte[]> _sendQueue;
protected string _host;
protected int _timeout, _heartbeatInterval;
private DateTime _lastHeartbeat; private DateTime _lastHeartbeat;
private bool _isConnected; private bool _isConnected;


public DiscordWebSocket(DiscordClient client, int timeout, int interval)
public DiscordWebSocket(DiscordClient client, int timeout, int interval, bool isDebug)
{ {
_client = client; _client = client;
_timeout = timeout; _timeout = timeout;
_sendInterval = interval; _sendInterval = interval;
_isDebug = isDebug;


_sendQueue = new ConcurrentQueue<byte[]>(); _sendQueue = new ConcurrentQueue<byte[]>();
} }


+ 14
- 0
src/Discord.Net/Helpers/JsonHttpClient.Events.cs View File

@@ -0,0 +1,14 @@
using System;

namespace Discord.Helpers
{
internal partial class JsonHttpClient
{
public event EventHandler<LogMessageEventArgs> OnDebugMessage;
protected void RaiseOnDebugMessage(DebugMessageType type, string message)
{
if (OnDebugMessage != null)
OnDebugMessage(this, new LogMessageEventArgs(type, message));
}
}
}

+ 31
- 25
src/Discord.Net/Helpers/JsonHttpClient.cs View File

@@ -1,7 +1,6 @@
using Discord.API; using Discord.API;
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Globalization; using System.Globalization;
using System.Net.Http; using System.Net.Http;
@@ -9,24 +8,22 @@ using System.Net;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Diagnostics;


namespace Discord.Helpers namespace Discord.Helpers
{ {
internal class JsonHttpClient
internal partial class JsonHttpClient
{ {
#if TEST_RESPONSES
private const bool _isDebug = true;
#else
private const bool _isDebug = false;
#endif
private bool _isDebug;
private readonly HttpClient _client; private readonly HttpClient _client;
private readonly HttpMethod _patch; private readonly HttpMethod _patch;
#if TEST_RESPONSES #if TEST_RESPONSES
private readonly JsonSerializerSettings _settings; private readonly JsonSerializerSettings _settings;
#endif #endif


public JsonHttpClient()
public JsonHttpClient(bool isDebug)
{ {
_isDebug = isDebug;
_patch = new HttpMethod("PATCH"); //Not sure why this isn't a default... _patch = new HttpMethod("PATCH"); //Not sure why this isn't a default...


_client = new HttpClient(new HttpClientHandler _client = new HttpClient(new HttpClientHandler
@@ -131,8 +128,8 @@ namespace Discord.Helpers
private async Task<string> Send(HttpMethod method, string path, HttpContent content) private async Task<string> Send(HttpMethod method, string path, HttpContent content)
{ {
string responseJson = await SendRequest(method, path, content, true); string responseJson = await SendRequest(method, path, content, true);
if (path.StartsWith(Endpoints.BaseApi))
CheckEmptyResponse(responseJson);
if (path.StartsWith(Endpoints.BaseApi) && !string.IsNullOrEmpty(responseJson))
throw new Exception("API check failed: Response is not empty.");
return responseJson; return responseJson;
} }
#else #else
@@ -142,9 +139,25 @@ namespace Discord.Helpers


private async Task<string> SendRequest(HttpMethod method, string path, HttpContent content, bool hasResponse) private async Task<string> SendRequest(HttpMethod method, string path, HttpContent content, bool hasResponse)
{ {
#if TEST_RESPONSES
Stopwatch stopwatch = Stopwatch.StartNew();
#endif
Stopwatch stopwatch = null;
if (_isDebug)
{
if (content != null)
{
if (content is StringContent)
{
string json = await (content as StringContent).ReadAsStringAsync();
RaiseOnDebugMessage(DebugMessageType.XHRRawOutput, $"{method} {path}: {json}");
}
else
{
byte[] bytes = await content.ReadAsByteArrayAsync();
RaiseOnDebugMessage(DebugMessageType.XHRRawOutput, $"{method} {path}: {bytes.Length} bytes");
}
}
stopwatch = Stopwatch.StartNew();
}

string result; string result;
using (HttpRequestMessage msg = new HttpRequestMessage(method, path)) using (HttpRequestMessage msg = new HttpRequestMessage(method, path))
{ {
@@ -168,21 +181,14 @@ namespace Discord.Helpers
} }
} }


#if TEST_RESPONSES
stopwatch.Stop();
Debug.WriteLine($"{method} {path}: {Math.Round(stopwatch.ElapsedTicks / (double)TimeSpan.TicksPerMillisecond, 2)}ms");
#endif
if (_isDebug)
{
stopwatch.Stop();
RaiseOnDebugMessage(DebugMessageType.XHRTiming, $"{method} {path}: {Math.Round(stopwatch.ElapsedTicks / (double)TimeSpan.TicksPerMillisecond, 2)}ms");
}
return result; return result;
} }


#if TEST_RESPONSES
private void CheckEmptyResponse(string json)
{
if (!string.IsNullOrEmpty(json))
throw new Exception("API check failed: Response is not empty.");
}
#endif

private StringContent AsJson(object obj) private StringContent AsJson(object obj)
{ {
return new StringContent(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json"); return new StringContent(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json");


Loading…
Cancel
Save