Isolated API definitions to their own library

This commit is contained in:
RogueException
2016-12-23 15:10:45 -04:00
parent ca6eb6aff4
commit 8326d01f62
200 changed files with 183 additions and 73 deletions

View File

@@ -1,251 +0,0 @@
#pragma warning disable CS1591
using Discord.API.Gateway;
using Discord.API.Rest;
using Discord.Net.Queue;
using Discord.Net.Rest;
using Discord.Net.WebSockets;
using Discord.WebSocket;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Discord.API
{
public class DiscordSocketApiClient : DiscordRestApiClient
{
public event Func<GatewayOpCode, Task> SentGatewayMessage { add { _sentGatewayMessageEvent.Add(value); } remove { _sentGatewayMessageEvent.Remove(value); } }
private readonly AsyncEvent<Func<GatewayOpCode, Task>> _sentGatewayMessageEvent = new AsyncEvent<Func<GatewayOpCode, Task>>();
public event Func<GatewayOpCode, int?, string, object, Task> ReceivedGatewayEvent { add { _receivedGatewayEvent.Add(value); } remove { _receivedGatewayEvent.Remove(value); } }
private readonly AsyncEvent<Func<GatewayOpCode, int?, string, object, Task>> _receivedGatewayEvent = new AsyncEvent<Func<GatewayOpCode, int?, string, object, Task>>();
public event Func<Exception, Task> Disconnected { add { _disconnectedEvent.Add(value); } remove { _disconnectedEvent.Remove(value); } }
private readonly AsyncEvent<Func<Exception, Task>> _disconnectedEvent = new AsyncEvent<Func<Exception, Task>>();
private readonly IWebSocketClient _gatewayClient;
private CancellationTokenSource _connectCancelToken;
private string _gatewayUrl;
public ConnectionState ConnectionState { get; private set; }
public DiscordSocketApiClient(RestClientProvider restClientProvider, string userAgent, WebSocketProvider webSocketProvider,
RetryMode defaultRetryMode = RetryMode.AlwaysRetry, JsonSerializer serializer = null, RequestQueue requestQueue = null)
: base(restClientProvider, userAgent, defaultRetryMode, serializer, requestQueue, true)
{
_gatewayClient = webSocketProvider();
//_gatewayClient.SetHeader("user-agent", DiscordConfig.UserAgent); (Causes issues in .NET Framework 4.6+)
_gatewayClient.BinaryMessage += async (data, index, count) =>
{
using (var compressed = new MemoryStream(data, index + 2, count - 2))
using (var decompressed = new MemoryStream())
{
using (var zlib = new DeflateStream(compressed, CompressionMode.Decompress))
zlib.CopyTo(decompressed);
decompressed.Position = 0;
using (var reader = new StreamReader(decompressed))
using (var jsonReader = new JsonTextReader(reader))
{
var msg = _serializer.Deserialize<SocketFrame>(jsonReader);
await _receivedGatewayEvent.InvokeAsync((GatewayOpCode)msg.Operation, msg.Sequence, msg.Type, msg.Payload).ConfigureAwait(false);
}
}
};
_gatewayClient.TextMessage += async text =>
{
using (var reader = new StringReader(text))
using (var jsonReader = new JsonTextReader(reader))
{
var msg = _serializer.Deserialize<SocketFrame>(jsonReader);
await _receivedGatewayEvent.InvokeAsync((GatewayOpCode)msg.Operation, msg.Sequence, msg.Type, msg.Payload).ConfigureAwait(false);
}
};
_gatewayClient.Closed += async ex =>
{
await DisconnectAsync().ConfigureAwait(false);
await _disconnectedEvent.InvokeAsync(ex).ConfigureAwait(false);
};
}
internal override void Dispose(bool disposing)
{
if (!_isDisposed)
{
if (disposing)
{
_connectCancelToken?.Dispose();
(_gatewayClient as IDisposable)?.Dispose();
}
_isDisposed = true;
}
}
public async Task ConnectAsync()
{
await _stateLock.WaitAsync().ConfigureAwait(false);
try
{
await ConnectInternalAsync().ConfigureAwait(false);
}
finally { _stateLock.Release(); }
}
internal override async Task ConnectInternalAsync()
{
if (LoginState != LoginState.LoggedIn)
throw new InvalidOperationException("You must log in before connecting.");
if (_gatewayClient == null)
throw new NotSupportedException("This client is not configured with websocket support.");
ConnectionState = ConnectionState.Connecting;
try
{
_connectCancelToken = new CancellationTokenSource();
if (_gatewayClient != null)
_gatewayClient.SetCancelToken(_connectCancelToken.Token);
if (_gatewayUrl == null)
{
var gatewayResponse = await GetGatewayAsync().ConfigureAwait(false);
_gatewayUrl = $"{gatewayResponse.Url}?v={DiscordConfig.APIVersion}&encoding={DiscordSocketConfig.GatewayEncoding}";
}
await _gatewayClient.ConnectAsync(_gatewayUrl).ConfigureAwait(false);
ConnectionState = ConnectionState.Connected;
}
catch (Exception)
{
_gatewayUrl = null; //Uncache in case the gateway url changed
await DisconnectInternalAsync().ConfigureAwait(false);
throw;
}
}
public async Task DisconnectAsync()
{
await _stateLock.WaitAsync().ConfigureAwait(false);
try
{
await DisconnectInternalAsync().ConfigureAwait(false);
}
finally { _stateLock.Release(); }
}
public async Task DisconnectAsync(Exception ex)
{
await _stateLock.WaitAsync().ConfigureAwait(false);
try
{
await DisconnectInternalAsync().ConfigureAwait(false);
}
finally { _stateLock.Release(); }
}
internal override async Task DisconnectInternalAsync()
{
if (_gatewayClient == null)
throw new NotSupportedException("This client is not configured with websocket support.");
if (ConnectionState == ConnectionState.Disconnected) return;
ConnectionState = ConnectionState.Disconnecting;
try { _connectCancelToken?.Cancel(false); }
catch { }
await _gatewayClient.DisconnectAsync().ConfigureAwait(false);
ConnectionState = ConnectionState.Disconnected;
}
//Core
public Task SendGatewayAsync(GatewayOpCode opCode, object payload, RequestOptions options = null)
=> SendGatewayInternalAsync(opCode, payload, options);
private async Task SendGatewayInternalAsync(GatewayOpCode opCode, object payload, RequestOptions options)
{
CheckState();
//TODO: Add ETF
byte[] bytes = null;
payload = new SocketFrame { Operation = (int)opCode, Payload = payload };
if (payload != null)
bytes = Encoding.UTF8.GetBytes(SerializeJson(payload));
await RequestQueue.SendAsync(new WebSocketRequest(_gatewayClient, null, bytes, true, options)).ConfigureAwait(false);
await _sentGatewayMessageEvent.InvokeAsync(opCode).ConfigureAwait(false);
}
//Gateway
public async Task<GetGatewayResponse> GetGatewayAsync(RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
return await SendAsync<GetGatewayResponse>("GET", () => "gateway", new BucketIds(), options: options).ConfigureAwait(false);
}
public async Task SendIdentifyAsync(int largeThreshold = 100, bool useCompression = true, int shardID = 0, int totalShards = 1, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
var props = new Dictionary<string, string>
{
["$device"] = "Discord.Net"
};
var msg = new IdentifyParams()
{
Token = _authToken,
Properties = props,
LargeThreshold = largeThreshold,
UseCompression = useCompression,
};
if (totalShards > 1)
msg.ShardingParams = new int[] { shardID, totalShards };
await SendGatewayAsync(GatewayOpCode.Identify, msg, options: options).ConfigureAwait(false);
}
public async Task SendResumeAsync(string sessionId, int lastSeq, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
var msg = new ResumeParams()
{
Token = _authToken,
SessionId = sessionId,
Sequence = lastSeq
};
await SendGatewayAsync(GatewayOpCode.Resume, msg, options: options).ConfigureAwait(false);
}
public async Task SendHeartbeatAsync(int lastSeq, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
await SendGatewayAsync(GatewayOpCode.Heartbeat, lastSeq, options: options).ConfigureAwait(false);
}
public async Task SendStatusUpdateAsync(UserStatus status, bool isAFK, long? since, Game game, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
var args = new StatusUpdateParams
{
Status = status,
IdleSince = since,
IsAFK = isAFK,
Game = game
};
await SendGatewayAsync(GatewayOpCode.StatusUpdate, args, options: options).ConfigureAwait(false);
}
public async Task SendRequestMembersAsync(IEnumerable<ulong> guildIds, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
await SendGatewayAsync(GatewayOpCode.RequestGuildMembers, new RequestMembersParams { GuildIds = guildIds, Query = "", Limit = 0 }, options: options).ConfigureAwait(false);
}
public async Task SendVoiceStateUpdateAsync(ulong guildId, ulong? channelId, bool selfDeaf, bool selfMute, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
var payload = new VoiceStateUpdateParams
{
GuildId = guildId,
ChannelId = channelId,
SelfDeaf = selfDeaf,
SelfMute = selfMute
};
await SendGatewayAsync(GatewayOpCode.VoiceStateUpdate, payload, options: options).ConfigureAwait(false);
}
public async Task SendGuildSyncAsync(IEnumerable<ulong> guildIds, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
await SendGatewayAsync(GatewayOpCode.GuildSync, guildIds, options: options).ConfigureAwait(false);
}
}
}

