Browse Source

Added Before/After to update events, added dynamic IL generation

pull/22/head
RogueException 9 years ago
parent
commit
23c5137a5f
23 changed files with 367 additions and 127 deletions
  1. +14
    -13
      src/Discord.Net.Modules/ModuleManager.cs
  2. +48
    -30
      src/Discord.Net.Net45/Discord.Net.csproj
  3. +20
    -26
      src/Discord.Net/DiscordClient.Events.cs
  4. +17
    -9
      src/Discord.Net/DiscordClient.cs
  5. +3
    -0
      src/Discord.Net/DiscordConfig.cs
  6. +37
    -0
      src/Discord.Net/DynamicIL.cs
  7. +18
    -0
      src/Discord.Net/Events/ChannelUpdatedEventArgs.cs
  8. +20
    -0
      src/Discord.Net/Events/MessageUpdatedEventArgs.cs
  9. +18
    -0
      src/Discord.Net/Events/RoleUpdatedEventArgs.cs
  10. +16
    -0
      src/Discord.Net/Events/ServerUpdatedEventArgs.cs
  11. +17
    -0
      src/Discord.Net/Events/UserUpdatedEventArgs.cs
  12. +11
    -1
      src/Discord.Net/Models/Channel.cs
  13. +12
    -2
      src/Discord.Net/Models/Color.cs
  14. +0
    -9
      src/Discord.Net/Models/Emoji.cs
  15. +13
    -5
      src/Discord.Net/Models/Invite.cs
  16. +14
    -9
      src/Discord.Net/Models/Message.cs
  17. +34
    -10
      src/Discord.Net/Models/Permissions.cs
  18. +10
    -0
      src/Discord.Net/Models/Profile.cs
  19. +1
    -1
      src/Discord.Net/Models/Region.cs
  20. +12
    -2
      src/Discord.Net/Models/Role.cs
  21. +18
    -8
      src/Discord.Net/Models/Server.cs
  22. +12
    -2
      src/Discord.Net/Models/User.cs
  23. +2
    -0
      src/Discord.Net/project.json

+ 14
- 13
src/Discord.Net.Modules/ModuleManager.cs View File

@@ -15,31 +15,31 @@ namespace Discord.Modules
public event EventHandler<ChannelEventArgs> ChannelDisabled = delegate { };

public event EventHandler<ServerEventArgs> LeftServer = delegate { };
public event EventHandler<ServerEventArgs> ServerUpdated = delegate { };
public event EventHandler<ServerUpdatedEventArgs> ServerUpdated = delegate { };
public event EventHandler<ServerEventArgs> ServerUnavailable = delegate { };
public event EventHandler<ServerEventArgs> ServerAvailable = delegate { };
public event EventHandler<ChannelEventArgs> ChannelCreated = delegate { };
public event EventHandler<ChannelEventArgs> ChannelDestroyed = delegate { };
public event EventHandler<ChannelEventArgs> ChannelUpdated = delegate { };
public event EventHandler<ChannelUpdatedEventArgs> ChannelUpdated = delegate { };

public event EventHandler<RoleEventArgs> RoleCreated = delegate { };
public event EventHandler<RoleEventArgs> RoleUpdated = delegate { };
public event EventHandler<RoleUpdatedEventArgs> RoleUpdated = delegate { };
public event EventHandler<RoleEventArgs> RoleDeleted = delegate { };

public event EventHandler<UserEventArgs> UserBanned = delegate { };
public event EventHandler<UserEventArgs> UserJoined = delegate { };
public event EventHandler<UserEventArgs> UserLeft = delegate { };
public event EventHandler<UserEventArgs> UserUpdated = delegate { };
public event EventHandler<UserEventArgs> UserPresenceUpdated = delegate { };
public event EventHandler<UserEventArgs> UserVoiceStateUpdated = delegate { };
public event EventHandler<UserUpdatedEventArgs> UserUpdated = delegate { };
//public event EventHandler<UserEventArgs> UserPresenceUpdated = delegate { };
//public event EventHandler<UserEventArgs> UserVoiceStateUpdated = delegate { };
public event EventHandler<UserEventArgs> UserUnbanned = delegate { };
public event EventHandler<ChannelUserEventArgs> UserIsTypingUpdated = delegate { };
public event EventHandler<ChannelUserEventArgs> UserIsTyping = delegate { };

public event EventHandler<MessageEventArgs> MessageReceived = delegate { };
public event EventHandler<MessageEventArgs> MessageSent = delegate { };
public event EventHandler<MessageEventArgs> MessageDeleted = delegate { };
public event EventHandler<MessageEventArgs> MessageUpdated = delegate { };
public event EventHandler<MessageUpdatedEventArgs> MessageUpdated = delegate { };
public event EventHandler<MessageEventArgs> MessageReadRemotely = delegate { };
private readonly bool _useServerWhitelist, _useChannelWhitelist, _allowAll, _allowPrivate;
@@ -79,11 +79,12 @@ namespace Discord.Modules
if (_allowAll || _useServerWhitelist) //Server-only events
{
client.ChannelCreated += (s, e) => { if (e.Server != null && HasServer(e.Server)) ChannelCreated(s, e); };
client.UserVoiceStateUpdated += (s, e) => { if (HasServer(e.Server)) UserVoiceStateUpdated(s, e); };
//TODO: This *is* a channel update if the before/after voice channel is whitelisted
//client.UserVoiceStateUpdated += (s, e) => { if (HasServer(e.Server)) UserVoiceStateUpdated(s, e); };
}

