Browse Source

Added RPC channel and guild entities, Get and Select methods

tags/1.0-rc
RogueException 8 years ago
parent
commit
16c67e79e9
39 changed files with 848 additions and 101 deletions
  1. +3
    -0
      src/Discord.Net.Core/Net/WebSockets/DefaultWebSocketClient.cs
  2. +22
    -15
      src/Discord.Net.Rpc/API/DiscordRpcApiClient.cs
  3. +34
    -0
      src/Discord.Net.Rpc/API/Rpc/Channel.cs
  4. +1
    -1
      src/Discord.Net.Rpc/API/Rpc/ChannelSummary.cs
  5. +1
    -1
      src/Discord.Net.Rpc/API/Rpc/ExtendedVoiceState.cs
  6. +2
    -1
      src/Discord.Net.Rpc/API/Rpc/GetChannelsResponse.cs
  7. +1
    -0
      src/Discord.Net.Rpc/API/Rpc/GetGuildsParams.cs
  8. +1
    -1
      src/Discord.Net.Rpc/API/Rpc/GetGuildsResponse.cs
  9. +6
    -1
      src/Discord.Net.Rpc/API/Rpc/Guild.cs
  10. +15
    -0
      src/Discord.Net.Rpc/API/Rpc/GuildMember.cs
  11. +1
    -1
      src/Discord.Net.Rpc/API/Rpc/GuildSummary.cs
  12. +1
    -1
      src/Discord.Net.Rpc/API/Rpc/Message.cs
  13. +1
    -1
      src/Discord.Net.Rpc/API/Rpc/MessageEvent.cs
  14. +0
    -11
      src/Discord.Net.Rpc/API/Rpc/RpcChannel.cs
  15. +0
    -13
      src/Discord.Net.Rpc/API/Rpc/RpcGuild.cs
  16. +3
    -1
      src/Discord.Net.Rpc/API/Rpc/SelectChannelParams.cs
  17. +18
    -0
      src/Discord.Net.Rpc/API/Rpc/UserVoiceSettings.cs
  18. +4
    -4
      src/Discord.Net.Rpc/DiscordRpcClient.Events.cs
  19. +67
    -7
      src/Discord.Net.Rpc/DiscordRpcClient.cs
  20. +9
    -0
      src/Discord.Net.Rpc/Entities/Channels/IRpcAudioChannel.cs
  21. +9
    -0
      src/Discord.Net.Rpc/Entities/Channels/IRpcMessageChannel.cs
  22. +6
    -0
      src/Discord.Net.Rpc/Entities/Channels/IRpcPrivateChannel.cs
  23. +27
    -19
      src/Discord.Net.Rpc/Entities/Channels/RpcChannel.cs
  24. +32
    -0
      src/Discord.Net.Rpc/Entities/Channels/RpcChannelSummary.cs
  25. +124
    -0
      src/Discord.Net.Rpc/Entities/Channels/RpcDMChannel.cs
  26. +123
    -0
      src/Discord.Net.Rpc/Entities/Channels/RpcGroupChannel.cs
  27. +94
    -0
      src/Discord.Net.Rpc/Entities/Channels/RpcGuildChannel.cs
  28. +113
    -0
      src/Discord.Net.Rpc/Entities/Channels/RpcTextChannel.cs
  29. +49
    -0
      src/Discord.Net.Rpc/Entities/Channels/RpcVoiceChannel.cs
  30. +15
    -9
      src/Discord.Net.Rpc/Entities/Guilds/RpcGuild.cs
  31. +2
    -2
      src/Discord.Net.Rpc/Entities/Guilds/RpcGuildStatus.cs
  32. +30
    -0
      src/Discord.Net.Rpc/Entities/Guilds/RpcGuildSummary.cs
  33. +1
    -1
      src/Discord.Net.Rpc/Entities/Messages/RpcMessage.cs
  34. +1
    -1
      src/Discord.Net.Rpc/Entities/Messages/RpcSystemMessage.cs
  35. +1
    -1
      src/Discord.Net.Rpc/Entities/Messages/RpcUserMessage.cs
  36. +29
    -0
      src/Discord.Net.Rpc/Entities/Users/RpcGuildUser.cs
  37. +1
    -7
      src/Discord.Net.Rpc/Entities/Users/RpcUser.cs
  38. +1
    -1
      src/Discord.Net.Rpc/Entities/Users/RpcVoiceState.cs
  39. +0
    -1
      src/Discord.Net.WebSocket/Entities/Channels/SocketChannel.cs

+ 3
- 0
src/Discord.Net.Core/Net/WebSockets/DefaultWebSocketClient.cs View File

@@ -154,6 +154,7 @@ namespace Discord.Net.WebSockets
while (!cancelToken.IsCancellationRequested)
{
WebSocketReceiveResult socketResult = await _client.ReceiveAsync(buffer, cancelToken).ConfigureAwait(false);
System.Diagnostics.Debug.WriteLine("Got " + socketResult.Count);
byte[] result;
int resultCount;
@@ -193,6 +194,7 @@ namespace Discord.Net.WebSockets
result = buffer.Array;
}

System.Diagnostics.Debug.WriteLine("Start");
if (socketResult.MessageType == WebSocketMessageType.Text)
{
string text = Encoding.UTF8.GetString(result, 0, resultCount);
@@ -200,6 +202,7 @@ namespace Discord.Net.WebSockets
}
else
await BinaryMessage(result, 0, resultCount).ConfigureAwait(false);
System.Diagnostics.Debug.WriteLine("Stop");
}
}
catch (Win32Exception ex) when (ex.HResult == HR_TIMEOUT)


+ 22
- 15
src/Discord.Net.Rpc/API/DiscordRpcApiClient.cs View File

