I shan't, it's Christmas!

This commit is contained in:
RogueException
2015-12-23 04:35:14 -04:00
parent f832eadba8
commit 89eba9acb4
14 changed files with 88 additions and 126 deletions

View File

@@ -68,7 +68,7 @@ namespace Discord.Commands
client.MessageReceived += async (s, e) =>
{
if (_allCommands.Count == 0) return;
if (e.Message.User.Id == _client.CurrentUser.Id) return;
if (e.Message.User == null || e.Message.User.Id == _client.CurrentUser.Id) return;
string msg = e.Message.RawText;
if (msg.Length == 0) return;

View File

@@ -9,8 +9,7 @@ namespace Discord.API.Client
{
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("id")]
[JsonConverter(typeof(LongStringConverter))]
[JsonProperty("id"), JsonConverter(typeof(LongStringConverter))]
public ulong Id { get; set; }
[JsonProperty("deny")]
public uint Deny { get; set; }

View File

@@ -7,8 +7,8 @@ namespace Discord.API.Client
{
[JsonProperty("id"), JsonConverter(typeof(LongStringConverter))]
public ulong Id { get; set; }
[JsonProperty("guild_id"), JsonConverter(typeof(LongStringConverter))]
public ulong GuildId { get; set; }
[JsonProperty("guild_id"), JsonConverter(typeof(NullableLongStringConverter))]
public ulong? GuildId { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("type")]

View File

@@ -5,7 +5,7 @@ namespace Discord.API.Client
{
public class MemberReference
{
[JsonProperty("guild_id"), JsonConverter(typeof(LongStringConverter))]
[JsonProperty("guild_id"), JsonConverter(typeof(NullableLongStringConverter))]
public ulong? GuildId { get; set; }
[JsonProperty("user")]
public UserReference User { get; set; }

View File

@@ -171,10 +171,7 @@ namespace Discord
State = ConnectionState.Connecting;
_disconnectedEvent.Reset();
await Login(email, password, token).ConfigureAwait(false);
ClientAPI.Token = token;
GatewaySocket.Token = token;
await Login(email, password, token).ConfigureAwait(false);
await GatewaySocket.Connect().ConfigureAwait(false);
List<Task> tasks = new List<Task>();
@@ -233,6 +230,9 @@ namespace Discord
}
}
ClientAPI.Token = token;
GatewaySocket.Token = token;
//Get gateway and check token
try
{
@@ -309,22 +309,10 @@ namespace Discord
}
#region Channels
private Channel AddChannel(ulong id, ulong? guildId, ulong? recipientId)
internal void AddChannel(Channel channel)
{
Channel channel;
if (recipientId != null)
{
channel = _privateChannels.GetOrAdd(recipientId.Value,
x => new Channel(this, x, new User(this, recipientId.Value, null)));
}
else
{
var server = GetServer(guildId.Value);
channel = server.AddChannel(id);
}
_channels[channel.Id] = channel;
return channel;
}
}
private Channel RemoveChannel(ulong id)
{
Channel channel;
@@ -337,20 +325,26 @@ namespace Discord
}
return channel;
}
internal Channel GetChannel(ulong id)
public Channel GetChannel(ulong id)
{
Channel channel;
_channels.TryGetValue(id, out channel);
return channel;
}
private Channel AddPrivateChannel(ulong id, ulong recipientId)
{
Channel channel;
if (_privateChannels.TryGetOrAdd(recipientId, x => new Channel(this, id, new User(this, x, null)), out channel))
AddChannel(channel);
return channel;
}
internal Channel GetPrivateChannel(ulong recipientId)
{
Channel channel;
_privateChannels.TryGetValue(recipientId, out channel);
return channel;
}
internal async Task<Channel> CreatePrivateChannel(User user)
{
var channel = GetPrivateChannel(user.Id);
@@ -358,8 +352,8 @@ namespace Discord
var request = new CreatePrivateChannelRequest() { RecipientId = user.Id };
var response = await ClientAPI.Send(request).ConfigureAwait(false);
channel = AddChannel(response.Id, null, response.Recipient.Id);
channel = AddPrivateChannel(response.Id, user.Id);
channel.Update(response);
return channel;
}
@@ -453,6 +447,7 @@ namespace Discord
SessionId = data.SessionId;
PrivateUser = new User(this, data.User.Id, null);
PrivateUser.Update(data.User);
CurrentUser = new Profile(this, data.User.Id);
CurrentUser.Update(data.User);
foreach (var model in data.Guilds)
{
@@ -464,7 +459,7 @@ namespace Discord
}
foreach (var model in data.PrivateChannels)
{
var channel = AddChannel(model.Id, null, model.Recipient.Id);
var channel = AddPrivateChannel(model.Id, model.Recipient.Id);
channel.Update(model);
}
}
@@ -523,10 +518,22 @@ namespace Discord
case "CHANNEL_CREATE":
{
var data = e.Payload.ToObject<ChannelCreateEvent>(_serializer);
Channel channel = AddChannel(data.Id, data.GuildId, data.Recipient.Id);
channel.Update(data);
Logger.Info($"Channel Created: {channel.Server?.Name ?? "[Private]"}/{channel.Name}");
OnChannelCreated(channel);
Channel channel = null;
if (data.GuildId != null)
{
var server = GetServer(data.GuildId.Value);
if (server != null)
channel = server.AddChannel(data.Id);
}
else
channel = AddPrivateChannel(data.Id, data.Recipient.Id);
if (channel != null)
{
channel.Update(data);
Logger.Info($"Channel Created: {channel.Server?.Name ?? "[Private]"}/{channel.Name}");
OnChannelCreated(channel);
}
}
break;
case "CHANNEL_UPDATE":