client.ChannelDestroyed += (s, e) => { if (HasChannel(e.Channel)) ChannelDestroyed(s, e); };
client.ChannelUpdated += (s, e) => { if (HasChannel(e.Channel)) ChannelUpdated(s, e); };
client.ChannelUpdated += (s, e) => { if (HasChannel(e.After)) ChannelUpdated(s, e); };

client.MessageReceived += (s, e) => { if (HasChannel(e.Channel)) MessageReceived(s, e); };
client.MessageSent += (s, e) => { if (HasChannel(e.Channel)) MessageSent(s, e); };
@@ -96,16 +97,16 @@ namespace Discord.Modules
client.RoleDeleted += (s, e) => { if (HasIndirectServer(e.Server)) RoleDeleted(s, e); };

client.LeftServer += (s, e) => { if (HasIndirectServer(e.Server)) { DisableServer(e.Server); LeftServer(s, e); } };
client.ServerUpdated += (s, e) => { if (HasIndirectServer(e.Server)) ServerUpdated(s, e); };
client.ServerUpdated += (s, e) => { if (HasIndirectServer(e.After)) ServerUpdated(s, e); };
client.ServerUnavailable += (s, e) => { if (HasIndirectServer(e.Server)) ServerUnavailable(s, e); };
client.ServerAvailable += (s, e) => { if (HasIndirectServer(e.Server)) ServerAvailable(s, e); };

client.UserJoined += (s, e) => { if (HasIndirectServer(e.Server)) UserJoined(s, e); };
client.UserLeft += (s, e) => { if (HasIndirectServer(e.Server)) UserLeft(s, e); };
client.UserUpdated += (s, e) => { if (HasIndirectServer(e.Server)) UserUpdated(s, e); };
client.UserIsTypingUpdated += (s, e) => { if (HasChannel(e.Channel)) UserIsTypingUpdated(s, e); };
client.UserIsTyping += (s, e) => { if (HasChannel(e.Channel)) UserIsTyping(s, e); };
//TODO: We aren't getting events from UserPresence if AllowPrivate is enabled, but the server we know that user through isn't on the whitelist
client.UserPresenceUpdated += (s, e) => { if (HasIndirectServer(e.Server)) UserPresenceUpdated(s, e); };
//client.UserPresenceUpdated += (s, e) => { if (HasIndirectServer(e.Server)) UserPresenceUpdated(s, e); };
client.UserBanned += (s, e) => { if (HasIndirectServer(e.Server)) UserBanned(s, e); };
client.UserUnbanned += (s, e) => { if (HasIndirectServer(e.Server)) UserUnbanned(s, e); };
}


+ 48
- 30
src/Discord.Net.Net45/Discord.Net.csproj View File

@@ -385,18 +385,9 @@
<Compile Include="..\Discord.Net\API\Status\Rest\UpcomingMaintenances.cs">
<Link>API\Status\Rest\UpcomingMaintenances.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\ChannelEventArgs.cs">
<Link>ChannelEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\ChannelUserEventArgs.cs">
<Link>ChannelUserEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Config.cs">
<Link>Config.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\DisconnectedEventArgs.cs">
<Link>DisconnectedEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\DiscordClient.cs">
<Link>DiscordClient.cs</Link>
</Compile>
@@ -406,6 +397,9 @@
<Compile Include="..\Discord.Net\DiscordConfig.cs">
<Link>DiscordConfig.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\DynamicIL.cs">
<Link>DynamicIL.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Enums\ChannelType.cs">
<Link>Enums\ChannelType.cs</Link>
</Compile>
@@ -418,12 +412,57 @@
<Compile Include="..\Discord.Net\Enums\PermissionTarget.cs">
<Link>Enums\PermissionTarget.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Enums\Relative.cs">
<Link>Enums\Relative.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Enums\StringEnum.cs">
<Link>Enums\StringEnum.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Enums\UserStatus.cs">
<Link>Enums\UserStatus.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Events\ChannelEventArgs.cs">
<Link>Events\ChannelEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Events\ChannelUpdatedEventArgs.cs">
<Link>Events\ChannelUpdatedEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Events\ChannelUserEventArgs.cs">
<Link>Events\ChannelUserEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Events\DisconnectedEventArgs.cs">
<Link>Events\DisconnectedEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Events\LogMessageEventArgs.cs">
<Link>Events\LogMessageEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Events\MessageEventArgs.cs">
<Link>Events\MessageEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Events\MessageUpdatedEventArgs.cs">
<Link>Events\MessageUpdatedEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Events\ProfileUpdatedEventArgs.cs">
<Link>Events\ProfileUpdatedEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Events\RoleEventArgs.cs">
<Link>Events\RoleEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Events\RoleUpdatedEventArgs.cs">
<Link>Events\RoleUpdatedEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Events\ServerEventArgs.cs">
<Link>Events\ServerEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Events\ServerUpdatedEventArgs.cs">
<Link>Events\ServerUpdatedEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Events\UserEventArgs.cs">
<Link>Events\UserEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Events\UserUpdatedEventArgs.cs">
<Link>Events\UserUpdatedEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Extensions.cs">
<Link>Extensions.cs</Link>
</Compile>
@@ -445,12 +484,6 @@
<Compile Include="..\Discord.Net\Logging\LogManager.cs">
<Link>Logging\LogManager.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\LogMessageEventArgs.cs">
<Link>LogMessageEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\MessageEventArgs.cs">
<Link>MessageEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\MessageQueue.cs">
<Link>MessageQueue.cs</Link>
</Compile>
@@ -532,27 +565,12 @@
<Compile Include="..\Discord.Net\Net\WebSockets\WS4NetEngine.cs">
<Link>Net\WebSockets\WS4NetEngine.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\ProfileEventArgs.cs">
<Link>ProfileEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\Relative.cs">
<Link>Relative.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\RoleEventArgs.cs">
<Link>RoleEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\ServerEventArgs.cs">
<Link>ServerEventArgs.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\ServiceManager.cs">
<Link>ServiceManager.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\TaskManager.cs">
<Link>TaskManager.cs</Link>
</Compile>
<Compile Include="..\Discord.Net\UserEventArgs.cs">
<Link>UserEventArgs.cs</Link>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>


