using Maki.Structures.Channels; using Maki.Structures.Gateway; using Maki.Structures.Guilds; using Maki.Structures.Messages; using Maki.Structures.Presences; using Maki.Structures.Users; using System; using System.Collections.Generic; using System.Linq; namespace Maki.Gateway { /// /// Gateway connection shard manager /// class GatewayShardClient : IDisposable { /// /// Managed (active) shards /// private readonly List Shards = new List(); private readonly object Lock = new object(); /// /// Parent DiscordClient instance /// private Discord Client; /// /// Number of active managed shards /// public int ShardCount => Shards.Count; /// /// Constructor /// /// Parent DiscordClient instance public GatewayShardClient(Discord client) => Client = client; /// /// Creates a new Gateway Shard /// /// Id of the shard /// New Gateway Shard public GatewayShard Create(int id) { GatewayShard shard = new GatewayShard(id, Client); ApplyEvents(shard); lock (Lock) Shards.Add(shard); return shard; } /// /// Destroys a Gateway Shard /// /// Shard to destroy public void Destroy(GatewayShard shard) { lock (Lock) Shards.Remove(shard); // Disconnect and Dispose are called separately so OnSocketClose is called properly shard.Disconnect(); RemoveEvents(shard); shard.Dispose(); } /// /// Destroys all shards /// public void Disconnect() { lock (Lock) Shards.ToList().ForEach(x => Destroy(x)); } /// /// Links all gateway events handlers to the shard /// /// Shard to link events to private void ApplyEvents(GatewayShard shard) { shard.OnCallCreate += OnCallCreate; shard.OnCallDelete += OnCallDelete; shard.OnCallUpdate += OnCallUpdate; shard.OnVoiceServerUpdate += OnVoiceServerUpdate; shard.OnVoiceStateUpdate += OnVoiceStateUpdate; shard.OnChannelCreate += OnChannelCreate; shard.OnChannelDelete += OnChannelDelete; shard.OnChannelPinsAck += OnChannelPinsAck; shard.OnChannelPinsUpdate += OnChannelPinsUpdate; shard.OnChannelRecipientAdd += OnChannelRecipientAdd; shard.OnChannelRecipientRemove += OnChannelRecipientRemove; shard.OnChannelUpdate += OnChannelUpdate; shard.OnGuildBanAdd += OnGuildBanAdd; shard.OnGuildBanRemove += OnGuildBanRemove; shard.OnGuildCreate += OnGuildCreate; shard.OnGuildDelete += OnGuildDelete; shard.OnGuildEmojisUpdate += OnGuildEmojisUpdate; shard.OnGuildIntegrationsUpdate += OnGuildIntegrationsUpdate; shard.OnGuildMemberAdd += OnGuildMemberAdd; shard.OnGuildMemberUpdate += OnGuildMemberUpdate; shard.OnGuildMemberRemove += OnGuildMemberRemove; shard.OnGuildMembersChunk += OnGuildMembersChunk; shard.OnGuildRoleCreate += OnGuildRoleCreate; shard.OnGuildRoleUpdate += OnGuildRoleUpdate; shard.OnGuildRoleDelete += OnGuildRoleDelete; shard.OnGuildUpdate += OnGuildUpdate; shard.OnMessageAck += OnMessageAck; shard.OnMessageCreate += OnMessageCreate; shard.OnMessageDelete += OnMessageDelete; shard.OnMessageDeleteBulk += OnMessageDeleteBulk; shard.OnMessageReactionAdd += OnMessageReactionAdd; shard.OnMessageReactionRemove += OnMessageReactionRemove; shard.OnMessageReactionsRemoveAll += OnMessageReactionsRemoveAll; shard.OnMessageUpdate += OnMessageUpdate; shard.OnTypingStart += OnTypingStart; shard.OnPresenceUpdate += OnPresenceUpdate; shard.OnPresencesReplace += OnPresencesReplace; shard.OnFriendSuggestionDelete += OnFriendSuggestionDelete; shard.OnRelationshipAdd += OnRelationshipAdd; shard.OnRelationshipRemove += OnRelationshipRemove; shard.OnReady += OnReady; shard.OnResumed += OnResumed; shard.OnUserUpdate += OnUserUpdate; shard.OnUserNoteUpdate += OnUserNoteUpdate; shard.OnUserSettingsUpdate += OnUserSettingsUpdate; shard.OnSocketOpen += OnSocketOpen; shard.OnSocketClose += OnSocketClose; shard.OnSocketError += OnSocketError; shard.OnSocketMessage += OnSocketMessage; } /// /// Unlinks all gateway events handlers from the shard /// /// Shard to unlink events from public void RemoveEvents(GatewayShard shard) { shard.OnCallCreate -= OnCallCreate; shard.OnCallDelete -= OnCallDelete; shard.OnCallUpdate -= OnCallUpdate; shard.OnVoiceServerUpdate -= OnVoiceServerUpdate; shard.OnVoiceStateUpdate -= OnVoiceStateUpdate; shard.OnChannelCreate -= OnChannelCreate; shard.OnChannelDelete -= OnChannelDelete; shard.OnChannelPinsAck -= OnChannelPinsAck; shard.OnChannelPinsUpdate -= OnChannelPinsUpdate; shard.OnChannelRecipientAdd -= OnChannelRecipientAdd; shard.OnChannelRecipientRemove -= OnChannelRecipientRemove; shard.OnChannelUpdate -= OnChannelUpdate; shard.OnGuildBanAdd -= OnGuildBanAdd; shard.OnGuildBanRemove -= OnGuildBanRemove; shard.OnGuildCreate -= OnGuildCreate; shard.OnGuildDelete -= OnGuildDelete; shard.OnGuildEmojisUpdate -= OnGuildEmojisUpdate; shard.OnGuildIntegrationsUpdate -= OnGuildIntegrationsUpdate; shard.OnGuildMemberAdd -= OnGuildMemberAdd; shard.OnGuildMemberUpdate -= OnGuildMemberUpdate; shard.OnGuildMemberRemove -= OnGuildMemberRemove; shard.OnGuildMembersChunk -= OnGuildMembersChunk; shard.OnGuildRoleCreate -= OnGuildRoleCreate; shard.OnGuildRoleUpdate -= OnGuildRoleUpdate; shard.OnGuildRoleDelete -= OnGuildRoleDelete; shard.OnGuildUpdate -= OnGuildUpdate; shard.OnMessageAck -= OnMessageAck; shard.OnMessageCreate -= OnMessageCreate; shard.OnMessageDelete -= OnMessageDelete; shard.OnMessageDeleteBulk -= OnMessageDeleteBulk; shard.OnMessageReactionAdd -= OnMessageReactionAdd; shard.OnMessageReactionRemove -= OnMessageReactionRemove; shard.OnMessageReactionsRemoveAll -= OnMessageReactionsRemoveAll; shard.OnMessageUpdate -= OnMessageUpdate; shard.OnTypingStart -= OnTypingStart; shard.OnPresenceUpdate -= OnPresenceUpdate; shard.OnPresencesReplace -= OnPresencesReplace; shard.OnFriendSuggestionDelete -= OnFriendSuggestionDelete; shard.OnRelationshipAdd -= OnRelationshipAdd; shard.OnRelationshipRemove -= OnRelationshipRemove; shard.OnReady -= OnReady; shard.OnResumed -= OnResumed; shard.OnUserUpdate -= OnUserUpdate; shard.OnUserNoteUpdate -= OnUserNoteUpdate; shard.OnUserSettingsUpdate -= OnUserSettingsUpdate; shard.OnSocketOpen -= OnSocketOpen; shard.OnSocketClose -= OnSocketClose; shard.OnSocketError -= OnSocketError; shard.OnSocketMessage -= OnSocketMessage; } #region Events public event Action OnCallCreate; public event Action OnCallDelete; public event Action OnCallUpdate; public event Action OnVoiceServerUpdate; public event Action OnVoiceStateUpdate; public event Action OnChannelCreate; public event Action OnChannelDelete; public event Action OnChannelPinsAck; public event Action OnChannelPinsUpdate; public event Action OnChannelRecipientAdd; public event Action OnChannelRecipientRemove; public event Action OnChannelUpdate; public event Action OnGuildBanAdd; public event Action OnGuildBanRemove; public event Action OnGuildCreate; public event Action OnGuildDelete; public event Action OnGuildEmojisUpdate; public event Action OnGuildIntegrationsUpdate; public event Action OnGuildMemberAdd; public event Action OnGuildMemberUpdate; public event Action OnGuildMemberRemove; public event Action OnGuildMembersChunk; public event Action OnGuildRoleCreate; public event Action OnGuildRoleUpdate; public event Action OnGuildRoleDelete; public event Action OnGuildUpdate; public event Action OnMessageAck; public event Action OnMessageCreate; public event Action OnMessageDelete; public event Action OnMessageDeleteBulk; public event Action OnMessageReactionAdd; public event Action OnMessageReactionRemove; public event Action OnMessageReactionsRemoveAll; public event Action OnMessageUpdate; public event Action OnTypingStart; public event Action OnPresenceUpdate; public event Action OnPresencesReplace; public event Action OnFriendSuggestionDelete; public event Action OnRelationshipAdd; public event Action OnRelationshipRemove; public event Action OnReady; public event Action OnResumed; public event Action OnUserUpdate; public event Action OnUserNoteUpdate; public event Action OnUserSettingsUpdate; public event Action OnSocketOpen; public event Action OnSocketClose; public event Action OnSocketError; public event Action OnSocketMessage; #endregion #region IDisposable private bool IsDisposed = false; /// /// Releases all unmanaged resources used by this object /// private void Dispose(bool disposing) { if (IsDisposed) return; IsDisposed = true; Disconnect(); if (disposing) GC.SuppressFinalize(true); } ~GatewayShardClient() => Dispose(false); public void Dispose() => Dispose(true); #endregion } }