View File

@@ -1,253 +0,0 @@
#pragma warning disable CS1591
using Discord.API;
using Discord.API.Voice;
using Discord.Net.Converters;
using Discord.Net.Udp;
using Discord.Net.WebSockets;
using Newtonsoft.Json;
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Discord.Audio
{
public class DiscordVoiceAPIClient
{
public const int MaxBitrate = 128;
public const string Mode = "xsalsa20_poly1305";
public event Func<string, string, double, Task> SentRequest { add { _sentRequestEvent.Add(value); } remove { _sentRequestEvent.Remove(value); } }
private readonly AsyncEvent<Func<string, string, double, Task>> _sentRequestEvent = new AsyncEvent<Func<string, string, double, Task>>();
public event Func<VoiceOpCode, Task> SentGatewayMessage { add { _sentGatewayMessageEvent.Add(value); } remove { _sentGatewayMessageEvent.Remove(value); } }
private readonly AsyncEvent<Func<VoiceOpCode, Task>> _sentGatewayMessageEvent = new AsyncEvent<Func<VoiceOpCode, Task>>();
public event Func<Task> SentDiscovery { add { _sentDiscoveryEvent.Add(value); } remove { _sentDiscoveryEvent.Remove(value); } }
private readonly AsyncEvent<Func<Task>> _sentDiscoveryEvent = new AsyncEvent<Func<Task>>();
public event Func<int, Task> SentData { add { _sentDataEvent.Add(value); } remove { _sentDataEvent.Remove(value); } }
private readonly AsyncEvent<Func<int, Task>> _sentDataEvent = new AsyncEvent<Func<int, Task>>();
public event Func<VoiceOpCode, object, Task> ReceivedEvent { add { _receivedEvent.Add(value); } remove { _receivedEvent.Remove(value); } }
private readonly AsyncEvent<Func<VoiceOpCode, object, Task>> _receivedEvent = new AsyncEvent<Func<VoiceOpCode, object, Task>>();
public event Func<byte[], Task> ReceivedPacket { add { _receivedPacketEvent.Add(value); } remove { _receivedPacketEvent.Remove(value); } }
private readonly AsyncEvent<Func<byte[], Task>> _receivedPacketEvent = new AsyncEvent<Func<byte[], Task>>();
public event Func<Exception, Task> Disconnected { add { _disconnectedEvent.Add(value); } remove { _disconnectedEvent.Remove(value); } }
private readonly AsyncEvent<Func<Exception, Task>> _disconnectedEvent = new AsyncEvent<Func<Exception, Task>>();
private readonly JsonSerializer _serializer;
private readonly IWebSocketClient _webSocketClient;
private readonly SemaphoreSlim _connectionLock;
private CancellationTokenSource _connectCancelToken;
private IUdpSocket _udp;
private bool _isDisposed;
public ulong GuildId { get; }
public ConnectionState ConnectionState { get; private set; }
internal DiscordVoiceAPIClient(ulong guildId, WebSocketProvider webSocketProvider, UdpSocketProvider udpSocketProvider, JsonSerializer serializer = null)
{
GuildId = guildId;
_connectionLock = new SemaphoreSlim(1, 1);
_udp = udpSocketProvider();
_udp.ReceivedDatagram += async (data, index, count) =>
{
if (index != 0)
{
var newData = new byte[count];
Buffer.BlockCopy(data, index, newData, 0, count);
data = newData;
}
await _receivedPacketEvent.InvokeAsync(data).ConfigureAwait(false);
};
_webSocketClient = webSocketProvider();
//_gatewayClient.SetHeader("user-agent", DiscordConfig.UserAgent); (Causes issues in .Net 4.6+)
_webSocketClient.BinaryMessage += async (data, index, count) =>
{
using (var compressed = new MemoryStream(data, index + 2, count - 2))
using (var decompressed = new MemoryStream())
{
using (var zlib = new DeflateStream(compressed, CompressionMode.Decompress))
zlib.CopyTo(decompressed);
decompressed.Position = 0;
using (var reader = new StreamReader(decompressed))
{
var msg = JsonConvert.DeserializeObject<SocketFrame>(reader.ReadToEnd());
await _receivedEvent.InvokeAsync((VoiceOpCode)msg.Operation, msg.Payload).ConfigureAwait(false);
}
}
};
_webSocketClient.TextMessage += async text =>
{
var msg = JsonConvert.DeserializeObject<SocketFrame>(text);
await _receivedEvent.InvokeAsync((VoiceOpCode)msg.Operation, msg.Payload).ConfigureAwait(false);
};
_webSocketClient.Closed += async ex =>
{
await DisconnectAsync().ConfigureAwait(false);
await _disconnectedEvent.InvokeAsync(ex).ConfigureAwait(false);
};
_serializer = serializer ?? new JsonSerializer { ContractResolver = new DiscordContractResolver() };
}
private void Dispose(bool disposing)
{
if (!_isDisposed)
{
if (disposing)
{
_connectCancelToken?.Dispose();
(_udp as IDisposable)?.Dispose();
(_webSocketClient as IDisposable)?.Dispose();
}
_isDisposed = true;
}
}
public void Dispose() => Dispose(true);
public async Task SendAsync(VoiceOpCode opCode, object payload, RequestOptions options = null)
{
byte[] bytes = null;
payload = new SocketFrame { Operation = (int)opCode, Payload = payload };
if (payload != null)
bytes = Encoding.UTF8.GetBytes(SerializeJson(payload));
await _webSocketClient.SendAsync(bytes, 0, bytes.Length, true).ConfigureAwait(false);
await _sentGatewayMessageEvent.InvokeAsync(opCode).ConfigureAwait(false);
}
public async Task SendAsync(byte[] data, int bytes)
{
await _udp.SendAsync(data, 0, bytes).ConfigureAwait(false);
await _sentDataEvent.InvokeAsync(bytes).ConfigureAwait(false);
}
//WebSocket
public async Task SendHeartbeatAsync(RequestOptions options = null)
{
await SendAsync(VoiceOpCode.Heartbeat, DateTimeUtils.ToUnixMilliseconds(DateTimeOffset.UtcNow), options: options).ConfigureAwait(false);
}
public async Task SendIdentityAsync(ulong userId, string sessionId, string token)
{
await SendAsync(VoiceOpCode.Identify, new IdentifyParams
{
GuildId = GuildId,
UserId = userId,
SessionId = sessionId,
Token = token
}).ConfigureAwait(false);
}
public async Task SendSelectProtocol(string externalIp, int externalPort)
{
await SendAsync(VoiceOpCode.SelectProtocol, new SelectProtocolParams
{
Protocol = "udp",
Data = new UdpProtocolInfo
{
Address = externalIp,
Port = externalPort,
Mode = Mode
}
}).ConfigureAwait(false);
}
public async Task SendSetSpeaking(bool value)
{
await SendAsync(VoiceOpCode.Speaking, new SpeakingParams
{
IsSpeaking = value,
Delay = 0
}).ConfigureAwait(false);
}
public async Task ConnectAsync(string url)
{
await _connectionLock.WaitAsync().ConfigureAwait(false);
try
{
await ConnectInternalAsync(url).ConfigureAwait(false);
}
finally { _connectionLock.Release(); }
}
private async Task ConnectInternalAsync(string url)
{
ConnectionState = ConnectionState.Connecting;
try
{
_connectCancelToken = new CancellationTokenSource();
var cancelToken = _connectCancelToken.Token;
_webSocketClient.SetCancelToken(cancelToken);
await _webSocketClient.ConnectAsync(url).ConfigureAwait(false);
_udp.SetCancelToken(cancelToken);
await _udp.StartAsync().ConfigureAwait(false);
ConnectionState = ConnectionState.Connected;
}
catch (Exception)
{
await DisconnectInternalAsync().ConfigureAwait(false);
throw;
}
}
public async Task DisconnectAsync()
{
await _connectionLock.WaitAsync().ConfigureAwait(false);
try
{
await DisconnectInternalAsync().ConfigureAwait(false);
}
finally { _connectionLock.Release(); }
}
private async Task DisconnectInternalAsync()
{
if (ConnectionState == ConnectionState.Disconnected) return;
ConnectionState = ConnectionState.Disconnecting;
try { _connectCancelToken?.Cancel(false); }
catch { }
//Wait for tasks to complete
await _udp.StopAsync().ConfigureAwait(false);
await _webSocketClient.DisconnectAsync().ConfigureAwait(false);
ConnectionState = ConnectionState.Disconnected;
}
//Udp
public async Task SendDiscoveryAsync(uint ssrc)
{
var packet = new byte[70];
packet[0] = (byte)(ssrc >> 24);
packet[1] = (byte)(ssrc >> 16);
packet[2] = (byte)(ssrc >> 8);
packet[3] = (byte)(ssrc >> 0);
await SendAsync(packet, 70).ConfigureAwait(false);
await _sentDiscoveryEvent.InvokeAsync().ConfigureAwait(false);
}
public void SetUdpEndpoint(string host, int port)
{
_udp.SetDestination(host, port);
}
//Helpers
private static double ToMilliseconds(Stopwatch stopwatch) => Math.Round((double)stopwatch.ElapsedTicks / (double)Stopwatch.Frequency * 1000.0, 2);
private string SerializeJson(object value)
{
var sb = new StringBuilder(256);
using (TextWriter text = new StringWriter(sb, CultureInfo.InvariantCulture))
using (JsonWriter writer = new JsonTextWriter(text))
_serializer.Serialize(writer, value);
return sb.ToString();
}
private T DeserializeJson<T>(Stream jsonStream)
{
using (TextReader text = new StreamReader(jsonStream))
using (JsonReader reader = new JsonTextReader(text))
return _serializer.Deserialize<T>(reader);
}
}
}

