| @@ -269,14 +269,14 @@ namespace Discord.API | |||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| return await SendRpcAsync<GetGuildsResponse>("GET_GUILDS", null, options: options).ConfigureAwait(false); | return await SendRpcAsync<GetGuildsResponse>("GET_GUILDS", null, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| public async Task<RpcGuild> SendGetGuildAsync(ulong guildId, RequestOptions options = null) | |||||
| public async Task<Rpc.RpcGuild> SendGetGuildAsync(ulong guildId, RequestOptions options = null) | |||||
| { | { | ||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| var msg = new GetGuildParams | var msg = new GetGuildParams | ||||
| { | { | ||||
| GuildId = guildId | GuildId = guildId | ||||
| }; | }; | ||||
| return await SendRpcAsync<RpcGuild>("GET_GUILD", msg, options: options).ConfigureAwait(false); | |||||
| return await SendRpcAsync<Rpc.RpcGuild>("GET_GUILD", msg, options: options).ConfigureAwait(false); | |||||
| } | } | ||||
| public async Task<GetChannelsResponse> SendGetChannelsAsync(ulong guildId, RequestOptions options = null) | public async Task<GetChannelsResponse> SendGetChannelsAsync(ulong guildId, RequestOptions options = null) | ||||
| { | { | ||||
| @@ -287,14 +287,14 @@ namespace Discord.API | |||||
| }; | }; | ||||
| return await SendRpcAsync<GetChannelsResponse>("GET_CHANNELS", msg, options: options).ConfigureAwait(false); | return await SendRpcAsync<GetChannelsResponse>("GET_CHANNELS", msg, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| public async Task<RpcChannel> SendGetChannelAsync(ulong channelId, RequestOptions options = null) | |||||
| public async Task<Rpc.RpcChannel> SendGetChannelAsync(ulong channelId, RequestOptions options = null) | |||||
| { | { | ||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| var msg = new GetChannelParams | var msg = new GetChannelParams | ||||
| { | { | ||||
| ChannelId = channelId | ChannelId = channelId | ||||
| }; | }; | ||||
| return await SendRpcAsync<RpcChannel>("GET_CHANNEL", msg, options: options).ConfigureAwait(false); | |||||
| return await SendRpcAsync<Rpc.RpcChannel>("GET_CHANNEL", msg, options: options).ConfigureAwait(false); | |||||
| } | } | ||||
| public async Task<SetLocalVolumeResponse> SendSetLocalVolumeAsync(int volume, RequestOptions options = null) | public async Task<SetLocalVolumeResponse> SendSetLocalVolumeAsync(int volume, RequestOptions options = null) | ||||
| @@ -306,59 +306,63 @@ namespace Discord.API | |||||
| }; | }; | ||||
| return await SendRpcAsync<SetLocalVolumeResponse>("SET_LOCAL_VOLUME", msg, options: options).ConfigureAwait(false); | return await SendRpcAsync<SetLocalVolumeResponse>("SET_LOCAL_VOLUME", msg, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| public async Task<RpcChannel> SendSelectVoiceChannelAsync(ulong channelId, RequestOptions options = null) | |||||
| public async Task<Rpc.RpcChannel> SendSelectVoiceChannelAsync(ulong channelId, RequestOptions options = null) | |||||
| { | { | ||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| var msg = new SelectVoiceChannelParams | var msg = new SelectVoiceChannelParams | ||||
| { | { | ||||
| ChannelId = channelId | ChannelId = channelId | ||||
| }; | }; | ||||
| return await SendRpcAsync<RpcChannel>("SELECT_VOICE_CHANNEL", msg, options: options).ConfigureAwait(false); | |||||
| return await SendRpcAsync<Rpc.RpcChannel>("SELECT_VOICE_CHANNEL", msg, options: options).ConfigureAwait(false); | |||||
| } | } | ||||
| public async Task<SubscriptionResponse> SendChannelSubscribeAsync(string evt, ulong channelId, RequestOptions options = null) | |||||
| public async Task<SubscriptionResponse> SendGlobalSubscribeAsync(string evt, RequestOptions options = null) | |||||
| { | { | ||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| var msg = new ChannelSubscriptionParams | |||||
| { | |||||
| ChannelId = channelId | |||||
| }; | |||||
| var msg = new object(); | |||||
| return await SendRpcAsync<SubscriptionResponse>("SUBSCRIBE", msg, evt: evt, options: options).ConfigureAwait(false); | return await SendRpcAsync<SubscriptionResponse>("SUBSCRIBE", msg, evt: evt, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| public async Task<SubscriptionResponse> SendChannelUnsubscribeAsync(string evt, ulong channelId, RequestOptions options = null) | |||||
| public async Task<SubscriptionResponse> SendGlobalUnsubscribeAsync(string evt, RequestOptions options = null) | |||||
| { | { | ||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| var msg = new ChannelSubscriptionParams | |||||
| { | |||||
| ChannelId = channelId | |||||
| }; | |||||
| var msg = new object(); | |||||
| return await SendRpcAsync<SubscriptionResponse>("UNSUBSCRIBE", msg, evt: evt, options: options).ConfigureAwait(false); | return await SendRpcAsync<SubscriptionResponse>("UNSUBSCRIBE", msg, evt: evt, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| public async Task<SubscriptionResponse> SendGlobalSubscribeAsync(string evt, RequestOptions options = null) | |||||
| public async Task<SubscriptionResponse> SendGuildSubscribeAsync(string evt, ulong guildId, RequestOptions options = null) | |||||
| { | { | ||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| var msg = new ChannelSubscriptionParams | |||||
| var msg = new GuildSubscriptionParams | |||||
| { | { | ||||
| GuildId = guildId | |||||
| }; | }; | ||||
| return await SendRpcAsync<SubscriptionResponse>("SUBSCRIBE", msg, evt: evt, options: options).ConfigureAwait(false); | return await SendRpcAsync<SubscriptionResponse>("SUBSCRIBE", msg, evt: evt, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| public async Task<SubscriptionResponse> SendGuildSubscribeAsync(string evt, ulong guildId, RequestOptions options = null) | |||||
| public async Task<SubscriptionResponse> SendGuildUnsubscribeAsync(string evt, ulong guildId, RequestOptions options = null) | |||||
| { | { | ||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| var msg = new GuildSubscriptionParams | var msg = new GuildSubscriptionParams | ||||
| { | { | ||||
| GuildId = guildId | GuildId = guildId | ||||
| }; | }; | ||||
| return await SendRpcAsync<SubscriptionResponse>("UNSUBSCRIBE", msg, evt: evt, options: options).ConfigureAwait(false); | |||||
| } | |||||
| public async Task<SubscriptionResponse> SendChannelSubscribeAsync(string evt, ulong channelId, RequestOptions options = null) | |||||
| { | |||||
| options = RequestOptions.CreateOrClone(options); | |||||
| var msg = new ChannelSubscriptionParams | |||||
| { | |||||
| ChannelId = channelId | |||||
| }; | |||||
| return await SendRpcAsync<SubscriptionResponse>("SUBSCRIBE", msg, evt: evt, options: options).ConfigureAwait(false); | return await SendRpcAsync<SubscriptionResponse>("SUBSCRIBE", msg, evt: evt, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| public async Task<SubscriptionResponse> SendGuildUnsubscribeAsync(string evt, ulong guildId, RequestOptions options = null) | |||||
| public async Task<SubscriptionResponse> SendChannelUnsubscribeAsync(string evt, ulong channelId, RequestOptions options = null) | |||||
| { | { | ||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| var msg = new GuildSubscriptionParams | |||||
| var msg = new ChannelSubscriptionParams | |||||
| { | { | ||||
| GuildId = guildId | |||||
| ChannelId = channelId | |||||
| }; | }; | ||||
| return await SendRpcAsync<SubscriptionResponse>("UNSUBSCRIBE", msg, evt: evt, options: options).ConfigureAwait(false); | return await SendRpcAsync<SubscriptionResponse>("UNSUBSCRIBE", msg, evt: evt, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| @@ -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; } | |||||
| } | |||||
| } | |||||
| @@ -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; } | |||||
| } | |||||
| } | |||||
| @@ -25,13 +25,27 @@ namespace Discord.Rpc | |||||
| } | } | ||||
| private readonly AsyncEvent<Func<Task>> _readyEvent = new AsyncEvent<Func<Task>>(); | private readonly AsyncEvent<Func<Task>> _readyEvent = new AsyncEvent<Func<Task>>(); | ||||
| //Channel | |||||
| public event Func<RpcChannel, Task> ChannelCreated | |||||
| { | |||||
| add { _channelCreatedEvent.Add(value); } | |||||
| remove { _channelCreatedEvent.Remove(value); } | |||||
| } | |||||
| private readonly AsyncEvent<Func<RpcChannel, Task>> _channelCreatedEvent = new AsyncEvent<Func<RpcChannel, Task>>(); | |||||
| //Guild | //Guild | ||||
| public event Func<Task> GuildUpdated | |||||
| public event Func<RpcGuild, Task> GuildCreated | |||||
| { | |||||
| add { _guildCreatedEvent.Add(value); } | |||||
| remove { _guildCreatedEvent.Remove(value); } | |||||
| } | |||||
| private readonly AsyncEvent<Func<RpcGuild, Task>> _guildCreatedEvent = new AsyncEvent<Func<RpcGuild, Task>>(); | |||||
| public event Func<RpcGuildStatus, Task> GuildStatusUpdated | |||||
| { | { | ||||
| add { _guildUpdatedEvent.Add(value); } | |||||
| remove { _guildUpdatedEvent.Remove(value); } | |||||
| add { _guildStatusUpdatedEvent.Add(value); } | |||||
| remove { _guildStatusUpdatedEvent.Remove(value); } | |||||
| } | } | ||||
| private readonly AsyncEvent<Func<Task>> _guildUpdatedEvent = new AsyncEvent<Func<Task>>(); | |||||
| private readonly AsyncEvent<Func<RpcGuildStatus, Task>> _guildStatusUpdatedEvent = new AsyncEvent<Func<RpcGuildStatus, Task>>(); | |||||
| //Voice | //Voice | ||||
| public event Func<RpcVoiceState, Task> VoiceStateCreated | public event Func<RpcVoiceState, Task> VoiceStateCreated | ||||
| @@ -228,6 +228,18 @@ namespace Discord.Rpc | |||||
| return result.Code; | 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) | public async Task SubscribeGuild(ulong guildId, params RpcChannelEvent[] events) | ||||
| { | { | ||||
| Preconditions.AtLeast(events?.Length ?? 0, 1, nameof(events)); | Preconditions.AtLeast(events?.Length ?? 0, 1, nameof(events)); | ||||
| @@ -253,6 +265,16 @@ namespace Discord.Rpc | |||||
| await ApiClient.SendChannelUnsubscribeAsync(GetEventName(events[i]), channelId); | 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) | private static string GetEventName(RpcGuildEvent rpcEvent) | ||||
| { | { | ||||
| switch (rpcEvent) | switch (rpcEvent) | ||||
| @@ -266,14 +288,14 @@ namespace Discord.Rpc | |||||
| { | { | ||||
| switch (rpcEvent) | 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.MessageCreate: return "MESSAGE_CREATE"; | ||||
| case RpcChannelEvent.MessageUpdate: return "MESSAGE_UPDATE"; | case RpcChannelEvent.MessageUpdate: return "MESSAGE_UPDATE"; | ||||
| case RpcChannelEvent.MessageDelete: return "MESSAGE_DELETE"; | 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: | default: | ||||
| throw new InvalidOperationException($"Unknown RPC Channel Event: {rpcEvent}"); | throw new InvalidOperationException($"Unknown RPC Channel Event: {rpcEvent}"); | ||||
| } | } | ||||
| @@ -321,12 +343,34 @@ namespace Discord.Rpc | |||||
| } | } | ||||
| break; | break; | ||||
| //Channels | |||||
| case "CHANNEL_CREATE": | |||||
| { | |||||
| await _rpcLogger.DebugAsync("Received Dispatch (CHANNEL_CREATE)").ConfigureAwait(false); | |||||
| var data = (payload.Value as JToken).ToObject<ChannelCreatedEvent>(_serializer); | |||||
| var channel = RpcChannel.Create(data); | |||||
| await _channelCreatedEvent.InvokeAsync(channel).ConfigureAwait(false); | |||||
| } | |||||
| break; | |||||
| //Guilds | //Guilds | ||||
| case "GUILD_CREATE": | |||||
| { | |||||
| await _rpcLogger.DebugAsync("Received Dispatch (GUILD_CREATE)").ConfigureAwait(false); | |||||
| var data = (payload.Value as JToken).ToObject<GuildCreatedEvent>(_serializer); | |||||
| var guild = RpcGuild.Create(data); | |||||
| await _guildCreatedEvent.InvokeAsync(guild).ConfigureAwait(false); | |||||
| } | |||||
| break; | |||||
| case "GUILD_STATUS": | case "GUILD_STATUS": | ||||
| { | { | ||||
| await _rpcLogger.DebugAsync("Received Dispatch (GUILD_STATUS)").ConfigureAwait(false); | await _rpcLogger.DebugAsync("Received Dispatch (GUILD_STATUS)").ConfigureAwait(false); | ||||
| var data = (payload.Value as JToken).ToObject<GuildStatusEvent>(_serializer); | |||||
| var guildStatus = RpcGuildStatus.Create(data); | |||||
| await _guildUpdatedEvent.InvokeAsync().ConfigureAwait(false); | |||||
| await _guildStatusUpdatedEvent.InvokeAsync(guildStatus).ConfigureAwait(false); | |||||
| } | } | ||||
| break; | break; | ||||
| @@ -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; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -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 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; | Name = model.Name; | ||||
| } | } | ||||
| }*/ | |||||
| } | |||||
| } | } | ||||
| @@ -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; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,8 @@ | |||||
| namespace Discord.Rpc | |||||
| { | |||||
| public enum RpcGlobalEvent | |||||
| { | |||||
| ChannelCreated, | |||||
| GuildCreated | |||||
| } | |||||
| } | |||||