+ 20
- 26
src/Discord.Net/DiscordClient.Events.cs View File

@@ -9,29 +9,27 @@ namespace Discord
public event EventHandler<DisconnectedEventArgs> Disconnected = delegate { };
public event EventHandler<ChannelEventArgs> ChannelCreated = delegate { };
public event EventHandler<ChannelEventArgs> ChannelDestroyed = delegate { };
public event EventHandler<ChannelEventArgs> ChannelUpdated = delegate { };
public event EventHandler<ChannelUpdatedEventArgs> ChannelUpdated = delegate { };
public event EventHandler<MessageEventArgs> MessageAcknowledged = delegate { };
public event EventHandler<MessageEventArgs> MessageDeleted = delegate { };
public event EventHandler<MessageEventArgs> MessageReceived = delegate { };
public event EventHandler<MessageEventArgs> MessageSent = delegate { };
public event EventHandler<MessageEventArgs> MessageUpdated = delegate { };
public event EventHandler<ProfileEventArgs> ProfileUpdated = delegate { };
public event EventHandler<MessageUpdatedEventArgs> MessageUpdated = delegate { };
public event EventHandler<ProfileUpdatedEventArgs> ProfileUpdated = delegate { };
public event EventHandler<RoleEventArgs> RoleCreated = delegate { };
public event EventHandler<RoleEventArgs> RoleUpdated = delegate { };
public event EventHandler<RoleUpdatedEventArgs> RoleUpdated = delegate { };
public event EventHandler<RoleEventArgs> RoleDeleted = delegate { };
public event EventHandler<ServerEventArgs> JoinedServer = delegate { };
public event EventHandler<ServerEventArgs> LeftServer = delegate { };
public event EventHandler<ServerEventArgs> ServerAvailable = delegate { };
public event EventHandler<ServerEventArgs> ServerUpdated = delegate { };
public event EventHandler<ServerUpdatedEventArgs> ServerUpdated = delegate { };
public event EventHandler<ServerEventArgs> ServerUnavailable = delegate { };
public event EventHandler<UserEventArgs> UserBanned = delegate { };
public event EventHandler<ChannelUserEventArgs> UserIsTypingUpdated = delegate { };
public event EventHandler<ChannelUserEventArgs> UserIsTyping = delegate { };
public event EventHandler<UserEventArgs> UserJoined = delegate { };
public event EventHandler<UserEventArgs> UserLeft = delegate { };
public event EventHandler<UserEventArgs> UserPresenceUpdated = delegate { };
public event EventHandler<UserEventArgs> UserUpdated = delegate { };
public event EventHandler<UserUpdatedEventArgs> UserUpdated = delegate { };
public event EventHandler<UserEventArgs> UserUnbanned = delegate { };
public event EventHandler<UserEventArgs> UserVoiceStateUpdated = delegate { };

private void OnConnected()
=> OnEvent(Connected);
@@ -42,8 +40,8 @@ namespace Discord
=> OnEvent(ChannelCreated, new ChannelEventArgs(channel));
private void OnChannelDestroyed(Channel channel)
=> OnEvent(ChannelDestroyed, new ChannelEventArgs(channel));
private void OnChannelUpdated(Channel channel)
=> OnEvent(ChannelUpdated, new ChannelEventArgs(channel));
private void OnChannelUpdated(Channel before, Channel after)
=> OnEvent(ChannelUpdated, new ChannelUpdatedEventArgs(before, after));
private void OnMessageAcknowledged(Message msg)
=> OnEvent(MessageAcknowledged, new MessageEventArgs(msg));
@@ -53,18 +51,18 @@ namespace Discord
=> OnEvent(MessageReceived, new MessageEventArgs(msg));
internal void OnMessageSent(Message msg)
=> OnEvent(MessageSent, new MessageEventArgs(msg));
private void OnMessageUpdated(Message msg)
=> OnEvent(MessageUpdated, new MessageEventArgs(msg));
private void OnMessageUpdated(Message before, Message after)
=> OnEvent(MessageUpdated, new MessageUpdatedEventArgs(before, after));