@@ -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<Rpc.RpcGuild> SendGetGuildAsync(ulong guildId, RequestOptions options = null)
public async Task<Rpc.Guild> SendGetGuildAsync(ulong guildId, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
var msg = new GetGuildParams
{
GuildId = guildId
};
return await SendRpcAsync<Rpc.RpcGuild>("GET_GUILD", msg, options: options).ConfigureAwait(false);
return await SendRpcAsync<Rpc.Guild>("GET_GUILD", msg, options: options).ConfigureAwait(false);
}
public async Task<GetChannelsResponse> SendGetChannelsAsync(ulong guildId, RequestOptions options = null)
{
@@ -287,33 +287,34 @@ namespace Discord.API
};
return await SendRpcAsync<GetChannelsResponse>("GET_CHANNELS", msg, options: options).ConfigureAwait(false);
}
public async Task<Rpc.RpcChannel> SendGetChannelAsync(ulong channelId, RequestOptions options = null)
public async Task<Rpc.Channel> SendGetChannelAsync(ulong channelId, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
var msg = new GetChannelParams
{
ChannelId = channelId
};
return await SendRpcAsync<Rpc.RpcChannel>("GET_CHANNEL", msg, options: options).ConfigureAwait(false);
return await SendRpcAsync<Rpc.Channel>("GET_CHANNEL", msg, options: options).ConfigureAwait(false);
}
public async Task<SetLocalVolumeResponse> SendSetLocalVolumeAsync(int volume, RequestOptions options = null)
public async Task<Rpc.Channel> SendSelectTextChannelAsync(ulong channelId, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
var msg = new SetLocalVolumeParams
var msg = new SelectChannelParams
{
Volume = volume
ChannelId = channelId
};
return await SendRpcAsync<SetLocalVolumeResponse>("SET_LOCAL_VOLUME", msg, options: options).ConfigureAwait(false);
return await SendRpcAsync<Rpc.Channel>("SELECT_TEXT_CHANNEL", msg, options: options).ConfigureAwait(false);
}
public async Task<Rpc.RpcChannel> SendSelectVoiceChannelAsync(ulong channelId, RequestOptions options = null)
public async Task<Rpc.Channel> SendSelectVoiceChannelAsync(ulong channelId, bool force = false, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
var msg = new SelectVoiceChannelParams
var msg = new SelectChannelParams
{
ChannelId = channelId
ChannelId = channelId,
Force = force
};
return await SendRpcAsync<Rpc.RpcChannel>("SELECT_VOICE_CHANNEL", msg, options: options).ConfigureAwait(false);
return await SendRpcAsync<Rpc.Channel>("SELECT_VOICE_CHANNEL", msg, options: options).ConfigureAwait(false);
}

public async Task<SubscriptionResponse> SendGlobalSubscribeAsync(string evt, RequestOptions options = null)
@@ -370,10 +371,16 @@ namespace Discord.API
options = RequestOptions.CreateOrClone(options);
return await SendRpcAsync<API.Rpc.VoiceSettings>("GET_VOICE_SETTINGS", null, options: options).ConfigureAwait(false);
}
public async Task<API.Rpc.VoiceSettings> SetVoiceSettingsAsync(API.Rpc.VoiceSettings settings, RequestOptions options = null)
public async Task SetVoiceSettingsAsync(API.Rpc.VoiceSettings settings, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
await SendRpcAsync<API.Rpc.VoiceSettings>("SET_VOICE_SETTINGS", settings, options: options).ConfigureAwait(false);
}
public async Task SetUserVoiceSettingsAsync(ulong userId, API.Rpc.UserVoiceSettings settings, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
return await SendRpcAsync<API.Rpc.VoiceSettings>("SET_VOICE_SETTINGS", settings, options: options).ConfigureAwait(false);
settings.UserId = userId;
await SendRpcAsync<API.Rpc.UserVoiceSettings>("SET_USER_VOICE_SETTINGS", settings, options: options).ConfigureAwait(false);
}

private bool ProcessMessage(API.Rpc.RpcFrame msg)


+ 34
- 0
src/Discord.Net.Rpc/API/Rpc/Channel.cs View File

@@ -0,0 +1,34 @@
#pragma warning disable CS1591
using Newtonsoft.Json;

namespace Discord.API.Rpc
{
public class Channel
{
//Shared
[JsonProperty("id")]
public ulong Id { get; set; }
[JsonProperty("type")]
public ChannelType Type { get; set; }

//GuildChannel
[JsonProperty("guild_id")]
public Optional<ulong> GuildId { get; set; }
[JsonProperty("name")]
public Optional<string> Name { get; set; }
[JsonProperty("position")]
public Optional<int> Position { get; set; }

//IMessageChannel
[JsonProperty("messages")]
public Message[] Messages { get; set; }

//VoiceChannel
[JsonProperty("bitrate")]
public Optional<int> Bitrate { get; set; }
[JsonProperty("user_limit")]
public Optional<int> UserLimit { get; set; }
[JsonProperty("voice_states")]
public ExtendedVoiceState[] VoiceStates { get; set; }
}
}

src/Discord.Net.Rpc/API/Rpc/ChannelCreatedEvent.cs → src/Discord.Net.Rpc/API/Rpc/ChannelSummary.cs View File

@@ -2,7 +2,7 @@