View File

@@ -1,25 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
using System;
namespace Discord.API.Gateway
{
public class ExtendedGuild : Guild
{
[JsonProperty("unavailable")]
public bool? Unavailable { get; set; }
[JsonProperty("member_count")]
public int MemberCount { get; set; }
[JsonProperty("large")]
public bool Large { get; set; }
[JsonProperty("presences")]
public Presence[] Presences { get; set; }
[JsonProperty("members")]
public GuildMember[] Members { get; set; }
[JsonProperty("channels")]
public Channel[] Channels { get; set; }
[JsonProperty("joined_at")]
public DateTimeOffset JoinedAt { get; set; }
}
}

View File

@@ -1,33 +0,0 @@
#pragma warning disable CS1591
namespace Discord.API.Gateway
{
public enum GatewayOpCode : byte
{
/// <summary> C←S - Used to send most events. </summary>
Dispatch = 0,
/// <summary> C↔S - Used to keep the connection alive and measure latency. </summary>
Heartbeat = 1,
/// <summary> C→S - Used to associate a connection with a token and specify configuration. </summary>
Identify = 2,
/// <summary> C→S - Used to update client's status and current game id. </summary>
StatusUpdate = 3,
/// <summary> C→S - Used to join a particular voice channel. </summary>
VoiceStateUpdate = 4,
/// <summary> C→S - Used to ensure the guild's voice server is alive. </summary>
VoiceServerPing = 5,
/// <summary> C→S - Used to resume a connection after a redirect occurs. </summary>
Resume = 6,
/// <summary> C←S - Used to notify a client that they must reconnect to another gateway. </summary>
Reconnect = 7,
/// <summary> C→S - Used to request members that were withheld by large_threshold </summary>
RequestGuildMembers = 8,
/// <summary> C←S - Used to notify the client that their session has expired and cannot be resumed. </summary>
InvalidSession = 9,
/// <summary> C←S - Used to provide information to the client immediately on connection. </summary>
Hello = 10,
/// <summary> C←S - Used to reply to a client's heartbeat. </summary>
HeartbeatAck = 11,
/// <summary> C→S - Used to request presence updates from particular guilds. </summary>
GuildSync = 12
}
}

