| @@ -15,31 +15,31 @@ namespace Discord.Modules | |||||
| public event EventHandler<ChannelEventArgs> ChannelDisabled = delegate { }; | public event EventHandler<ChannelEventArgs> ChannelDisabled = delegate { }; | ||||
| public event EventHandler<ServerEventArgs> LeftServer = 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> ServerUnavailable = delegate { }; | ||||
| public event EventHandler<ServerEventArgs> ServerAvailable = delegate { }; | public event EventHandler<ServerEventArgs> ServerAvailable = delegate { }; | ||||
| public event EventHandler<ChannelEventArgs> ChannelCreated = delegate { }; | public event EventHandler<ChannelEventArgs> ChannelCreated = delegate { }; | ||||
| public event EventHandler<ChannelEventArgs> ChannelDestroyed = 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> RoleCreated = delegate { }; | ||||
| public event EventHandler<RoleEventArgs> RoleUpdated = delegate { }; | |||||
| public event EventHandler<RoleUpdatedEventArgs> RoleUpdated = delegate { }; | |||||
| public event EventHandler<RoleEventArgs> RoleDeleted = delegate { }; | public event EventHandler<RoleEventArgs> RoleDeleted = delegate { }; | ||||
| public event EventHandler<UserEventArgs> UserBanned = delegate { }; | public event EventHandler<UserEventArgs> UserBanned = delegate { }; | ||||
| public event EventHandler<UserEventArgs> UserJoined = delegate { }; | public event EventHandler<UserEventArgs> UserJoined = delegate { }; | ||||
| public event EventHandler<UserEventArgs> UserLeft = 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<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> MessageReceived = delegate { }; | ||||
| public event EventHandler<MessageEventArgs> MessageSent = delegate { }; | public event EventHandler<MessageEventArgs> MessageSent = delegate { }; | ||||
| public event EventHandler<MessageEventArgs> MessageDeleted = 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 { }; | public event EventHandler<MessageEventArgs> MessageReadRemotely = delegate { }; | ||||
| private readonly bool _useServerWhitelist, _useChannelWhitelist, _allowAll, _allowPrivate; | private readonly bool _useServerWhitelist, _useChannelWhitelist, _allowAll, _allowPrivate; | ||||
| @@ -79,11 +79,12 @@ namespace Discord.Modules | |||||
| if (_allowAll || _useServerWhitelist) //Server-only events | if (_allowAll || _useServerWhitelist) //Server-only events | ||||
| { | { | ||||
| client.ChannelCreated += (s, e) => { if (e.Server != null && HasServer(e.Server)) ChannelCreated(s, e); }; | 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.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.MessageReceived += (s, e) => { if (HasChannel(e.Channel)) MessageReceived(s, e); }; | ||||
| client.MessageSent += (s, e) => { if (HasChannel(e.Channel)) MessageSent(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.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.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.ServerUnavailable += (s, e) => { if (HasIndirectServer(e.Server)) ServerUnavailable(s, e); }; | ||||
| client.ServerAvailable += (s, e) => { if (HasIndirectServer(e.Server)) ServerAvailable(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.UserJoined += (s, e) => { if (HasIndirectServer(e.Server)) UserJoined(s, e); }; | ||||
| client.UserLeft += (s, e) => { if (HasIndirectServer(e.Server)) UserLeft(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.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 | //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.UserBanned += (s, e) => { if (HasIndirectServer(e.Server)) UserBanned(s, e); }; | ||||
| client.UserUnbanned += (s, e) => { if (HasIndirectServer(e.Server)) UserUnbanned(s, e); }; | client.UserUnbanned += (s, e) => { if (HasIndirectServer(e.Server)) UserUnbanned(s, e); }; | ||||
| } | } | ||||
| @@ -385,18 +385,9 @@ | |||||
| <Compile Include="..\Discord.Net\API\Status\Rest\UpcomingMaintenances.cs"> | <Compile Include="..\Discord.Net\API\Status\Rest\UpcomingMaintenances.cs"> | ||||
| <Link>API\Status\Rest\UpcomingMaintenances.cs</Link> | <Link>API\Status\Rest\UpcomingMaintenances.cs</Link> | ||||
| </Compile> | </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"> | <Compile Include="..\Discord.Net\Config.cs"> | ||||
| <Link>Config.cs</Link> | <Link>Config.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\DisconnectedEventArgs.cs"> | |||||
| <Link>DisconnectedEventArgs.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\DiscordClient.cs"> | <Compile Include="..\Discord.Net\DiscordClient.cs"> | ||||
| <Link>DiscordClient.cs</Link> | <Link>DiscordClient.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| @@ -406,6 +397,9 @@ | |||||
| <Compile Include="..\Discord.Net\DiscordConfig.cs"> | <Compile Include="..\Discord.Net\DiscordConfig.cs"> | ||||
| <Link>DiscordConfig.cs</Link> | <Link>DiscordConfig.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\DynamicIL.cs"> | |||||
| <Link>DynamicIL.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\Enums\ChannelType.cs"> | <Compile Include="..\Discord.Net\Enums\ChannelType.cs"> | ||||
| <Link>Enums\ChannelType.cs</Link> | <Link>Enums\ChannelType.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| @@ -418,12 +412,57 @@ | |||||
| <Compile Include="..\Discord.Net\Enums\PermissionTarget.cs"> | <Compile Include="..\Discord.Net\Enums\PermissionTarget.cs"> | ||||
| <Link>Enums\PermissionTarget.cs</Link> | <Link>Enums\PermissionTarget.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\Enums\Relative.cs"> | |||||
| <Link>Enums\Relative.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\Enums\StringEnum.cs"> | <Compile Include="..\Discord.Net\Enums\StringEnum.cs"> | ||||
| <Link>Enums\StringEnum.cs</Link> | <Link>Enums\StringEnum.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\Enums\UserStatus.cs"> | <Compile Include="..\Discord.Net\Enums\UserStatus.cs"> | ||||
| <Link>Enums\UserStatus.cs</Link> | <Link>Enums\UserStatus.cs</Link> | ||||
| </Compile> | </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"> | <Compile Include="..\Discord.Net\Extensions.cs"> | ||||
| <Link>Extensions.cs</Link> | <Link>Extensions.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| @@ -445,12 +484,6 @@ | |||||
| <Compile Include="..\Discord.Net\Logging\LogManager.cs"> | <Compile Include="..\Discord.Net\Logging\LogManager.cs"> | ||||
| <Link>Logging\LogManager.cs</Link> | <Link>Logging\LogManager.cs</Link> | ||||
| </Compile> | </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"> | <Compile Include="..\Discord.Net\MessageQueue.cs"> | ||||
| <Link>MessageQueue.cs</Link> | <Link>MessageQueue.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| @@ -532,27 +565,12 @@ | |||||
| <Compile Include="..\Discord.Net\Net\WebSockets\WS4NetEngine.cs"> | <Compile Include="..\Discord.Net\Net\WebSockets\WS4NetEngine.cs"> | ||||
| <Link>Net\WebSockets\WS4NetEngine.cs</Link> | <Link>Net\WebSockets\WS4NetEngine.cs</Link> | ||||
| </Compile> | </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"> | <Compile Include="..\Discord.Net\ServiceManager.cs"> | ||||
| <Link>ServiceManager.cs</Link> | <Link>ServiceManager.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\TaskManager.cs"> | <Compile Include="..\Discord.Net\TaskManager.cs"> | ||||
| <Link>TaskManager.cs</Link> | <Link>TaskManager.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\UserEventArgs.cs"> | |||||
| <Link>UserEventArgs.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="Properties\AssemblyInfo.cs" /> | <Compile Include="Properties\AssemblyInfo.cs" /> | ||||
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| @@ -9,29 +9,27 @@ namespace Discord | |||||
| public event EventHandler<DisconnectedEventArgs> Disconnected = delegate { }; | public event EventHandler<DisconnectedEventArgs> Disconnected = delegate { }; | ||||
| public event EventHandler<ChannelEventArgs> ChannelCreated = delegate { }; | public event EventHandler<ChannelEventArgs> ChannelCreated = delegate { }; | ||||
| public event EventHandler<ChannelEventArgs> ChannelDestroyed = 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> MessageAcknowledged = delegate { }; | ||||
| public event EventHandler<MessageEventArgs> MessageDeleted = delegate { }; | public event EventHandler<MessageEventArgs> MessageDeleted = delegate { }; | ||||
| public event EventHandler<MessageEventArgs> MessageReceived = delegate { }; | public event EventHandler<MessageEventArgs> MessageReceived = delegate { }; | ||||
| public event EventHandler<MessageEventArgs> MessageSent = 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> RoleCreated = delegate { }; | ||||
| public event EventHandler<RoleEventArgs> RoleUpdated = delegate { }; | |||||
| public event EventHandler<RoleUpdatedEventArgs> RoleUpdated = delegate { }; | |||||
| public event EventHandler<RoleEventArgs> RoleDeleted = delegate { }; | public event EventHandler<RoleEventArgs> RoleDeleted = delegate { }; | ||||
| public event EventHandler<ServerEventArgs> JoinedServer = delegate { }; | public event EventHandler<ServerEventArgs> JoinedServer = delegate { }; | ||||
| public event EventHandler<ServerEventArgs> LeftServer = delegate { }; | public event EventHandler<ServerEventArgs> LeftServer = delegate { }; | ||||
| public event EventHandler<ServerEventArgs> ServerAvailable = 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<ServerEventArgs> ServerUnavailable = delegate { }; | ||||
| public event EventHandler<UserEventArgs> UserBanned = 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> UserJoined = delegate { }; | ||||
| public event EventHandler<UserEventArgs> UserLeft = 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> UserUnbanned = delegate { }; | ||||
| public event EventHandler<UserEventArgs> UserVoiceStateUpdated = delegate { }; | |||||
| private void OnConnected() | private void OnConnected() | ||||
| => OnEvent(Connected); | => OnEvent(Connected); | ||||
| @@ -42,8 +40,8 @@ namespace Discord | |||||
| => OnEvent(ChannelCreated, new ChannelEventArgs(channel)); | => OnEvent(ChannelCreated, new ChannelEventArgs(channel)); | ||||
| private void OnChannelDestroyed(Channel channel) | private void OnChannelDestroyed(Channel channel) | ||||
| => OnEvent(ChannelDestroyed, new ChannelEventArgs(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) | private void OnMessageAcknowledged(Message msg) | ||||
| => OnEvent(MessageAcknowledged, new MessageEventArgs(msg)); | => OnEvent(MessageAcknowledged, new MessageEventArgs(msg)); | ||||
| @@ -53,18 +51,18 @@ namespace Discord | |||||
| => OnEvent(MessageReceived, new MessageEventArgs(msg)); | => OnEvent(MessageReceived, new MessageEventArgs(msg)); | ||||
| internal void OnMessageSent(Message msg) | internal void OnMessageSent(Message msg) | ||||
| => OnEvent(MessageSent, new MessageEventArgs(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) | private void OnRoleCreated(Role role) | ||||
| => OnEvent(RoleCreated, new RoleEventArgs(role)); | => OnEvent(RoleCreated, new RoleEventArgs(role)); | ||||
| private void OnRoleDeleted(Role role) | private void OnRoleDeleted(Role role) | ||||
| => OnEvent(RoleDeleted, new RoleEventArgs(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) | private void OnJoinedServer(Server server) | ||||
| => OnEvent(JoinedServer, new ServerEventArgs(server)); | => OnEvent(JoinedServer, new ServerEventArgs(server)); | ||||
| @@ -72,27 +70,23 @@ namespace Discord | |||||
| => OnEvent(LeftServer, new ServerEventArgs(server)); | => OnEvent(LeftServer, new ServerEventArgs(server)); | ||||
| private void OnServerAvailable(Server server) | private void OnServerAvailable(Server server) | ||||
| => OnEvent(ServerAvailable, new ServerEventArgs(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) | private void OnServerUnavailable(Server server) | ||||
| => OnEvent(ServerUnavailable, new ServerEventArgs(server)); | => OnEvent(ServerUnavailable, new ServerEventArgs(server)); | ||||
| private void OnUserBanned(User user) | private void OnUserBanned(User user) | ||||
| => OnEvent(UserBanned, new UserEventArgs(user)); | => OnEvent(UserBanned, new UserEventArgs(user)); | ||||
| private void OnUserIsTypingUpdated(Channel channel, User 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) | private void OnUserJoined(User user) | ||||
| => OnEvent(UserJoined, new UserEventArgs(user)); | => OnEvent(UserJoined, new UserEventArgs(user)); | ||||
| private void OnUserLeft(User user) | private void OnUserLeft(User user) | ||||
| => OnEvent(UserLeft, new UserEventArgs(user)); | => OnEvent(UserLeft, new UserEventArgs(user)); | ||||
| private void OnUserPresenceUpdated(User user) | |||||
| => OnEvent(UserPresenceUpdated, new UserEventArgs(user)); | |||||
| private void OnUserUnbanned(User user) | private void OnUserUnbanned(User user) | ||||
| => OnEvent(UserUnbanned, new UserEventArgs(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) | private void OnEvent<T>(EventHandler<T> handler, T eventArgs, [CallerMemberName] string callerName = null) | ||||
| { | { | ||||
| @@ -546,10 +546,11 @@ namespace Discord | |||||
| var server = GetServer(data.Id); | var server = GetServer(data.Id); | ||||
| if (server != null) | if (server != null) | ||||
| { | { | ||||
| var before = Config.EnablePreUpdateEvents ? server.Clone() : null; | |||||
| server.Update(data); | server.Update(data); | ||||
| if (Config.LogEvents) | if (Config.LogEvents) | ||||
| Logger.Info($"Server Updated: {server.Name}"); | Logger.Info($"Server Updated: {server.Name}"); | ||||
| OnServerUpdated(server); | |||||
| OnServerUpdated(before, server); | |||||
| } | } | ||||
| else | else | ||||
| Logger.Warning("GUILD_UPDATE referenced an unknown guild."); | Logger.Warning("GUILD_UPDATE referenced an unknown guild."); | ||||
| @@ -609,10 +610,11 @@ namespace Discord | |||||
| var channel = GetChannel(data.Id); | var channel = GetChannel(data.Id); | ||||
| if (channel != null) | if (channel != null) | ||||
| { | { | ||||
| var before = Config.EnablePreUpdateEvents ? channel.Clone() : null; | |||||
| channel.Update(data); | channel.Update(data); | ||||
| if (Config.LogEvents) | if (Config.LogEvents) | ||||
| Logger.Info($"Channel Updated: {channel.Server?.Name ?? "[Private]"}/{channel.Name}"); | Logger.Info($"Channel Updated: {channel.Server?.Name ?? "[Private]"}/{channel.Name}"); | ||||
| OnChannelUpdated(channel); | |||||
| OnChannelUpdated(before, channel); | |||||
| } | } | ||||
| else | else | ||||
| Logger.Warning("CHANNEL_UPDATE referenced an unknown channel."); | Logger.Warning("CHANNEL_UPDATE referenced an unknown channel."); | ||||
| @@ -660,10 +662,11 @@ namespace Discord | |||||
| var user = server.GetUser(data.User.Id); | var user = server.GetUser(data.User.Id); | ||||
| if (user != null) | if (user != null) | ||||
| { | { | ||||
| var before = Config.EnablePreUpdateEvents ? user.Clone() : null; | |||||
| user.Update(data); | user.Update(data); | ||||
| if (Config.LogEvents) | if (Config.LogEvents) | ||||
| Logger.Info($"User Updated: {server.Name}/{user.Name}"); | Logger.Info($"User Updated: {server.Name}/{user.Name}"); | ||||
| OnUserUpdated(user); | |||||
| OnUserUpdated(before, user); | |||||
| } | } | ||||
| else | else | ||||
| Logger.Warning("GUILD_MEMBER_UPDATE referenced an unknown user."); | Logger.Warning("GUILD_MEMBER_UPDATE referenced an unknown user."); | ||||
| @@ -721,7 +724,7 @@ namespace Discord | |||||
| role.Update(data.Data); | role.Update(data.Data); | ||||
| if (Config.LogEvents) | if (Config.LogEvents) | ||||
| Logger.Info($"Role Created: {server.Name}/{role.Name}"); | Logger.Info($"Role Created: {server.Name}/{role.Name}"); | ||||
| OnRoleUpdated(role); | |||||
| OnRoleCreated(role); | |||||
| } | } | ||||
| else | else | ||||
| Logger.Warning("GUILD_ROLE_CREATE referenced an unknown guild."); | Logger.Warning("GUILD_ROLE_CREATE referenced an unknown guild."); | ||||
| @@ -736,10 +739,11 @@ namespace Discord | |||||
| var role = server.GetRole(data.Data.Id); | var role = server.GetRole(data.Data.Id); | ||||
| if (role != null) | if (role != null) | ||||
| { | { | ||||
| var before = Config.EnablePreUpdateEvents ? role.Clone() : null; | |||||
| role.Update(data.Data); | role.Update(data.Data); | ||||
| if (Config.LogEvents) | if (Config.LogEvents) | ||||
| Logger.Info($"Role Updated: {server.Name}/{role.Name}"); | Logger.Info($"Role Updated: {server.Name}/{role.Name}"); | ||||
| OnRoleUpdated(role); | |||||
| OnRoleUpdated(before, role); | |||||
| } | } | ||||
| else | else | ||||
| Logger.Warning("GUILD_ROLE_UPDATE referenced an unknown role."); | Logger.Warning("GUILD_ROLE_UPDATE referenced an unknown role."); | ||||
| @@ -860,10 +864,11 @@ namespace Discord | |||||
| if (channel != null) | if (channel != null) | ||||
| { | { | ||||
| var msg = channel.GetMessage(data.Id, data.Author?.Id); | var msg = channel.GetMessage(data.Id, data.Author?.Id); | ||||
| var before = Config.EnablePreUpdateEvents ? msg.Clone() : null; | |||||
| msg.Update(data); | msg.Update(data); | ||||
| if (Config.LogEvents) | if (Config.LogEvents) | ||||
| Logger.Verbose($"Message Update: {channel.Server?.Name ?? "[Private]"}/{channel.Name}"); | Logger.Verbose($"Message Update: {channel.Server?.Name ?? "[Private]"}/{channel.Name}"); | ||||
| OnMessageUpdated(msg); | |||||
| OnMessageUpdated(before, msg); | |||||
| } | } | ||||
| else | else | ||||
| Logger.Warning("MESSAGE_UPDATE referenced an unknown channel."); | Logger.Warning("MESSAGE_UPDATE referenced an unknown channel."); | ||||
| @@ -936,9 +941,10 @@ namespace Discord | |||||
| if (user != null) | if (user != null) | ||||
| { | { | ||||
| var before = Config.EnablePreUpdateEvents ? user.Clone() : null; | |||||
| user.Update(data); | user.Update(data); | ||||
| //Logger.Verbose($"Presence Updated: {server.Name}/{user.Name}"); | //Logger.Verbose($"Presence Updated: {server.Name}/{user.Name}"); | ||||
| OnUserPresenceUpdated(user); | |||||
| OnUserUpdated(before, user); | |||||
| } | } | ||||
| /*else //Occurs when a user leaves a server | /*else //Occurs when a user leaves a server | ||||
| Logger.Warning("PRESENCE_UPDATE referenced an unknown user.");*/ | Logger.Warning("PRESENCE_UPDATE referenced an unknown user.");*/ | ||||
| @@ -982,9 +988,10 @@ namespace Discord | |||||
| var user = server.GetUser(data.UserId); | var user = server.GetUser(data.UserId); | ||||
| if (user != null) | if (user != null) | ||||
| { | { | ||||
| var before = Config.EnablePreUpdateEvents ? user.Clone() : null; | |||||
| user.Update(data); | user.Update(data); | ||||
| //Logger.Verbose($"Voice Updated: {server.Name}/{user.Name}"); | //Logger.Verbose($"Voice Updated: {server.Name}/{user.Name}"); | ||||
| OnUserVoiceStateUpdated(user); | |||||
| OnUserUpdated(user, user); | |||||
| } | } | ||||
| /*else //Occurs when a user leaves a server | /*else //Occurs when a user leaves a server | ||||
| Logger.Warning("VOICE_STATE_UPDATE referenced an unknown user.");*/ | Logger.Warning("VOICE_STATE_UPDATE referenced an unknown user.");*/ | ||||
| @@ -1000,13 +1007,14 @@ namespace Discord | |||||
| var data = e.Payload.ToObject<UserUpdateEvent>(Serializer); | var data = e.Payload.ToObject<UserUpdateEvent>(Serializer); | ||||
| if (data.Id == CurrentUser.Id) | if (data.Id == CurrentUser.Id) | ||||
| { | { | ||||
| var before = Config.EnablePreUpdateEvents ? CurrentUser.Clone() : null; | |||||
| CurrentUser.Update(data); | CurrentUser.Update(data); | ||||
| PrivateUser.Update(data); | PrivateUser.Update(data); | ||||
| foreach (var server in _servers) | foreach (var server in _servers) | ||||
| server.Value.CurrentUser.Update(data); | server.Value.CurrentUser.Update(data); | ||||
| if (Config.LogEvents) | if (Config.LogEvents) | ||||
| Logger.Info("Profile Updated"); | Logger.Info("Profile Updated"); | ||||
| OnProfileUpdated(CurrentUser); | |||||
| OnProfileUpdated(before, CurrentUser); | |||||
| } | } | ||||
| } | } | ||||
| break; | break; | ||||
| @@ -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> | /// <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); } } | public bool UsePermissionsCache { get { return _usePermissionsCache; } set { SetValue(ref _usePermissionsCache, value); } } | ||||
| private bool _usePermissionsCache = true; | 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() | public DiscordConfig() | ||||
| { | { | ||||
| @@ -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()); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -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; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -14,6 +14,8 @@ namespace Discord | |||||
| { | { | ||||
| public sealed class Channel : IMentionable | public sealed class Channel : IMentionable | ||||
| { | { | ||||
| private readonly static Action<Channel, Channel> _cloner = DynamicIL.CreateCloner<Channel>(); | |||||
| private struct Member | private struct Member | ||||
| { | { | ||||
| public readonly User User; | public readonly User User; | ||||
| @@ -102,7 +104,7 @@ namespace Discord | |||||
| return Enumerable.Empty<User>(); | return Enumerable.Empty<User>(); | ||||
| } | } | ||||
| } | } | ||||
| internal Channel(DiscordClient client, ulong id, Server server) | internal Channel(DiscordClient client, ulong id, Server server) | ||||
| : this(client, id) | : this(client, id) | ||||
| { | { | ||||
| @@ -598,6 +600,14 @@ namespace Discord | |||||
| } | } | ||||
| #endregion | #endregion | ||||
| internal Channel Clone() | |||||
| { | |||||
| var result = new Channel(); | |||||
| _cloner(this, result); | |||||
| return result; | |||||
| } | |||||
| private Channel() { } | |||||
| public override string ToString() => Name ?? Id.ToIdString(); | public override string ToString() => Name ?? Id.ToIdString(); | ||||
| } | } | ||||
| } | } | ||||
| @@ -3,8 +3,10 @@ | |||||
| namespace Discord | namespace Discord | ||||
| { | { | ||||
| public sealed class Color : IEquatable<Color> | 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 Teal = PresetColor(0x1ABC9C); | ||||
| public static readonly Color DarkTeal = PresetColor(0x11806A); | 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 override bool Equals(object obj) => (obj as Color)?.Equals(this) ?? false; | ||||
| public bool Equals(Color color) => color != null && color._rawValue == _rawValue; | 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"); | public override string ToString() => '#' + _rawValue.ToString("X"); | ||||
| } | } | ||||
| } | } | ||||
| @@ -1,9 +0,0 @@ | |||||
| using Discord.API.Client; | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Threading.Tasks; | |||||
| namespace Discord.Models | |||||
| { | |||||
| } | |||||
| @@ -9,8 +9,10 @@ using APIInvite = Discord.API.Client.Invite; | |||||
| namespace Discord | namespace Discord | ||||
| { | { | ||||
| public sealed class Invite | 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> | /// <summary> Returns the unique identifier of this server. </summary> | ||||
| public ulong Id { get; } | public ulong Id { get; } | ||||
| @@ -126,8 +128,14 @@ namespace Discord | |||||
| public Task Accept() | public Task Accept() | ||||
| => Client.ClientAPI.Send(new AcceptInviteRequest(Code)); | => 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; | |||||
| } | } | ||||
| } | } | ||||
| @@ -1,12 +1,9 @@ | |||||
| using Discord.API.Client.Rest; | using Discord.API.Client.Rest; | ||||
| using Discord.Net; | using Discord.Net; | ||||
| using Newtonsoft.Json; | |||||
| using Newtonsoft.Json.Serialization; | |||||
| using System; | using System; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Linq; | using System.Linq; | ||||
| using System.Net; | using System.Net; | ||||
| using System.Reflection; | |||||
| using System.Text.RegularExpressions; | using System.Text.RegularExpressions; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using APIMessage = Discord.API.Client.Message; | using APIMessage = Discord.API.Client.Message; | ||||
| @@ -27,9 +24,11 @@ namespace Discord | |||||
| public sealed class Message | 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 Attachment[] _initialAttachments = new Attachment[0]; | ||||
| private static readonly Embed[] _initialEmbeds = new Embed[0]; | private static readonly Embed[] _initialEmbeds = new Embed[0]; | ||||
| @@ -369,8 +368,14 @@ namespace Discord | |||||
| return Resolve(Channel, text); | 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}"; | |||||
| } | } | ||||
| } | } | ||||
| @@ -32,16 +32,24 @@ namespace Discord | |||||
| } | } | ||||
| public sealed class ServerPermissions : Permissions | 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 static ServerPermissions All { get; } = new ServerPermissions(Convert.ToUInt32("00000011111100111111110000111111", 2)); | ||||
| public ServerPermissions() : base() { } | public ServerPermissions() : base() { } | ||||
| public ServerPermissions(uint rawValue) : base(rawValue) { } | public ServerPermissions(uint rawValue) : base(rawValue) { } | ||||
| public ServerPermissions Copy() => new ServerPermissions(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> | /// <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); } } | 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> | /// <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 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 TextOnly { get; } = new ChannelPermissions(Convert.ToUInt32("00000000000000111111110000011001", 2)); | ||||
| public static ChannelPermissions PrivateOnly { get; } = new ChannelPermissions(Convert.ToUInt32("00000000000000011100110000000000", 2)); | public static ChannelPermissions PrivateOnly { get; } = new ChannelPermissions(Convert.ToUInt32("00000000000000011100110000000000", 2)); | ||||
| public static ChannelPermissions VoiceOnly { get; } = new ChannelPermissions(Convert.ToUInt32("00000011111100000000000000011001", 2)); | public static ChannelPermissions VoiceOnly { get; } = new ChannelPermissions(Convert.ToUInt32("00000011111100000000000000011001", 2)); | ||||
| @@ -70,9 +80,15 @@ namespace Discord | |||||
| public ChannelPermissions() : base() { } | public ChannelPermissions() : base() { } | ||||
| public ChannelPermissions(uint rawValue) : base(rawValue) { } | public ChannelPermissions(uint rawValue) : base(rawValue) { } | ||||
| public ChannelPermissions Copy() => new ChannelPermissions(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> | /// <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); } } | public bool ManageChannel { get { return GetBit(PermissionsBits.ManageChannel); } set { SetBit(PermissionsBits.ManageChannel, value); } } | ||||
| } | } | ||||
| @@ -152,8 +168,10 @@ namespace Discord | |||||
| } | } | ||||
| public sealed class DualChannelPermissions | 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 ChannelPermissions Deny { get; } | ||||
| public DualChannelPermissions(uint allow = 0, uint deny = 0) | public DualChannelPermissions(uint allow = 0, uint deny = 0) | ||||
| @@ -233,6 +251,12 @@ namespace Discord | |||||
| Deny.Lock(); | Deny.Lock(); | ||||
| } | } | ||||
| public DualChannelPermissions Copy() => new DualChannelPermissions(Allow.RawValue, Deny.RawValue); | 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) => ((object)a == null && (object)b == null) || (a?.Equals(b) ?? false); | ||||
| public static bool operator !=(DualChannelPermissions a, DualChannelPermissions b) => !(a == b); | public static bool operator !=(DualChannelPermissions a, DualChannelPermissions b) => !(a == b); | ||||
| @@ -8,6 +8,8 @@ namespace Discord | |||||
| { | { | ||||
| public sealed class Profile | public sealed class Profile | ||||
| { | { | ||||
| private readonly static Action<Profile, Profile> _cloner = DynamicIL.CreateCloner<Profile>(); | |||||
| internal DiscordClient Client { get; } | internal DiscordClient Client { get; } | ||||
| /// <summary> Gets the unique identifier for this user. </summary> | /// <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(); | public override string ToString() => Id.ToIdString(); | ||||
| } | } | ||||
| } | } | ||||
| @@ -16,5 +16,5 @@ | |||||
| Port = port; | Port = port; | ||||
| Vip = vip; | Vip = vip; | ||||
| } | } | ||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -11,6 +11,8 @@ namespace Discord | |||||
| { | { | ||||
| public sealed class Role : IMentionable | public sealed class Role : IMentionable | ||||
| { | { | ||||
| private readonly static Action<Role, Role> _cloner = DynamicIL.CreateCloner<Role>(); | |||||
| internal DiscordClient Client => Server.Client; | internal DiscordClient Client => Server.Client; | ||||
| /// <summary> Gets the unique identifier for this role. </summary> | /// <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); } | try { await Client.ClientAPI.Send(new DeleteRoleRequest(Server.Id, Id)).ConfigureAwait(false); } | ||||
| catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | 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(); | |||||
| } | } | ||||
| } | } | ||||
| @@ -14,6 +14,8 @@ namespace Discord | |||||
| /// <summary> Represents a Discord server (also known as a guild). </summary> | /// <summary> Represents a Discord server (also known as a guild). </summary> | ||||
| public sealed class Server | public sealed class Server | ||||
| { | { | ||||
| private readonly static Action<Server, Server> _cloner = DynamicIL.CreateCloner<Server>(); | |||||
| internal static string GetIconUrl(ulong serverId, string iconId) | internal static string GetIconUrl(ulong serverId, string iconId) | ||||
| => iconId != null ? $"{DiscordConfig.ClientAPIUrl}guilds/${serverId}/icons/${iconId}.jpg" : null; | => iconId != null ? $"{DiscordConfig.ClientAPIUrl}guilds/${serverId}/icons/${iconId}.jpg" : null; | ||||
| internal static string GetSplashUrl(ulong serverId, string splashId) | internal static string GetSplashUrl(ulong serverId, string splashId) | ||||
| @@ -85,8 +87,9 @@ namespace Discord | |||||
| public Channel AFKChannel => _afkChannelId != null ? GetChannel(_afkChannelId.Value) : null; | public Channel AFKChannel => _afkChannelId != null ? GetChannel(_afkChannelId.Value) : null; | ||||
| /// <summary> Gets the current user in this server. </summary> | /// <summary> Gets the current user in this server. </summary> | ||||
| public User CurrentUser => GetUser(Client.CurrentUser.Id); | 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); | public string IconUrl => GetIconUrl(Id, IconId); | ||||
| /// <summary> Gets the URL to this servers's splash image. </summary> | |||||
| public string SplashUrl => GetSplashUrl(Id, SplashId); | public string SplashUrl => GetSplashUrl(Id, SplashId); | ||||
| /// <summary> Gets a collection of all channels in this server. </summary> | /// <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() | Roles = x.RoleIds.Select(y => GetRole(y)).Where(y => y != null).ToArray() | ||||
| }).ToArray(); | }).ToArray(); | ||||
| } | } | ||||
| //Can be null | |||||
| _afkChannelId = model.AFKChannelId; | |||||
| SplashId = model.Splash; | |||||
| if (model.Roles != null) | if (model.Roles != null) | ||||
| { | { | ||||
| foreach (var x in model.Roles) | foreach (var x in model.Roles) | ||||
| AddRole(x.Id).Update(x); | AddRole(x.Id).Update(x); | ||||
| } | } | ||||
| //Can be null | |||||
| _afkChannelId = model.AFKChannelId; | |||||
| SplashId = model.Splash; | |||||
| } | } | ||||
| internal void Update(ExtendedGuild model) | internal void Update(ExtendedGuild model) | ||||
| { | { | ||||
| @@ -498,7 +500,15 @@ namespace Discord | |||||
| public void RequestOfflineUsers() | public void RequestOfflineUsers() | ||||
| => Client.GatewaySocket.SendRequestMembers(Id, "", 0); | => Client.GatewaySocket.SendRequestMembers(Id, "", 0); | ||||
| #endregion | #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(); | |||||
| } | } | ||||
| } | } | ||||
| @@ -9,8 +9,10 @@ using APIMember = Discord.API.Client.Member; | |||||
| namespace Discord | 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) | internal static string GetAvatarUrl(ulong userId, string avatarId) | ||||
| => avatarId != null ? $"{DiscordConfig.ClientAPIUrl}users/{userId}/avatars/{avatarId}.jpg" : null; | => avatarId != null ? $"{DiscordConfig.ClientAPIUrl}users/{userId}/avatars/{avatarId}.jpg" : null; | ||||
| @@ -338,6 +340,14 @@ namespace Discord | |||||
| => Edit(roles: Roles.Except(roles)); | => Edit(roles: Roles.Except(roles)); | ||||
| #endregion | #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(); | |||||
| } | } | ||||
| } | } | ||||
| @@ -50,6 +50,8 @@ | |||||
| "System.Net.Sockets": "4.1.0-beta-23409", | "System.Net.Sockets": "4.1.0-beta-23409", | ||||
| "System.Net.Requests": "4.0.11-beta-23516", | "System.Net.Requests": "4.0.11-beta-23516", | ||||
| "System.Net.WebSockets.Client": "4.0.0-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.Runtime.InteropServices": "4.0.21-beta-23516", | ||||
| "System.Security.Cryptography.Algorithms": "4.0.0-beta-23516", | "System.Security.Cryptography.Algorithms": "4.0.0-beta-23516", | ||||
| "System.Text.RegularExpressions": "4.0.11-beta-23516", | "System.Text.RegularExpressions": "4.0.11-beta-23516", | ||||