namespace Discord.API.Rpc
{
public class ChannelCreatedEvent
public class ChannelSummary
{
[JsonProperty("id")]
public ulong Id { get; set; }

src/Discord.Net.Rpc/API/Rpc/VoiceStateEvent.cs → src/Discord.Net.Rpc/API/Rpc/ExtendedVoiceState.cs View File

@@ -3,7 +3,7 @@ using Newtonsoft.Json;

namespace Discord.API.Rpc
{
public class VoiceStateEvent
public class ExtendedVoiceState
{
[JsonProperty("user")]
public User User { get; set; }

+ 2
- 1
src/Discord.Net.Rpc/API/Rpc/GetChannelsResponse.cs View File

@@ -1,11 +1,12 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
using System.Collections.Generic;

namespace Discord.API.Rpc
{
public class GetChannelsResponse
{
[JsonProperty("channels")]
public RpcChannel[] Channels { get; set; }
public IReadOnlyCollection<ChannelSummary> Channels { get; set; }
}
}

+ 1
- 0
src/Discord.Net.Rpc/API/Rpc/GetGuildsParams.cs View File

@@ -1,4 +1,5 @@
#pragma warning disable CS1591

namespace Discord.API.Rpc
{
public class GetGuildsParams


+ 1
- 1
src/Discord.Net.Rpc/API/Rpc/GetGuildsResponse.cs View File

@@ -6,6 +6,6 @@ namespace Discord.API.Rpc
public class GetGuildsResponse
{
[JsonProperty("guilds")]
public RpcUserGuild[] Guilds { get; set; }
public GuildSummary[] Guilds { get; set; }
}
}

src/Discord.Net.Rpc/API/Rpc/RpcUserGuild.cs → src/Discord.Net.Rpc/API/Rpc/Guild.cs View File

@@ -1,13 +1,18 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
using System.Collections.Generic;

namespace Discord.API.Rpc
{
public class RpcUserGuild
public class Guild
{
[JsonProperty("id")]
public ulong Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("icon_url")]
public string IconUrl { get; set; }
[JsonProperty("members")]
public IEnumerable<GuildMember> Members { get; set; }
}
}

+ 15
- 0
src/Discord.Net.Rpc/API/Rpc/GuildMember.cs View File

@@ -0,0 +1,15 @@
#pragma warning disable CS1591
using Newtonsoft.Json;

namespace Discord.API.Rpc
{
public class GuildMember
{
[JsonProperty("user")]
public User User { get; set; }
[JsonProperty("status")]
public UserStatus Status { get; set; }
/*[JsonProperty("activity")]
public object Activity { get; set; }*/
}
}

src/Discord.Net.Rpc/API/Rpc/GuildCreatedEvent.cs → src/Discord.Net.Rpc/API/Rpc/GuildSummary.cs View File

@@ -2,7 +2,7 @@

namespace Discord.API.Rpc
{
public class GuildCreatedEvent
public class GuildSummary
{
[JsonProperty("id")]
public ulong Id { get; set; }

src/Discord.Net.Rpc/API/Rpc/RpcMessage.cs → src/Discord.Net.Rpc/API/Rpc/Message.cs View File

@@ -2,7 +2,7 @@

namespace Discord.API.Rpc
{
public class RpcMessage : Message
public class Message : Discord.API.Message
{
[JsonProperty("blocked")]
public Optional<bool> IsBlocked { get; }

+ 1
- 1
src/Discord.Net.Rpc/API/Rpc/MessageEvent.cs View File

@@ -7,6 +7,6 @@ namespace Discord.API.Rpc
[JsonProperty("channel_id")]
public ulong ChannelId { get; set; }
[JsonProperty("message")]
public RpcMessage Message { get; set; }
public Message Message { get; set; }
}
}

+ 0
- 11
src/Discord.Net.Rpc/API/Rpc/RpcChannel.cs View File

@@ -1,11 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;

namespace Discord.API.Rpc
{
public class RpcChannel : Channel
{
[JsonProperty("voice_states")]
public VoiceState[] VoiceStates { get; set; }
}
}

+ 0
- 13
src/Discord.Net.Rpc/API/Rpc/RpcGuild.cs View File

@@ -1,13 +0,0 @@
#pragma warning disable CS1591
using Newtonsoft.Json;

namespace Discord.API.Rpc
{
public class RpcGuild : Guild
{
[JsonProperty("online")]
public int Online { get; set; }
[JsonProperty("members")]
public GuildMember[] Members { get; set; }
}
}

src/Discord.Net.Rpc/API/Rpc/SelectVoiceChannelParams.cs → src/Discord.Net.Rpc/API/Rpc/SelectChannelParams.cs View File

@@ -3,9 +3,11 @@ using Newtonsoft.Json;

namespace Discord.API.Rpc
{
public class SelectVoiceChannelParams
public class SelectChannelParams
{
[JsonProperty("channel_id")]
public ulong? ChannelId { get; set; }
[JsonProperty("force")]
public Optional<bool> Force { get; set; }
}
}

+ 18
- 0
src/Discord.Net.Rpc/API/Rpc/UserVoiceSettings.cs View File

@@ -0,0 +1,18 @@
#pragma warning disable CS1591

using Newtonsoft.Json;

namespace Discord.API.Rpc
{
public class UserVoiceSettings
{
[JsonProperty("userId")]
internal ulong UserId { get; set; }
[JsonProperty("pan")]
public Optional<Pan> Pan { get; set; }
[JsonProperty("volume")]
public Optional<int> Volume { get; set; }
[JsonProperty("mute")]
public Optional<bool> Mute { get; set; }
}
}

+ 4
- 4
src/Discord.Net.Rpc/DiscordRpcClient.Events.cs View File

@@ -26,20 +26,20 @@ namespace Discord.Rpc
private readonly AsyncEvent<Func<Task>> _readyEvent = new AsyncEvent<Func<Task>>();

//Channel
public event Func<RpcChannel, Task> ChannelCreated
public event Func<RpcChannelSummary, Task> ChannelCreated
{
add { _channelCreatedEvent.Add(value); }
remove { _channelCreatedEvent.Remove(value); }
}
private readonly AsyncEvent<Func<RpcChannel, Task>> _channelCreatedEvent = new AsyncEvent<Func<RpcChannel, Task>>();
private readonly AsyncEvent<Func<RpcChannelSummary, Task>> _channelCreatedEvent = new AsyncEvent<Func<RpcChannelSummary, Task>>();

//Guild
public event Func<RpcGuild, Task> GuildCreated
public event Func<RpcGuildSummary, Task> GuildCreated
{
add { _guildCreatedEvent.Add(value); }
remove { _guildCreatedEvent.Remove(value); }
}
private readonly AsyncEvent<Func<RpcGuild, Task>> _guildCreatedEvent = new AsyncEvent<Func<RpcGuild, Task>>();
private readonly AsyncEvent<Func<RpcGuildSummary, Task>> _guildCreatedEvent = new AsyncEvent<Func<RpcGuildSummary, Task>>();
public event Func<RpcGuildStatus, Task> GuildStatusUpdated
{
add { _guildStatusUpdatedEvent.Add(value); }


+ 67
- 7
src/Discord.Net.Rpc/DiscordRpcClient.cs View File

@@ -8,6 +8,7 @@ using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

@@ -265,6 +266,59 @@ namespace Discord.Rpc
await ApiClient.SendChannelUnsubscribeAsync(GetEventName(events[i]), channelId);
}

public async Task<RpcGuild> GetRpcGuildAsync(ulong id)
{
var model = await ApiClient.SendGetGuildAsync(id).ConfigureAwait(false);
return RpcGuild.Create(this, model);
}
public async Task<IReadOnlyCollection<RpcGuildSummary>> GetRpcGuildsAsync()
{
var models = await ApiClient.SendGetGuildsAsync().ConfigureAwait(false);
return models.Guilds.Select(x => RpcGuildSummary.Create(x)).ToImmutableArray();
}
public async Task<RpcChannel> GetRpcChannelAsync(ulong id)
{
var model = await ApiClient.SendGetChannelAsync(id).ConfigureAwait(false);
return RpcChannel.Create(this, model);
}
public async Task<IReadOnlyCollection<RpcChannelSummary>> GetRpcChannelsAsync(ulong guildId)
{
var models = await ApiClient.SendGetChannelsAsync(guildId).ConfigureAwait(false);
return models.Channels.Select(x => RpcChannelSummary.Create(x)).ToImmutableArray();
}

public async Task<IMessageChannel> SelectTextChannelAsync(IChannel channel)
{
var model = await ApiClient.SendSelectTextChannelAsync(channel.Id).ConfigureAwait(false);
return RpcChannel.Create(this, model) as IMessageChannel;
}
public async Task<IMessageChannel> SelectTextChannelAsync(RpcChannelSummary channel)
{
var model = await ApiClient.SendSelectTextChannelAsync(channel.Id).ConfigureAwait(false);
return RpcChannel.Create(this, model) as IMessageChannel;
}
public async Task<IMessageChannel> SelectTextChannelAsync(ulong channelId)
{
var model = await ApiClient.SendSelectTextChannelAsync(channelId).ConfigureAwait(false);
return RpcChannel.Create(this, model) as IMessageChannel;
}

public async Task<IRpcAudioChannel> SelectVoiceChannelAsync(IChannel channel, bool force = false)
{
var model = await ApiClient.SendSelectVoiceChannelAsync(channel.Id, force).ConfigureAwait(false);
return RpcChannel.Create(this, model) as IRpcAudioChannel;
}
public async Task<IRpcAudioChannel> SelectVoiceChannelAsync(RpcChannelSummary channel, bool force = false)
{
var model = await ApiClient.SendSelectVoiceChannelAsync(channel.Id, force).ConfigureAwait(false);
return RpcChannel.Create(this, model) as IRpcAudioChannel;
}
public async Task<IRpcAudioChannel> SelectVoiceChannelAsync(ulong channelId, bool force = false)
{
var model = await ApiClient.SendSelectVoiceChannelAsync(channelId, force).ConfigureAwait(false);
return RpcChannel.Create(this, model) as IRpcAudioChannel;
}

public async Task<VoiceSettings> GetVoiceSettingsAsync()
{
var model = await ApiClient.GetVoiceSettingsAsync().ConfigureAwait(false);
@@ -279,6 +333,12 @@ namespace Discord.Rpc
func(settings);
await ApiClient.SetVoiceSettingsAsync(settings).ConfigureAwait(false);
}
public async Task SetUserVoiceSettingsAsync(ulong userId, Action<API.Rpc.UserVoiceSettings> func)
{
var settings = new API.Rpc.UserVoiceSettings();
func(settings);
await ApiClient.SetUserVoiceSettingsAsync(userId, settings).ConfigureAwait(false);
}

private static string GetEventName(RpcGlobalEvent rpcEvent)
{
@@ -363,8 +423,8 @@ namespace Discord.Rpc
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);
var data = (payload.Value as JToken).ToObject<ChannelSummary>(_serializer);
var channel = RpcChannelSummary.Create(data);

await _channelCreatedEvent.InvokeAsync(channel).ConfigureAwait(false);
}
@@ -374,8 +434,8 @@ namespace Discord.Rpc
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);
var data = (payload.Value as JToken).ToObject<GuildSummary>(_serializer);
var guild = RpcGuildSummary.Create(data);

await _guildCreatedEvent.InvokeAsync(guild).ConfigureAwait(false);
}
@@ -394,7 +454,7 @@ namespace Discord.Rpc
case "VOICE_STATE_CREATE":
{
await _rpcLogger.DebugAsync("Received Dispatch (VOICE_STATE_CREATE)").ConfigureAwait(false);
var data = (payload.Value as JToken).ToObject<VoiceStateEvent>(_serializer);
var data = (payload.Value as JToken).ToObject<ExtendedVoiceState>(_serializer);
var voiceState = RpcVoiceState.Create(this, data);

await _voiceStateCreatedEvent.InvokeAsync(voiceState).ConfigureAwait(false);
@@ -403,7 +463,7 @@ namespace Discord.Rpc
case "VOICE_STATE_UPDATE":
{
await _rpcLogger.DebugAsync("Received Dispatch (VOICE_STATE_UPDATE)").ConfigureAwait(false);
var data = (payload.Value as JToken).ToObject<VoiceStateEvent>(_serializer);
var data = (payload.Value as JToken).ToObject<ExtendedVoiceState>(_serializer);
var voiceState = RpcVoiceState.Create(this, data);

await _voiceStateUpdatedEvent.InvokeAsync(voiceState).ConfigureAwait(false);
@@ -412,7 +472,7 @@ namespace Discord.Rpc
case "VOICE_STATE_DELETE":
{
await _rpcLogger.DebugAsync("Received Dispatch (VOICE_STATE_DELETE)").ConfigureAwait(false);
var data = (payload.Value as JToken).ToObject<VoiceStateEvent>(_serializer);
var data = (payload.Value as JToken).ToObject<ExtendedVoiceState>(_serializer);
var voiceState = RpcVoiceState.Create(this, data);

await _voiceStateDeletedEvent.InvokeAsync(voiceState).ConfigureAwait(false);


+ 9
- 0
src/Discord.Net.Rpc/Entities/Channels/IRpcAudioChannel.cs View File

@@ -0,0 +1,9 @@
using System.Collections.Generic;

namespace Discord.Rpc
{
public interface IRpcAudioChannel : IAudioChannel
{
IReadOnlyCollection<RpcVoiceState> VoiceStates { get; }
}
}

+ 9
- 0
src/Discord.Net.Rpc/Entities/Channels/IRpcMessageChannel.cs View File

@@ -0,0 +1,9 @@
using System.Collections.Generic;

namespace Discord.Rpc
{
public interface IRpcMessageChannel : IMessageChannel
{
IReadOnlyCollection<RpcMessage> CachedMessages { get; }
}
}

+ 6
- 0
src/Discord.Net.Rpc/Entities/Channels/IRpcPrivateChannel.cs View File

@@ -0,0 +1,6 @@
namespace Discord.Rpc
{
public interface IRpcPrivateChannel
{
}
}

+ 27
- 19
src/Discord.Net.Rpc/Entities/Channels/RpcChannel.cs View File

@@ -1,32 +1,40 @@
using System.Diagnostics;
using Model = Discord.API.Rpc.ChannelCreatedEvent;
using System;

using Model = Discord.API.Rpc.Channel;

namespace Discord.Rpc
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RpcChannel
public class RpcChannel : RpcEntity<ulong>
{
public ulong Id { get; }
public string Name { get; set; }
public ChannelType Type { get; set; }
public string Name { get; private set; }

internal RpcChannel(ulong id)
internal RpcChannel(DiscordRpcClient discord, ulong id)
: base(discord, id)
{
Id = id;
}
internal static RpcChannel Create(Model model)
internal static RpcChannel Create(DiscordRpcClient discord, Model model)
{
var entity = new RpcChannel(model.Id);
entity.Update(model);
return entity;
if (model.GuildId.IsSpecified)
return RpcGuildChannel.Create(discord, model);
else
return CreatePrivate(discord, model);
}
internal void Update(Model model)
internal static RpcChannel CreatePrivate(DiscordRpcClient discord, Model model)
{
Name = model.Name;
Type = model.Type;
switch (model.Type)
{
case ChannelType.DM:
return RpcDMChannel.Create(discord, model);
case ChannelType.Group:
return RpcGroupChannel.Create(discord, model);
default:
throw new InvalidOperationException($"Unexpected channel type: {model.Type}");
}
}
internal virtual void Update(Model model)
{
if (model.Name.IsSpecified)
Name = model.Name.Value;
}

public override string ToString() => Name;
private string DebuggerDisplay => $"{Name} ({Id}, {Type})";
}
}

+ 32
- 0
src/Discord.Net.Rpc/Entities/Channels/RpcChannelSummary.cs View File

@@ -0,0 +1,32 @@
using System.Diagnostics;
using Model = Discord.API.Rpc.ChannelSummary;

namespace Discord.Rpc
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RpcChannelSummary
{
public ulong Id { get; }
public string Name { get; set; }
public ChannelType Type { get; set; }

internal RpcChannelSummary(ulong id)
{
Id = id;
}
internal static RpcChannelSummary Create(Model model)
{
var entity = new RpcChannelSummary(model.Id);
entity.Update(model);
return entity;
}
internal void Update(Model model)
{
Name = model.Name;
Type = model.Type;
}

public override string ToString() => Name;
private string DebuggerDisplay => $"{Name} ({Id}, {Type})";
}
}

+ 124
- 0
src/Discord.Net.Rpc/Entities/Channels/RpcDMChannel.cs View File

@@ -0,0 +1,124 @@
using Discord.Rest;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Model = Discord.API.Rpc.Channel;

namespace Discord.Rpc
{
public class RpcDMChannel : RpcChannel, IRpcMessageChannel, IRpcPrivateChannel, IDMChannel
{
public IReadOnlyCollection<RpcMessage> CachedMessages { get; private set; }

internal RpcDMChannel(DiscordRpcClient discord, ulong id)
: base(discord, id)
{
}
internal static new RpcDMChannel Create(DiscordRpcClient discord, Model model)
{
var entity = new RpcDMChannel(discord, model.Id);
entity.Update(model);
return entity;
}
internal override void Update(Model model)
{
base.Update(model);
CachedMessages = model.Messages.Select(x => RpcMessage.Create(Discord, Id, x)).ToImmutableArray();
}

public Task CloseAsync(RequestOptions options = null)
=> ChannelHelper.DeleteAsync(this, Discord, options);

//TODO: Use RPC cache
public Task<RestMessage> GetMessageAsync(ulong id, RequestOptions options = null)
=> ChannelHelper.GetMessageAsync(this, Discord, id, null, options);
public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
=> ChannelHelper.GetMessagesAsync(this, Discord, null, Direction.Before, limit, null, options);
public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
=> ChannelHelper.GetMessagesAsync(this, Discord, fromMessageId, dir, limit, null, options);
public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
=> ChannelHelper.GetMessagesAsync(this, Discord, fromMessage.Id, dir, limit, null, options);
public Task<IReadOnlyCollection<RestMessage>> GetPinnedMessagesAsync(RequestOptions options = null)
=> ChannelHelper.GetPinnedMessagesAsync(this, Discord, null, options);

public Task<RestUserMessage> SendMessageAsync(string text, bool isTTS, RequestOptions options = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, null, options);
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, null, options);
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, null, options);

public Task DeleteMessagesAsync(IEnumerable<IMessage> messages, RequestOptions options = null)
=> ChannelHelper.DeleteMessagesAsync(this, Discord, messages, options);

public Task TriggerTypingAsync(RequestOptions options = null)
=> ChannelHelper.TriggerTypingAsync(this, Discord, options);
public IDisposable EnterTypingState(RequestOptions options = null)
=> ChannelHelper.EnterTypingState(this, Discord, options);

public override string ToString() => Id.ToString();
private string DebuggerDisplay => $"({Id}, DM)";

//IDMChannel
IUser IDMChannel.Recipient { get { throw new NotSupportedException(); } }

//IPrivateChannel
IReadOnlyCollection<IUser> IPrivateChannel.Recipients { get { throw new NotSupportedException(); } }

//IMessageChannel
async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
return await GetMessageAsync(id, options);
else
return null;
}
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(int limit, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
return GetMessagesAsync(limit, options);
else
return AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>();
}
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(ulong fromMessageId, Direction dir, int limit, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
return GetMessagesAsync(fromMessageId, dir, limit, options);
else
return AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>();
}
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(IMessage fromMessage, Direction dir, int limit, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
return GetMessagesAsync(fromMessage, dir, limit, options);
else
return AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>();
}
async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options)
=> await GetPinnedMessagesAsync(options);

async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, RequestOptions options)
=> await SendFileAsync(filePath, text, isTTS, options);
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, RequestOptions options)
=> await SendFileAsync(stream, filename, text, isTTS, options);
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, RequestOptions options)
=> await SendMessageAsync(text, isTTS, options);
IDisposable IMessageChannel.EnterTypingState(RequestOptions options)
=> EnterTypingState(options);