private void OnProfileUpdated(Profile profile)
=> OnEvent(ProfileUpdated, new ProfileEventArgs(profile));
private void OnProfileUpdated(Profile before, Profile after)
=> OnEvent(ProfileUpdated, new ProfileUpdatedEventArgs(before, after));

private void OnRoleCreated(Role role)
=> OnEvent(RoleCreated, new RoleEventArgs(role));
private void OnRoleDeleted(Role role)
=> OnEvent(RoleDeleted, new RoleEventArgs(role));
private void OnRoleUpdated(Role role)
=> OnEvent(RoleUpdated, new RoleEventArgs(role));
private void OnRoleUpdated(Role before, Role after)
=> OnEvent(RoleUpdated, new RoleUpdatedEventArgs(before, after));

private void OnJoinedServer(Server server)
=> OnEvent(JoinedServer, new ServerEventArgs(server));
@@ -72,27 +70,23 @@ namespace Discord
=> OnEvent(LeftServer, new ServerEventArgs(server));
private void OnServerAvailable(Server server)
=> OnEvent(ServerAvailable, new ServerEventArgs(server));
private void OnServerUpdated(Server server)
=> OnEvent(ServerUpdated, new ServerEventArgs(server));
private void OnServerUpdated(Server before, Server after)
=> OnEvent(ServerUpdated, new ServerUpdatedEventArgs(before, after));
private void OnServerUnavailable(Server server)
=> OnEvent(ServerUnavailable, new ServerEventArgs(server));

private void OnUserBanned(User user)
=> OnEvent(UserBanned, new UserEventArgs(user));
private void OnUserIsTypingUpdated(Channel channel, User user)
=> OnEvent(UserIsTypingUpdated, new ChannelUserEventArgs(channel, user));
=> OnEvent(UserIsTyping, new ChannelUserEventArgs(channel, user));
private void OnUserJoined(User user)
=> OnEvent(UserJoined, new UserEventArgs(user));
private void OnUserLeft(User user)
=> OnEvent(UserLeft, new UserEventArgs(user));
private void OnUserPresenceUpdated(User user)
=> OnEvent(UserPresenceUpdated, new UserEventArgs(user));
private void OnUserUnbanned(User user)
=> OnEvent(UserUnbanned, new UserEventArgs(user));
private void OnUserUpdated(User user)
=> OnEvent(UserUpdated, new UserEventArgs(user));
private void OnUserVoiceStateUpdated(User user)
=> OnEvent(UserVoiceStateUpdated, new UserEventArgs(user));
private void OnUserUpdated(User before, User after)
=> OnEvent(UserUpdated, new UserUpdatedEventArgs(before, after));

private void OnEvent<T>(EventHandler<T> handler, T eventArgs, [CallerMemberName] string callerName = null)
{


+ 17
- 9
src/Discord.Net/DiscordClient.cs View File

@@ -546,10 +546,11 @@ namespace Discord
var server = GetServer(data.Id);
if (server != null)
{
var before = Config.EnablePreUpdateEvents ? server.Clone() : null;
server.Update(data);
if (Config.LogEvents)
Logger.Info($"Server Updated: {server.Name}");
OnServerUpdated(server);
OnServerUpdated(before, server);
}
else
Logger.Warning("GUILD_UPDATE referenced an unknown guild.");
@@ -609,10 +610,11 @@ namespace Discord
var channel = GetChannel(data.Id);
if (channel != null)
{
var before = Config.EnablePreUpdateEvents ? channel.Clone() : null;
channel.Update(data);
if (Config.LogEvents)
Logger.Info($"Channel Updated: {channel.Server?.Name ?? "[Private]"}/{channel.Name}");
OnChannelUpdated(channel);
OnChannelUpdated(before, channel);
}
else
Logger.Warning("CHANNEL_UPDATE referenced an unknown channel.");
@@ -660,10 +662,11 @@ namespace Discord
var user = server.GetUser(data.User.Id);
if (user != null)
{
var before = Config.EnablePreUpdateEvents ? user.Clone() : null;
user.Update(data);
if (Config.LogEvents)
Logger.Info($"User Updated: {server.Name}/{user.Name}");
OnUserUpdated(user);
OnUserUpdated(before, user);
}
else
Logger.Warning("GUILD_MEMBER_UPDATE referenced an unknown user.");
@@ -721,7 +724,7 @@ namespace Discord
role.Update(data.Data);
if (Config.LogEvents)
Logger.Info($"Role Created: {server.Name}/{role.Name}");
OnRoleUpdated(role);
OnRoleCreated(role);
}
else
Logger.Warning("GUILD_ROLE_CREATE referenced an unknown guild.");
@@ -736,10 +739,11 @@ namespace Discord
var role = server.GetRole(data.Data.Id);
if (role != null)
{
var before = Config.EnablePreUpdateEvents ? role.Clone() : null;
role.Update(data.Data);
if (Config.LogEvents)
Logger.Info($"Role Updated: {server.Name}/{role.Name}");
OnRoleUpdated(role);
OnRoleUpdated(before, role);
}
else
Logger.Warning("GUILD_ROLE_UPDATE referenced an unknown role.");
@@ -860,10 +864,11 @@ namespace Discord
if (channel != null)
{
var msg = channel.GetMessage(data.Id, data.Author?.Id);
var before = Config.EnablePreUpdateEvents ? msg.Clone() : null;
msg.Update(data);
if (Config.LogEvents)
Logger.Verbose($"Message Update: {channel.Server?.Name ?? "[Private]"}/{channel.Name}");
OnMessageUpdated(msg);
OnMessageUpdated(before, msg);
}
else
Logger.Warning("MESSAGE_UPDATE referenced an unknown channel.");
@@ -936,9 +941,10 @@ namespace Discord

