diff --git a/src/Discord.Net/DiscordClient.cs b/src/Discord.Net/DiscordClient.cs
index 61644efab..c74faf03a 100644
--- a/src/Discord.Net/DiscordClient.cs
+++ b/src/Discord.Net/DiscordClient.cs
@@ -11,36 +11,52 @@ using System.Threading.Tasks;
namespace Discord
{
+ /// Provides a connection to the DiscordApp service.
public partial class DiscordClient
{
- public const int ReconnectDelay = 1000; //Time in milliseconds to wait after an unexpected disconnect before retrying
- public const int FailedReconnectDelay = 10000; //Time in milliseconds to wait after a failed reconnect attempt
-
private DiscordWebSocket _webSocket;
- private bool _isReady;
+ private ManualResetEventSlim _isStopping;
+ /// Returns the User object for the current logged in user.
+ public User User { get; private set; }
public string UserId { get; private set; }
- public User User => _users[UserId];
+ /// Returns a collection of all users the client can see across all servers.
+ /// This collection does not guarantee any ordering.
public IEnumerable Users => _users;
private AsyncCache _users;
+ /// Returns a collection of all servers the client is a member of.
+ /// This collection does not guarantee any ordering.
public IEnumerable Servers => _servers;
private AsyncCache _servers;
+ /// Returns a collection of all channels the client can see across all servers.
+ /// This collection does not guarantee any ordering.
public IEnumerable Channels => _channels;
private AsyncCache _channels;
+ /// Returns a collection of all messages the client has in cache.
+ /// This collection does not guarantee any ordering.
public IEnumerable Messages => _messages;
private AsyncCache _messages;
+ /// Returns a collection of all roles the client can see across all servers.
+ /// This collection does not guarantee any ordering.
public IEnumerable Roles => _roles;
private AsyncCache _roles;
- private ManualResetEventSlim _isStopping;
-
+ /// Returns true if the user has successfully logged in and the websocket connection has been established.
public bool IsConnected => _isReady;
+ private bool _isReady;
+ /// Gets or sets the time (in milliseconds) to wait after an unexpected disconnect before reconnecting.
+ public int ReconnectDelay { get; set; } = 1000;
+ /// Gets or sets the time (in milliseconds) to wait after an reconnect fails before retrying.
+ public int FailedReconnectDelay { get; set; } = 10000;
+
+
+ /// Initializes a new instance of the DiscordClient class.
public DiscordClient()
{
_isStopping = new ManualResetEventSlim(false);
@@ -50,7 +66,7 @@ namespace Discord
(server, model) =>
{
server.Name = model.Name;
- if (!server.Channels.Any()) //Assume a default channel exists with the same id as the server. Not sure if this is safe?
+ if (!server.Channels.Any()) //A default channel always exists with the same id as the server.
{
var defaultChannel = new ChannelReference() { Id = server.DefaultChannelId, GuildId = server.Id };
_channels.Update(defaultChannel.Id, defaultChannel.GuildId, defaultChannel);
@@ -173,8 +189,9 @@ namespace Discord
await _webSocket.ConnectAsync(Endpoints.WebSocket_Hub, true);
break;
}
- catch (Exception)
+ catch (Exception ex)
{
+ RaiseOnDebugMessage($"Reconnect Failed: {ex.Message}");
//Net is down? We can keep trying to reconnect until the user runs Disconnect()
await Task.Delay(FailedReconnectDelay);
}
@@ -194,7 +211,7 @@ namespace Discord
_users.Clear();
UserId = data.User.Id;
- _users.Update(data.User.Id, data.User);
+ User = _users.Update(data.User.Id, data.User);
foreach (var server in data.Guilds)
_servers.Update(server.Id, server);
foreach (var channel in data.PrivateChannels)
@@ -416,101 +433,131 @@ namespace Discord
};
_webSocket.OnDebugMessage += (s, e) => RaiseOnDebugMessage(e.Message);
}
+
- //Collections
+ /// Returns the user with the specified id, or null if none was found.
public User GetUser(string id) => _users[id];
- public User FindUser(string name)
- {
- return _users
- .Where(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase))
- .FirstOrDefault();
- }
- public User FindUser(string name, string discriminator)
+ /// Returns the user with the specified name and discriminator, or null if none was found.
+ /// Name formats supported: Name and @Name. Search is case-insensitive.
+ public User GetUser(string name, string discriminator)
{
if (name.StartsWith("@"))
name = name.Substring(1);
return _users
- .Where(x =>
+ .Where(x =>
string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase) &&
x.Discriminator == discriminator
- )
+ )
.FirstOrDefault();
}
- public Membership FindMember(string serverId, string name)
- => FindMember(GetServer(serverId), name);
- public Membership FindMember(Server server, string name)
+ /// Returns all users with the specified name.
+ /// Name formats supported: Name and @Name. Search is case-insensitive.
+ /*public IEnumerable FindUsers(string name)
{
- if (server == null)
- return null;
-
- if (name.StartsWith("<@") && name.EndsWith(">"))
+ if (name.StartsWith("@"))
{
- var user = GetUser(name.Substring(2, name.Length - 3));
- if (user == null)
- return null;
- return server.GetMembership(user.Id);
- }
+ string name2 = name.Substring(1);
+ return _users.Where(x =>
+ string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase) || string.Equals(x.Name, name2, StringComparison.OrdinalIgnoreCase));
+ }
+ else
+ {
+ return _users.Where(x =>
+ string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase));
+ }
+ }*/
+ /// Returns all users in with the specified server and name, along with their server-specific data.
+ /// Name formats supported: Name and @Name. Search is case-insensitive.
+ public IEnumerable FindUsers(string serverId, string name)
+ => FindUsers(GetServer(serverId), name);
+ /// Returns all users in with the specified server and name, along with their server-specific data.
+ /// Name formats supported: Name and @Name. Search is case-insensitive.
+ public IEnumerable FindUsers(Server server, string name)
+ {
+ if (server == null)
+ return new Membership[0];
if (name.StartsWith("@"))
- name = name.Substring(1);
-
- return server.Members
- .Where(x => string.Equals(x.User.Name, name, StringComparison.OrdinalIgnoreCase))
- .FirstOrDefault();
+ {
+ string name2 = name.Substring(1);
+ return server.Members.Where(x =>
+ {
+ var user = x.User;
+ return string.Equals(user.Name, name, StringComparison.OrdinalIgnoreCase) || string.Equals(user.Name, name2, StringComparison.OrdinalIgnoreCase);
+ });
+ }
+ else
+ {
+ return server.Members.Where(x =>
+ string.Equals(x.User.Name, name, StringComparison.OrdinalIgnoreCase));
+ }
}
+ /// Returns the server with the specified id, or null if none was found.
public Server GetServer(string id) => _servers[id];
- public Server FindServer(string name)
+ /// Returns all servers with the specified name.
+ /// Search is case-insensitive.
+ public IEnumerable FindServers(string name)
{
- return _servers
- .Where(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase))
- .FirstOrDefault();
+ return _servers.Where(x =>
+ string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase));
}
+ /// Returns the channel with the specified id, or null if none was found.
public Channel GetChannel(string id) => _channels[id];
- public Channel FindChannel(string name)
+ /// Returns all channels with the specified server and name.
+ /// Name formats supported: Name and #Name. Search is case-insensitive.
+ public IEnumerable FindChannels(Server server, string name)
+ => FindChannels(server.Id, name);
+ /// Returns all channels with the specified server and name.
+ /// Name formats supported: Name and #Name. Search is case-insensitive.
+ public IEnumerable FindChannels(string serverId, string name)
{
- if (name.StartsWith("<#") && name.EndsWith(">"))
- return GetChannel(name.Substring(2, name.Length - 3));
-
if (name.StartsWith("#"))
- name = name.Substring(1);
- return _channels
- .Where(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase))
- .FirstOrDefault();
- }
- public Channel FindChannel(Server server, string name)
- => FindChannel(server.Id, name);
- public Channel FindChannel(string serverId, string name)
- {
- if (name.StartsWith("<#") && name.EndsWith(">"))
- return GetChannel(name.Substring(2, name.Length - 3));
-
- if (name.StartsWith("#"))
- name = name.Substring(1);
- return _channels
- .Where(x =>
- string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase) &&
- x.ServerId == serverId
- )
- .FirstOrDefault();
+ {
+ string name2 = name.Substring(1);
+ return _channels.Where(x => x.ServerId == serverId &&
+ string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase) || string.Equals(x.Name, name2, StringComparison.OrdinalIgnoreCase));
+ }
+ else
+ {
+ return _channels.Where(x => x.ServerId == serverId &&
+ string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase));
+ }
}
+ /// Returns the role with the specified id, or null if none was found.
public Role GetRole(string id) => _roles[id];
- public Role FindRole(Server server, string name)
- => FindRole(server.Id, name);
- public Role FindRole(string serverId, string name)
+ /// Returns all roles with the specified server and name.
+ /// Name formats supported: Name and @Name. Search is case-insensitive.
+ public IEnumerable FindRoles(Server server, string name)
+ => FindRoles(server.Id, name);
+ /// Returns all roles with the specified server and name.
+ /// Name formats supported: Name and @Name. Search is case-insensitive.
+ public IEnumerable FindRoles(string serverId, string name)
{
- return _roles
- .Where(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase))
- .FirstOrDefault();
+ if (name.StartsWith("@"))
+ {
+ string name2 = name.Substring(1);
+ return _roles.Where(x => x.ServerId == serverId &&
+ string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase) || string.Equals(x.Name, name2, StringComparison.OrdinalIgnoreCase));
+ }
+ else
+ {
+ return _roles.Where(x => x.ServerId == serverId &&
+ string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase));
+ }
}
+ /// Returns the message with the specified id, or null if none was found.
public Message GetMessage(string id) => _messages[id];
- public Task DownloadMessages(Channel channel, int count)
+
+ /// Downloads last count messages from the server, starting at beforeMessageId if it's provided.
+ public Task DownloadMessages(Channel channel, int count, string beforeMessageId = null)
=> DownloadMessages(channel.Id, count);
- public async Task DownloadMessages(string channelId, int count)
+ /// Downloads last count messages from the server, starting at beforeMessageId if it's provided.
+ public async Task DownloadMessages(string channelId, int count, string beforeMessageId = null)
{
Channel channel = GetChannel(channelId);
if (channel != null && channel.Type == ChannelTypes.Text)