//IChannel
string IChannel.Name { get { throw new NotSupportedException(); } }

Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
{
throw new NotSupportedException();
}
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
{
throw new NotSupportedException();
}
}
}

+ 123
- 0
src/Discord.Net.Rpc/Entities/Channels/RpcGroupChannel.cs View File

@@ -0,0 +1,123 @@
using Discord.Rest;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Model = Discord.API.Rpc.Channel;

namespace Discord.Rpc
{
public class RpcGroupChannel : RpcChannel, IRpcMessageChannel, IRpcAudioChannel, IRpcPrivateChannel, IGroupChannel
{
public IReadOnlyCollection<RpcMessage> CachedMessages { get; private set; }
public IReadOnlyCollection<RpcVoiceState> VoiceStates { get; private set; }

internal RpcGroupChannel(DiscordRpcClient discord, ulong id)
: base(discord, id)
{
}
internal new static RpcGroupChannel Create(DiscordRpcClient discord, Model model)
{
var entity = new RpcGroupChannel(discord, model.Id);
entity.Update(model);
return entity;
}
internal override void Update(Model model)
{
base.Update(model);
CachedMessages = model.Messages.Select(x => RpcMessage.Create(Discord, Id, x)).ToImmutableArray();
VoiceStates = model.VoiceStates.Select(x => RpcVoiceState.Create(Discord, x)).ToImmutableArray();
}

public Task LeaveAsync(RequestOptions options = null)
=> ChannelHelper.DeleteAsync(this, Discord, options);

//TODO: Use RPC cache
public Task<RestMessage> GetMessageAsync(ulong id, RequestOptions options = null)
=> ChannelHelper.GetMessageAsync(this, Discord, id, null, options);
public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
=> ChannelHelper.GetMessagesAsync(this, Discord, null, Direction.Before, limit, null, options);
public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
=> ChannelHelper.GetMessagesAsync(this, Discord, fromMessageId, dir, limit, null, options);
public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
=> ChannelHelper.GetMessagesAsync(this, Discord, fromMessage.Id, dir, limit, null, options);
public Task<IReadOnlyCollection<RestMessage>> GetPinnedMessagesAsync(RequestOptions options = null)
=> ChannelHelper.GetPinnedMessagesAsync(this, Discord, null, options);

public Task<RestUserMessage> SendMessageAsync(string text, bool isTTS, RequestOptions options = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, null, options);
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, null, options);
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, null, options);