if (user != null)
{
var before = Config.EnablePreUpdateEvents ? user.Clone() : null;
user.Update(data);
//Logger.Verbose($"Presence Updated: {server.Name}/{user.Name}");
OnUserPresenceUpdated(user);
OnUserUpdated(before, user);
}
/*else //Occurs when a user leaves a server
Logger.Warning("PRESENCE_UPDATE referenced an unknown user.");*/
@@ -982,9 +988,10 @@ namespace Discord
var user = server.GetUser(data.UserId);
if (user != null)
{
var before = Config.EnablePreUpdateEvents ? user.Clone() : null;
user.Update(data);
//Logger.Verbose($"Voice Updated: {server.Name}/{user.Name}");
OnUserVoiceStateUpdated(user);
OnUserUpdated(user, user);
}
/*else //Occurs when a user leaves a server
Logger.Warning("VOICE_STATE_UPDATE referenced an unknown user.");*/
@@ -1000,13 +1007,14 @@ namespace Discord
var data = e.Payload.ToObject<UserUpdateEvent>(Serializer);
if (data.Id == CurrentUser.Id)
{
var before = Config.EnablePreUpdateEvents ? CurrentUser.Clone() : null;
CurrentUser.Update(data);
PrivateUser.Update(data);
foreach (var server in _servers)
server.Value.CurrentUser.Update(data);
if (Config.LogEvents)
Logger.Info("Profile Updated");
OnProfileUpdated(CurrentUser);
OnProfileUpdated(before, CurrentUser);
}
}
break;


+ 3
- 0
src/Discord.Net/DiscordConfig.cs View File

@@ -103,6 +103,9 @@ namespace Discord
/// <summary> Gets or sets whether the permissions cache should be used. This makes operations such as User.GetPermissions(Channel), User.ServerPermissions and Channel.Members </summary>
public bool UsePermissionsCache { get { return _usePermissionsCache; } set { SetValue(ref _usePermissionsCache, value); } }
private bool _usePermissionsCache = true;
/// <summary> Gets or sets whether the a copy of a model is generated on an update event to allow a user to check which properties changed. </summary>
public bool EnablePreUpdateEvents { get { return _enablePreUpdateEvents; } set { SetValue(ref _enablePreUpdateEvents, value); } }
private bool _enablePreUpdateEvents = true;

public DiscordConfig()
{


+ 37
- 0
src/Discord.Net/DynamicIL.cs View File

@@ -0,0 +1,37 @@
using System;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;

namespace Discord
{
internal static class DynamicIL
{
public static Action<T, T> CreateCloner<T>()
{
var method = new DynamicMethod("CopyFields", null, new[] { typeof(T), typeof(T) }, typeof(T), true);
var generator = method.GetILGenerator();
var typeInfo = typeof(T).GetTypeInfo();
CopyFields(generator, typeInfo);

generator.Emit(OpCodes.Ret);

return method.CreateDelegate(typeof(Action<T, T>)) as Action<T, T>;
}
private static void CopyFields(ILGenerator generator, TypeInfo typeInfo)
{
foreach (var field in typeInfo.DeclaredFields.Where(x => !x.IsStatic))
{
generator.Emit(OpCodes.Ldarg_1); //Stack: TargetRef
generator.Emit(OpCodes.Ldarg_0); //Stack: TargetRef, SourceRef
generator.Emit(OpCodes.Ldfld, field); //Stack: TargetRef, Value
generator.Emit(OpCodes.Stfld, field); //Stack:
}

var baseType = typeInfo.BaseType;
if (baseType != null && baseType.AssemblyQualifiedName == typeInfo.AssemblyQualifiedName)
CopyFields(generator, baseType.GetTypeInfo());
}
}
}

+ 18
- 0
src/Discord.Net/Events/ChannelUpdatedEventArgs.cs View File

@@ -0,0 +1,18 @@
using System;

namespace Discord
{
public class ChannelUpdatedEventArgs : EventArgs
{
public Channel Before { get; }
public Channel After { get; }

public Server Server => After.Server;

public ChannelUpdatedEventArgs(Channel before, Channel after)
{
Before = before;
After = after;
}
}
}

+ 20
- 0
src/Discord.Net/Events/MessageUpdatedEventArgs.cs View File

@@ -0,0 +1,20 @@
using System;

namespace Discord
{
public class MessageUpdatedEventArgs : EventArgs
{
public Message Before { get; }
public Message After { get; }

public User User => After.User;
public Channel Channel => After.Channel;
public Server Server => After.Server;

public MessageUpdatedEventArgs(Message before, Message after)
{
Before = before;
After = after;
}
}
}

+ 18
- 0
src/Discord.Net/Events/RoleUpdatedEventArgs.cs View File

@@ -0,0 +1,18 @@
using System;

namespace Discord
{
public class RoleUpdatedEventArgs : EventArgs
{
public Role Before { get; }
public Role After { get; }

public Server Server => After.Server;

public RoleUpdatedEventArgs(Role before, Role after)
{
Before = before;
After = after;
}
}
}

+ 16
- 0
src/Discord.Net/Events/ServerUpdatedEventArgs.cs View File

@@ -0,0 +1,16 @@
using System;

namespace Discord
{
public class ServerUpdatedEventArgs : EventArgs
{
public Server Before { get; }
public Server After { get; }

public ServerUpdatedEventArgs(Server before, Server after)
{
Before = before;
After = after;
}
}
}

+ 17
- 0
src/Discord.Net/Events/UserUpdatedEventArgs.cs View File

@@ -0,0 +1,17 @@
using System;
namespace Discord
{
public class UserUpdatedEventArgs : EventArgs
{
public User Before { get; }
public User After { get; }

public Server Server => After.Server;

public UserUpdatedEventArgs(User before, User after)
{
Before = before;
After = after;
}
}
}

+ 11
- 1
src/Discord.Net/Models/Channel.cs View File

@@ -14,6 +14,8 @@ namespace Discord
{
public sealed class Channel : IMentionable
{
private readonly static Action<Channel, Channel> _cloner = DynamicIL.CreateCloner<Channel>();

private struct Member
{
public readonly User User;
@@ -102,7 +104,7 @@ namespace Discord
return Enumerable.Empty<User>();
}
}
internal Channel(DiscordClient client, ulong id, Server server)
: this(client, id)
{
@@ -598,6 +600,14 @@ namespace Discord
}
#endregion

internal Channel Clone()
{
var result = new Channel();
_cloner(this, result);
return result;
}
private Channel() { }

public override string ToString() => Name ?? Id.ToIdString();
}
}