View File

@@ -1,13 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
public class GuildBanEvent
{
[JsonProperty("guild_id")]
public ulong GuildId { get; set; }
[JsonProperty("user")]
public User User { get; set; }
}
}

View File

@@ -1,13 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
public class GuildEmojiUpdateEvent
{
[JsonProperty("guild_id")]
public ulong GuildId { get; set; }
[JsonProperty("emojis")]
public Emoji[] Emojis { get; set; }
}
}

View File

@@ -1,11 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
public class GuildMemberAddEvent : GuildMember
{
[JsonProperty("guild_id")]
public ulong GuildId { get; set; }
}
}

View File

@@ -1,13 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
public class GuildMemberRemoveEvent
{
[JsonProperty("guild_id")]
public ulong GuildId { get; set; }
[JsonProperty("user")]
public User User { get; set; }
}
}

View File

@@ -1,11 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
public class GuildMemberUpdateEvent : GuildMember
{
[JsonProperty("guild_id")]
public ulong GuildId { get; set; }
}
}

View File

@@ -1,13 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
public class GuildMembersChunkEvent
{
[JsonProperty("guild_id")]
public ulong GuildId { get; set; }
[JsonProperty("members")]
public GuildMember[] Members { get; set; }
}
}

View File

@@ -1,13 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
public class GuildRoleCreateEvent
{
[JsonProperty("guild_id")]
public ulong GuildId { get; set; }
[JsonProperty("role")]
public Role Role { get; set; }
}
}

