Archived
1
0
Fork 0

Shard cleanup part 2

This commit is contained in:
flash 2017-11-13 12:39:27 +01:00
parent 75e7e29b0a
commit 2620ce3765
5 changed files with 254 additions and 658 deletions

View file

@ -271,11 +271,6 @@ namespace Maki
ShardClient.OnResumed += ShardManager_OnResumed; ShardClient.OnResumed += ShardManager_OnResumed;
ShardClient.OnUserUpdate += ShardManager_OnUserUpdate; ShardClient.OnUserUpdate += ShardManager_OnUserUpdate;
ShardClient.OnSocketOpen += ShardManager_OnSocketOpen;
ShardClient.OnSocketClose += ShardManager_OnSocketClose;
ShardClient.OnSocketError += ShardManager_OnSocketError;
ShardClient.OnSocketMessage += ShardManager_OnSocketMessage;
#endregion #endregion
} }
@ -855,22 +850,10 @@ namespace Maki
OnUserUpdate?.Invoke(user); OnUserUpdate?.Invoke(user);
} }
private void ShardManager_OnSocketOpen(GatewayShard shard)
{
}
private void ShardManager_OnSocketClose(GatewayShard shard, bool wasClean, ushort code, string reason)
{
}
private void ShardManager_OnSocketError(GatewayShard shard, Exception ex) private void ShardManager_OnSocketError(GatewayShard shard, Exception ex)
{ {
} }
private void ShardManager_OnSocketMessage(GatewayShard shard, string text)
{
}
#endregion #endregion
#region IDisposable #region IDisposable

View file