+ 12
- 2
src/Discord.Net/Models/Color.cs View File

@@ -3,8 +3,10 @@
namespace Discord
{
public sealed class Color : IEquatable<Color>
{
public static readonly Color Default = PresetColor(0);
{
private readonly static Action<Color, Color> _cloner = DynamicIL.CreateCloner<Color>();

public static readonly Color Default = PresetColor(0);

public static readonly Color Teal = PresetColor(0x1ABC9C);
public static readonly Color DarkTeal = PresetColor(0x11806A);
@@ -83,6 +85,14 @@ namespace Discord
public override bool Equals(object obj) => (obj as Color)?.Equals(this) ?? false;
public bool Equals(Color color) => color != null && color._rawValue == _rawValue;

internal Color Clone()
{
var result = new Color();
_cloner(this, result);
return result;
}
private Color() { } //Used for cloning

public override string ToString() => '#' + _rawValue.ToString("X");
}
}

+ 0
- 9
src/Discord.Net/Models/Emoji.cs View File

@@ -1,9 +0,0 @@
using Discord.API.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Discord.Models
{
}

+ 13
- 5
src/Discord.Net/Models/Invite.cs View File

@@ -9,8 +9,10 @@ using APIInvite = Discord.API.Client.Invite;
namespace Discord
{
public sealed class Invite
{
public sealed class ServerInfo
{
private readonly static Action<Invite, Invite> _cloner = DynamicIL.CreateCloner<Invite>();

public sealed class ServerInfo
{
/// <summary> Returns the unique identifier of this server. </summary>
public ulong Id { get; }
@@ -126,8 +128,14 @@ namespace Discord
public Task Accept()
=> Client.ClientAPI.Send(new AcceptInviteRequest(Code));

public override bool Equals(object obj) => obj is Invite && (obj as Invite).Code == Code;
public override int GetHashCode() => unchecked(Code.GetHashCode() + 9980);
public override string ToString() => XkcdCode ?? Code;
internal Invite Clone()
{
var result = new Invite();
_cloner(this, result);
return result;
}
private Invite() { } //Used for cloning

public override string ToString() => XkcdCode ?? Code;
}
}

+ 14
- 9
src/Discord.Net/Models/Message.cs View File

@@ -1,12 +1,9 @@
using Discord.API.Client.Rest;
using Discord.Net;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using APIMessage = Discord.API.Client.Message;
@@ -27,9 +24,11 @@ namespace Discord

public sealed class Message
{
private static readonly Regex _userRegex = new Regex(@"<@[0-9]+>", RegexOptions.Compiled);
private static readonly Regex _channelRegex = new Regex(@"<#[0-9]+>", RegexOptions.Compiled);
private static readonly Regex _roleRegex = new Regex(@"@everyone", RegexOptions.Compiled);
private readonly static Action<Message, Message> _cloner = DynamicIL.CreateCloner<Message>();

private static readonly Regex _userRegex = new Regex(@"<@[0-9]+>");
private static readonly Regex _channelRegex = new Regex(@"<#[0-9]+>");
private static readonly Regex _roleRegex = new Regex(@"@everyone");
private static readonly Attachment[] _initialAttachments = new Attachment[0];
private static readonly Embed[] _initialEmbeds = new Embed[0];

@@ -369,8 +368,14 @@ namespace Discord
return Resolve(Channel, text);
}

public override bool Equals(object obj) => obj is Message && (obj as Message).Id == Id;
public override int GetHashCode() => unchecked(Id.GetHashCode() + 9979);
public override string ToString() => $"{User?.Name ?? "Unknown User"}: {RawText}";
internal Message Clone()
{
var result = new Message();
_cloner(this, result);
return result;
}
private Message() { } //Used for cloning

public override string ToString() => $"{User?.Name ?? "Unknown User"}: {RawText}";
}
}

+ 34
- 10
src/Discord.Net/Models/Permissions.cs View File

@@ -32,16 +32,24 @@ namespace Discord
}