View File

@@ -1,13 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
public class GuildRoleDeleteEvent
{
[JsonProperty("guild_id")]
public ulong GuildId { get; set; }
[JsonProperty("role_id")]
public ulong RoleId { get; set; }
}
}

View File

@@ -1,13 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
public class GuildRoleUpdateEvent
{
[JsonProperty("guild_id")]
public ulong GuildId { get; set; }
[JsonProperty("role")]
public Role Role { get; set; }
}
}

View File

@@ -1,18 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
public class GuildSyncEvent
{
[JsonProperty("id")]
public ulong Id { get; set; }
[JsonProperty("large")]
public bool Large { get; set; }
[JsonProperty("presences")]
public Presence[] Presences { get; set; }
[JsonProperty("members")]
public GuildMember[] Members { get; set; }
}
}

View File

@@ -1,11 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
public class HelloEvent
{
[JsonProperty("heartbeat_interval")]
public int HeartbeatInterval { get; set; }
}
}

View File

@@ -1,21 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
using System.Collections.Generic;
namespace Discord.API.Gateway
{
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class IdentifyParams
{
[JsonProperty("token")]
public string Token { get; set; }
[JsonProperty("properties")]
public IDictionary<string, string> Properties { get; set; }
[JsonProperty("large_threshold")]
public int LargeThreshold { get; set; }
[JsonProperty("compress")]
public bool UseCompression { get; set; }
[JsonProperty("shard")]
public Optional<int[]> ShardingParams { get; set; }
}
}