@ -1,192 +0,0 @@
namespace Maki.Gateway
{
/// <summary>
/// Gateway Dispatch Events
/// </summary>
enum GatewayEvent
{
#region Voice Events
CALL_CREATE,
CALL_DELETE,
CALL_UPDATE,
/// <summary>
/// Sent when a guild's voice server is updated. This is sent when initially connecting to voice, and when the current voice instance fails over to a new server.
/// </summary>
VOICE_SERVER_UPDATE,
/// <summary>
/// Sent when someone joins/leaves/moves voice channels. Inner payload is a voice state object.
/// </summary>
VOICE_STATE_UPDATE,
#endregion
#region Channel Events
/// <summary>
/// Sent when a new channel is created, relevant to the current user. The inner payload is a DM or Guild channel object.
/// </summary>
CHANNEL_CREATE,
/// <summary>
/// Sent when a channel relevant to the current user is deleted. The inner payload is a DM or Guild channel object.
/// </summary>
CHANNEL_DELETE,
CHANNEL_PINS_ACK,
CHANNEL_PINS_UPDATE,
CHANNEL_RECIPIENT_ADD,
CHANNEL_RECIPIENT_REMOVE,
/// <summary>
/// Sent when a channel is updated. The inner payload is a guild channel object.
/// </summary>
CHANNEL_UPDATE,
#endregion
#region Guild Events
/// <summary>
/// Sent when a user is banned from a guild. The inner payload is a user object, with an extra guild_id key.
/// </summary>
GUILD_BAN_ADD,
/// <summary>
/// Sent when a user is unbanned from a guild. The inner payload is a user object, with an extra guild_id key.
/// </summary>
GUILD_BAN_REMOVE,
/// <summary>
/// This event can be sent in three different scenarios:
/// 1. When a user is initially connecting, to lazily load and backfill information for all unavailable guilds sent in the ready event.
/// 2. When a Guild becomes available again to the client.
/// 3. When the current user joins a new Guild.
/// The inner payload is a guild object, with all the extra fields specified.
/// </summary>
GUILD_CREATE,
/// <summary>
/// Sent when a guild becomes unavailable during a guild outage, or when the user leaves or is removed from a guild. See GUILD_CREATE for more information about how to handle this event.
/// </summary>
GUILD_DELETE,
/// <summary>
/// Sent when a guild's emojis have been updated.
/// </summary>
GUILD_EMOJIS_UPDATE,
/// <summary>
/// Sent when a guild integration is updated.
/// </summary>
GUILD_INTEGRATIONS_UPDATE,
/// <summary>
/// Sent when a new user joins a guild. The inner payload is a guild member objec, with an extra guild_id key.
/// </summary>
GUILD_MEMBER_ADD,
/// <summary>
/// Sent when a guild member is updated.
/// </summary>
GUILD_MEMBER_UPDATE,
/// <summary>
/// Sent when a user is removed from a guild (leave/kick/ban).
/// </summary>
GUILD_MEMBER_REMOVE,
/// <summary>
/// Sent in response to Gateway Request Guild Members.
/// </summary>
GUILD_MEMBERS_CHUNK,
/// <summary>
/// Sent when a guild role is created.
/// </summary>
GUILD_ROLE_CREATE,
/// <summary>
/// Sent when a guild role is updated.
/// </summary>
GUILD_ROLE_UPDATE,
/// <summary>
/// Sent when a guild role is deleted.
/// </summary>
GUILD_ROLE_DELETE,
/// <summary>
/// Sent when a guild is updated. The inner payload is a guild object.
/// </summary>
GUILD_UPDATE,
#endregion
#region Message Events
MESSAGE_ACK,
/// <summary>
/// Sent when a message is created. The inner payload is a message object.
/// </summary>
MESSAGE_CREATE,
/// <summary>
/// Sent when a message is deleted.
/// </summary>
MESSAGE_DELETE,
/// <summary>
/// Sent when multiple messages are deleted at once.
/// </summary>
MESSAGE_DELETE_BULK,
MESSAGE_REACTION_ADD,
MESSAGE_REACTION_REMOVE,
MESSAGE_REACTIONS_REMOVE_ALL,
/// <summary>
/// Sent when a message is updated. The inner payload is a message object.
/// </summary>
MESSAGE_UPDATE,
#endregion
#region Presence Events
/// <summary>
/// Sent when a user starts typing in a channel.
/// </summary>
TYPING_START,
/// <summary>
/// A user's presence is their current state on a guild. This event is sent when a user's presence is updated for a guild.
/// </summary>
PRESENCE_UPDATE,
PRESENCES_REPLACE,
#endregion
#region Relation Events
FRIEND_SUGGESTION_DELETE,
RELATIONSHIP_ADD,
RELATIONSHIP_REMOVE,
#endregion
#region State Events
/// <summary>
/// The ready event is dispatched when a client has completed the initial handshake with the gateway (for new sessions). The ready event can be the largest and most complex event the gateway will send, as it contains all the state required for a client to begin interacting with the rest of the platform.
/// </summary>
READY,
/// <summary>
/// The resumed event is dispatched when a client has sent a resume payload to the gateway (for resuming existing sessions).
/// </summary>
RESUMED,
#endregion
#region User Events
/// <summary>
/// Sent when properties about the user change. Inner payload is a user object.
/// </summary>
USER_UPDATE,
USER_NOTE_UPDATE,
/// <summary>
/// Sent when the current user updates their settings. Inner payload is a user settings object.
/// </summary>
USER_SETTINGS_UPDATE,
#endregion
}
}

View file