public Task DeleteMessagesAsync(IEnumerable<IMessage> messages, RequestOptions options = null)
=> ChannelHelper.DeleteMessagesAsync(this, Discord, messages, options);

public Task TriggerTypingAsync(RequestOptions options = null)
=> ChannelHelper.TriggerTypingAsync(this, Discord, options);
public IDisposable EnterTypingState(RequestOptions options = null)
=> ChannelHelper.EnterTypingState(this, Discord, options);

public override string ToString() => Id.ToString();
private string DebuggerDisplay => $"({Id}, Group)";
//IPrivateChannel
IReadOnlyCollection<IUser> IPrivateChannel.Recipients { get { throw new NotSupportedException(); } }

//IMessageChannel
async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
return await GetMessageAsync(id, options);
else
return null;
}
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(int limit, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
return GetMessagesAsync(limit, options);
else
return AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>();
}
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(ulong fromMessageId, Direction dir, int limit, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
return GetMessagesAsync(fromMessageId, dir, limit, options);
else
return AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>();
}
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(IMessage fromMessage, Direction dir, int limit, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
return GetMessagesAsync(fromMessage, dir, limit, options);
else
return AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>();
}
async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options)
=> await GetPinnedMessagesAsync(options);

async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, RequestOptions options)
=> await SendFileAsync(filePath, text, isTTS, options);
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, RequestOptions options)
=> await SendFileAsync(stream, filename, text, isTTS, options);
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, RequestOptions options)
=> await SendMessageAsync(text, isTTS, options);
IDisposable IMessageChannel.EnterTypingState(RequestOptions options)
=> EnterTypingState(options);