View File

@@ -1,14 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
using System.Collections.Generic;
namespace Discord.API.Gateway
{
public class MessageDeleteBulkEvent
{
[JsonProperty("channel_id")]
public ulong ChannelId { get; set; }
[JsonProperty("ids")]
public IEnumerable<ulong> Ids { get; set; }
}
}

View File

@@ -1,16 +0,0 @@
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
public class Reaction
{
[JsonProperty("user_id")]
public ulong UserId { get; set; }
[JsonProperty("message_id")]
public ulong MessageId { get; set; }
[JsonProperty("channel_id")]
public ulong ChannelId { get; set; }
[JsonProperty("emoji")]
public Emoji Emoji { get; set; }
}
}

View File

@@ -1,38 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
public class ReadyEvent
{
public class ReadState
{
[JsonProperty("id")]
public string ChannelId { get; set; }
[JsonProperty("mention_count")]
public int MentionCount { get; set; }
[JsonProperty("last_message_id")]
public string LastMessageId { get; set; }
}
[JsonProperty("v")]
public int Version { get; set; }
[JsonProperty("user")]
public User User { get; set; }
[JsonProperty("session_id")]
public string SessionId { get; set; }
[JsonProperty("read_state")]
public ReadState[] ReadStates { get; set; }
[JsonProperty("guilds")]
public ExtendedGuild[] Guilds { get; set; }
[JsonProperty("private_channels")]
public Channel[] PrivateChannels { get; set; }
[JsonProperty("relationships")]
public Relationship[] Relationships { get; set; }
//Ignored
/*[JsonProperty("user_settings")]
[JsonProperty("user_guild_settings")]
[JsonProperty("tutorial")]*/
}
}

