From 15e8ef06dc7eea5aeac697e71b3a325d5d88e581 Mon Sep 17 00:00:00 2001 From: RogueException Date: Fri, 7 Oct 2016 23:18:45 -0300 Subject: [PATCH] Added RPC ChannelCreated, GuildCreated and GuildStatusUpdated events --- .../API/DiscordRpcApiClient.cs | 50 +++++++++-------- .../API/Rpc/ChannelCreatedEvent.cs | 14 +++++ .../API/Rpc/GuildCreatedEvent.cs | 12 ++++ .../DiscordRpcClient.Events.cs | 22 ++++++-- src/Discord.Net.Rpc/DiscordRpcClient.cs | 56 +++++++++++++++++-- .../Entities/Channels/RpcChannel.cs | 27 +++++++++ .../Entities/Guilds/RpcGuild.cs | 27 +++++---- .../Entities/Guilds/RpcGuildStatus.cs | 25 +++++++++ src/Discord.Net.Rpc/RpcGlobalEvent.cs | 8 +++ 9 files changed, 196 insertions(+), 45 deletions(-) create mode 100644 src/Discord.Net.Rpc/API/Rpc/ChannelCreatedEvent.cs create mode 100644 src/Discord.Net.Rpc/API/Rpc/GuildCreatedEvent.cs create mode 100644 src/Discord.Net.Rpc/Entities/Channels/RpcChannel.cs create mode 100644 src/Discord.Net.Rpc/Entities/Guilds/RpcGuildStatus.cs create mode 100644 src/Discord.Net.Rpc/RpcGlobalEvent.cs diff --git a/src/Discord.Net.Rpc/API/DiscordRpcApiClient.cs b/src/Discord.Net.Rpc/API/DiscordRpcApiClient.cs index 1d0fab516..540f9eb28 100644 --- a/src/Discord.Net.Rpc/API/DiscordRpcApiClient.cs +++ b/src/Discord.Net.Rpc/API/DiscordRpcApiClient.cs @@ -269,14 +269,14 @@ namespace Discord.API options = RequestOptions.CreateOrClone(options); return await SendRpcAsync("GET_GUILDS", null, options: options).ConfigureAwait(false); } - public async Task SendGetGuildAsync(ulong guildId, RequestOptions options = null) + public async Task SendGetGuildAsync(ulong guildId, RequestOptions options = null) { options = RequestOptions.CreateOrClone(options); var msg = new GetGuildParams { GuildId = guildId }; - return await SendRpcAsync("GET_GUILD", msg, options: options).ConfigureAwait(false); + return await SendRpcAsync("GET_GUILD", msg, options: options).ConfigureAwait(false); } public async Task SendGetChannelsAsync(ulong guildId, RequestOptions options = null) { @@ -287,14 +287,14 @@ namespace Discord.API }; return await SendRpcAsync("GET_CHANNELS", msg, options: options).ConfigureAwait(false); } - public async Task SendGetChannelAsync(ulong channelId, RequestOptions options = null) + public async Task SendGetChannelAsync(ulong channelId, RequestOptions options = null) { options = RequestOptions.CreateOrClone(options); var msg = new GetChannelParams { ChannelId = channelId }; - return await SendRpcAsync("GET_CHANNEL", msg, options: options).ConfigureAwait(false); + return await SendRpcAsync("GET_CHANNEL", msg, options: options).ConfigureAwait(false); } public async Task SendSetLocalVolumeAsync(int volume, RequestOptions options = null) @@ -306,59 +306,63 @@ namespace Discord.API }; return await SendRpcAsync("SET_LOCAL_VOLUME", msg, options: options).ConfigureAwait(false); } - public async Task SendSelectVoiceChannelAsync(ulong channelId, RequestOptions options = null) + public async Task SendSelectVoiceChannelAsync(ulong channelId, RequestOptions options = null) { options = RequestOptions.CreateOrClone(options); var msg = new SelectVoiceChannelParams { ChannelId = channelId }; - return await SendRpcAsync("SELECT_VOICE_CHANNEL", msg, options: options).ConfigureAwait(false); + return await SendRpcAsync("SELECT_VOICE_CHANNEL", msg, options: options).ConfigureAwait(false); } - public async Task SendChannelSubscribeAsync(string evt, ulong channelId, RequestOptions options = null) + public async Task SendGlobalSubscribeAsync(string evt, RequestOptions options = null) { options = RequestOptions.CreateOrClone(options); - var msg = new ChannelSubscriptionParams - { - ChannelId = channelId - }; + var msg = new object(); return await SendRpcAsync("SUBSCRIBE", msg, evt: evt, options: options).ConfigureAwait(false); } - public async Task SendChannelUnsubscribeAsync(string evt, ulong channelId, RequestOptions options = null) + public async Task SendGlobalUnsubscribeAsync(string evt, RequestOptions options = null) { options = RequestOptions.CreateOrClone(options); - var msg = new ChannelSubscriptionParams - { - ChannelId = channelId - }; + var msg = new object(); return await SendRpcAsync("UNSUBSCRIBE", msg, evt: evt, options: options).ConfigureAwait(false); } - public async Task SendGlobalSubscribeAsync(string evt, RequestOptions options = null) + public async Task SendGuildSubscribeAsync(string evt, ulong guildId, RequestOptions options = null) { options = RequestOptions.CreateOrClone(options); - var msg = new ChannelSubscriptionParams + var msg = new GuildSubscriptionParams { + GuildId = guildId }; return await SendRpcAsync("SUBSCRIBE", msg, evt: evt, options: options).ConfigureAwait(false); } - - public async Task SendGuildSubscribeAsync(string evt, ulong guildId, RequestOptions options = null) + public async Task SendGuildUnsubscribeAsync(string evt, ulong guildId, RequestOptions options = null) { options = RequestOptions.CreateOrClone(options); var msg = new GuildSubscriptionParams { GuildId = guildId }; + return await SendRpcAsync("UNSUBSCRIBE", msg, evt: evt, options: options).ConfigureAwait(false); + } + + public async Task SendChannelSubscribeAsync(string evt, ulong channelId, RequestOptions options = null) + { + options = RequestOptions.CreateOrClone(options); + var msg = new ChannelSubscriptionParams + { + ChannelId = channelId + }; return await SendRpcAsync("SUBSCRIBE", msg, evt: evt, options: options).ConfigureAwait(false); } - public async Task SendGuildUnsubscribeAsync(string evt, ulong guildId, RequestOptions options = null) + public async Task SendChannelUnsubscribeAsync(string evt, ulong channelId, RequestOptions options = null) { options = RequestOptions.CreateOrClone(options); - var msg = new GuildSubscriptionParams + var msg = new ChannelSubscriptionParams { - GuildId = guildId + ChannelId = channelId }; return await SendRpcAsync("UNSUBSCRIBE", msg, evt: evt, options: options).ConfigureAwait(false); } diff --git a/src/Discord.Net.Rpc/API/Rpc/ChannelCreatedEvent.cs b/src/Discord.Net.Rpc/API/Rpc/ChannelCreatedEvent.cs new file mode 100644 index 000000000..baa7caa6e --- /dev/null +++ b/src/Discord.Net.Rpc/API/Rpc/ChannelCreatedEvent.cs @@ -0,0 +1,14 @@ +using Newtonsoft.Json; + +namespace Discord.API.Rpc +{ + public class ChannelCreatedEvent + { + [JsonProperty("id")] + public ulong Id { get; set; } + [JsonProperty("name")] + public string Name { get; set; } + [JsonProperty("type")] + public ChannelType Type { get; set; } + } +} diff --git a/src/Discord.Net.Rpc/API/Rpc/GuildCreatedEvent.cs b/src/Discord.Net.Rpc/API/Rpc/GuildCreatedEvent.cs new file mode 100644 index 000000000..6cfaa862f --- /dev/null +++ b/src/Discord.Net.Rpc/API/Rpc/GuildCreatedEvent.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace Discord.API.Rpc +{ + public class GuildCreatedEvent + { + [JsonProperty("id")] + public ulong Id { get; set; } + [JsonProperty("name")] + public string Name { get; set; } + } +} diff --git a/src/Discord.Net.Rpc/DiscordRpcClient.Events.cs b/src/Discord.Net.Rpc/DiscordRpcClient.Events.cs index 5639bdbae..7e7553ffb 100644 --- a/src/Discord.Net.Rpc/DiscordRpcClient.Events.cs +++ b/src/Discord.Net.Rpc/DiscordRpcClient.Events.cs @@ -25,13 +25,27 @@ namespace Discord.Rpc } private readonly AsyncEvent> _readyEvent = new AsyncEvent>(); + //Channel + public event Func ChannelCreated + { + add { _channelCreatedEvent.Add(value); } + remove { _channelCreatedEvent.Remove(value); } + } + private readonly AsyncEvent> _channelCreatedEvent = new AsyncEvent>(); + //Guild - public event Func GuildUpdated + public event Func GuildCreated + { + add { _guildCreatedEvent.Add(value); } + remove { _guildCreatedEvent.Remove(value); } + } + private readonly AsyncEvent> _guildCreatedEvent = new AsyncEvent>(); + public event Func GuildStatusUpdated { - add { _guildUpdatedEvent.Add(value); } - remove { _guildUpdatedEvent.Remove(value); } + add { _guildStatusUpdatedEvent.Add(value); } + remove { _guildStatusUpdatedEvent.Remove(value); } } - private readonly AsyncEvent> _guildUpdatedEvent = new AsyncEvent>(); + private readonly AsyncEvent> _guildStatusUpdatedEvent = new AsyncEvent>(); //Voice public event Func VoiceStateCreated diff --git a/src/Discord.Net.Rpc/DiscordRpcClient.cs b/src/Discord.Net.Rpc/DiscordRpcClient.cs index a5fcd827a..4d3b92b5c 100644 --- a/src/Discord.Net.Rpc/DiscordRpcClient.cs +++ b/src/Discord.Net.Rpc/DiscordRpcClient.cs @@ -228,6 +228,18 @@ namespace Discord.Rpc return result.Code; } + public async Task SubscribeGlobal(params RpcGlobalEvent[] events) + { + Preconditions.AtLeast(events?.Length ?? 0, 1, nameof(events)); + for (int i = 0; i < events.Length; i++) + await ApiClient.SendGlobalSubscribeAsync(GetEventName(events[i])); + } + public async Task UnsubscribeGlobal(params RpcGlobalEvent[] events) + { + Preconditions.AtLeast(events?.Length ?? 0, 1, nameof(events)); + for (int i = 0; i < events.Length; i++) + await ApiClient.SendGlobalUnsubscribeAsync(GetEventName(events[i])); + } public async Task SubscribeGuild(ulong guildId, params RpcChannelEvent[] events) { Preconditions.AtLeast(events?.Length ?? 0, 1, nameof(events)); @@ -253,6 +265,16 @@ namespace Discord.Rpc await ApiClient.SendChannelUnsubscribeAsync(GetEventName(events[i]), channelId); } + private static string GetEventName(RpcGlobalEvent rpcEvent) + { + switch (rpcEvent) + { + case RpcGlobalEvent.ChannelCreated: return "CHANNEL_CREATE"; + case RpcGlobalEvent.GuildCreated: return "GUILD_CREATE"; + default: + throw new InvalidOperationException($"Unknown RPC Global Event: {rpcEvent}"); + } + } private static string GetEventName(RpcGuildEvent rpcEvent) { switch (rpcEvent) @@ -266,14 +288,14 @@ namespace Discord.Rpc { switch (rpcEvent) { - case RpcChannelEvent.VoiceStateCreate: return "VOICE_STATE_CREATE"; - case RpcChannelEvent.VoiceStateUpdate: return "VOICE_STATE_UPDATE"; - case RpcChannelEvent.VoiceStateDelete: return "VOICE_STATE_DELETE"; - case RpcChannelEvent.SpeakingStart: return "SPEAKING_START"; - case RpcChannelEvent.SpeakingStop: return "SPEAKING_STOP"; case RpcChannelEvent.MessageCreate: return "MESSAGE_CREATE"; case RpcChannelEvent.MessageUpdate: return "MESSAGE_UPDATE"; case RpcChannelEvent.MessageDelete: return "MESSAGE_DELETE"; + case RpcChannelEvent.SpeakingStart: return "SPEAKING_START"; + case RpcChannelEvent.SpeakingStop: return "SPEAKING_STOP"; + case RpcChannelEvent.VoiceStateCreate: return "VOICE_STATE_CREATE"; + case RpcChannelEvent.VoiceStateUpdate: return "VOICE_STATE_UPDATE"; + case RpcChannelEvent.VoiceStateDelete: return "VOICE_STATE_DELETE"; default: throw new InvalidOperationException($"Unknown RPC Channel Event: {rpcEvent}"); } @@ -321,12 +343,34 @@ namespace Discord.Rpc } break; + //Channels + case "CHANNEL_CREATE": + { + await _rpcLogger.DebugAsync("Received Dispatch (CHANNEL_CREATE)").ConfigureAwait(false); + var data = (payload.Value as JToken).ToObject(_serializer); + var channel = RpcChannel.Create(data); + + await _channelCreatedEvent.InvokeAsync(channel).ConfigureAwait(false); + } + break; + //Guilds + case "GUILD_CREATE": + { + await _rpcLogger.DebugAsync("Received Dispatch (GUILD_CREATE)").ConfigureAwait(false); + var data = (payload.Value as JToken).ToObject(_serializer); + var guild = RpcGuild.Create(data); + + await _guildCreatedEvent.InvokeAsync(guild).ConfigureAwait(false); + } + break; case "GUILD_STATUS": { await _rpcLogger.DebugAsync("Received Dispatch (GUILD_STATUS)").ConfigureAwait(false); + var data = (payload.Value as JToken).ToObject(_serializer); + var guildStatus = RpcGuildStatus.Create(data); - await _guildUpdatedEvent.InvokeAsync().ConfigureAwait(false); + await _guildStatusUpdatedEvent.InvokeAsync(guildStatus).ConfigureAwait(false); } break; diff --git a/src/Discord.Net.Rpc/Entities/Channels/RpcChannel.cs b/src/Discord.Net.Rpc/Entities/Channels/RpcChannel.cs new file mode 100644 index 000000000..dbaa413fc --- /dev/null +++ b/src/Discord.Net.Rpc/Entities/Channels/RpcChannel.cs @@ -0,0 +1,27 @@ +using Model = Discord.API.Rpc.ChannelCreatedEvent; + +namespace Discord.Rpc +{ + public class RpcChannel + { + public ulong Id { get; } + public string Name { get; set; } + public ChannelType Type { get; set; } + + internal RpcChannel(ulong id) + { + Id = id; + } + internal static RpcChannel Create(Model model) + { + var entity = new RpcChannel(model.Id); + entity.Update(model); + return entity; + } + internal void Update(Model model) + { + Name = model.Name; + Type = model.Type; + } + } +} diff --git a/src/Discord.Net.Rpc/Entities/Guilds/RpcGuild.cs b/src/Discord.Net.Rpc/Entities/Guilds/RpcGuild.cs index 3c0216dc9..6a16a721b 100644 --- a/src/Discord.Net.Rpc/Entities/Guilds/RpcGuild.cs +++ b/src/Discord.Net.Rpc/Entities/Guilds/RpcGuild.cs @@ -1,22 +1,25 @@ -namespace Discord.Rpc +using Model = Discord.API.Rpc.GuildCreatedEvent; + +namespace Discord.Rpc { - /*internal class RemoteUserGuild : RpcEntity, IRemoteUserGuild, ISnowflakeEntity + public class RpcGuild { public ulong Id { get; } - public DiscordRestClient Discord { get; } - public string Name { get; private set; } - - public DateTimeOffset CreatedAt => DateTimeUtils.FromSnowflake(Id); + public string Name { get; set; } - internal RemoteUserGuild(DiscordRestClient discord, Model model) + internal RpcGuild(ulong id) + { + Id = id; + } + internal static RpcGuild Create(Model model) { - Id = model.Id; - Discord = discord; - Update(model); + var entity = new RpcGuild(model.Id); + entity.Update(model); + return entity; } - public void Update(Model model) + internal void Update(Model model) { Name = model.Name; } - }*/ + } } diff --git a/src/Discord.Net.Rpc/Entities/Guilds/RpcGuildStatus.cs b/src/Discord.Net.Rpc/Entities/Guilds/RpcGuildStatus.cs new file mode 100644 index 000000000..f8095a18e --- /dev/null +++ b/src/Discord.Net.Rpc/Entities/Guilds/RpcGuildStatus.cs @@ -0,0 +1,25 @@ +using Model = Discord.API.Rpc.GuildStatusEvent; + +namespace Discord.Rpc +{ + public class RpcGuildStatus + { + public RpcGuild Guild { get; } + public int Online { get; private set; } + + internal RpcGuildStatus(ulong guildId) + { + Guild = new RpcGuild(guildId); + } + internal static RpcGuildStatus Create(Model model) + { + var entity = new RpcGuildStatus(model.Guild.Id); + entity.Update(model); + return entity; + } + internal void Update(Model model) + { + Online = model.Online; + } + } +} diff --git a/src/Discord.Net.Rpc/RpcGlobalEvent.cs b/src/Discord.Net.Rpc/RpcGlobalEvent.cs new file mode 100644 index 000000000..989e3f52e --- /dev/null +++ b/src/Discord.Net.Rpc/RpcGlobalEvent.cs @@ -0,0 +1,8 @@ +namespace Discord.Rpc +{ + public enum RpcGlobalEvent + { + ChannelCreated, + GuildCreated + } +}