You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

ModuleManager.cs 10 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. namespace Discord.Modules
  6. {
  7. public class ModuleManager
  8. {
  9. public event EventHandler<ServerEventArgs> ServerEnabled;
  10. public event EventHandler<ServerEventArgs> ServerDisabled;
  11. public event EventHandler<ChannelEventArgs> ChannelEnabled;
  12. public event EventHandler<ChannelEventArgs> ChannelDisabled;
  13. public event EventHandler<ServerEventArgs> LeftServer;
  14. public event EventHandler<ServerEventArgs> ServerUpdated;
  15. public event EventHandler<ServerEventArgs> ServerUnavailable;
  16. public event EventHandler<ServerEventArgs> ServerAvailable;
  17. public event EventHandler<BanEventArgs> UserBanned;
  18. public event EventHandler<BanEventArgs> UserUnbanned;
  19. public event EventHandler<ChannelEventArgs> ChannelCreated;
  20. public event EventHandler<ChannelEventArgs> ChannelDestroyed;
  21. public event EventHandler<ChannelEventArgs> ChannelUpdated;
  22. public event EventHandler<RoleEventArgs> RoleCreated;
  23. public event EventHandler<RoleEventArgs> RoleUpdated;
  24. public event EventHandler<RoleEventArgs> RoleDeleted;
  25. public event EventHandler<UserEventArgs> UserJoined;
  26. public event EventHandler<UserEventArgs> UserLeft;
  27. public event EventHandler<UserEventArgs> UserUpdated;
  28. public event EventHandler<UserEventArgs> UserPresenceUpdated;
  29. public event EventHandler<UserEventArgs> UserVoiceStateUpdated;
  30. public event EventHandler<UserChannelEventArgs> UserIsTypingUpdated;
  31. public event EventHandler<UserIsSpeakingEventArgs> UserIsSpeakingUpdated;
  32. public event EventHandler<MessageEventArgs> MessageReceived;
  33. public event EventHandler<MessageEventArgs> MessageSent;
  34. public event EventHandler<MessageEventArgs> MessageDeleted;
  35. public event EventHandler<MessageEventArgs> MessageUpdated;
  36. public event EventHandler<MessageEventArgs> MessageReadRemotely;
  37. private readonly DiscordClient _client;
  38. private readonly bool _allowServerWhitelist, _allowChannelWhitelist, _allowPrivate;
  39. private readonly ConcurrentDictionary<string, Server> _enabledServers;
  40. private readonly ConcurrentDictionary<string, Channel> _enabledChannels;
  41. private readonly ConcurrentDictionary<string, int> _indirectServers;
  42. public DiscordClient Client => _client;
  43. public IEnumerable<Server> EnabledServers => _enabledServers.Select(x => x.Value);
  44. public IEnumerable<Channel> EnabledChannels => _enabledChannels.Select(x => x.Value);
  45. internal ModuleManager(DiscordClient client, FilterType type)
  46. {
  47. _client = client;
  48. _allowServerWhitelist = type.HasFlag(FilterType.Server);
  49. _allowChannelWhitelist = type.HasFlag(FilterType.Channel);
  50. _allowPrivate = type.HasFlag(FilterType.AllowPrivate);
  51. _enabledServers = new ConcurrentDictionary<string, Server>();
  52. _enabledChannels = new ConcurrentDictionary<string, Channel>();
  53. _indirectServers = new ConcurrentDictionary<string, int>();
  54. if (_allowServerWhitelist) //Server-only events
  55. {
  56. client.LeftServer += (s, e) => { if (LeftServer != null && HasIndirectServer(e.Server)) DisableServer(e.Server); LeftServer(s, e); };
  57. client.ServerUpdated += (s, e) => { if (ServerUpdated != null && HasIndirectServer(e.Server)) ServerUpdated(s, e); };
  58. client.ServerUnavailable += (s, e) => { if (ServerUnavailable != null && HasIndirectServer(e.Server)) ServerUnavailable(s, e); };
  59. client.ServerAvailable += (s, e) => { if (ServerAvailable != null && HasIndirectServer(e.Server)) ServerAvailable(s, e); };
  60. client.UserBanned += (s, e) => { if (UserBanned != null && HasIndirectServer(e.Server)) UserBanned(s, e); };
  61. client.UserUnbanned += (s, e) => { if (UserUnbanned != null && HasIndirectServer(e.Server)) UserUnbanned(s, e); };
  62. client.ChannelCreated += (s, e) => { if (ChannelCreated != null && HasServer(e.Server)) ChannelCreated(s, e); };
  63. client.ChannelDestroyed += (s, e) => { if (ChannelDestroyed != null && HasChannel(e.Channel)) ChannelDestroyed(s, e); };
  64. client.ChannelUpdated += (s, e) => { if (ChannelUpdated != null && HasChannel(e.Channel)) ChannelUpdated(s, e); };
  65. client.RoleCreated += (s, e) => { if (RoleCreated != null && HasIndirectServer(e.Server)) RoleCreated(s, e); };
  66. client.RoleUpdated += (s, e) => { if (RoleUpdated != null && HasIndirectServer(e.Server)) RoleUpdated(s, e); };
  67. client.RoleDeleted += (s, e) => { if (RoleDeleted != null && HasIndirectServer(e.Server)) RoleDeleted(s, e); };
  68. client.UserJoined += (s, e) => { if (UserJoined != null && HasIndirectServer(e.Server)) UserJoined(s, e); };
  69. client.UserLeft += (s, e) => { if (UserLeft != null && HasIndirectServer(e.Server)) UserLeft(s, e); };
  70. client.UserUpdated += (s, e) => { if (UserUpdated != null && HasIndirectServer(e.Server)) UserUpdated(s, e); };
  71. client.UserPresenceUpdated += (s, e) => { if (UserPresenceUpdated != null && HasIndirectServer(e.Server)) UserPresenceUpdated(s, e); };
  72. client.UserVoiceStateUpdated += (s, e) => { if (UserVoiceStateUpdated != null && HasServer(e.Server)) UserVoiceStateUpdated(s, e); };
  73. client.UserIsTypingUpdated += (s, e) => { if (UserIsSpeakingUpdated != null && HasChannel(e.Channel)) UserIsTypingUpdated(s, e); };
  74. client.UserIsSpeakingUpdated += (s, e) => { if (UserIsSpeakingUpdated != null && HasServer(e.Server)) UserIsSpeakingUpdated(s, e); };
  75. client.MessageReceived += (s, e) => { if (MessageReceived != null && HasChannel(e.Channel)) MessageReceived(s, e); };
  76. client.MessageSent += (s, e) => { if (MessageSent != null && HasChannel(e.Channel)) MessageSent(s, e); };
  77. client.MessageDeleted += (s, e) => { if (MessageDeleted != null && HasChannel(e.Channel)) MessageDeleted(s, e); };
  78. client.MessageUpdated += (s, e) => { if (MessageUpdated != null && HasChannel(e.Channel)) MessageUpdated(s, e); };
  79. client.MessageReadRemotely += (s, e) => { if (MessageReadRemotely != null && HasChannel(e.Channel)) MessageReadRemotely(s, e); };
  80. client.MessageReceived += (s, e) => { if (MessageReceived != null && HasChannel(e.Channel)) MessageReceived(s, e); };
  81. }
  82. }
  83. public bool EnableServer(Server server)
  84. {
  85. if (server == null) throw new ArgumentNullException(nameof(server));
  86. if (!_allowServerWhitelist) throw new InvalidOperationException("This module is not configured to use a server whitelist.");
  87. lock (this)
  88. {
  89. if (_enabledServers.TryAdd(server.Id, server))
  90. {
  91. if (ServerEnabled != null)
  92. ServerEnabled(this, new ServerEventArgs(server));
  93. return true;
  94. }
  95. return false;
  96. }
  97. }
  98. public bool DisableServer(Server server)
  99. {
  100. if (server == null) throw new ArgumentNullException(nameof(server));
  101. if (!_allowServerWhitelist) throw new InvalidOperationException("This module is not configured to use a server whitelist.");
  102. lock (this)
  103. {
  104. if (_enabledServers.TryRemove(server.Id, out server))
  105. {
  106. if (ServerDisabled != null)
  107. ServerDisabled(this, new ServerEventArgs(server));
  108. return true;
  109. }
  110. return false;
  111. }
  112. }
  113. public void DisableAllServers()
  114. {
  115. if (!_allowServerWhitelist) throw new InvalidOperationException("This module is not configured to use a server whitelist.");
  116. lock (this)
  117. {
  118. if (ServerDisabled != null)
  119. {
  120. foreach (var server in _enabledServers)
  121. ServerDisabled(this, new ServerEventArgs(server.Value));
  122. }
  123. _enabledServers.Clear();
  124. }
  125. }
  126. public bool EnableChannel(Channel channel)
  127. {
  128. if (channel == null) throw new ArgumentNullException(nameof(channel));
  129. if (!_allowChannelWhitelist) throw new InvalidOperationException("This module is not configured to use a channel whitelist.");
  130. lock (this)
  131. {
  132. if (_enabledChannels.TryAdd(channel.Id, channel))
  133. {
  134. var server = channel.Server;
  135. if (server != null)
  136. {
  137. int value = 0;
  138. _indirectServers.TryGetValue(server.Id, out value);
  139. value++;
  140. _indirectServers[server.Id] = value;
  141. }
  142. if (ChannelEnabled != null)
  143. ChannelEnabled(this, new ChannelEventArgs(channel));
  144. return true;
  145. }
  146. return false;
  147. }
  148. }
  149. public bool DisableChannel(Channel channel)
  150. {
  151. if (channel == null) throw new ArgumentNullException(nameof(channel));
  152. if (!_allowChannelWhitelist) throw new InvalidOperationException("This module is not configured to use a channel whitelist.");
  153. lock (this)
  154. {
  155. Channel ignored;
  156. if (_enabledChannels.TryRemove(channel.Id, out ignored))
  157. {
  158. var server = channel.Server;
  159. if (server != null)
  160. {
  161. int value = 0;
  162. _indirectServers.TryGetValue(server.Id, out value);
  163. value--;
  164. if (value <= 0)
  165. _indirectServers.TryRemove(server.Id, out value);
  166. else
  167. _indirectServers[server.Id] = value;
  168. }
  169. if (ChannelDisabled != null)
  170. ChannelDisabled(this, new ChannelEventArgs(channel));
  171. return true;
  172. }
  173. return false;
  174. }
  175. }
  176. public void DisableAllChannels()
  177. {
  178. if (!_allowChannelWhitelist) throw new InvalidOperationException("This module is not configured to use a channel whitelist.");
  179. lock (this)
  180. {
  181. if (ChannelDisabled != null)
  182. {
  183. foreach (var channel in _enabledChannels)
  184. ChannelDisabled(this, new ChannelEventArgs(channel.Value));
  185. }
  186. _enabledChannels.Clear();
  187. _indirectServers.Clear();
  188. }
  189. }
  190. public void DisableAll()
  191. {
  192. if (_allowServerWhitelist)
  193. DisableAllServers();
  194. if (_allowChannelWhitelist)
  195. DisableAllChannels();
  196. }
  197. private bool HasServer(Server server) =>
  198. _allowServerWhitelist && _enabledServers.ContainsKey(server.Id);
  199. private bool HasIndirectServer(Server server) =>
  200. (_allowServerWhitelist && _enabledServers.ContainsKey(server.Id)) ||
  201. (_allowChannelWhitelist && _indirectServers.ContainsKey(server.Id));
  202. private bool HasChannel(Channel channel)
  203. {
  204. if (channel.IsPrivate) return _allowPrivate;
  205. if (_allowChannelWhitelist && _enabledChannels.ContainsKey(channel.Id)) return true;
  206. if (_allowServerWhitelist)
  207. {
  208. var server = channel.Server;
  209. if (server == null) return false;
  210. if (_enabledServers.ContainsKey(server.Id)) return true;
  211. }
  212. return false;
  213. }
  214. }
  215. }