public sealed class ServerPermissions : Permissions
{
public static ServerPermissions None { get; } = new ServerPermissions();
{
private readonly static Action<ServerPermissions, ServerPermissions> _cloner = DynamicIL.CreateCloner<ServerPermissions>();

public static ServerPermissions None { get; } = new ServerPermissions();
public static ServerPermissions All { get; } = new ServerPermissions(Convert.ToUInt32("00000011111100111111110000111111", 2));

public ServerPermissions() : base() { }
public ServerPermissions(uint rawValue) : base(rawValue) { }
public ServerPermissions Copy() => new ServerPermissions(RawValue);
internal ServerPermissions Clone()
{
var result = new ServerPermissions();
_cloner(this, result);
return result;
}

/// <summary> If True, a user may ban users from the server. </summary>
public bool BanMembers { get { return GetBit(PermissionsBits.BanMembers); } set { SetBit(PermissionsBits.BanMembers, value); } }
/// <summary> If True, a user may ban users from the server. </summary>
public bool BanMembers { get { return GetBit(PermissionsBits.BanMembers); } set { SetBit(PermissionsBits.BanMembers, value); } }
/// <summary> If True, a user may kick users from the server. </summary>
public bool KickMembers { get { return GetBit(PermissionsBits.KickMembers); } set { SetBit(PermissionsBits.KickMembers, value); } }
/// <summary> If True, a user may adjust roles. This also implictly grants all other permissions. </summary>
@@ -53,8 +61,10 @@ namespace Discord
}

public sealed class ChannelPermissions : Permissions
{
public static ChannelPermissions None { get; } = new ChannelPermissions();
{
private readonly static Action<ChannelPermissions, ChannelPermissions> _cloner = DynamicIL.CreateCloner<ChannelPermissions>();

public static ChannelPermissions None { get; } = new ChannelPermissions();
public static ChannelPermissions TextOnly { get; } = new ChannelPermissions(Convert.ToUInt32("00000000000000111111110000011001", 2));
public static ChannelPermissions PrivateOnly { get; } = new ChannelPermissions(Convert.ToUInt32("00000000000000011100110000000000", 2));
public static ChannelPermissions VoiceOnly { get; } = new ChannelPermissions(Convert.ToUInt32("00000011111100000000000000011001", 2));
@@ -70,9 +80,15 @@ namespace Discord
public ChannelPermissions() : base() { }
public ChannelPermissions(uint rawValue) : base(rawValue) { }
public ChannelPermissions Copy() => new ChannelPermissions(RawValue);
internal ChannelPermissions Clone()
{
var result = new ChannelPermissions();
_cloner(this, result);
return result;
}

/// <summary> If True, a user may adjust permissions. This also implictly grants all other permissions. </summary>
public bool ManagePermissions { get { return GetBit(PermissionsBits.ManageRolesOrPermissions); } set { SetBit(PermissionsBits.ManageRolesOrPermissions, value); } }
/// <summary> If True, a user may adjust permissions. This also implictly grants all other permissions. </summary>
public bool ManagePermissions { get { return GetBit(PermissionsBits.ManageRolesOrPermissions); } set { SetBit(PermissionsBits.ManageRolesOrPermissions, value); } }
/// <summary> If True, a user may create, delete and modify this channel. </summary>
public bool ManageChannel { get { return GetBit(PermissionsBits.ManageChannel); } set { SetBit(PermissionsBits.ManageChannel, value); } }
}
@@ -152,8 +168,10 @@ namespace Discord
}

public sealed class DualChannelPermissions
{
public ChannelPermissions Allow { get; }
{
private readonly static Action<DualChannelPermissions, DualChannelPermissions> _cloner = DynamicIL.CreateCloner<DualChannelPermissions>();

public ChannelPermissions Allow { get; }
public ChannelPermissions Deny { get; }
public DualChannelPermissions(uint allow = 0, uint deny = 0)
@@ -233,6 +251,12 @@ namespace Discord
Deny.Lock();
}
public DualChannelPermissions Copy() => new DualChannelPermissions(Allow.RawValue, Deny.RawValue);
internal DualChannelPermissions Clone()
{
var result = new DualChannelPermissions();
_cloner(this, result);
return result;
}

public static bool operator ==(DualChannelPermissions a, DualChannelPermissions b) => ((object)a == null && (object)b == null) || (a?.Equals(b) ?? false);
public static bool operator !=(DualChannelPermissions a, DualChannelPermissions b) => !(a == b);


+ 10
- 0
src/Discord.Net/Models/Profile.cs View File

@@ -8,6 +8,8 @@ namespace Discord
{
public sealed class Profile
{
private readonly static Action<Profile, Profile> _cloner = DynamicIL.CreateCloner<Profile>();

internal DiscordClient Client { get; }

/// <summary> Gets the unique identifier for this user. </summary>
@@ -75,6 +77,14 @@ namespace Discord
}
}

internal Profile Clone()
{
var result = new Profile();
_cloner(this, result);
return result;
}
private Profile() { } //Used for cloning

public override string ToString() => Id.ToIdString();
}
}