View File

@@ -27,15 +27,22 @@ namespace Discord
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool HasBit(this uint value, byte bit) => ((value >> bit) & 1U) == 1;
public static bool TryGetAdd<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> d,
public static bool TryGetOrAdd<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> d,
TKey key, Func<TKey, TValue> factory, out TValue result)
where TValue : class
{
TValue newValue = null;
while (true)
{
if (d.TryGetValue(key, out result))
return false;
if (d.TryAdd(key, factory(key)))
if (newValue == null)
newValue = factory(key);
if (d.TryAdd(key, newValue))
{
result = newValue;
return true;
}
}
}

View File

@@ -112,7 +112,6 @@ namespace Discord
: this(client, id)
{
Recipient = recipient;
Name = $"@{recipient}";
AddUser(client.PrivateUser);
AddUser(recipient);
}
@@ -143,7 +142,10 @@ namespace Discord
if (model.Topic != null)
Topic = model.Topic;
if (model.Recipient != null)
{
Recipient.Update(model.Recipient);
Name = $"@{Recipient}";
}
if (model.PermissionOverwrites != null)
{
@@ -263,9 +265,13 @@ namespace Discord
public Message GetMessage(ulong id)
{
Message result;
_messages.TryGetValue(id, out result);
return result;
if (Client.Config.MessageCacheSize > 0)
{
Message result;
_messages.TryGetValue(id, out result);
return result;
}
return null;
}
public async Task<Message[]> DownloadMessages(int limit = 100, ulong? relativeMessageId = null,
RelativeDirection relativeDir = RelativeDirection.Before, bool useCache = true)
@@ -556,6 +562,17 @@ namespace Discord
}
public User GetUser(ulong id)
{
if (!Client.Config.UsePermissionsCache)
{
var user = Server.GetUser(id);
ChannelPermissions perms = new ChannelPermissions();
UpdatePermissions(user, perms);
if (perms.ReadMessages)
return user;
else
return null;
}
Member result;
_users.TryGetValue(id, out result);
return result.User;

View File

@@ -28,7 +28,6 @@ namespace Discord
public static readonly Color LightGrey = PresetColor(0x979C9F);
public static readonly Color DarkerGrey = PresetColor(0x546E7A);
private static Color PresetColor(uint packedValue)
{
Color color = new Color(packedValue);

View File

@@ -1,79 +0,0 @@
using Newtonsoft.Json;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using APIUser = Discord.API.Client.User;
namespace Discord
{
/*public sealed class GlobalUser : CachedObject<ulong>
{
/// <summary> Returns the email for this user. Note: this field is only ever populated for the current logged in user. </summary>
[JsonIgnore]
public string Email { get; private set; }
/// <summary> Returns if the email for this user has been verified. Note: this field is only ever populated for the current logged in user. </summary>
[JsonIgnore]
public bool? IsVerified { get; private set; }
/// <summary> Returns the private messaging channel with this user, if one exists. </summary>
[JsonIgnore]
public Channel PrivateChannel
{
get { return _privateChannel; }
set
{
_privateChannel = value;
if (value == null)
CheckUser();
}
}
[JsonProperty]
private ulong? PrivateChannelId => _privateChannel?.Id;
private Channel _privateChannel;
/// <summary> Returns a collection of all server-specific data for every server this user is a member of. </summary>
[JsonIgnore]
public IEnumerable<User> Memberships => _users.Select(x => x.Value);
[JsonProperty]
private IEnumerable<ulong> ServerIds => _users.Select(x => x.Key);
private readonly ConcurrentDictionary<ulong, User> _users;
/// <summary> Returns the string used to mention this user. </summary>
public string Mention => $"<@{Id}>";
internal GlobalUser(DiscordClient client, ulong id)
: base(client, id)
{
_users = new ConcurrentDictionary<ulong, User>();
}
internal override bool LoadReferences() { return true; }
internal override void UnloadReferences()
{
//Don't need to clean _users - they're considered owned by server
}
internal void Update(APIUser model)
{
if (model.Email != null)
Email = model.Email;
if (model.IsVerified != null)
IsVerified = model.IsVerified;
}
internal void AddUser(User user) => _users.TryAdd(user.Server?.Id ?? 0, user);
internal void RemoveUser(User user)
{
if (_users.TryRemove(user.Server?.Id ?? 0, out user))
CheckUser();
}
internal void CheckUser()
{
if (_users.Count == 0 && PrivateChannel == null)
_client.GlobalUsers.TryRemove(Id);
}
public override bool Equals(object obj) => obj is GlobalUser && (obj as GlobalUser).Id == Id;
public override int GetHashCode() => unchecked(Id.GetHashCode() + 7891);
public override string ToString() => IdConvert.ToString(Id);
}*/
}

View File

@@ -201,6 +201,10 @@ namespace Discord
internal Message(ulong id, Channel channel, ulong userId)
{
Id = id;
Channel = channel;
_userId = userId;
Attachments = _initialAttachments;
Embeds = _initialEmbeds;
}

View File

@@ -11,20 +11,21 @@ namespace Discord
internal DiscordClient Client { get; }
/// <summary> Gets the unique identifier for this user. </summary>
public ulong Id { get; private set; }
public ulong Id { get; }
/// <summary> Gets the email for this user. </summary>
public string Email { get; private set; }
/// <summary> Gets if the email for this user has been verified. </summary>
public bool? IsVerified { get; private set; }
internal Profile(DiscordClient client)
internal Profile(DiscordClient client, ulong id)
{
Client = client;
Id = id;
}
internal void Update(APIUser model)
{
Id = model.Id;
Email = model.Email;
IsVerified = model.IsVerified;
}

View File

@@ -52,6 +52,7 @@ namespace Discord
{
Id = id;
Server = server;
Permissions = new ServerPermissions(0);
Permissions.Lock();
Color = new Color(0);

View File

@@ -78,6 +78,7 @@ namespace Discord
{
Client = client;
Id = id;
_channels = new ConcurrentDictionary<ulong, Channel>();
_roles = new ConcurrentDictionary<ulong, Role>();
_users = new ConcurrentDictionary<ulong, Member>();
@@ -97,7 +98,7 @@ namespace Discord
if (model.AFKTimeout != null)
AFKTimeout = model.AFKTimeout.Value;
_afkChannelId = model.AFKChannelId.Value; //Can be null
_afkChannelId = model.AFKChannelId; //Can be null
if (model.JoinedAt != null)
JoinedAt = model.JoinedAt.Value;
if (model.OwnerId != null)
@@ -196,7 +197,11 @@ namespace Discord
#region Channels
internal Channel AddChannel(ulong id)
=> _channels.GetOrAdd(id, x => new Channel(Client, x, this));
{
var channel = _channels.GetOrAdd(id, x => new Channel(Client, x, this));
Client.AddChannel(channel);
return channel;
}
internal Channel RemoveChannel(ulong id)
{
Channel channel;

View File

@@ -136,9 +136,10 @@ namespace Discord
internal User(DiscordClient client, ulong id, Server server)
{
Client = client;
Id = id;
Server = server;
_roles = new Dictionary<ulong, Role>();
_roles = new Dictionary<ulong, Role>();
Status = UserStatus.Offline;
if (server == null)