//IChannel
string IChannel.Name { get { throw new NotSupportedException(); } }

Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
{
throw new NotSupportedException();
}
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
{
throw new NotSupportedException();
}
}
}

+ 94
- 0
src/Discord.Net.Rpc/Entities/Channels/RpcGuildChannel.cs View File

@@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Discord.API.Rest;
using Model = Discord.API.Rpc.Channel;
using Discord.Rest;

namespace Discord.Rpc
{
public class RpcGuildChannel : RpcChannel, IGuildChannel
{
public ulong GuildId { get; }
public int Position { get; private set; }

internal RpcGuildChannel(DiscordRpcClient discord, ulong id, ulong guildId)
: base(discord, id)
{
GuildId = guildId;
}
internal new static RpcGuildChannel Create(DiscordRpcClient discord, Model model)
{
switch (model.Type)
{
case ChannelType.Text:
return RpcTextChannel.Create(discord, model);
case ChannelType.Voice:
return RpcVoiceChannel.Create(discord, model);
default:
throw new InvalidOperationException("Unknown guild channel type");
}
}
internal override void Update(Model model)
{
base.Update(model);
if (model.Position.IsSpecified)
Position = model.Position.Value;
}

public Task ModifyAsync(Action<ModifyGuildChannelParams> func, RequestOptions options = null)
=> ChannelHelper.ModifyAsync(this, Discord, func, options);
public Task DeleteAsync(RequestOptions options = null)
=> ChannelHelper.DeleteAsync(this, Discord, options);

public Task AddPermissionOverwriteAsync(IUser user, OverwritePermissions perms, RequestOptions options = null)
=> ChannelHelper.AddPermissionOverwriteAsync(this, Discord, user, perms, options);
public Task AddPermissionOverwriteAsync(IRole role, OverwritePermissions perms, RequestOptions options = null)
=> ChannelHelper.AddPermissionOverwriteAsync(this, Discord, role, perms, options);
public Task RemovePermissionOverwriteAsync(IUser user, RequestOptions options = null)
=> ChannelHelper.RemovePermissionOverwriteAsync(this, Discord, user, options);
public Task RemovePermissionOverwriteAsync(IRole role, RequestOptions options = null)
=> ChannelHelper.RemovePermissionOverwriteAsync(this, Discord, role, options);

public async Task<IReadOnlyCollection<RestInviteMetadata>> GetInvitesAsync(RequestOptions options = null)
=> await ChannelHelper.GetInvitesAsync(this, Discord, options);
public async Task<RestInviteMetadata> CreateInviteAsync(int? maxAge = 3600, int? maxUses = null, bool isTemporary = true, RequestOptions options = null)
=> await ChannelHelper.CreateInviteAsync(this, Discord, maxAge, maxUses, isTemporary, options);

public override string ToString() => Name;

//IGuildChannel
async Task<IReadOnlyCollection<IInviteMetadata>> IGuildChannel.GetInvitesAsync(RequestOptions options)
=> await GetInvitesAsync(options);
async Task<IInviteMetadata> IGuildChannel.CreateInviteAsync(int? maxAge, int? maxUses, bool isTemporary, RequestOptions options)
=> await CreateInviteAsync(maxAge, maxUses, isTemporary, options);

IReadOnlyCollection<Overwrite> IGuildChannel.PermissionOverwrites { get { throw new NotSupportedException(); } }
OverwritePermissions? IGuildChannel.GetPermissionOverwrite(IUser user)
{
throw new NotSupportedException();
}
OverwritePermissions? IGuildChannel.GetPermissionOverwrite(IRole role)
{
throw new NotSupportedException();
}
IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
{
throw new NotSupportedException();
}
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
{
throw new NotSupportedException();
}

//IChannel
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
{
throw new NotSupportedException();
}
Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
{
throw new NotSupportedException();
}
}
}