View File

@@ -1,13 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
public class RecipientEvent
{
[JsonProperty("user")]
public User User { get; set; }
[JsonProperty("channel_id")]
public ulong ChannelId { get; set; }
}
}

View File

@@ -1,12 +0,0 @@
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
public class RemoveAllReactionsEvent
{
[JsonProperty("channel_id")]
public ulong ChannelId { get; set; }
[JsonProperty("message_id")]
public ulong MessageId { get; set; }
}
}

View File

@@ -1,18 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
using System.Collections.Generic;
namespace Discord.API.Gateway
{
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class RequestMembersParams
{
[JsonProperty("query")]
public string Query { get; set; }
[JsonProperty("limit")]
public int Limit { get; set; }
[JsonProperty("guild_id")]
public IEnumerable<ulong> GuildIds { get; set; }
}
}

View File

@@ -1,16 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class ResumeParams
{
[JsonProperty("token")]
public string Token { get; set; }
[JsonProperty("session_id")]
public string SessionId { get; set; }
[JsonProperty("seq")]
public int Sequence { get; set; }
}
}

View File

@@ -1,11 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
public class ResumedEvent
{
[JsonProperty("heartbeat_interval")]
public int HeartbeatInterval { get; set; }
}
}

View File

@@ -1,18 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class StatusUpdateParams
{
[JsonProperty("status")]
public UserStatus Status { get; set; }
[JsonProperty("since"), Int53]
public long? IdleSince { get; set; }
[JsonProperty("afk")]
public bool IsAFK { get; set; }
[JsonProperty("game")]
public Game Game { get; set; }
}
}

View File

