@@ -269,14 +269,14 @@ namespace Discord.API | |||
options = RequestOptions.CreateOrClone(options); | |||
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); | |||
var msg = new GetGuildParams | |||
{ | |||
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) | |||
{ | |||
@@ -287,14 +287,14 @@ namespace Discord.API | |||
}; | |||
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); | |||
var msg = new GetChannelParams | |||
{ | |||
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) | |||
@@ -306,59 +306,63 @@ namespace Discord.API | |||
}; | |||
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); | |||
var msg = new SelectVoiceChannelParams | |||
{ | |||
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); | |||
var msg = new ChannelSubscriptionParams | |||
{ | |||
ChannelId = channelId | |||
}; | |||
var msg = new object(); | |||
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); | |||
var msg = new ChannelSubscriptionParams | |||
{ | |||
ChannelId = channelId | |||
}; | |||
var msg = new object(); | |||
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); | |||
var msg = new ChannelSubscriptionParams | |||
var msg = new GuildSubscriptionParams | |||
{ | |||
GuildId = guildId | |||
}; | |||
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); | |||
var msg = new GuildSubscriptionParams | |||
{ | |||
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); | |||
} | |||
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); | |||
var msg = new GuildSubscriptionParams | |||
var msg = new ChannelSubscriptionParams | |||
{ | |||
GuildId = guildId | |||
ChannelId = channelId | |||
}; | |||
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>>(); | |||
//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 | |||
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 | |||
public event Func<RpcVoiceState, Task> VoiceStateCreated | |||
@@ -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<ChannelCreatedEvent>(_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<GuildCreatedEvent>(_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<GuildStatusEvent>(_serializer); | |||
var guildStatus = RpcGuildStatus.Create(data); | |||
await _guildUpdatedEvent.InvokeAsync().ConfigureAwait(false); | |||
await _guildStatusUpdatedEvent.InvokeAsync(guildStatus).ConfigureAwait(false); | |||
} | |||
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 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; | |||
} | |||
}*/ | |||
} | |||
} |
@@ -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 | |||
} | |||
} |