+ 113
- 0
src/Discord.Net.Rpc/Entities/Channels/RpcTextChannel.cs View File

@@ -0,0 +1,113 @@
using Discord.API.Rest;
using Discord.Rest;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Model = Discord.API.Rpc.Channel;

namespace Discord.Rpc
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RpcTextChannel : RpcGuildChannel, IRpcMessageChannel, ITextChannel
{
public IReadOnlyCollection<RpcMessage> CachedMessages { get; private set; }

public string Mention => MentionUtils.MentionChannel(Id);

internal RpcTextChannel(DiscordRpcClient discord, ulong id, ulong guildId)
: base(discord, id, guildId)
{
}
internal new static RpcVoiceChannel Create(DiscordRpcClient discord, Model model)
{
var entity = new RpcVoiceChannel(discord, model.Id, model.GuildId.Value);
entity.Update(model);
return entity;
}
internal override void Update(Model model)
{
base.Update(model);
CachedMessages = model.Messages.Select(x => RpcMessage.Create(Discord, Id, x)).ToImmutableArray();
}

public Task ModifyAsync(Action<ModifyTextChannelParams> func, RequestOptions options = null)
=> ChannelHelper.ModifyAsync(this, Discord, func, options);

//TODO: Use RPC cache
public Task<RestMessage> GetMessageAsync(ulong id, RequestOptions options = null)
=> ChannelHelper.GetMessageAsync(this, Discord, id, null, options);
public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
=> ChannelHelper.GetMessagesAsync(this, Discord, null, Direction.Before, limit, null, options);
public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
=> ChannelHelper.GetMessagesAsync(this, Discord, fromMessageId, dir, limit, null, options);
public IAsyncEnumerable<IReadOnlyCollection<RestMessage>> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
=> ChannelHelper.GetMessagesAsync(this, Discord, fromMessage.Id, dir, limit, null, options);
public Task<IReadOnlyCollection<RestMessage>> GetPinnedMessagesAsync(RequestOptions options = null)
=> ChannelHelper.GetPinnedMessagesAsync(this, Discord, null, options);

public Task<RestUserMessage> SendMessageAsync(string text, bool isTTS, RequestOptions options = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, null, options);
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, null, options);
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, null, options);

public Task DeleteMessagesAsync(IEnumerable<IMessage> messages, RequestOptions options = null)
=> ChannelHelper.DeleteMessagesAsync(this, Discord, messages, options);

public Task TriggerTypingAsync(RequestOptions options = null)
=> ChannelHelper.TriggerTypingAsync(this, Discord, options);
public IDisposable EnterTypingState(RequestOptions options = null)
=> ChannelHelper.EnterTypingState(this, Discord, options);
private string DebuggerDisplay => $"{Name} ({Id}, Text)";
//ITextChannel
string ITextChannel.Topic { get { throw new NotSupportedException(); } }

//IMessageChannel
async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
return await GetMessageAsync(id, options);
else
return null;
}
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(int limit, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
return GetMessagesAsync(limit, options);
else
return AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>();
}
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(ulong fromMessageId, Direction dir, int limit, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
return GetMessagesAsync(fromMessageId, dir, limit, options);
else
return AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>();
}
IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync(IMessage fromMessage, Direction dir, int limit, CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
return GetMessagesAsync(fromMessage, dir, limit, options);
else
return AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>();
}
async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options)
=> await GetPinnedMessagesAsync(options);

async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, RequestOptions options)
=> await SendFileAsync(filePath, text, isTTS, options);
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, RequestOptions options)
=> await SendFileAsync(stream, filename, text, isTTS, options);
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, RequestOptions options)
=> await SendMessageAsync(text, isTTS, options);
IDisposable IMessageChannel.EnterTypingState(RequestOptions options)
=> EnterTypingState(options);
}
}

+ 49
- 0
src/Discord.Net.Rpc/Entities/Channels/RpcVoiceChannel.cs View File

@@ -0,0 +1,49 @@
using Discord.API.Rest;
using Discord.Audio;
using Discord.Rest;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Model = Discord.API.Rpc.Channel;

namespace Discord.Rpc
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RpcVoiceChannel : RpcGuildChannel, IRpcAudioChannel, IVoiceChannel
{
public int UserLimit { get; private set; }
public int Bitrate { get; private set; }
public IReadOnlyCollection<RpcVoiceState> VoiceStates { get; private set; }

internal RpcVoiceChannel(DiscordRpcClient discord, ulong id, ulong guildId)
: base(discord, id, guildId)
{
}
internal new static RpcVoiceChannel Create(DiscordRpcClient discord, Model model)
{
var entity = new RpcVoiceChannel(discord, model.Id, model.GuildId.Value);
entity.Update(model);
return entity;
}
internal override void Update(Model model)
{
base.Update(model);
if (model.UserLimit.IsSpecified)
UserLimit = model.UserLimit.Value;
if (model.Bitrate.IsSpecified)
Bitrate = model.Bitrate.Value;
VoiceStates = model.VoiceStates.Select(x => RpcVoiceState.Create(Discord, x)).ToImmutableArray();
}

public Task ModifyAsync(Action<ModifyVoiceChannelParams> func, RequestOptions options = null)
=> ChannelHelper.ModifyAsync(this, Discord, func, options);

private string DebuggerDisplay => $"{Name} ({Id}, Voice)";

//IVoiceChannel
Task<IAudioClient> IVoiceChannel.ConnectAsync() { throw new NotSupportedException(); }
}
}