@@ -1,15 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
public class TypingStartEvent
{
[JsonProperty("user_id")]
public ulong UserId { get; set; }
[JsonProperty("channel_id")]
public ulong ChannelId { get; set; }
[JsonProperty("timestamp")]
public int Timestamp { get; set; }
}
}

View File

@@ -1,15 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
public class VoiceServerUpdateEvent
{
[JsonProperty("guild_id")]
public ulong GuildId { get; set; }
[JsonProperty("endpoint")]
public string Endpoint { get; set; }
[JsonProperty("token")]
public string Token { get; set; }
}
}

View File

@@ -1,22 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Gateway
{
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class VoiceStateUpdateParams
{
[JsonProperty("self_mute")]
public bool SelfMute { get; set; }
[JsonProperty("self_deaf")]
public bool SelfDeaf { get; set; }
[JsonProperty("guild_id")]
public ulong? GuildId { get; set; }
public IGuild Guild { set { GuildId = value?.Id; } }
[JsonProperty("channel_id")]
public ulong? ChannelId { get; set; }
public IChannel Channel { set { ChannelId = value?.Id; } }
}
}

View File

@@ -1,17 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API
{
public class SocketFrame
{
[JsonProperty("op")]
public int Operation { get; set; }
[JsonProperty("t", NullValueHandling = NullValueHandling.Ignore)]
public string Type { get; set; }
[JsonProperty("s", NullValueHandling = NullValueHandling.Ignore)]
public int? Sequence { get; set; }
[JsonProperty("d")]
public object Payload { get; set; }
}
}

View File

@@ -1,17 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Voice
{
public class IdentifyParams
{
[JsonProperty("server_id")]
public ulong GuildId { get; set; }
[JsonProperty("user_id")]
public ulong UserId { get; set; }
[JsonProperty("session_id")]
public string SessionId { get; set; }
[JsonProperty("token")]
public string Token { get; set; }
}
}

View File

@@ -1,17 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Voice
{
public class ReadyEvent
{
[JsonProperty("ssrc")]
public uint SSRC { get; set; }
[JsonProperty("port")]
public ushort Port { get; set; }
[JsonProperty("modes")]
public string[] Modes { get; set; }
[JsonProperty("heartbeat_interval")]
public int HeartbeatInterval { get; set; }
}
}

View File

@@ -1,13 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Voice
{
public class SelectProtocolParams
{
[JsonProperty("protocol")]
public string Protocol { get; set; }
[JsonProperty("data")]
public UdpProtocolInfo Data { get; set; }
}
}

View File

@@ -1,13 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Voice
{
public class SessionDescriptionEvent
{
[JsonProperty("secret_key")]
public byte[] SecretKey { get; set; }
[JsonProperty("mode")]
public string Mode { get; set; }
}
}

View File

@@ -1,13 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Voice
{
public class SpeakingParams
{
[JsonProperty("speaking")]
public bool IsSpeaking { get; set; }
[JsonProperty("delay")]
public int Delay { get; set; }
}
}

View File

@@ -1,15 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Voice
{
public class UdpProtocolInfo
{
[JsonProperty("address")]
public string Address { get; set; }
[JsonProperty("port")]
public int Port { get; set; }
[JsonProperty("mode")]
public string Mode { get; set; }
}
}

View File

@@ -1,21 +0,0 @@
#pragma warning disable CS1591
namespace Discord.API.Voice
{
public enum VoiceOpCode : byte
{
/// <summary> C→S - Used to associate a connection with a token. </summary>
Identify = 0,
/// <summary> C→S - Used to specify configuration. </summary>
SelectProtocol = 1,
/// <summary> C←S - Used to notify that the voice connection was successful and informs the client of available protocols. </summary>
Ready = 2,
/// <summary> C→S - Used to keep the connection alive and measure latency. </summary>
Heartbeat = 3,
/// <summary> C←S - Used to reply to a client's heartbeat. </summary>
HeartbeatAck = 3,
/// <summary> C←S - Used to provide an encryption key to the client. </summary>
SessionDescription = 4,
/// <summary> C↔S - Used to inform that a certain user is speaking. </summary>
Speaking = 5
}
}