Cleaned up WebSocket entities. Renamed CachedXXX -> SocketXXX.

This commit is contained in:
RogueException
2016-07-26 17:26:58 -03:00
parent 12c43cdf80
commit f0a6899bc7
35 changed files with 318 additions and 316 deletions

View File

@@ -1,6 +1,5 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq; using System.Linq;
namespace Discord.Commands namespace Discord.Commands

View File

@@ -49,7 +49,7 @@ namespace Discord.Audio
private uint _ssrc; private uint _ssrc;
private byte[] _secretKey; private byte[] _secretKey;
public CachedGuild Guild { get; } public SocketGuild Guild { get; }
public DiscordVoiceAPIClient ApiClient { get; private set; } public DiscordVoiceAPIClient ApiClient { get; private set; }
public ConnectionState ConnectionState { get; private set; } public ConnectionState ConnectionState { get; private set; }
public int Latency { get; private set; } public int Latency { get; private set; }
@@ -57,7 +57,7 @@ namespace Discord.Audio
private DiscordSocketClient Discord => Guild.Discord; private DiscordSocketClient Discord => Guild.Discord;
/// <summary> Creates a new REST/WebSocket discord client. </summary> /// <summary> Creates a new REST/WebSocket discord client. </summary>
public AudioClient(CachedGuild guild, int id) public AudioClient(SocketGuild guild, int id)
{ {
Guild = guild; Guild = guild;

View File

@@ -13,76 +13,76 @@ namespace Discord
private const double AverageUsersPerGuild = 47.78; //Source: Googie2149 private const double AverageUsersPerGuild = 47.78; //Source: Googie2149
private const double CollectionMultiplier = 1.05; //Add 5% buffer to handle growth private const double CollectionMultiplier = 1.05; //Add 5% buffer to handle growth
private readonly ConcurrentDictionary<ulong, ICachedChannel> _channels; private readonly ConcurrentDictionary<ulong, ISocketChannel> _channels;
private readonly ConcurrentDictionary<ulong, CachedDMChannel> _dmChannels; private readonly ConcurrentDictionary<ulong, SocketDMChannel> _dmChannels;
private readonly ConcurrentDictionary<ulong, CachedGuild> _guilds; private readonly ConcurrentDictionary<ulong, SocketGuild> _guilds;
private readonly ConcurrentDictionary<ulong, CachedGlobalUser> _users; private readonly ConcurrentDictionary<ulong, SocketGlobalUser> _users;
private readonly ConcurrentHashSet<ulong> _groupChannels; private readonly ConcurrentHashSet<ulong> _groupChannels;
internal IReadOnlyCollection<ICachedChannel> Channels => _channels.ToReadOnlyCollection(); internal IReadOnlyCollection<ISocketChannel> Channels => _channels.ToReadOnlyCollection();
internal IReadOnlyCollection<CachedDMChannel> DMChannels => _dmChannels.ToReadOnlyCollection(); internal IReadOnlyCollection<SocketDMChannel> DMChannels => _dmChannels.ToReadOnlyCollection();
internal IReadOnlyCollection<CachedGroupChannel> GroupChannels => _groupChannels.Select(x => GetChannel(x) as CachedGroupChannel).ToReadOnlyCollection(_groupChannels); internal IReadOnlyCollection<SocketGroupChannel> GroupChannels => _groupChannels.Select(x => GetChannel(x) as SocketGroupChannel).ToReadOnlyCollection(_groupChannels);
internal IReadOnlyCollection<CachedGuild> Guilds => _guilds.ToReadOnlyCollection(); internal IReadOnlyCollection<SocketGuild> Guilds => _guilds.ToReadOnlyCollection();
internal IReadOnlyCollection<CachedGlobalUser> Users => _users.ToReadOnlyCollection(); internal IReadOnlyCollection<SocketGlobalUser> Users => _users.ToReadOnlyCollection();
internal IReadOnlyCollection<ICachedPrivateChannel> PrivateChannels => internal IReadOnlyCollection<ISocketPrivateChannel> PrivateChannels =>
_dmChannels.Select(x => x.Value as ICachedPrivateChannel).Concat( _dmChannels.Select(x => x.Value as ISocketPrivateChannel).Concat(
_groupChannels.Select(x => GetChannel(x) as ICachedPrivateChannel)) _groupChannels.Select(x => GetChannel(x) as ISocketPrivateChannel))
.ToReadOnlyCollection(() => _dmChannels.Count + _groupChannels.Count); .ToReadOnlyCollection(() => _dmChannels.Count + _groupChannels.Count);
public DataStore(int guildCount, int dmChannelCount) public DataStore(int guildCount, int dmChannelCount)
{ {
double estimatedChannelCount = guildCount * AverageChannelsPerGuild + dmChannelCount; double estimatedChannelCount = guildCount * AverageChannelsPerGuild + dmChannelCount;
double estimatedUsersCount = guildCount * AverageUsersPerGuild; double estimatedUsersCount = guildCount * AverageUsersPerGuild;
_channels = new ConcurrentDictionary<ulong, ICachedChannel>(CollectionConcurrencyLevel, (int)(estimatedChannelCount * CollectionMultiplier)); _channels = new ConcurrentDictionary<ulong, ISocketChannel>(CollectionConcurrencyLevel, (int)(estimatedChannelCount * CollectionMultiplier));
_dmChannels = new ConcurrentDictionary<ulong, CachedDMChannel>(CollectionConcurrencyLevel, (int)(dmChannelCount * CollectionMultiplier)); _dmChannels = new ConcurrentDictionary<ulong, SocketDMChannel>(CollectionConcurrencyLevel, (int)(dmChannelCount * CollectionMultiplier));
_guilds = new ConcurrentDictionary<ulong, CachedGuild>(CollectionConcurrencyLevel, (int)(guildCount * CollectionMultiplier)); _guilds = new ConcurrentDictionary<ulong, SocketGuild>(CollectionConcurrencyLevel, (int)(guildCount * CollectionMultiplier));
_users = new ConcurrentDictionary<ulong, CachedGlobalUser>(CollectionConcurrencyLevel, (int)(estimatedUsersCount * CollectionMultiplier)); _users = new ConcurrentDictionary<ulong, SocketGlobalUser>(CollectionConcurrencyLevel, (int)(estimatedUsersCount * CollectionMultiplier));
_groupChannels = new ConcurrentHashSet<ulong>(CollectionConcurrencyLevel, (int)(10 * CollectionMultiplier)); _groupChannels = new ConcurrentHashSet<ulong>(CollectionConcurrencyLevel, (int)(10 * CollectionMultiplier));
} }
internal ICachedChannel GetChannel(ulong id) internal ISocketChannel GetChannel(ulong id)
{ {
ICachedChannel channel; ISocketChannel channel;
if (_channels.TryGetValue(id, out channel)) if (_channels.TryGetValue(id, out channel))
return channel; return channel;
return null; return null;
} }
internal CachedDMChannel GetDMChannel(ulong userId) internal SocketDMChannel GetDMChannel(ulong userId)
{ {
CachedDMChannel channel; SocketDMChannel channel;
if (_dmChannels.TryGetValue(userId, out channel)) if (_dmChannels.TryGetValue(userId, out channel))
return channel; return channel;
return null; return null;
} }
internal void AddChannel(ICachedChannel channel) internal void AddChannel(ISocketChannel channel)
{ {
_channels[channel.Id] = channel; _channels[channel.Id] = channel;
var dmChannel = channel as CachedDMChannel; var dmChannel = channel as SocketDMChannel;
if (dmChannel != null) if (dmChannel != null)
_dmChannels[dmChannel.Recipient.Id] = dmChannel; _dmChannels[dmChannel.Recipient.Id] = dmChannel;
else else
{ {
var groupChannel = channel as CachedGroupChannel; var groupChannel = channel as SocketGroupChannel;
if (groupChannel != null) if (groupChannel != null)
_groupChannels.TryAdd(groupChannel.Id); _groupChannels.TryAdd(groupChannel.Id);
} }
} }
internal ICachedChannel RemoveChannel(ulong id) internal ISocketChannel RemoveChannel(ulong id)
{ {
ICachedChannel channel; ISocketChannel channel;
if (_channels.TryRemove(id, out channel)) if (_channels.TryRemove(id, out channel))
{ {
var dmChannel = channel as CachedDMChannel; var dmChannel = channel as SocketDMChannel;
if (dmChannel != null) if (dmChannel != null)
{ {
CachedDMChannel ignored; SocketDMChannel ignored;
_dmChannels.TryRemove(dmChannel.Recipient.Id, out ignored); _dmChannels.TryRemove(dmChannel.Recipient.Id, out ignored);
} }
else else
{ {
var groupChannel = channel as CachedGroupChannel; var groupChannel = channel as SocketGroupChannel;
if (groupChannel != null) if (groupChannel != null)
_groupChannels.TryRemove(id); _groupChannels.TryRemove(id);
} }
@@ -91,39 +91,39 @@ namespace Discord
return null; return null;
} }
internal CachedGuild GetGuild(ulong id) internal SocketGuild GetGuild(ulong id)
{ {
CachedGuild guild; SocketGuild guild;
if (_guilds.TryGetValue(id, out guild)) if (_guilds.TryGetValue(id, out guild))
return guild; return guild;
return null; return null;
} }
internal void AddGuild(CachedGuild guild) internal void AddGuild(SocketGuild guild)
{ {
_guilds[guild.Id] = guild; _guilds[guild.Id] = guild;
} }
internal CachedGuild RemoveGuild(ulong id) internal SocketGuild RemoveGuild(ulong id)
{ {
CachedGuild guild; SocketGuild guild;
if (_guilds.TryRemove(id, out guild)) if (_guilds.TryRemove(id, out guild))
return guild; return guild;
return null; return null;
} }
internal CachedGlobalUser GetUser(ulong id) internal SocketGlobalUser GetUser(ulong id)
{ {
CachedGlobalUser user; SocketGlobalUser user;
if (_users.TryGetValue(id, out user)) if (_users.TryGetValue(id, out user))
return user; return user;
return null; return null;
} }
internal CachedGlobalUser GetOrAddUser(ulong id, Func<ulong, CachedGlobalUser> userFactory) internal SocketGlobalUser GetOrAddUser(ulong id, Func<ulong, SocketGlobalUser> userFactory)
{ {
return _users.GetOrAdd(id, userFactory); return _users.GetOrAdd(id, userFactory);
} }
internal CachedGlobalUser RemoveUser(ulong id) internal SocketGlobalUser RemoveUser(ulong id)
{ {
CachedGlobalUser user; SocketGlobalUser user;
if (_users.TryRemove(id, out user)) if (_users.TryRemove(id, out user))
return user; return user;
return null; return null;

View File

@@ -10,7 +10,6 @@ using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Collections.Concurrent;
namespace Discord namespace Discord
{ {

View File

@@ -44,7 +44,7 @@ namespace Discord
/// <summary> Gets the estimated round-trip latency, in milliseconds, to the gateway server. </summary> /// <summary> Gets the estimated round-trip latency, in milliseconds, to the gateway server. </summary>
public int Latency { get; private set; } public int Latency { get; private set; }
//From DiscordConfig //From DiscordSocketConfig
internal int TotalShards { get; private set; } internal int TotalShards { get; private set; }
internal int ConnectionTimeout { get; private set; } internal int ConnectionTimeout { get; private set; }
internal int ReconnectDelay { get; private set; } internal int ReconnectDelay { get; private set; }
@@ -55,8 +55,8 @@ namespace Discord
internal DataStore DataStore { get; private set; } internal DataStore DataStore { get; private set; }
internal WebSocketProvider WebSocketProvider { get; private set; } internal WebSocketProvider WebSocketProvider { get; private set; }
internal CachedSelfUser CurrentUser => _currentUser as CachedSelfUser; internal SocketSelfUser CurrentUser => _currentUser as SocketSelfUser;
internal IReadOnlyCollection<CachedGuild> Guilds => DataStore.Guilds; internal IReadOnlyCollection<SocketGuild> Guilds => DataStore.Guilds;
internal IReadOnlyCollection<VoiceRegion> VoiceRegions => _voiceRegions.ToReadOnlyCollection(); internal IReadOnlyCollection<VoiceRegion> VoiceRegions => _voiceRegions.ToReadOnlyCollection();
/// <summary> Creates a new REST/WebSocket discord client. </summary> /// <summary> Creates a new REST/WebSocket discord client. </summary>
@@ -340,15 +340,15 @@ namespace Discord
{ {
return Task.FromResult<IReadOnlyCollection<IGuild>>(Guilds); return Task.FromResult<IReadOnlyCollection<IGuild>>(Guilds);
} }
internal CachedGuild AddGuild(ExtendedGuild model, DataStore dataStore) internal SocketGuild AddGuild(ExtendedGuild model, DataStore dataStore)
{ {
var guild = new CachedGuild(this, model, dataStore); var guild = new SocketGuild(this, model, dataStore);
dataStore.AddGuild(guild); dataStore.AddGuild(guild);
if (model.Large) if (model.Large)
_largeGuilds.Enqueue(model.Id); _largeGuilds.Enqueue(model.Id);
return guild; return guild;
} }
internal CachedGuild RemoveGuild(ulong id) internal SocketGuild RemoveGuild(ulong id)
{ {
var guild = DataStore.RemoveGuild(id); var guild = DataStore.RemoveGuild(id);
foreach (var channel in guild.Channels) foreach (var channel in guild.Channels)
@@ -367,7 +367,7 @@ namespace Discord
{ {
return Task.FromResult<IReadOnlyCollection<IPrivateChannel>>(DataStore.PrivateChannels); return Task.FromResult<IReadOnlyCollection<IPrivateChannel>>(DataStore.PrivateChannels);
} }
internal ICachedChannel AddPrivateChannel(API.Channel model, DataStore dataStore) internal ISocketChannel AddPrivateChannel(API.Channel model, DataStore dataStore)
{ {
switch (model.Type) switch (model.Type)
{ {
@@ -375,13 +375,13 @@ namespace Discord
{ {
var recipients = model.Recipients.Value; var recipients = model.Recipients.Value;
var user = GetOrAddUser(recipients[0], dataStore); var user = GetOrAddUser(recipients[0], dataStore);
var channel = new CachedDMChannel(this, new CachedDMUser(user), model); var channel = new SocketDMChannel(this, new SocketDMUser(user), model);
dataStore.AddChannel(channel); dataStore.AddChannel(channel);
return channel; return channel;
} }
case ChannelType.Group: case ChannelType.Group:
{ {
var channel = new CachedGroupChannel(this, model); var channel = new SocketGroupChannel(this, model);
channel.UpdateUsers(model.Recipients.Value, UpdateSource.Creation, dataStore); channel.UpdateUsers(model.Recipients.Value, UpdateSource.Creation, dataStore);
dataStore.AddChannel(channel); dataStore.AddChannel(channel);
return channel; return channel;
@@ -390,9 +390,9 @@ namespace Discord
throw new InvalidOperationException($"Unexpected channel type: {model.Type}"); throw new InvalidOperationException($"Unexpected channel type: {model.Type}");
} }
} }
internal ICachedChannel RemovePrivateChannel(ulong id) internal ISocketChannel RemovePrivateChannel(ulong id)
{ {
var channel = DataStore.RemoveChannel(id) as ICachedPrivateChannel; var channel = DataStore.RemoveChannel(id) as ISocketPrivateChannel;
foreach (var recipient in channel.Recipients) foreach (var recipient in channel.Recipients)
recipient.User.RemoveRef(this); recipient.User.RemoveRef(this);
return channel; return channel;
@@ -413,13 +413,13 @@ namespace Discord
{ {
return Task.FromResult<ISelfUser>(_currentUser); return Task.FromResult<ISelfUser>(_currentUser);
} }
internal CachedGlobalUser GetOrAddUser(API.User model, DataStore dataStore) internal SocketGlobalUser GetOrAddUser(API.User model, DataStore dataStore)
{ {
var user = dataStore.GetOrAddUser(model.Id, _ => new CachedGlobalUser(model)); var user = dataStore.GetOrAddUser(model.Id, _ => new SocketGlobalUser(model));
user.AddRef(); user.AddRef();
return user; return user;
} }
internal CachedGlobalUser RemoveUser(ulong id) internal SocketGlobalUser RemoveUser(ulong id)
{ {
return DataStore.RemoveUser(id); return DataStore.RemoveUser(id);
} }
@@ -429,10 +429,10 @@ namespace Discord
=> DownloadUsersAsync(DataStore.Guilds.Where(x => !x.HasAllMembers)); => DownloadUsersAsync(DataStore.Guilds.Where(x => !x.HasAllMembers));
/// <summary> Downloads the users list for the provided guilds, if they don't have a complete list. </summary> /// <summary> Downloads the users list for the provided guilds, if they don't have a complete list. </summary>
public Task DownloadUsersAsync(IEnumerable<IGuild> guilds) public Task DownloadUsersAsync(IEnumerable<IGuild> guilds)
=> DownloadUsersAsync(guilds.Select(x => x as CachedGuild).Where(x => x != null)); => DownloadUsersAsync(guilds.Select(x => x as SocketGuild).Where(x => x != null));
public Task DownloadUsersAsync(params IGuild[] guilds) public Task DownloadUsersAsync(params IGuild[] guilds)
=> DownloadUsersAsync(guilds.Select(x => x as CachedGuild).Where(x => x != null)); => DownloadUsersAsync(guilds.Select(x => x as SocketGuild).Where(x => x != null));
private async Task DownloadUsersAsync(IEnumerable<CachedGuild> guilds) private async Task DownloadUsersAsync(IEnumerable<SocketGuild> guilds)
{ {
var cachedGuilds = guilds.ToArray(); var cachedGuilds = guilds.ToArray();
if (cachedGuilds.Length == 0) return; if (cachedGuilds.Length == 0) return;
@@ -559,7 +559,7 @@ namespace Discord
var data = (payload as JToken).ToObject<ReadyEvent>(_serializer); var data = (payload as JToken).ToObject<ReadyEvent>(_serializer);
var dataStore = new DataStore(data.Guilds.Length, data.PrivateChannels.Length); var dataStore = new DataStore(data.Guilds.Length, data.PrivateChannels.Length);
var currentUser = new CachedSelfUser(this, data.User); var currentUser = new SocketSelfUser(this, data.User);
int unavailableGuilds = 0; int unavailableGuilds = 0;
for (int i = 0; i < data.Guilds.Length; i++) for (int i = 0; i < data.Guilds.Length; i++)
{ {
@@ -625,7 +625,7 @@ namespace Discord
} }
await _gatewayLogger.DebugAsync($"Received Dispatch ({type})").ConfigureAwait(false); await _gatewayLogger.DebugAsync($"Received Dispatch ({type})").ConfigureAwait(false);
CachedGuild guild; SocketGuild guild;
if (data.Unavailable != false) if (data.Unavailable != false)
{ {
guild = AddGuild(data, DataStore); guild = AddGuild(data, DataStore);
@@ -751,7 +751,7 @@ namespace Discord
await _gatewayLogger.DebugAsync("Received Dispatch (CHANNEL_CREATE)").ConfigureAwait(false); await _gatewayLogger.DebugAsync("Received Dispatch (CHANNEL_CREATE)").ConfigureAwait(false);
var data = (payload as JToken).ToObject<API.Channel>(_serializer); var data = (payload as JToken).ToObject<API.Channel>(_serializer);
ICachedChannel channel = null; ISocketChannel channel = null;
if (data.GuildId.IsSpecified) if (data.GuildId.IsSpecified)
{ {
var guild = DataStore.GetGuild(data.GuildId.Value); var guild = DataStore.GetGuild(data.GuildId.Value);
@@ -789,7 +789,7 @@ namespace Discord
var before = channel.Clone(); var before = channel.Clone();
channel.Update(data, UpdateSource.WebSocket); channel.Update(data, UpdateSource.WebSocket);
if (!((channel as ICachedGuildChannel)?.Guild.IsSynced ?? true)) if (!((channel as ISocketGuildChannel)?.Guild.IsSynced ?? true))
{ {
await _gatewayLogger.DebugAsync("Ignored CHANNEL_UPDATE, guild is not synced yet.").ConfigureAwait(false); await _gatewayLogger.DebugAsync("Ignored CHANNEL_UPDATE, guild is not synced yet.").ConfigureAwait(false);
return; return;
@@ -808,7 +808,7 @@ namespace Discord
{ {
await _gatewayLogger.DebugAsync("Received Dispatch (CHANNEL_DELETE)").ConfigureAwait(false); await _gatewayLogger.DebugAsync("Received Dispatch (CHANNEL_DELETE)").ConfigureAwait(false);
ICachedChannel channel = null; ISocketChannel channel = null;
var data = (payload as JToken).ToObject<API.Channel>(_serializer); var data = (payload as JToken).ToObject<API.Channel>(_serializer);
if (data.GuildId.IsSpecified) if (data.GuildId.IsSpecified)
{ {
@@ -978,7 +978,7 @@ namespace Discord
await _gatewayLogger.DebugAsync("Received Dispatch (CHANNEL_RECIPIENT_ADD)").ConfigureAwait(false); await _gatewayLogger.DebugAsync("Received Dispatch (CHANNEL_RECIPIENT_ADD)").ConfigureAwait(false);
var data = (payload as JToken).ToObject<RecipientEvent>(_serializer); var data = (payload as JToken).ToObject<RecipientEvent>(_serializer);
var channel = DataStore.GetChannel(data.ChannelId) as CachedGroupChannel; var channel = DataStore.GetChannel(data.ChannelId) as SocketGroupChannel;
if (channel != null) if (channel != null)
{ {
var user = channel.AddUser(data.User, DataStore); var user = channel.AddUser(data.User, DataStore);
@@ -996,7 +996,7 @@ namespace Discord
await _gatewayLogger.DebugAsync("Received Dispatch (CHANNEL_RECIPIENT_REMOVE)").ConfigureAwait(false); await _gatewayLogger.DebugAsync("Received Dispatch (CHANNEL_RECIPIENT_REMOVE)").ConfigureAwait(false);
var data = (payload as JToken).ToObject<RecipientEvent>(_serializer); var data = (payload as JToken).ToObject<RecipientEvent>(_serializer);
var channel = DataStore.GetChannel(data.ChannelId) as CachedGroupChannel; var channel = DataStore.GetChannel(data.ChannelId) as SocketGroupChannel;
if (channel != null) if (channel != null)
{ {
var user = channel.RemoveUser(data.User.Id); var user = channel.RemoveUser(data.User.Id);
@@ -1166,10 +1166,10 @@ namespace Discord
await _gatewayLogger.DebugAsync("Received Dispatch (MESSAGE_CREATE)").ConfigureAwait(false); await _gatewayLogger.DebugAsync("Received Dispatch (MESSAGE_CREATE)").ConfigureAwait(false);
var data = (payload as JToken).ToObject<API.Message>(_serializer); var data = (payload as JToken).ToObject<API.Message>(_serializer);
var channel = DataStore.GetChannel(data.ChannelId) as ICachedMessageChannel; var channel = DataStore.GetChannel(data.ChannelId) as ISocketMessageChannel;
if (channel != null) if (channel != null)
{ {
if (!((channel as ICachedGuildChannel)?.Guild.IsSynced ?? true)) if (!((channel as ISocketGuildChannel)?.Guild.IsSynced ?? true))
{ {
await _gatewayLogger.DebugAsync("Ignored MESSAGE_CREATE, guild is not synced yet.").ConfigureAwait(false); await _gatewayLogger.DebugAsync("Ignored MESSAGE_CREATE, guild is not synced yet.").ConfigureAwait(false);
return; return;
@@ -1200,17 +1200,17 @@ namespace Discord
await _gatewayLogger.DebugAsync("Received Dispatch (MESSAGE_UPDATE)").ConfigureAwait(false); await _gatewayLogger.DebugAsync("Received Dispatch (MESSAGE_UPDATE)").ConfigureAwait(false);
var data = (payload as JToken).ToObject<API.Message>(_serializer); var data = (payload as JToken).ToObject<API.Message>(_serializer);
var channel = DataStore.GetChannel(data.ChannelId) as ICachedMessageChannel; var channel = DataStore.GetChannel(data.ChannelId) as ISocketMessageChannel;
if (channel != null) if (channel != null)
{ {
if (!((channel as ICachedGuildChannel)?.Guild.IsSynced ?? true)) if (!((channel as ISocketGuildChannel)?.Guild.IsSynced ?? true))
{ {
await _gatewayLogger.DebugAsync("Ignored MESSAGE_UPDATE, guild is not synced yet.").ConfigureAwait(false); await _gatewayLogger.DebugAsync("Ignored MESSAGE_UPDATE, guild is not synced yet.").ConfigureAwait(false);
return; return;
} }
IMessage before = null, after = null; IMessage before = null, after = null;
CachedMessage cachedMsg = channel.GetMessage(data.Id); SocketMessage cachedMsg = channel.GetMessage(data.Id);
if (cachedMsg != null) if (cachedMsg != null)
{ {
before = cachedMsg.Clone(); before = cachedMsg.Clone();
@@ -1239,10 +1239,10 @@ namespace Discord
await _gatewayLogger.DebugAsync("Received Dispatch (MESSAGE_DELETE)").ConfigureAwait(false); await _gatewayLogger.DebugAsync("Received Dispatch (MESSAGE_DELETE)").ConfigureAwait(false);
var data = (payload as JToken).ToObject<API.Message>(_serializer); var data = (payload as JToken).ToObject<API.Message>(_serializer);
var channel = DataStore.GetChannel(data.ChannelId) as ICachedMessageChannel; var channel = DataStore.GetChannel(data.ChannelId) as ISocketMessageChannel;
if (channel != null) if (channel != null)
{ {
if (!((channel as ICachedGuildChannel)?.Guild.IsSynced ?? true)) if (!((channel as ISocketGuildChannel)?.Guild.IsSynced ?? true))
{ {
await _gatewayLogger.DebugAsync("Ignored MESSAGE_DELETE, guild is not synced yet.").ConfigureAwait(false); await _gatewayLogger.DebugAsync("Ignored MESSAGE_DELETE, guild is not synced yet.").ConfigureAwait(false);
return; return;
@@ -1266,10 +1266,10 @@ namespace Discord
await _gatewayLogger.DebugAsync("Received Dispatch (MESSAGE_DELETE_BULK)").ConfigureAwait(false); await _gatewayLogger.DebugAsync("Received Dispatch (MESSAGE_DELETE_BULK)").ConfigureAwait(false);
var data = (payload as JToken).ToObject<MessageDeleteBulkEvent>(_serializer); var data = (payload as JToken).ToObject<MessageDeleteBulkEvent>(_serializer);
var channel = DataStore.GetChannel(data.ChannelId) as ICachedMessageChannel; var channel = DataStore.GetChannel(data.ChannelId) as ISocketMessageChannel;
if (channel != null) if (channel != null)
{ {
if (!((channel as ICachedGuildChannel)?.Guild.IsSynced ?? true)) if (!((channel as ISocketGuildChannel)?.Guild.IsSynced ?? true))
{ {
await _gatewayLogger.DebugAsync("Ignored MESSAGE_DELETE_BULK, guild is not synced yet.").ConfigureAwait(false); await _gatewayLogger.DebugAsync("Ignored MESSAGE_DELETE_BULK, guild is not synced yet.").ConfigureAwait(false);
return; return;
@@ -1341,10 +1341,10 @@ namespace Discord
await _gatewayLogger.DebugAsync("Received Dispatch (TYPING_START)").ConfigureAwait(false); await _gatewayLogger.DebugAsync("Received Dispatch (TYPING_START)").ConfigureAwait(false);
var data = (payload as JToken).ToObject<TypingStartEvent>(_serializer); var data = (payload as JToken).ToObject<TypingStartEvent>(_serializer);
var channel = DataStore.GetChannel(data.ChannelId) as ICachedMessageChannel; var channel = DataStore.GetChannel(data.ChannelId) as ISocketMessageChannel;
if (channel != null) if (channel != null)
{ {
if (!((channel as ICachedGuildChannel)?.Guild.IsSynced ?? true)) if (!((channel as ISocketGuildChannel)?.Guild.IsSynced ?? true))
{ {
await _gatewayLogger.DebugAsync("Ignored TYPING_START, guild is not synced yet.").ConfigureAwait(false); await _gatewayLogger.DebugAsync("Ignored TYPING_START, guild is not synced yet.").ConfigureAwait(false);
return; return;
@@ -1385,7 +1385,7 @@ namespace Discord
var data = (payload as JToken).ToObject<API.VoiceState>(_serializer); var data = (payload as JToken).ToObject<API.VoiceState>(_serializer);
if (data.GuildId.HasValue) if (data.GuildId.HasValue)
{ {
ICachedUser user; ISocketUser user;
VoiceState before, after; VoiceState before, after;
if (data.GuildId != null) if (data.GuildId != null)
{ {
@@ -1418,7 +1418,7 @@ namespace Discord
} }
else else
{ {
var groupChannel = DataStore.GetChannel(data.ChannelId.Value) as CachedGroupChannel; var groupChannel = DataStore.GetChannel(data.ChannelId.Value) as SocketGroupChannel;
if (groupChannel != null) if (groupChannel != null)
{ {
if (data.ChannelId != null) if (data.ChannelId != null)

View File

@@ -24,8 +24,7 @@ namespace Discord
/// <summary> Gets a collection of messages in this channel. </summary> /// <summary> Gets a collection of messages in this channel. </summary>
Task<IReadOnlyCollection<IMessage>> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch); Task<IReadOnlyCollection<IMessage>> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch);
/// <summary> Bulk deletes multiple messages. </summary> /// <summary> Bulk deletes multiple messages. </summary>
Task DeleteMessagesAsync(IEnumerable<IMessage> messages); Task DeleteMessagesAsync(IEnumerable<IMessage> messages);
/// <summary> Broadcasts the "user is typing" message to all users in this channel, lasting 10 seconds.</summary> /// <summary> Broadcasts the "user is typing" message to all users in this channel, lasting 10 seconds.</summary>
Task TriggerTypingAsync(); Task TriggerTypingAsync();

View File

@@ -6,7 +6,8 @@
public abstract DiscordClient Discord { get; } public abstract DiscordClient Discord { get; }
bool IEntity<T>.IsAttached => false; internal virtual bool IsAttached => false;
bool IEntity<T>.IsAttached => IsAttached;
public Entity(T id) public Entity(T id)
{ {

View File

@@ -6,6 +6,9 @@ namespace Discord
{ {
internal class GroupUser : IGroupUser internal class GroupUser : IGroupUser
{ {
internal virtual bool IsAttached => false;
bool IEntity<ulong>.IsAttached => IsAttached;
public GroupChannel Channel { get; private set; } public GroupChannel Channel { get; private set; }
public User User { get; private set; } public User User { get; private set; }
@@ -14,7 +17,6 @@ namespace Discord
public DateTimeOffset CreatedAt => User.CreatedAt; public DateTimeOffset CreatedAt => User.CreatedAt;
public string Discriminator => User.Discriminator; public string Discriminator => User.Discriminator;
public ushort DiscriminatorValue => User.DiscriminatorValue; public ushort DiscriminatorValue => User.DiscriminatorValue;
public bool IsAttached => User.IsAttached;
public bool IsBot => User.IsBot; public bool IsBot => User.IsBot;
public string Username => User.Username; public string Username => User.Username;
public string Mention => MentionUtils.Mention(this, false); public string Mention => MentionUtils.Mention(this, false);

View File

@@ -13,6 +13,9 @@ namespace Discord
[DebuggerDisplay("{DebuggerDisplay,nq}")] [DebuggerDisplay("{DebuggerDisplay,nq}")]
internal class GuildUser : IGuildUser, ISnowflakeEntity internal class GuildUser : IGuildUser, ISnowflakeEntity
{ {
internal virtual bool IsAttached => false;
bool IEntity<ulong>.IsAttached => IsAttached;
private long? _joinedAtTicks; private long? _joinedAtTicks;
public string Nickname { get; private set; } public string Nickname { get; private set; }
@@ -27,7 +30,6 @@ namespace Discord
public DateTimeOffset CreatedAt => User.CreatedAt; public DateTimeOffset CreatedAt => User.CreatedAt;
public string Discriminator => User.Discriminator; public string Discriminator => User.Discriminator;
public ushort DiscriminatorValue => User.DiscriminatorValue; public ushort DiscriminatorValue => User.DiscriminatorValue;
public bool IsAttached => User.IsAttached;
public bool IsBot => User.IsBot; public bool IsBot => User.IsBot;
public string Mention => MentionUtils.Mention(this, Nickname != null); public string Mention => MentionUtils.Mention(this, Nickname != null);
public string Username => User.Username; public string Username => User.Username;

View File

@@ -1,19 +0,0 @@
using Model = Discord.API.Message;
namespace Discord
{
internal class CachedMessage : Message
{
bool IEntity<ulong>.IsAttached => true;
public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient;
public new ICachedMessageChannel Channel => base.Channel as ICachedMessageChannel;
public CachedMessage(ICachedMessageChannel channel, IUser author, Model model)
: base(channel, author, model)
{
}
public CachedMessage Clone() => MemberwiseClone() as CachedMessage;
}
}

View File

@@ -1,21 +0,0 @@
using System;
using Model = Discord.API.User;
namespace Discord
{
internal class CachedSelfUser : SelfUser, ICachedUser
{
bool IEntity<ulong>.IsAttached => true;
public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient;
CachedGlobalUser ICachedUser.User { get { throw new NotSupportedException(); } }
public CachedSelfUser(DiscordSocketClient discord, Model model)
: base(discord, model)
{
}
public CachedSelfUser Clone() => MemberwiseClone() as CachedSelfUser;
ICachedUser ICachedUser.Clone() => Clone();
}
}

View File

@@ -2,10 +2,10 @@
namespace Discord namespace Discord
{ {
internal interface ICachedChannel : IChannel, ICachedEntity<ulong> internal interface ISocketChannel : IChannel
{ {
void Update(Model model, UpdateSource source); void Update(Model model, UpdateSource source);
ICachedChannel Clone(); ISocketChannel Clone();
} }
} }

View File

@@ -0,0 +1,7 @@
namespace Discord
{
internal interface ISocketGuildChannel : ISocketChannel, IGuildChannel
{
new SocketGuild Guild { get; }
}
}

View File

@@ -0,0 +1,16 @@
using System.Collections.Generic;
using MessageModel = Discord.API.Message;
namespace Discord
{
internal interface ISocketMessageChannel : ISocketChannel, IMessageChannel
{
IReadOnlyCollection<ISocketUser> Users { get; }
SocketMessage AddMessage(ISocketUser author, MessageModel model);
SocketMessage GetMessage(ulong id);
SocketMessage RemoveMessage(ulong id);
ISocketUser GetUser(ulong id, bool skipCheck = false);
}
}

View File

@@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace Discord
{
internal interface ISocketPrivateChannel : ISocketChannel, IPrivateChannel
{
new IReadOnlyCollection<ISocketUser> Recipients { get; }
}
}

View File

@@ -10,51 +10,51 @@ namespace Discord
{ {
internal class MessageCache : MessageManager internal class MessageCache : MessageManager
{ {
private readonly ConcurrentDictionary<ulong, CachedMessage> _messages; private readonly ConcurrentDictionary<ulong, SocketMessage> _messages;
private readonly ConcurrentQueue<ulong> _orderedMessages; private readonly ConcurrentQueue<ulong> _orderedMessages;
private readonly int _size; private readonly int _size;
public override IReadOnlyCollection<CachedMessage> Messages => _messages.ToReadOnlyCollection(); public override IReadOnlyCollection<SocketMessage> Messages => _messages.ToReadOnlyCollection();
public MessageCache(DiscordSocketClient discord, ICachedMessageChannel channel) public MessageCache(DiscordSocketClient discord, ISocketMessageChannel channel)
: base(discord, channel) : base(discord, channel)
{ {
_size = discord.MessageCacheSize; _size = discord.MessageCacheSize;
_messages = new ConcurrentDictionary<ulong, CachedMessage>(1, (int)(_size * 1.05)); _messages = new ConcurrentDictionary<ulong, SocketMessage>(1, (int)(_size * 1.05));
_orderedMessages = new ConcurrentQueue<ulong>(); _orderedMessages = new ConcurrentQueue<ulong>();
} }
public override void Add(CachedMessage message) public override void Add(SocketMessage message)
{ {
if (_messages.TryAdd(message.Id, message)) if (_messages.TryAdd(message.Id, message))
{ {
_orderedMessages.Enqueue(message.Id); _orderedMessages.Enqueue(message.Id);
ulong msgId; ulong msgId;
CachedMessage msg; SocketMessage msg;
while (_orderedMessages.Count > _size && _orderedMessages.TryDequeue(out msgId)) while (_orderedMessages.Count > _size && _orderedMessages.TryDequeue(out msgId))
_messages.TryRemove(msgId, out msg); _messages.TryRemove(msgId, out msg);
} }
} }
public override CachedMessage Remove(ulong id) public override SocketMessage Remove(ulong id)
{ {
CachedMessage msg; SocketMessage msg;
_messages.TryRemove(id, out msg); _messages.TryRemove(id, out msg);
return msg; return msg;
} }
public override CachedMessage Get(ulong id) public override SocketMessage Get(ulong id)
{ {
CachedMessage result; SocketMessage result;
if (_messages.TryGetValue(id, out result)) if (_messages.TryGetValue(id, out result))
return result; return result;
return null; return null;
} }
public override IImmutableList<CachedMessage> GetMany(ulong? fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch) public override IImmutableList<SocketMessage> GetMany(ulong? fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch)
{ {
if (limit < 0) throw new ArgumentOutOfRangeException(nameof(limit)); if (limit < 0) throw new ArgumentOutOfRangeException(nameof(limit));
if (limit == 0) return ImmutableArray<CachedMessage>.Empty; if (limit == 0) return ImmutableArray<SocketMessage>.Empty;
IEnumerable<ulong> cachedMessageIds; IEnumerable<ulong> cachedMessageIds;
if (fromMessageId == null) if (fromMessageId == null)
@@ -68,7 +68,7 @@ namespace Discord
.Take(limit) .Take(limit)
.Select(x => .Select(x =>
{ {
CachedMessage msg; SocketMessage msg;
if (_messages.TryGetValue(x, out msg)) if (_messages.TryGetValue(x, out msg))
return msg; return msg;
return null; return null;
@@ -77,7 +77,7 @@ namespace Discord
.ToImmutableArray(); .ToImmutableArray();
} }
public override async Task<CachedMessage> DownloadAsync(ulong id) public override async Task<SocketMessage> DownloadAsync(ulong id)
{ {
var msg = Get(id); var msg = Get(id);
if (msg != null) if (msg != null)

View File

@@ -10,36 +10,36 @@ namespace Discord
internal class MessageManager internal class MessageManager
{ {
private readonly DiscordSocketClient _discord; private readonly DiscordSocketClient _discord;
private readonly ICachedMessageChannel _channel; private readonly ISocketMessageChannel _channel;
public virtual IReadOnlyCollection<CachedMessage> Messages public virtual IReadOnlyCollection<SocketMessage> Messages
=> ImmutableArray.Create<CachedMessage>(); => ImmutableArray.Create<SocketMessage>();
public MessageManager(DiscordSocketClient discord, ICachedMessageChannel channel) public MessageManager(DiscordSocketClient discord, ISocketMessageChannel channel)
{ {
_discord = discord; _discord = discord;
_channel = channel; _channel = channel;
} }
public virtual void Add(CachedMessage message) { } public virtual void Add(SocketMessage message) { }
public virtual CachedMessage Remove(ulong id) => null; public virtual SocketMessage Remove(ulong id) => null;
public virtual CachedMessage Get(ulong id) => null; public virtual SocketMessage Get(ulong id) => null;
public virtual IImmutableList<CachedMessage> GetMany(ulong? fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch) public virtual IImmutableList<SocketMessage> GetMany(ulong? fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch)
=> ImmutableArray.Create<CachedMessage>(); => ImmutableArray.Create<SocketMessage>();
public virtual async Task<CachedMessage> DownloadAsync(ulong id) public virtual async Task<SocketMessage> DownloadAsync(ulong id)
{ {
var model = await _discord.ApiClient.GetChannelMessageAsync(_channel.Id, id).ConfigureAwait(false); var model = await _discord.ApiClient.GetChannelMessageAsync(_channel.Id, id).ConfigureAwait(false);
if (model != null) if (model != null)
return new CachedMessage(_channel, new User(model.Author.Value), model); return new SocketMessage(_channel, new User(model.Author.Value), model);
return null; return null;
} }
public async Task<IReadOnlyCollection<CachedMessage>> DownloadAsync(ulong? fromId, Direction dir, int limit) public async Task<IReadOnlyCollection<SocketMessage>> DownloadAsync(ulong? fromId, Direction dir, int limit)
{ {
//TODO: Test heavily, especially the ordering of messages //TODO: Test heavily, especially the ordering of messages
if (limit < 0) throw new ArgumentOutOfRangeException(nameof(limit)); if (limit < 0) throw new ArgumentOutOfRangeException(nameof(limit));
if (limit == 0) return ImmutableArray<CachedMessage>.Empty; if (limit == 0) return ImmutableArray<SocketMessage>.Empty;
var cachedMessages = GetMany(fromId, dir, limit); var cachedMessages = GetMany(fromId, dir, limit);
if (cachedMessages.Count == limit) if (cachedMessages.Count == limit)
@@ -61,7 +61,7 @@ namespace Discord
}; };
var downloadedMessages = await _discord.ApiClient.GetChannelMessagesAsync(_channel.Id, args).ConfigureAwait(false); var downloadedMessages = await _discord.ApiClient.GetChannelMessagesAsync(_channel.Id, args).ConfigureAwait(false);
var guild = (_channel as ICachedGuildChannel)?.Guild; var guild = (_channel as ISocketGuildChannel)?.Guild;
return cachedMessages.Concat(downloadedMessages.Select(x => return cachedMessages.Concat(downloadedMessages.Select(x =>
{ {
IUser user = _channel.GetUser(x.Author.Value.Id, true); IUser user = _channel.GetUser(x.Author.Value.Id, true);
@@ -73,7 +73,7 @@ namespace Discord
else else
user = newUser; user = newUser;
} }
return new CachedMessage(_channel, user, x); return new SocketMessage(_channel, user, x);
})).ToImmutableArray(); })).ToImmutableArray();
} }
} }

View File

@@ -6,18 +6,18 @@ using Model = Discord.API.Channel;
namespace Discord namespace Discord
{ {
internal class CachedDMChannel : DMChannel, IDMChannel, ICachedChannel, ICachedMessageChannel, ICachedPrivateChannel internal class SocketDMChannel : DMChannel, IDMChannel, ISocketChannel, ISocketMessageChannel, ISocketPrivateChannel
{ {
bool IEntity<ulong>.IsAttached => true; internal override bool IsAttached => true;
private readonly MessageManager _messages; private readonly MessageManager _messages;
public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient; public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient;
public new CachedDMUser Recipient => base.Recipient as CachedDMUser; public new SocketDMUser Recipient => base.Recipient as SocketDMUser;
public IReadOnlyCollection<ICachedUser> Members => ImmutableArray.Create<ICachedUser>(Discord.CurrentUser, Recipient); public IReadOnlyCollection<ISocketUser> Users => ImmutableArray.Create<ISocketUser>(Discord.CurrentUser, Recipient);
IReadOnlyCollection<ICachedUser> ICachedPrivateChannel.Recipients => ImmutableArray.Create(Recipient); IReadOnlyCollection<ISocketUser> ISocketPrivateChannel.Recipients => ImmutableArray.Create(Recipient);
public CachedDMChannel(DiscordSocketClient discord, CachedDMUser recipient, Model model) public SocketDMChannel(DiscordSocketClient discord, SocketDMUser recipient, Model model)
: base(discord, recipient, model) : base(discord, recipient, model)
{ {
if (Discord.MessageCacheSize > 0) if (Discord.MessageCacheSize > 0)
@@ -27,8 +27,8 @@ namespace Discord
} }
public override Task<IUser> GetUserAsync(ulong id) => Task.FromResult<IUser>(GetUser(id)); public override Task<IUser> GetUserAsync(ulong id) => Task.FromResult<IUser>(GetUser(id));
public override Task<IReadOnlyCollection<IUser>> GetUsersAsync() => Task.FromResult<IReadOnlyCollection<IUser>>(Members); public override Task<IReadOnlyCollection<IUser>> GetUsersAsync() => Task.FromResult<IReadOnlyCollection<IUser>>(Users);
public ICachedUser GetUser(ulong id) public ISocketUser GetUser(ulong id)
{ {
var currentUser = Discord.CurrentUser; var currentUser = Discord.CurrentUser;
if (id == Recipient.Id) if (id == Recipient.Id)
@@ -51,25 +51,25 @@ namespace Discord
{ {
return await _messages.DownloadAsync(fromMessageId, dir, limit).ConfigureAwait(false); return await _messages.DownloadAsync(fromMessageId, dir, limit).ConfigureAwait(false);
} }
public CachedMessage AddMessage(ICachedUser author, MessageModel model) public SocketMessage AddMessage(ISocketUser author, MessageModel model)
{ {
var msg = new CachedMessage(this, author, model); var msg = new SocketMessage(this, author, model);
_messages.Add(msg); _messages.Add(msg);
return msg; return msg;
} }
public CachedMessage GetMessage(ulong id) public SocketMessage GetMessage(ulong id)
{ {
return _messages.Get(id); return _messages.Get(id);
} }
public CachedMessage RemoveMessage(ulong id) public SocketMessage RemoveMessage(ulong id)
{ {
return _messages.Remove(id); return _messages.Remove(id);
} }
public CachedDMChannel Clone() => MemberwiseClone() as CachedDMChannel; public SocketDMChannel Clone() => MemberwiseClone() as SocketDMChannel;
IMessage IMessageChannel.GetCachedMessage(ulong id) => GetMessage(id); IMessage IMessageChannel.GetCachedMessage(ulong id) => GetMessage(id);
ICachedUser ICachedMessageChannel.GetUser(ulong id, bool skipCheck) => GetUser(id); ISocketUser ISocketMessageChannel.GetUser(ulong id, bool skipCheck) => GetUser(id);
ICachedChannel ICachedChannel.Clone() => Clone(); ISocketChannel ISocketChannel.Clone() => Clone();
} }
} }

View File

@@ -11,19 +11,19 @@ using VoiceStateModel = Discord.API.VoiceState;
namespace Discord namespace Discord
{ {
internal class CachedGroupChannel : GroupChannel, IGroupChannel, ICachedChannel, ICachedMessageChannel, ICachedPrivateChannel internal class SocketGroupChannel : GroupChannel, IGroupChannel, ISocketChannel, ISocketMessageChannel, ISocketPrivateChannel
{ {
bool IEntity<ulong>.IsAttached => true; internal override bool IsAttached => true;
private readonly MessageManager _messages; private readonly MessageManager _messages;
private ConcurrentDictionary<ulong, VoiceState> _voiceStates; private ConcurrentDictionary<ulong, VoiceState> _voiceStates;
public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient; public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient;
public IReadOnlyCollection<ICachedUser> Members public IReadOnlyCollection<ISocketUser> Users
=> _users.Select(x => x.Value as ICachedUser).Concat(ImmutableArray.Create(Discord.CurrentUser)).ToReadOnlyCollection(() => _users.Count + 1); => _users.Select(x => x.Value as ISocketUser).Concat(ImmutableArray.Create(Discord.CurrentUser)).ToReadOnlyCollection(() => _users.Count + 1);
public new IReadOnlyCollection<ICachedUser> Recipients => _users.Select(x => x.Value as ICachedUser).ToReadOnlyCollection(_users); public new IReadOnlyCollection<ISocketUser> Recipients => _users.Select(x => x.Value as ISocketUser).ToReadOnlyCollection(_users);
public CachedGroupChannel(DiscordSocketClient discord, Model model) public SocketGroupChannel(DiscordSocketClient discord, Model model)
: base(discord, model) : base(discord, model)
{ {
if (Discord.MessageCacheSize > 0) if (Discord.MessageCacheSize > 0)
@@ -45,46 +45,46 @@ namespace Discord
for (int i = 0; i < models.Length; i++) for (int i = 0; i < models.Length; i++)
{ {
var globalUser = Discord.GetOrAddUser(models[i], dataStore); var globalUser = Discord.GetOrAddUser(models[i], dataStore);
users[models[i].Id] = new CachedGroupUser(this, globalUser); users[models[i].Id] = new SocketGroupUser(this, globalUser);
} }
_users = users; _users = users;
} }
internal override void UpdateUsers(UserModel[] models, UpdateSource source) internal override void UpdateUsers(UserModel[] models, UpdateSource source)
=> UpdateUsers(models, source, Discord.DataStore); => UpdateUsers(models, source, Discord.DataStore);
public CachedGroupUser AddUser(UserModel model, DataStore dataStore) public SocketGroupUser AddUser(UserModel model, DataStore dataStore)
{ {
GroupUser user; GroupUser user;
if (_users.TryGetValue(model.Id, out user)) if (_users.TryGetValue(model.Id, out user))
return user as CachedGroupUser; return user as SocketGroupUser;
else else
{ {
var globalUser = Discord.GetOrAddUser(model, dataStore); var globalUser = Discord.GetOrAddUser(model, dataStore);
var privateUser = new CachedGroupUser(this, globalUser); var privateUser = new SocketGroupUser(this, globalUser);
_users[privateUser.Id] = privateUser; _users[privateUser.Id] = privateUser;
return privateUser; return privateUser;
} }
} }
public ICachedUser GetUser(ulong id) public ISocketUser GetUser(ulong id)
{ {
GroupUser user; GroupUser user;
if (_users.TryGetValue(id, out user)) if (_users.TryGetValue(id, out user))
return user as CachedGroupUser; return user as SocketGroupUser;
if (id == Discord.CurrentUser.Id) if (id == Discord.CurrentUser.Id)
return Discord.CurrentUser; return Discord.CurrentUser;
return null; return null;
} }
public CachedGroupUser RemoveUser(ulong id) public SocketGroupUser RemoveUser(ulong id)
{ {
GroupUser user; GroupUser user;
if (_users.TryRemove(id, out user)) if (_users.TryRemove(id, out user))
return user as CachedGroupUser; return user as SocketGroupUser;
return null; return null;
} }
public VoiceState AddOrUpdateVoiceState(VoiceStateModel model, DataStore dataStore, ConcurrentDictionary<ulong, VoiceState> voiceStates = null) public VoiceState AddOrUpdateVoiceState(VoiceStateModel model, DataStore dataStore, ConcurrentDictionary<ulong, VoiceState> voiceStates = null)
{ {
var voiceChannel = dataStore.GetChannel(model.ChannelId.Value) as CachedVoiceChannel; var voiceChannel = dataStore.GetChannel(model.ChannelId.Value) as SocketVoiceChannel;
var voiceState = new VoiceState(voiceChannel, model); var voiceState = new VoiceState(voiceChannel, model);
(voiceStates ?? _voiceStates)[model.UserId] = voiceState; (voiceStates ?? _voiceStates)[model.UserId] = voiceState;
return voiceState; return voiceState;
@@ -116,25 +116,25 @@ namespace Discord
{ {
return await _messages.DownloadAsync(fromMessageId, dir, limit).ConfigureAwait(false); return await _messages.DownloadAsync(fromMessageId, dir, limit).ConfigureAwait(false);
} }
public CachedMessage AddMessage(ICachedUser author, MessageModel model) public SocketMessage AddMessage(ISocketUser author, MessageModel model)
{ {
var msg = new CachedMessage(this, author, model); var msg = new SocketMessage(this, author, model);
_messages.Add(msg); _messages.Add(msg);
return msg; return msg;
} }
public CachedMessage GetMessage(ulong id) public SocketMessage GetMessage(ulong id)
{ {
return _messages.Get(id); return _messages.Get(id);
} }
public CachedMessage RemoveMessage(ulong id) public SocketMessage RemoveMessage(ulong id)
{ {
return _messages.Remove(id); return _messages.Remove(id);
} }
public CachedDMChannel Clone() => MemberwiseClone() as CachedDMChannel; public SocketDMChannel Clone() => MemberwiseClone() as SocketDMChannel;
IMessage IMessageChannel.GetCachedMessage(ulong id) => GetMessage(id); IMessage IMessageChannel.GetCachedMessage(ulong id) => GetMessage(id);
ICachedUser ICachedMessageChannel.GetUser(ulong id, bool skipCheck) => GetUser(id); ISocketUser ISocketMessageChannel.GetUser(ulong id, bool skipCheck) => GetUser(id);
ICachedChannel ICachedChannel.Clone() => Clone(); ISocketChannel ISocketChannel.Clone() => Clone();
} }
} }

View File

@@ -7,19 +7,19 @@ using Model = Discord.API.Channel;
namespace Discord namespace Discord
{ {
internal class CachedTextChannel : TextChannel, ICachedGuildChannel, ICachedMessageChannel internal class SocketTextChannel : TextChannel, ISocketGuildChannel, ISocketMessageChannel
{ {
bool IEntity<ulong>.IsAttached => true; internal override bool IsAttached => true;
private readonly MessageManager _messages; private readonly MessageManager _messages;
public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient; public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient;
public new CachedGuild Guild => base.Guild as CachedGuild; public new SocketGuild Guild => base.Guild as SocketGuild;
public IReadOnlyCollection<CachedGuildUser> Members public IReadOnlyCollection<SocketGuildUser> Members
=> Guild.Members.Where(x => Permissions.GetValue(Permissions.ResolveChannel(x, this, x.GuildPermissions.RawValue), ChannelPermission.ReadMessages)).ToImmutableArray(); => Guild.Members.Where(x => Permissions.GetValue(Permissions.ResolveChannel(x, this, x.GuildPermissions.RawValue), ChannelPermission.ReadMessages)).ToImmutableArray();
public CachedTextChannel(CachedGuild guild, Model model) public SocketTextChannel(SocketGuild guild, Model model)
: base(guild, model) : base(guild, model)
{ {
if (Discord.MessageCacheSize > 0) if (Discord.MessageCacheSize > 0)
@@ -30,7 +30,7 @@ namespace Discord
public override Task<IGuildUser> GetUserAsync(ulong id) => Task.FromResult<IGuildUser>(GetUser(id)); public override Task<IGuildUser> GetUserAsync(ulong id) => Task.FromResult<IGuildUser>(GetUser(id));
public override Task<IReadOnlyCollection<IGuildUser>> GetUsersAsync() => Task.FromResult<IReadOnlyCollection<IGuildUser>>(Members); public override Task<IReadOnlyCollection<IGuildUser>> GetUsersAsync() => Task.FromResult<IReadOnlyCollection<IGuildUser>>(Members);
public CachedGuildUser GetUser(ulong id, bool skipCheck = false) public SocketGuildUser GetUser(ulong id, bool skipCheck = false)
{ {
var user = Guild.GetUser(id); var user = Guild.GetUser(id);
if (skipCheck) return user; if (skipCheck) return user;
@@ -57,27 +57,27 @@ namespace Discord
return await _messages.DownloadAsync(fromMessageId, dir, limit).ConfigureAwait(false); return await _messages.DownloadAsync(fromMessageId, dir, limit).ConfigureAwait(false);
} }
public CachedMessage AddMessage(ICachedUser author, MessageModel model) public SocketMessage AddMessage(ISocketUser author, MessageModel model)
{ {
var msg = new CachedMessage(this, author, model); var msg = new SocketMessage(this, author, model);
_messages.Add(msg); _messages.Add(msg);
return msg; return msg;
} }
public CachedMessage GetMessage(ulong id) public SocketMessage GetMessage(ulong id)
{ {
return _messages.Get(id); return _messages.Get(id);
} }
public CachedMessage RemoveMessage(ulong id) public SocketMessage RemoveMessage(ulong id)
{ {
return _messages.Remove(id); return _messages.Remove(id);
} }
public CachedTextChannel Clone() => MemberwiseClone() as CachedTextChannel; public SocketTextChannel Clone() => MemberwiseClone() as SocketTextChannel;
IReadOnlyCollection<ICachedUser> ICachedMessageChannel.Members => Members; IReadOnlyCollection<ISocketUser> ISocketMessageChannel.Users => Members;
IMessage IMessageChannel.GetCachedMessage(ulong id) => GetMessage(id); IMessage IMessageChannel.GetCachedMessage(ulong id) => GetMessage(id);
ICachedUser ICachedMessageChannel.GetUser(ulong id, bool skipCheck) => GetUser(id, skipCheck); ISocketUser ISocketMessageChannel.GetUser(ulong id, bool skipCheck) => GetUser(id, skipCheck);
ICachedChannel ICachedChannel.Clone() => Clone(); ISocketChannel ISocketChannel.Clone() => Clone();
} }
} }

View File

@@ -8,17 +8,17 @@ using Model = Discord.API.Channel;
namespace Discord namespace Discord
{ {
internal class CachedVoiceChannel : VoiceChannel, ICachedGuildChannel internal class SocketVoiceChannel : VoiceChannel, ISocketGuildChannel
{ {
bool IEntity<ulong>.IsAttached => true; internal override bool IsAttached => true;
public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient; public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient;
public new CachedGuild Guild => base.Guild as CachedGuild; public new SocketGuild Guild => base.Guild as SocketGuild;
public IReadOnlyCollection<IGuildUser> Members public IReadOnlyCollection<IGuildUser> Members
=> Guild.VoiceStates.Where(x => x.Value.VoiceChannel.Id == Id).Select(x => Guild.GetUser(x.Key)).ToImmutableArray(); => Guild.VoiceStates.Where(x => x.Value.VoiceChannel.Id == Id).Select(x => Guild.GetUser(x.Key)).ToImmutableArray();
public CachedVoiceChannel(CachedGuild guild, Model model) public SocketVoiceChannel(SocketGuild guild, Model model)
: base(guild, model) : base(guild, model)
{ {
} }
@@ -48,8 +48,8 @@ namespace Discord
//TODO: Block and return //TODO: Block and return
} }
public CachedVoiceChannel Clone() => MemberwiseClone() as CachedVoiceChannel; public SocketVoiceChannel Clone() => MemberwiseClone() as SocketVoiceChannel;
ICachedChannel ICachedChannel.Clone() => Clone(); ISocketChannel ISocketChannel.Clone() => Clone();
} }
} }

View File

@@ -19,14 +19,14 @@ using VoiceStateModel = Discord.API.VoiceState;
namespace Discord namespace Discord
{ {
internal class CachedGuild : Guild, IGuild, IUserGuild internal class SocketGuild : Guild, IGuild, IUserGuild
{ {
bool IEntity<ulong>.IsAttached => true; internal override bool IsAttached => true;
private readonly SemaphoreSlim _audioLock; private readonly SemaphoreSlim _audioLock;
private TaskCompletionSource<bool> _syncPromise, _downloaderPromise; private TaskCompletionSource<bool> _syncPromise, _downloaderPromise;
private ConcurrentHashSet<ulong> _channels; private ConcurrentHashSet<ulong> _channels;
private ConcurrentDictionary<ulong, CachedGuildUser> _members; private ConcurrentDictionary<ulong, SocketGuildUser> _members;
private ConcurrentDictionary<ulong, VoiceState> _voiceStates; private ConcurrentDictionary<ulong, VoiceState> _voiceStates;
internal bool _available; internal bool _available;
@@ -41,20 +41,20 @@ namespace Discord
public Task DownloaderPromise => _downloaderPromise.Task; public Task DownloaderPromise => _downloaderPromise.Task;
public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient; public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient;
public CachedGuildUser CurrentUser => GetUser(Discord.CurrentUser.Id); public SocketGuildUser CurrentUser => GetUser(Discord.CurrentUser.Id);
public IReadOnlyCollection<ICachedGuildChannel> Channels public IReadOnlyCollection<ISocketGuildChannel> Channels
{ {
get get
{ {
var channels = _channels; var channels = _channels;
var store = Discord.DataStore; var store = Discord.DataStore;
return channels.Select(x => store.GetChannel(x) as ICachedGuildChannel).Where(x => x != null).ToReadOnlyCollection(channels); return channels.Select(x => store.GetChannel(x) as ISocketGuildChannel).Where(x => x != null).ToReadOnlyCollection(channels);
} }
} }
public IReadOnlyCollection<CachedGuildUser> Members => _members.ToReadOnlyCollection(); public IReadOnlyCollection<SocketGuildUser> Members => _members.ToReadOnlyCollection();
public IEnumerable<KeyValuePair<ulong, VoiceState>> VoiceStates => _voiceStates; public IEnumerable<KeyValuePair<ulong, VoiceState>> VoiceStates => _voiceStates;
public CachedGuild(DiscordSocketClient discord, ExtendedModel model, DataStore dataStore) : base(discord, model) public SocketGuild(DiscordSocketClient discord, ExtendedModel model, DataStore dataStore) : base(discord, model)
{ {
_audioLock = new SemaphoreSlim(1, 1); _audioLock = new SemaphoreSlim(1, 1);
_syncPromise = new TaskCompletionSource<bool>(); _syncPromise = new TaskCompletionSource<bool>();
@@ -72,7 +72,7 @@ namespace Discord
if (_channels == null) if (_channels == null)
_channels = new ConcurrentHashSet<ulong>(); _channels = new ConcurrentHashSet<ulong>();
if (_members == null) if (_members == null)
_members = new ConcurrentDictionary<ulong, CachedGuildUser>(); _members = new ConcurrentDictionary<ulong, SocketGuildUser>();
if (_roles == null) if (_roles == null)
_roles = new ConcurrentDictionary<ulong, Role>(); _roles = new ConcurrentDictionary<ulong, Role>();
if (Emojis == null) if (Emojis == null)
@@ -93,7 +93,7 @@ namespace Discord
} }
_channels = channels; _channels = channels;
var members = new ConcurrentDictionary<ulong, CachedGuildUser>(1, (int)(model.Presences.Length * 1.05)); var members = new ConcurrentDictionary<ulong, SocketGuildUser>(1, (int)(model.Presences.Length * 1.05));
{ {
DownloadedMemberCount = 0; DownloadedMemberCount = 0;
for (int i = 0; i < model.Members.Length; i++) for (int i = 0; i < model.Members.Length; i++)
@@ -121,7 +121,7 @@ namespace Discord
{ {
if (source == UpdateSource.Rest && IsAttached) return; if (source == UpdateSource.Rest && IsAttached) return;
var members = new ConcurrentDictionary<ulong, CachedGuildUser>(1, (int)(model.Presences.Length * 1.05)); var members = new ConcurrentDictionary<ulong, SocketGuildUser>(1, (int)(model.Presences.Length * 1.05));
{ {
DownloadedMemberCount = 0; DownloadedMemberCount = 0;
for (int i = 0; i < model.Members.Length; i++) for (int i = 0; i < model.Members.Length; i++)
@@ -154,14 +154,14 @@ namespace Discord
(channels ?? _channels).TryAdd(model.Id); (channels ?? _channels).TryAdd(model.Id);
dataStore.AddChannel(channel); dataStore.AddChannel(channel);
} }
public ICachedGuildChannel GetChannel(ulong id) public ISocketGuildChannel GetChannel(ulong id)
{ {
return Discord.DataStore.GetChannel(id) as ICachedGuildChannel; return Discord.DataStore.GetChannel(id) as ISocketGuildChannel;
} }
public ICachedGuildChannel RemoveChannel(ulong id) public ISocketGuildChannel RemoveChannel(ulong id)
{ {
_channels.TryRemove(id); _channels.TryRemove(id);
return Discord.DataStore.RemoveChannel(id) as ICachedGuildChannel; return Discord.DataStore.RemoveChannel(id) as ISocketGuildChannel;
} }
public Role AddRole(RoleModel model, ConcurrentDictionary<ulong, Role> roles = null) public Role AddRole(RoleModel model, ConcurrentDictionary<ulong, Role> roles = null)
@@ -183,48 +183,48 @@ namespace Discord
=> Task.FromResult<IGuildUser>(CurrentUser); => Task.FromResult<IGuildUser>(CurrentUser);
public override Task<IReadOnlyCollection<IGuildUser>> GetUsersAsync() public override Task<IReadOnlyCollection<IGuildUser>> GetUsersAsync()
=> Task.FromResult<IReadOnlyCollection<IGuildUser>>(Members); => Task.FromResult<IReadOnlyCollection<IGuildUser>>(Members);
public CachedGuildUser AddUser(MemberModel model, DataStore dataStore, ConcurrentDictionary<ulong, CachedGuildUser> members = null) public SocketGuildUser AddUser(MemberModel model, DataStore dataStore, ConcurrentDictionary<ulong, SocketGuildUser> members = null)
{ {
members = members ?? _members; members = members ?? _members;
CachedGuildUser member; SocketGuildUser member;
if (members.TryGetValue(model.User.Id, out member)) if (members.TryGetValue(model.User.Id, out member))
member.Update(model, UpdateSource.WebSocket); member.Update(model, UpdateSource.WebSocket);
else else
{ {
var user = Discord.GetOrAddUser(model.User, dataStore); var user = Discord.GetOrAddUser(model.User, dataStore);
member = new CachedGuildUser(this, user, model); member = new SocketGuildUser(this, user, model);
members[user.Id] = member; members[user.Id] = member;
DownloadedMemberCount++; DownloadedMemberCount++;
} }
return member; return member;
} }
public CachedGuildUser AddOrUpdateUser(PresenceModel model, DataStore dataStore, ConcurrentDictionary<ulong, CachedGuildUser> members = null) public SocketGuildUser AddOrUpdateUser(PresenceModel model, DataStore dataStore, ConcurrentDictionary<ulong, SocketGuildUser> members = null)
{ {
members = members ?? _members; members = members ?? _members;
CachedGuildUser member; SocketGuildUser member;
if (members.TryGetValue(model.User.Id, out member)) if (members.TryGetValue(model.User.Id, out member))
member.Update(model, UpdateSource.WebSocket); member.Update(model, UpdateSource.WebSocket);
else else
{ {
var user = Discord.GetOrAddUser(model.User, dataStore); var user = Discord.GetOrAddUser(model.User, dataStore);
member = new CachedGuildUser(this, user, model); member = new SocketGuildUser(this, user, model);
members[user.Id] = member; members[user.Id] = member;
DownloadedMemberCount++; DownloadedMemberCount++;
} }
return member; return member;
} }
public CachedGuildUser GetUser(ulong id) public SocketGuildUser GetUser(ulong id)
{ {
CachedGuildUser member; SocketGuildUser member;
if (_members.TryGetValue(id, out member)) if (_members.TryGetValue(id, out member))
return member; return member;
return null; return null;
} }
public CachedGuildUser RemoveUser(ulong id) public SocketGuildUser RemoveUser(ulong id)
{ {
CachedGuildUser member; SocketGuildUser member;
if (_members.TryRemove(id, out member)) if (_members.TryRemove(id, out member))
return member; return member;
return null; return null;
@@ -240,7 +240,7 @@ namespace Discord
public VoiceState AddOrUpdateVoiceState(VoiceStateModel model, DataStore dataStore, ConcurrentDictionary<ulong, VoiceState> voiceStates = null) public VoiceState AddOrUpdateVoiceState(VoiceStateModel model, DataStore dataStore, ConcurrentDictionary<ulong, VoiceState> voiceStates = null)
{ {
var voiceChannel = dataStore.GetChannel(model.ChannelId.Value) as CachedVoiceChannel; var voiceChannel = dataStore.GetChannel(model.ChannelId.Value) as SocketVoiceChannel;
var voiceState = new VoiceState(voiceChannel, model); var voiceState = new VoiceState(voiceChannel, model);
(voiceStates ?? _voiceStates)[model.UserId] = voiceState; (voiceStates ?? _voiceStates)[model.UserId] = voiceState;
return voiceState; return voiceState;
@@ -309,16 +309,16 @@ namespace Discord
await audioClient.ConnectAsync(url, CurrentUser.Id, voiceState.VoiceSessionId, token).ConfigureAwait(false); await audioClient.ConnectAsync(url, CurrentUser.Id, voiceState.VoiceSessionId, token).ConfigureAwait(false);
} }
public CachedGuild Clone() => MemberwiseClone() as CachedGuild; public SocketGuild Clone() => MemberwiseClone() as SocketGuild;
new internal ICachedGuildChannel ToChannel(ChannelModel model) new internal ISocketGuildChannel ToChannel(ChannelModel model)
{ {
switch (model.Type) switch (model.Type)
{ {
case ChannelType.Text: case ChannelType.Text:
return new CachedTextChannel(this, model); return new SocketTextChannel(this, model);
case ChannelType.Voice: case ChannelType.Voice:
return new CachedVoiceChannel(this, model); return new SocketVoiceChannel(this, model);
default: default:
throw new InvalidOperationException($"Unexpected channel type: {model.Type}"); throw new InvalidOperationException($"Unexpected channel type: {model.Type}");
} }

View File

@@ -1,7 +0,0 @@
namespace Discord
{
internal interface ICachedGuildChannel : ICachedChannel, IGuildChannel
{
new CachedGuild Guild { get; }
}
}

View File

@@ -1,16 +0,0 @@
using System.Collections.Generic;
using MessageModel = Discord.API.Message;
namespace Discord
{
internal interface ICachedMessageChannel : ICachedChannel, IMessageChannel
{
IReadOnlyCollection<ICachedUser> Members { get; }
CachedMessage AddMessage(ICachedUser author, MessageModel model);
CachedMessage GetMessage(ulong id);
CachedMessage RemoveMessage(ulong id);
ICachedUser GetUser(ulong id, bool skipCheck = false);
}
}

View File

@@ -1,9 +0,0 @@
using System.Collections.Generic;
namespace Discord
{
internal interface ICachedPrivateChannel : ICachedChannel, IPrivateChannel
{
new IReadOnlyCollection<ICachedUser> Recipients { get; }
}
}

View File

@@ -1,9 +0,0 @@
namespace Discord
{
internal interface ICachedUser : IUser, ICachedEntity<ulong>
{
CachedGlobalUser User { get; }
ICachedUser Clone();
}
}

View File

@@ -0,0 +1,19 @@
using Model = Discord.API.Message;
namespace Discord
{
internal class SocketMessage : Message
{
internal override bool IsAttached => true;
public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient;
public new ISocketMessageChannel Channel => base.Channel as ISocketMessageChannel;
public SocketMessage(ISocketMessageChannel channel, IUser author, Model model)
: base(channel, author, model)
{
}
public SocketMessage Clone() => MemberwiseClone() as SocketMessage;
}
}

View File

@@ -0,0 +1,9 @@
namespace Discord
{
internal interface ISocketUser : IUser, IEntity<ulong>
{
SocketGlobalUser User { get; }
ISocketUser Clone();
}
}

View File

@@ -5,11 +5,12 @@ using PresenceModel = Discord.API.Presence;
namespace Discord namespace Discord
{ {
[DebuggerDisplay("{DebuggerDisplay,nq}")] [DebuggerDisplay("{DebuggerDisplay,nq}")]
internal class CachedDMUser : ICachedUser internal class SocketDMUser : ISocketUser
{ {
bool IEntity<ulong>.IsAttached => true; internal bool IsAttached => true;
bool IEntity<ulong>.IsAttached => IsAttached;
public CachedGlobalUser User { get; } public SocketGlobalUser User { get; }
public DiscordSocketClient Discord => User.Discord; public DiscordSocketClient Discord => User.Discord;
@@ -22,12 +23,11 @@ namespace Discord
public DateTimeOffset CreatedAt => User.CreatedAt; public DateTimeOffset CreatedAt => User.CreatedAt;
public string Discriminator => User.Discriminator; public string Discriminator => User.Discriminator;
public ushort DiscriminatorValue => User.DiscriminatorValue; public ushort DiscriminatorValue => User.DiscriminatorValue;
public bool IsAttached => User.IsAttached;
public bool IsBot => User.IsBot; public bool IsBot => User.IsBot;
public string Mention => MentionUtils.Mention(this); public string Mention => MentionUtils.Mention(this);
public string Username => User.Username; public string Username => User.Username;
public CachedDMUser(CachedGlobalUser user) public SocketDMUser(SocketGlobalUser user)
{ {
User = user; User = user;
} }
@@ -37,8 +37,8 @@ namespace Discord
User.Update(model, source); User.Update(model, source);
} }
public CachedDMUser Clone() => MemberwiseClone() as CachedDMUser; public SocketDMUser Clone() => MemberwiseClone() as SocketDMUser;
ICachedUser ICachedUser.Clone() => Clone(); ISocketUser ISocketUser.Clone() => Clone();
public override string ToString() => $"{Username}#{Discriminator}"; public override string ToString() => $"{Username}#{Discriminator}";
private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id})"; private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id})";

View File

@@ -4,18 +4,18 @@ using PresenceModel = Discord.API.Presence;
namespace Discord namespace Discord
{ {
internal class CachedGlobalUser : User, ICachedUser internal class SocketGlobalUser : User, ISocketUser
{ {
bool IEntity<ulong>.IsAttached => true; internal override bool IsAttached => true;
private ushort _references; private ushort _references;
public Presence Presence { get; private set; } public Presence Presence { get; private set; }
public new DiscordSocketClient Discord { get { throw new NotSupportedException(); } } public new DiscordSocketClient Discord { get { throw new NotSupportedException(); } }
CachedGlobalUser ICachedUser.User => this; SocketGlobalUser ISocketUser.User => this;
public CachedGlobalUser(Model model) public SocketGlobalUser(Model model)
: base(model) : base(model)
{ {
} }
@@ -53,7 +53,7 @@ namespace Discord
//} //}
} }
public CachedGlobalUser Clone() => MemberwiseClone() as CachedGlobalUser; public SocketGlobalUser Clone() => MemberwiseClone() as SocketGlobalUser;
ICachedUser ICachedUser.Clone() => Clone(); ISocketUser ISocketUser.Clone() => Clone();
} }
} }

View File

@@ -3,13 +3,13 @@
namespace Discord namespace Discord
{ {
[DebuggerDisplay("{DebuggerDisplay,nq}")] [DebuggerDisplay("{DebuggerDisplay,nq}")]
internal class CachedGroupUser : GroupUser, ICachedUser internal class SocketGroupUser : GroupUser, ISocketUser
{ {
bool IEntity<ulong>.IsAttached => true; internal override bool IsAttached => true;
public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient; public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient;
public new CachedGroupChannel Channel => base.Channel as CachedGroupChannel; public new SocketGroupChannel Channel => base.Channel as SocketGroupChannel;
public new CachedGlobalUser User => base.User as CachedGlobalUser; public new SocketGlobalUser User => base.User as SocketGlobalUser;
public Presence Presence => User.Presence; //{ get; private set; } public Presence Presence => User.Presence; //{ get; private set; }
public override Game Game => Presence.Game; public override Game Game => Presence.Game;
@@ -19,15 +19,15 @@ namespace Discord
public bool IsSelfDeafened => VoiceState?.IsSelfDeafened ?? false; public bool IsSelfDeafened => VoiceState?.IsSelfDeafened ?? false;
public bool IsSelfMuted => VoiceState?.IsSelfMuted ?? false; public bool IsSelfMuted => VoiceState?.IsSelfMuted ?? false;
public bool IsSuppressed => VoiceState?.IsSuppressed ?? false; public bool IsSuppressed => VoiceState?.IsSuppressed ?? false;
public CachedVoiceChannel VoiceChannel => VoiceState?.VoiceChannel; public SocketVoiceChannel VoiceChannel => VoiceState?.VoiceChannel;
public CachedGroupUser(CachedGroupChannel channel, CachedGlobalUser user) public SocketGroupUser(SocketGroupChannel channel, SocketGlobalUser user)
: base(channel, user) : base(channel, user)
{ {
} }
public CachedGroupUser Clone() => MemberwiseClone() as CachedGroupUser; public SocketGroupUser Clone() => MemberwiseClone() as SocketGroupUser;
ICachedUser ICachedUser.Clone() => Clone(); ISocketUser ISocketUser.Clone() => Clone();
public override string ToString() => $"{Username}#{Discriminator}"; public override string ToString() => $"{Username}#{Discriminator}";
private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id})"; private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id})";

View File

@@ -3,13 +3,13 @@ using PresenceModel = Discord.API.Presence;
namespace Discord namespace Discord
{ {
internal class CachedGuildUser : GuildUser, ICachedUser internal class SocketGuildUser : GuildUser, ISocketUser
{ {
bool IEntity<ulong>.IsAttached => true; internal override bool IsAttached => true;
public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient; public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient;
public new CachedGuild Guild => base.Guild as CachedGuild; public new SocketGuild Guild => base.Guild as SocketGuild;
public new CachedGlobalUser User => base.User as CachedGlobalUser; public new SocketGlobalUser User => base.User as SocketGlobalUser;
public Presence Presence => User.Presence; //{ get; private set; } public Presence Presence => User.Presence; //{ get; private set; }
public override Game Game => Presence.Game; public override Game Game => Presence.Game;
@@ -19,14 +19,14 @@ namespace Discord
public bool IsSelfDeafened => VoiceState?.IsSelfDeafened ?? false; public bool IsSelfDeafened => VoiceState?.IsSelfDeafened ?? false;
public bool IsSelfMuted => VoiceState?.IsSelfMuted ?? false; public bool IsSelfMuted => VoiceState?.IsSelfMuted ?? false;
public bool IsSuppressed => VoiceState?.IsSuppressed ?? false; public bool IsSuppressed => VoiceState?.IsSuppressed ?? false;
public CachedVoiceChannel VoiceChannel => VoiceState?.VoiceChannel; public SocketVoiceChannel VoiceChannel => VoiceState?.VoiceChannel;
public CachedGuildUser(CachedGuild guild, CachedGlobalUser user, Model model) public SocketGuildUser(SocketGuild guild, SocketGlobalUser user, Model model)
: base(guild, user, model) : base(guild, user, model)
{ {
//Presence = new Presence(null, UserStatus.Offline); //Presence = new Presence(null, UserStatus.Offline);
} }
public CachedGuildUser(CachedGuild guild, CachedGlobalUser user, PresenceModel model) public SocketGuildUser(SocketGuild guild, SocketGlobalUser user, PresenceModel model)
: base(guild, user, model) : base(guild, user, model)
{ {
} }
@@ -41,7 +41,7 @@ namespace Discord
User.Update(model, source); User.Update(model, source);
} }
public CachedGuildUser Clone() => MemberwiseClone() as CachedGuildUser; public SocketGuildUser Clone() => MemberwiseClone() as SocketGuildUser;
ICachedUser ICachedUser.Clone() => Clone(); ISocketUser ISocketUser.Clone() => Clone();
} }
} }

View File

@@ -0,0 +1,21 @@
using System;
using Model = Discord.API.User;
namespace Discord
{
internal class SocketSelfUser : SelfUser, ISocketUser
{
internal override bool IsAttached => true;
public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient;
SocketGlobalUser ISocketUser.User { get { throw new NotSupportedException(); } }
public SocketSelfUser(DiscordSocketClient discord, Model model)
: base(discord, model)
{
}
public SocketSelfUser Clone() => MemberwiseClone() as SocketSelfUser;
ISocketUser ISocketUser.Clone() => Clone();
}
}

View File

@@ -19,7 +19,7 @@ namespace Discord
private readonly Flags _voiceStates; private readonly Flags _voiceStates;
public CachedVoiceChannel VoiceChannel { get; } public SocketVoiceChannel VoiceChannel { get; }
public string VoiceSessionId { get; } public string VoiceSessionId { get; }
public bool IsMuted => (_voiceStates & Flags.Muted) != 0; public bool IsMuted => (_voiceStates & Flags.Muted) != 0;
@@ -28,9 +28,9 @@ namespace Discord
public bool IsSelfMuted => (_voiceStates & Flags.SelfMuted) != 0; public bool IsSelfMuted => (_voiceStates & Flags.SelfMuted) != 0;
public bool IsSelfDeafened => (_voiceStates & Flags.SelfDeafened) != 0; public bool IsSelfDeafened => (_voiceStates & Flags.SelfDeafened) != 0;
public VoiceState(CachedVoiceChannel voiceChannel, Model model) public VoiceState(SocketVoiceChannel voiceChannel, Model model)
: this(voiceChannel, model.SessionId, model.SelfMute, model.SelfDeaf, model.Suppress) { } : this(voiceChannel, model.SessionId, model.SelfMute, model.SelfDeaf, model.Suppress) { }
public VoiceState(CachedVoiceChannel voiceChannel, string sessionId, bool isSelfMuted, bool isSelfDeafened, bool isSuppressed) public VoiceState(SocketVoiceChannel voiceChannel, string sessionId, bool isSelfMuted, bool isSelfDeafened, bool isSuppressed)
{ {
VoiceChannel = voiceChannel; VoiceChannel = voiceChannel;
VoiceSessionId = sessionId; VoiceSessionId = sessionId;