+ 15
- 9
src/Discord.Net.Rpc/Entities/Guilds/RpcGuild.cs View File

@@ -1,27 +1,33 @@
using System.Diagnostics;
using Model = Discord.API.Rpc.GuildCreatedEvent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using Model = Discord.API.Rpc.Guild;

namespace Discord.Rpc
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RpcGuild
public class RpcGuild : RpcEntity<ulong>
{
public ulong Id { get; }
public string Name { get; set; }
public string Name { get; private set; }
public string IconUrl { get; private set; }
public IReadOnlyCollection<RpcGuildUser> Users { get; private set; }

internal RpcGuild(ulong id)
internal RpcGuild(DiscordRpcClient discord, ulong id)
: base(discord, id)
{
Id = id;
}
internal static RpcGuild Create(Model model)
internal static RpcGuild Create(DiscordRpcClient discord, Model model)
{
var entity = new RpcGuild(model.Id);
var entity = new RpcGuild(discord, model.Id);
entity.Update(model);
return entity;
}
internal void Update(Model model)
{
Name = model.Name;
IconUrl = model.IconUrl;
Users = model.Members.Select(x => RpcGuildUser.Create(Discord, x)).ToImmutableArray();
}

public override string ToString() => Name;


+ 2
- 2
src/Discord.Net.Rpc/Entities/Guilds/RpcGuildStatus.cs View File

@@ -6,12 +6,12 @@ namespace Discord.Rpc
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RpcGuildStatus
{
public RpcGuild Guild { get; }
public RpcGuildSummary Guild { get; }
public int Online { get; private set; }

internal RpcGuildStatus(ulong guildId)
{
Guild = new RpcGuild(guildId);
Guild = new RpcGuildSummary(guildId);
}
internal static RpcGuildStatus Create(Model model)
{


+ 30
- 0
src/Discord.Net.Rpc/Entities/Guilds/RpcGuildSummary.cs View File

@@ -0,0 +1,30 @@
using System.Diagnostics;
using Model = Discord.API.Rpc.GuildSummary;

namespace Discord.Rpc
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RpcGuildSummary
{
public ulong Id { get; }
public string Name { get; private set; }

internal RpcGuildSummary(ulong id)
{
Id = id;
}
internal static RpcGuildSummary Create(Model model)
{
var entity = new RpcGuildSummary(model.Id);
entity.Update(model);
return entity;
}
internal void Update(Model model)
{
Name = model.Name;
}

public override string ToString() => Name;
private string DebuggerDisplay => $"{Name} ({Id})";
}
}

+ 1
- 1
src/Discord.Net.Rpc/Entities/Messages/RpcMessage.cs View File

@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using Model = Discord.API.Rpc.RpcMessage;
using Model = Discord.API.Rpc.Message;

namespace Discord.Rpc
{


+ 1
- 1
src/Discord.Net.Rpc/Entities/Messages/RpcSystemMessage.cs View File

@@ -1,6 +1,6 @@
using Discord.Rest;
using System.Diagnostics;
using Model = Discord.API.Rpc.RpcMessage;
using Model = Discord.API.Rpc.Message;

namespace Discord.Rpc
{


+ 1
- 1
src/Discord.Net.Rpc/Entities/Messages/RpcUserMessage.cs View File

@@ -5,7 +5,7 @@ using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Threading.Tasks;
using Model = Discord.API.Rpc.RpcMessage;
using Model = Discord.API.Rpc.Message;

namespace Discord.Rpc
{


+ 29
- 0
src/Discord.Net.Rpc/Entities/Users/RpcGuildUser.cs View File

@@ -0,0 +1,29 @@
using Model = Discord.API.Rpc.GuildMember;

namespace Discord.Rpc
{
public class RpcGuildUser : RpcUser
{
private UserStatus _status;

public override UserStatus Status => _status;
//public object Acitivity { get; private set; }

internal RpcGuildUser(DiscordRpcClient discord, ulong id)
: base(discord, id)
{
}
internal static RpcGuildUser Create(DiscordRpcClient discord, Model model)
{
var entity = new RpcGuildUser(discord, model.User.Id);
entity.Update(model);
return entity;
}
internal void Update(Model model)
{
base.Update(model.User);
_status = model.Status;
//Activity = model.Activity;
}
}
}

+ 1
- 7
src/Discord.Net.Rpc/Entities/Users/RpcUser.cs View File

@@ -6,7 +6,7 @@ using Model = Discord.API.User;
namespace Discord.Rpc
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RpcUser : RpcEntity<ulong>, IUser, IUpdateable
public class RpcUser : RpcEntity<ulong>, IUser
{
public bool IsBot { get; private set; }
public string Username { get; private set; }
@@ -40,12 +40,6 @@ namespace Discord.Rpc
if (model.Username.IsSpecified)
Username = model.Username.Value;
}
public virtual async Task UpdateAsync(RequestOptions options = null)
{
var model = await Discord.ApiClient.GetUserAsync(Id, options);
Update(model);
}

public Task<RestDMChannel> CreateDMChannelAsync(RequestOptions options = null)
=> UserHelper.CreateDMChannelAsync(this, Discord, options);


+ 1
- 1
src/Discord.Net.Rpc/Entities/Users/RpcVoiceState.cs View File

@@ -1,6 +1,6 @@
using System;
using System.Diagnostics;
using Model = Discord.API.Rpc.VoiceStateEvent;
using Model = Discord.API.Rpc.ExtendedVoiceState;

namespace Discord.Rpc
{


+ 0
- 1
src/Discord.Net.WebSocket/Entities/Channels/SocketChannel.cs View File

@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;


Loading…
Cancel
Save