@ -1,9 +1,4 @@
using Maki.Structures.Channels; using Maki.Structures.Gateway;
using Maki.Structures.Gateway;
using Maki.Structures.Guilds;
using Maki.Structures.Messages;
using Maki.Structures.Presences;
using Maki.Structures.Users;
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using WebSocketSharp; using WebSocketSharp;
@ -18,7 +13,7 @@ namespace Maki.Gateway
/// <summary> /// <summary>
/// Session key for continuing a resuming after disconnecting /// Session key for continuing a resuming after disconnecting
/// </summary> /// </summary>
private string session; private string Session;
/// <summary> /// <summary>
/// Websocket container /// Websocket container
@ -43,72 +38,17 @@ namespace Maki.Gateway
/// <summary> /// <summary>
/// Parent DiscordClient instance /// Parent DiscordClient instance
/// </summary> /// </summary>
private readonly Discord client; private readonly Discord Client;
/// <summary> /// <summary>
/// Heartbeat handler /// Heartbeat handler
/// </summary> /// </summary>
private readonly GatewayHeartbeatManager heartbeatHandler; private readonly GatewayHeartbeatManager HeartbeatHandler;
#region Events /// <summary>
public event Action<GatewayShard> OnCallCreate; /// Fires when a payload is received.
public event Action<GatewayShard> OnCallDelete; /// </summary>
public event Action<GatewayShard> OnCallUpdate; public event Action<GatewayShard, GatewayPayload> OnSocketPayload;
public event Action<GatewayShard> OnVoiceServerUpdate;
public event Action<GatewayShard> OnVoiceStateUpdate;
public event Action<GatewayShard, Channel> OnChannelCreate;
public event Action<GatewayShard, Channel> OnChannelDelete;
public event Action<GatewayShard> OnChannelPinsAck;
public event Action<GatewayShard> OnChannelPinsUpdate;
public event Action<GatewayShard> OnChannelRecipientAdd;
public event Action<GatewayShard> OnChannelRecipientRemove;
public event Action<GatewayShard, Channel> OnChannelUpdate;
public event Action<GatewayShard, User> OnGuildBanAdd;
public event Action<GatewayShard, User> OnGuildBanRemove;
public event Action<GatewayShard, Guild> OnGuildCreate;
public event Action<GatewayShard, Guild> OnGuildDelete;
public event Action<GatewayShard, Guild> OnGuildEmojisUpdate;
public event Action<GatewayShard, GuildIntegration> OnGuildIntegrationsUpdate;
public event Action<GatewayShard, GuildMember> OnGuildMemberAdd;
public event Action<GatewayShard, GuildMember> OnGuildMemberUpdate;
public event Action<GatewayShard, GuildMember> OnGuildMemberRemove;
public event Action<GatewayShard, GuildMembersChunk> OnGuildMembersChunk;
public event Action<GatewayShard, GuildRole> OnGuildRoleCreate;
public event Action<GatewayShard, GuildRole> OnGuildRoleUpdate;
public event Action<GatewayShard, GuildRole> OnGuildRoleDelete;
public event Action<GatewayShard, Guild> OnGuildUpdate;
public event Action<GatewayShard> OnMessageAck;
public event Action<GatewayShard, Message> OnMessageCreate;
public event Action<GatewayShard, Message> OnMessageDelete;
public event Action<GatewayShard> OnMessageDeleteBulk;
public event Action<GatewayShard> OnMessageReactionAdd;
public event Action<GatewayShard> OnMessageReactionRemove;
public event Action<GatewayShard> OnMessageReactionsRemoveAll;
public event Action<GatewayShard, Message> OnMessageUpdate;
public event Action<GatewayShard, TypingStart> OnTypingStart;
public event Action<GatewayShard, Presence> OnPresenceUpdate;
public event Action<GatewayShard> OnPresencesReplace;
public event Action<GatewayShard> OnFriendSuggestionDelete;
public event Action<GatewayShard> OnRelationshipAdd;
public event Action<GatewayShard> OnRelationshipRemove;
public event Action<GatewayShard, GatewayReady> OnReady;
public event Action<GatewayShard> OnResumed;
public event Action<GatewayShard, User> OnUserUpdate;
public event Action<GatewayShard> OnUserNoteUpdate;
public event Action<GatewayShard> OnUserSettingsUpdate;
public event Action<GatewayShard> OnSocketOpen;
public event Action<GatewayShard, bool, ushort, string> OnSocketClose;
public event Action<GatewayShard, Exception> OnSocketError;
public event Action<GatewayShard, string> OnSocketMessage;
#endregion
/// <summary> /// <summary>
/// Constructor /// Constructor
@ -118,34 +58,19 @@ namespace Maki.Gateway
public GatewayShard(int id, Discord c) public GatewayShard(int id, Discord c)
{ {
Id = id; Id = id;
client = c; Client = c;
heartbeatHandler = new GatewayHeartbeatManager(this); HeartbeatHandler = new GatewayHeartbeatManager(this);
Connect(); Connect();
} }
/// <summary> /// <summary>
/// Event handler for WebSocketSharp's OnOpen event, forwards to our OnSocketOpen event /// Event handler for WebSocketSharp's OnClose event, stops heartbeats and reconnects if the close wasn't clean
/// </summary>
/// <param name="sender">Sender object</param>
/// <param name="e">Event arguments</param>
private void WebSocket_OnOpen(object sender, EventArgs e) => OnSocketOpen?.Invoke(this);
/// <summary>
/// Event handler for WebSocketSharp's OnError event, forwards to our OnSocketError event
/// </summary>
/// <param name="sender">Sender object</param>
/// <param name="e">Event arguments</param>
private void WebSocket_OnError(object sender, ErrorEventArgs e) => OnSocketError?.Invoke(this, e.Exception);
/// <summary>
/// Event handler for WebSocketSharp's OnClose event, stops heartbeats, forwards to our OnSocketClose event and reconnects if the close wasn't clean
/// </summary> /// </summary>
/// <param name="sender">Sender object</param> /// <param name="sender">Sender object</param>
/// <param name="e">Event arguments</param> /// <param name="e">Event arguments</param>
private void WebSocket_OnClose(object sender, CloseEventArgs e) private void WebSocket_OnClose(object sender, CloseEventArgs e)
{ {
heartbeatHandler.Stop(); HeartbeatHandler.Stop();
OnSocketClose?.Invoke(this, e.WasClean, e.Code, e.Reason);
if (!e.WasClean || e.Code != 1000) if (!e.WasClean || e.Code != 1000)
Connect(); Connect();
@ -162,217 +87,19 @@ namespace Maki.Gateway
if (!e.IsText) if (!e.IsText)
return; return;
Console.WriteLine(e.Data.Replace(client.Token, new string('*', client.Token.Length))); Console.WriteLine(e.Data.Replace(Client.Token, new string('*', Client.Token.Length)));
OnSocketMessage?.Invoke(this, e.Data);
GatewayPayload payload = JsonConvert.DeserializeObject<GatewayPayload>(e.Data); GatewayPayload payload = JsonConvert.DeserializeObject<GatewayPayload>(e.Data);
OnSocketPayload?.Invoke(this, payload);
switch (payload.OPCode) { switch (payload.OPCode) {
case GatewayOPCode.Dispatch: case GatewayOPCode.Dispatch:
LastSequence = payload.Sequence; LastSequence = payload.Sequence;
Enum.TryParse(payload.Name, out GatewayEvent evt);
switch (evt) { if (payload.Name == "READY")
#region Call {
case GatewayEvent.CALL_CREATE: GatewayReady ready = payload.DataAs<GatewayReady>();
OnCallCreate?.Invoke(this); Session = ready.Session;
break;
case GatewayEvent.CALL_DELETE:
OnCallDelete?.Invoke(this);
break;
case GatewayEvent.CALL_UPDATE:
OnCallUpdate?.Invoke(this);
break;
case GatewayEvent.VOICE_SERVER_UPDATE:
OnVoiceServerUpdate?.Invoke(this);
break;
case GatewayEvent.VOICE_STATE_UPDATE:
OnVoiceStateUpdate?.Invoke(this);
break;
#endregion
#region Channel
case GatewayEvent.CHANNEL_CREATE:
OnChannelCreate?.Invoke(this, payload.DataAs<Channel>());
break;
case GatewayEvent.CHANNEL_DELETE:
OnChannelDelete?.Invoke(this, payload.DataAs<Channel>());
break;
case GatewayEvent.CHANNEL_PINS_ACK:
OnChannelPinsAck?.Invoke(this);
break;
case GatewayEvent.CHANNEL_PINS_UPDATE:
OnChannelPinsUpdate?.Invoke(this);
break;
case GatewayEvent.CHANNEL_RECIPIENT_ADD:
OnChannelRecipientAdd?.Invoke(this);
break;
case GatewayEvent.CHANNEL_RECIPIENT_REMOVE:
OnChannelRecipientRemove?.Invoke(this);
break;
case GatewayEvent.CHANNEL_UPDATE:
OnChannelUpdate?.Invoke(this, payload.DataAs<Channel>());
break;
#endregion
#region Guild
case GatewayEvent.GUILD_BAN_ADD:
OnGuildBanAdd?.Invoke(this, payload.DataAs<User>());
break;
case GatewayEvent.GUILD_BAN_REMOVE:
OnGuildBanRemove?.Invoke(this, payload.DataAs<User>());
break;
case GatewayEvent.GUILD_CREATE:
OnGuildCreate?.Invoke(this, payload.DataAs<Guild>());
break;
case GatewayEvent.GUILD_DELETE:
OnGuildDelete?.Invoke(this, payload.DataAs<Guild>());
break;
case GatewayEvent.GUILD_EMOJIS_UPDATE:
OnGuildEmojisUpdate?.Invoke(this, payload.DataAs<Guild>());
break;
case GatewayEvent.GUILD_INTEGRATIONS_UPDATE:
OnGuildIntegrationsUpdate?.Invoke(this, payload.DataAs<GuildIntegration>());
break;
case GatewayEvent.GUILD_MEMBER_ADD:
OnGuildMemberAdd?.Invoke(this, payload.DataAs<GuildMember>());
break;
case GatewayEvent.GUILD_MEMBER_UPDATE:
OnGuildMemberUpdate?.Invoke(this, payload.DataAs<GuildMember>());
break;
case GatewayEvent.GUILD_MEMBER_REMOVE:
OnGuildMemberRemove?.Invoke(this, payload.DataAs<GuildMember>());
break;
case GatewayEvent.GUILD_MEMBERS_CHUNK:
OnGuildMembersChunk?.Invoke(this, payload.DataAs<GuildMembersChunk>());
break;
case GatewayEvent.GUILD_ROLE_CREATE:
OnGuildRoleCreate?.Invoke(this, payload.DataAs<GuildRole>());
break;
case GatewayEvent.GUILD_ROLE_UPDATE:
OnGuildRoleUpdate?.Invoke(this, payload.DataAs<GuildRole>());
break;
case GatewayEvent.GUILD_ROLE_DELETE:
OnGuildRoleDelete?.Invoke(this, payload.DataAs<GuildRole>());
break;
case GatewayEvent.GUILD_UPDATE:
OnGuildUpdate?.Invoke(this, payload.DataAs<Guild>());
break;
#endregion
#region Message
case GatewayEvent.MESSAGE_ACK:
OnMessageAck?.Invoke(this);
break;
case GatewayEvent.MESSAGE_CREATE:
OnMessageCreate?.Invoke(this, payload.DataAs<Message>());
break;
case GatewayEvent.MESSAGE_DELETE:
OnMessageDelete?.Invoke(this, payload.DataAs<Message>());
break;
case GatewayEvent.MESSAGE_DELETE_BULK:
OnMessageDeleteBulk?.Invoke(this);
break;
case GatewayEvent.MESSAGE_REACTION_ADD:
OnMessageReactionAdd?.Invoke(this);
break;
case GatewayEvent.MESSAGE_REACTION_REMOVE:
OnMessageReactionRemove?.Invoke(this);
break;
case GatewayEvent.MESSAGE_REACTIONS_REMOVE_ALL:
OnMessageReactionsRemoveAll?.Invoke(this);
break;
case GatewayEvent.MESSAGE_UPDATE:
OnMessageUpdate?.Invoke(this, payload.DataAs<Message>());
break;
#endregion
#region Presence
case GatewayEvent.TYPING_START:
OnTypingStart?.Invoke(this, payload.DataAs<TypingStart>());
break;
case GatewayEvent.PRESENCE_UPDATE:
OnPresenceUpdate?.Invoke(this, payload.DataAs<Presence>());
break;
case GatewayEvent.PRESENCES_REPLACE:
OnPresencesReplace?.Invoke(this);
break;
#endregion
#region Relations
case GatewayEvent.FRIEND_SUGGESTION_DELETE:
OnFriendSuggestionDelete?.Invoke(this);
break;
case GatewayEvent.RELATIONSHIP_ADD:
OnRelationshipAdd?.Invoke(this);
break;
case GatewayEvent.RELATIONSHIP_REMOVE:
OnRelationshipRemove?.Invoke(this);
break;
#endregion
#region State
case GatewayEvent.READY:
GatewayReady ready = payload.DataAs<GatewayReady>();
session = ready.Session;
OnReady?.Invoke(this, ready);
break;
case GatewayEvent.RESUMED:
OnResumed?.Invoke(this);
break;
#endregion
#region User
case GatewayEvent.USER_UPDATE:
OnUserUpdate?.Invoke(this, payload.DataAs<User>());
break;
case GatewayEvent.USER_NOTE_UPDATE:
OnUserNoteUpdate?.Invoke(this);
break;
case GatewayEvent.USER_SETTINGS_UPDATE:
OnUserSettingsUpdate?.Invoke(this);
break;
#endregion
default:
Console.WriteLine($"Unknown payload type: {payload.Name}");
break;
} }
break; break;
@ -380,15 +107,17 @@ namespace Maki.Gateway
GatewayHello hello = payload.DataAs<GatewayHello>(); GatewayHello hello = payload.DataAs<GatewayHello>();
HeartbeatInterval = TimeSpan.FromMilliseconds(hello.HeartbeatInterval); HeartbeatInterval = TimeSpan.FromMilliseconds(hello.HeartbeatInterval);
heartbeatHandler.Start(); HeartbeatHandler.Start();
if (string.IsNullOrEmpty(session)) if (string.IsNullOrEmpty(Session))
Send(GatewayOPCode.Identify, new GatewayIdentification { Send(GatewayOPCode.Identify, new GatewayIdentification
Token = client.Token, {
Token = Client.Token,
Compress = false, Compress = false,
LargeThreshold = 250, LargeThreshold = 250,
Shard = new int[] { Id, client.ShardClient.ShardCount }, Shard = new int[] { Id, Client.ShardClient.ShardCount },
Properties = new GatewayIdentificationProperties { Properties = new GatewayIdentificationProperties
{
OperatingSystem = "windows", OperatingSystem = "windows",
Browser = "Maki", Browser = "Maki",
Device = "Maki", Device = "Maki",
@ -397,10 +126,11 @@ namespace Maki.Gateway
} }
}); });
else else
Send(GatewayOPCode.Resume, new GatewayResume { Send(GatewayOPCode.Resume, new GatewayResume
{
LastSequence = LastSequence ?? default(int), LastSequence = LastSequence ?? default(int),
Token = client.Token, Token = Client.Token,
Session = session, Session = Session,
}); });
break; break;
} }
@ -435,14 +165,12 @@ namespace Maki.Gateway
/// </summary> /// </summary>
public void Connect() public void Connect()
{ {
WebSocket = new WebSocket($"{client.Gateway}?v={Discord.GATEWAY_VERSION}&encoding=json"); WebSocket = new WebSocket($"{Client.Gateway}?v={Discord.GATEWAY_VERSION}&encoding=json");
// make wss not log anything on its own // make wss not log anything on its own
WebSocket.Log.Output = (LogData logData, string path) => { }; WebSocket.Log.Output = (LogData logData, string path) => { };
WebSocket.OnOpen += WebSocket_OnOpen;
WebSocket.OnClose += WebSocket_OnClose; WebSocket.OnClose += WebSocket_OnClose;
WebSocket.OnError += WebSocket_OnError;
WebSocket.OnMessage += WebSocket_OnMessage; WebSocket.OnMessage += WebSocket_OnMessage;
WebSocket.Connect(); WebSocket.Connect();
@ -453,7 +181,7 @@ namespace Maki.Gateway
/// </summary> /// </summary>
public void Disconnect() public void Disconnect()
{ {
heartbeatHandler.Stop(); HeartbeatHandler.Stop();
if (WebSocket.ReadyState != WebSocketState.Closed) if (WebSocket.ReadyState != WebSocketState.Closed)
WebSocket?.Close(CloseStatusCode.Normal); WebSocket?.Close(CloseStatusCode.Normal);
@ -468,7 +196,7 @@ namespace Maki.Gateway
{ {
string json = JsonConvert.SerializeObject(data, typeof(T), new JsonSerializerSettings()); string json = JsonConvert.SerializeObject(data, typeof(T), new JsonSerializerSettings());
Console.WriteLine(json.Replace(client.Token, new string('*', client.Token.Length))); Console.WriteLine(json.Replace(Client.Token, new string('*', Client.Token.Length)));
WebSocket.Send(json); WebSocket.Send(json);
} }
@ -479,12 +207,10 @@ namespace Maki.Gateway
/// <param name="opcode">Opcode to use</param> /// <param name="opcode">Opcode to use</param>
/// <param name="data">Data to send</param> /// <param name="data">Data to send</param>
public void Send(GatewayOPCode opcode, object data) public void Send(GatewayOPCode opcode, object data)
{ => Send(new GatewayPayload
Send(new GatewayPayload
{ {
OPCode = opcode, OPCode = opcode,
Data = data Data = data
}); });
}
} }
} }

View file

@ -48,7 +48,7 @@ namespace Maki.Gateway
public GatewayShard Create(int id) public GatewayShard Create(int id)
{ {
GatewayShard shard = new GatewayShard(id, Client); GatewayShard shard = new GatewayShard(id, Client);
ApplyEvents(shard); shard.OnSocketPayload += Shard_OnSocketPayload;
lock (Lock) lock (Lock)
Shards.Add(shard); Shards.Add(shard);
@ -56,6 +56,219 @@ namespace Maki.Gateway
return shard; return shard;
} }
private void Shard_OnSocketPayload(GatewayShard shard, GatewayPayload payload)
{
switch (payload.OPCode)
{
case GatewayOPCode.Dispatch:
switch (payload.Name)
{
#region Call
case "CALL_CREATE":
OnCallCreate?.Invoke(shard);
break;
case "CALL_DELETE":
OnCallDelete?.Invoke(shard);
break;
case "CALL_UPDATE":
OnCallUpdate?.Invoke(shard);
break;
case "VOICE_SERVER_UPDATE":
OnVoiceServerUpdate?.Invoke(shard);
break;
case "VOICE_STATE_UPDATE":
OnVoiceStateUpdate?.Invoke(shard);
break;
#endregion
#region Channel
case "CHANNEL_CREATE":
OnChannelCreate?.Invoke(shard, payload.DataAs<Channel>());
break;
case "CHANNEL_DELETE":
OnChannelDelete?.Invoke(shard, payload.DataAs<Channel>());
break;
case "CHANNEL_PINS_ACK":
OnChannelPinsAck?.Invoke(shard);
break;
case "CHANNEL_PINS_UPDATE":
OnChannelPinsUpdate?.Invoke(shard);
break;
case "CHANNEL_RECIPIENT_ADD":
OnChannelRecipientAdd?.Invoke(shard);
break;
case "CHANNEL_RECIPIENT_REMOVE":
OnChannelRecipientRemove?.Invoke(shard);
break;
case "CHANNEL_UPDATE":
OnChannelUpdate?.Invoke(shard, payload.DataAs<Channel>());
break;
#endregion
#region Guild
case "GUILD_BAN_ADD":
OnGuildBanAdd?.Invoke(shard, payload.DataAs<User>());
break;
case "GUILD_BAN_REMOVE":
OnGuildBanRemove?.Invoke(shard, payload.DataAs<User>());
break;
case "GUILD_CREATE":
OnGuildCreate?.Invoke(shard, payload.DataAs<Guild>());
break;
case "GUILD_DELETE":
OnGuildDelete?.Invoke(shard, payload.DataAs<Guild>());
break;
case "GUILD_EMOJIS_UPDATE":
OnGuildEmojisUpdate?.Invoke(shard, payload.DataAs<Guild>());
break;
case "GUILD_INTEGRATIONS_UPDATE":
OnGuildIntegrationsUpdate?.Invoke(shard, payload.DataAs<GuildIntegration>());
break;
case "GUILD_MEMBER_ADD":
OnGuildMemberAdd?.Invoke(shard, payload.DataAs<GuildMember>());
break;
case "GUILD_MEMBER_UPDATE":
OnGuildMemberUpdate?.Invoke(shard, payload.DataAs<GuildMember>());
break;
case "GUILD_MEMBER_REMOVE":
OnGuildMemberRemove?.Invoke(shard, payload.DataAs<GuildMember>());
break;
case "GUILD_MEMBERS_CHUNK":
OnGuildMembersChunk?.Invoke(shard, payload.DataAs<GuildMembersChunk>());
break;
case "GUILD_ROLE_CREATE":
OnGuildRoleCreate?.Invoke(shard, payload.DataAs<GuildRole>());
break;
case "GUILD_ROLE_UPDATE":
OnGuildRoleUpdate?.Invoke(shard, payload.DataAs<GuildRole>());
break;
case "GUILD_ROLE_DELETE":
OnGuildRoleDelete?.Invoke(shard, payload.DataAs<GuildRole>());
break;
case "GUILD_UPDATE":
OnGuildUpdate?.Invoke(shard, payload.DataAs<Guild>());
break;
#endregion
#region Message
case "MESSAGE_ACK":
OnMessageAck?.Invoke(shard);
break;
case "MESSAGE_CREATE":
OnMessageCreate?.Invoke(shard, payload.DataAs<Message>());
break;
case "MESSAGE_DELETE":
OnMessageDelete?.Invoke(shard, payload.DataAs<Message>());
break;
case "MESSAGE_DELETE_BULK":
OnMessageDeleteBulk?.Invoke(shard);
break;
case "MESSAGE_REACTION_ADD":
OnMessageReactionAdd?.Invoke(shard);
break;
case "MESSAGE_REACTION_REMOVE":
OnMessageReactionRemove?.Invoke(shard);
break;
case "MESSAGE_REACTIONS_REMOVE_ALL":
OnMessageReactionsRemoveAll?.Invoke(shard);
break;
case "MESSAGE_UPDATE":
OnMessageUpdate?.Invoke(shard, payload.DataAs<Message>());
break;
#endregion
#region Presence
case "TYPING_START":
OnTypingStart?.Invoke(shard, payload.DataAs<TypingStart>());
break;
case "PRESENCE_UPDATE":
OnPresenceUpdate?.Invoke(shard, payload.DataAs<Presence>());
break;
case "PRESENCES_REPLACE":
OnPresencesReplace?.Invoke(shard);
break;
#endregion
#region Relations
case "FRIEND_SUGGESTION_DELETE":
OnFriendSuggestionDelete?.Invoke(shard);
break;
case "RELATIONSHIP_ADD":
OnRelationshipAdd?.Invoke(shard);
break;
case "RELATIONSHIP_REMOVE":
OnRelationshipRemove?.Invoke(shard);
break;
#endregion
#region State
case "READY":
OnReady?.Invoke(shard, payload.DataAs<GatewayReady>());
break;
case "RESUMED":
OnResumed?.Invoke(shard);
break;
#endregion
#region User
case "USER_UPDATE":
OnUserUpdate?.Invoke(shard, payload.DataAs<User>());
break;
case "USER_NOTE_UPDATE":
OnUserNoteUpdate?.Invoke(shard);
break;
case "USER_SETTINGS_UPDATE":
OnUserSettingsUpdate?.Invoke(shard);
break;
#endregion
#if DEBUG
default:
Console.WriteLine($"Unknown payload type: {payload.Name}");
break;
#endif
}
break;
}
}
/// <summary> /// <summary>
/// Destroys a Gateway Shard /// Destroys a Gateway Shard
/// </summary> /// </summary>
@ -67,7 +280,7 @@ namespace Maki.Gateway
// Disconnect and Dispose are called separately so OnSocketClose is called properly // Disconnect and Dispose are called separately so OnSocketClose is called properly
shard.Disconnect(); shard.Disconnect();
RemoveEvents(shard); shard.OnSocketPayload -= Shard_OnSocketPayload;
shard.Dispose(); shard.Dispose();
} }
@ -80,137 +293,8 @@ namespace Maki.Gateway
Shards.ToList().ForEach(x => Destroy(x)); Shards.ToList().ForEach(x => Destroy(x));
} }
/// <summary>
/// Links all gateway events handlers to the shard
/// </summary>
/// <param name="shard">Shard to link events to</param>
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;
}
/// <summary>
/// Unlinks all gateway events handlers from the shard
/// </summary>
/// <param name="shard">Shard to unlink events from</param>
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 #region Events
public event Action<GatewayShard> OnCallCreate; public event Action<GatewayShard> OnCallCreate;
public event Action<GatewayShard> OnCallDelete; public event Action<GatewayShard> OnCallDelete;
public event Action<GatewayShard> OnCallUpdate; public event Action<GatewayShard> OnCallUpdate;
@ -264,10 +348,6 @@ namespace Maki.Gateway
public event Action<GatewayShard> OnUserNoteUpdate; public event Action<GatewayShard> OnUserNoteUpdate;
public event Action<GatewayShard> OnUserSettingsUpdate; public event Action<GatewayShard> OnUserSettingsUpdate;
public event Action<GatewayShard> OnSocketOpen;
public event Action<GatewayShard, bool, ushort, string> OnSocketClose;
public event Action<GatewayShard, Exception> OnSocketError;
public event Action<GatewayShard, string> OnSocketMessage;
#endregion #endregion
#region IDisposable #region IDisposable

View file

@ -64,7 +64,6 @@
<Compile Include="DiscordServer.cs" /> <Compile Include="DiscordServer.cs" />
<Compile Include="DiscordUserStatus.cs" /> <Compile Include="DiscordUserStatus.cs" />
<Compile Include="DiscordUser.cs" /> <Compile Include="DiscordUser.cs" />
<Compile Include="Gateway\GatewayEvent.cs" />
<Compile Include="MemberManager.cs" /> <Compile Include="MemberManager.cs" />
<Compile Include="MessageManager.cs" /> <Compile Include="MessageManager.cs" />
<Compile Include="Rest\RestErrorCode.cs" /> <Compile Include="Rest\RestErrorCode.cs" />