+ 1
- 1
src/Discord.Net/Models/Region.cs View File

@@ -16,5 +16,5 @@
Port = port;
Vip = vip;
}
}
}
}

+ 12
- 2
src/Discord.Net/Models/Role.cs View File

@@ -11,6 +11,8 @@ namespace Discord
{
public sealed class Role : IMentionable
{
private readonly static Action<Role, Role> _cloner = DynamicIL.CreateCloner<Role>();

internal DiscordClient Client => Server.Client;

/// <summary> Gets the unique identifier for this role. </summary>
@@ -117,7 +119,15 @@ namespace Discord
try { await Client.ClientAPI.Send(new DeleteRoleRequest(Server.Id, Id)).ConfigureAwait(false); }
catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { }
}
public override string ToString() => Name ?? Id.ToIdString();

internal Role Clone()
{
var result = new Role();
_cloner(this, result);
return result;
}
private Role() { } //Used for cloning

public override string ToString() => Name ?? Id.ToIdString();
}
}

+ 18
- 8
src/Discord.Net/Models/Server.cs View File

@@ -14,6 +14,8 @@ namespace Discord
/// <summary> Represents a Discord server (also known as a guild). </summary>
public sealed class Server
{
private readonly static Action<Server, Server> _cloner = DynamicIL.CreateCloner<Server>();

internal static string GetIconUrl(ulong serverId, string iconId)
=> iconId != null ? $"{DiscordConfig.ClientAPIUrl}guilds/${serverId}/icons/${iconId}.jpg" : null;
internal static string GetSplashUrl(ulong serverId, string splashId)
@@ -85,8 +87,9 @@ namespace Discord
public Channel AFKChannel => _afkChannelId != null ? GetChannel(_afkChannelId.Value) : null;
/// <summary> Gets the current user in this server. </summary>
public User CurrentUser => GetUser(Client.CurrentUser.Id);
/// <summary> Gets the URL to this user's current avatar. </summary>
/// <summary> Gets the URL to this server's current icon. </summary>
public string IconUrl => GetIconUrl(Id, IconId);
/// <summary> Gets the URL to this servers's splash image. </summary>
public string SplashUrl => GetSplashUrl(Id, SplashId);

/// <summary> Gets a collection of all channels in this server. </summary>
@@ -143,16 +146,15 @@ namespace Discord
Roles = x.RoleIds.Select(y => GetRole(y)).Where(y => y != null).ToArray()
}).ToArray();
}

//Can be null
_afkChannelId = model.AFKChannelId;
SplashId = model.Splash;

if (model.Roles != null)
{
foreach (var x in model.Roles)
AddRole(x.Id).Update(x);
}

//Can be null
_afkChannelId = model.AFKChannelId;
SplashId = model.Splash;
}
internal void Update(ExtendedGuild model)
{
@@ -498,7 +500,15 @@ namespace Discord
public void RequestOfflineUsers()
=> Client.GatewaySocket.SendRequestMembers(Id, "", 0);
#endregion
public override string ToString() => Name ?? Id.ToIdString();

internal Server Clone()
{
var result = new Server();
_cloner(this, result);
return result;
}
private Server() { } //Used for cloning

public override string ToString() => Name ?? Id.ToIdString();
}
}

+ 12
- 2
src/Discord.Net/Models/User.cs View File

@@ -9,8 +9,10 @@ using APIMember = Discord.API.Client.Member;

namespace Discord
{
public sealed class User : IMentionable
public sealed class User
{
private readonly static Action<User, User> _cloner = DynamicIL.CreateCloner<User>();

internal static string GetAvatarUrl(ulong userId, string avatarId)
=> avatarId != null ? $"{DiscordConfig.ClientAPIUrl}users/{userId}/avatars/{avatarId}.jpg" : null;

@@ -338,6 +340,14 @@ namespace Discord
=> Edit(roles: Roles.Except(roles));
#endregion

public override string ToString() => Name != null ? $"{Name}#{Discriminator}" : Id.ToIdString();
internal User Clone()
{
var result = new User();
_cloner(this, result);
return result;
}
private User() { } //Used for cloning

public override string ToString() => Name != null ? $"{Name}#{Discriminator}" : Id.ToIdString();
}
}

+ 2
- 0
src/Discord.Net/project.json View File

@@ -50,6 +50,8 @@
"System.Net.Sockets": "4.1.0-beta-23409",
"System.Net.Requests": "4.0.11-beta-23516",
"System.Net.WebSockets.Client": "4.0.0-beta-23516",
"System.Reflection": "4.1.0-beta-23516",
"System.Reflection.Emit.Lightweight": "4.0.1-beta-23516",
"System.Runtime.InteropServices": "4.0.21-beta-23516",
"System.Security.Cryptography.Algorithms": "4.0.0-beta-23516",
"System.Text.RegularExpressions": "4.0.11-beta-23516",


Loading…
Cancel
Save