From 6a31124ec5a4d13f0aeafdaf1a738ca9235c285e Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Fri, 28 Aug 2020 16:02:38 -0500 Subject: [PATCH] Fix issues with reconnecting --- examples/basic.nim | 31 ++++++++++++++++++------------- src/nimcord/client.nim | 14 ++++++++------ 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/examples/basic.nim b/examples/basic.nim index 06f8a4a..eb80492 100644 --- a/examples/basic.nim +++ b/examples/basic.nim @@ -10,14 +10,14 @@ if (not isNil(tokenStream)): var bot = newDiscordClient(tkn, "?", newLog(ord(LoggerFlags.loggerFlagDebugSeverity))) let pingCommand = Command(name: "ping", commandBody: proc(ctx: CommandContext) = - discard ctx.channel.sendMessage("PONG") + asyncCheck ctx.channel.sendMessage("PONG") ) let modifyChannelTopicCommand = Command(name: "modifyChannelTopic", commandBody: proc(ctx: CommandContext) = let modifyTopic = ctx.message.content.substr(20) - discard ctx.channel.sendMessage("Modifing Channel!") - discard ctx.channel.modifyChannel(ChannelFields(topic: some(modifyTopic))) + asyncCheck ctx.channel.sendMessage("Modifing Channel!") + asyncCheck ctx.channel.modifyChannel(ChannelFields(topic: some(modifyTopic))) ) let deleteChannelCommand = Command(name: "deleteChannel", commandBody: proc(ctx: CommandContext) = @@ -26,9 +26,9 @@ let deleteChannelCommand = Command(name: "deleteChannel", commandBody: proc(ctx: # Check if we could find the channel to delete if (channel != nil): - discard channel.sendMessage("Deleting Channel!") - discard channel.deleteChannel() - discard ctx.channel.sendMessage("Deleted Channel!") + asyncCheck channel.sendMessage("Deleting Channel!") + asyncCheck channel.deleteChannel() + asyncCheck ctx.channel.sendMessage("Deleted Channel!") ) let bulkDeleteMessagesCommand = Command(name: "bulkDeleteMessages", commandBody: proc(ctx: CommandContext) = @@ -38,16 +38,16 @@ let bulkDeleteMessagesCommand = Command(name: "bulkDeleteMessages", commandBody: # Get the message to delete, then delete them. let messages = ctx.channel.getMessages(MessagesGetRequest(limit: some(amount), before: some(ctx.message.id))) - discard ctx.channel.bulkDeleteMessages(messages) + asyncCheck ctx.channel.bulkDeleteMessages(messages) # Delete the message that was used to run this command. - discard ctx.message.deleteMessage() + asyncCheck ctx.message.deleteMessage() ) let reactToMessageCommand = Command(name: "reactToMessage", commandBody: proc(ctx: CommandContext) = let emojis = @[newEmoji("⏮️"), newEmoji("⬅️"), newEmoji("⏹️"), newEmoji("➡️"), newEmoji("⏭️")] for emoji in emojis: - discard ctx.message.addReaction(emoji) + asyncCheck ctx.message.addReaction(emoji) ) let testEmbedCommand = Command(name: "testEmbed", commandBody: proc(ctx: CommandContext) = @@ -58,7 +58,7 @@ let testEmbedCommand = Command(name: "testEmbed", commandBody: proc(ctx: Command embed.addField("Inline-0", "This is an inline field 0", true) embed.addField("Inline-1", "This is an inline field 1", true) embed.setColor(0xffb900) - discard ctx.channel.sendMessage("", false, embed) + asyncCheck ctx.channel.sendMessage("", false, embed) ) let sendFileCommand = Command(name: "sendFile", commandBody: proc(ctx: CommandContext) = @@ -68,7 +68,7 @@ let sendFileCommand = Command(name: "sendFile", commandBody: proc(ctx: CommandCo let fileName = splitFile.name & splitFile.ext let file = DiscordFile(filePath: filePath, fileName: fileName) - discard ctx.channel.sendMessage("", false, nil, @[file]) + asyncCheck ctx.channel.sendMessage("", false, nil, @[file]) ) let sendImageCommand = Command(name: "sendImage", commandBody: proc(ctx: CommandContext) = @@ -82,12 +82,17 @@ let sendImageCommand = Command(name: "sendImage", commandBody: proc(ctx: Command var embed = Embed() embed.setTitle("Image attachment test.") embed.setImage("attachment://" & fileName) - discard ctx.channel.sendMessage("", false, embed, @[file]) + asyncCheck ctx.channel.sendMessage("", false, embed, @[file]) ) # You can even register commands like this: registerCommand(Command(name: "ping2", commandBody: proc(ctx: CommandContext) = - discard ctx.channel.sendMessage("PONG 2") + asyncCheck ctx.channel.sendMessage("PONG 2") +)) + +registerCommand(Command(name: "reconnect", commandBody: proc(ctx: CommandContext) = + asyncCheck ctx.channel.sendMessage("Reconnecting...") + asyncCheck ctx.client.shards[0].reconnectShard() )) # Listen for the ready event. diff --git a/src/nimcord/client.nim b/src/nimcord/client.nim index 6bb5aeb..161209d 100644 --- a/src/nimcord/client.nim +++ b/src/nimcord/client.nim @@ -1,5 +1,6 @@ import websocket, asyncdispatch, json, httpClient, eventdispatcher, strformat import nimcordutils, cache, clientobjects, strutils, options, presence, log +import tables type DiscordOpCode = enum @@ -23,7 +24,7 @@ proc handleHeartbeat(shard: Shard) {.async.} proc handleWebsocketPacket(shard: Shard) {.async.} proc newDiscordClient*(tkn: string, commandPrefix: string, log: Log = newLog(ord(LoggerFlags.loggerFlagWarnSeverity) or ord(LoggerFlags.loggerFlagInfoSeverity) or ord(LoggerFlags.loggerFlagErrorSeverity))): DiscordClient proc newShard(shardID: int, client: DiscordClient): Shard -proc reconnectShard(shard: Shard) {.async.} +proc reconnectShard*(shard: Shard) {.async.} proc sendGatewayRequest*(shard: Shard, request: JsonNode, msg: string = "") {.async.} proc startConnection*(client: DiscordClient, shardAmount: int = 1) {.async.} proc updateClientPresence*(shard: Shard, presence: Presence) {.async.} @@ -34,9 +35,9 @@ proc sendGatewayRequest*(shard: Shard, request: JsonNode, msg: string = "") {.as if msg.len == 0: shard.client.log.debug("[SHARD " & $shard.id & "] Sending gateway payload: " & $request) else: - shard.client.log.debug(msg) + shard.client.log.debug("[SHARD " & $shard.id & "] " & msg) - await shard.ws.sendText("[SHARD " & $shard.id & "] " & $request) + await shard.ws.sendText($request) proc handleHeartbeat(shard: Shard) {.async.} = while true: @@ -72,12 +73,13 @@ proc closeConnection*(shard: Shard, code: int = 1000) {.async.} = shard.client.log.warn("[SHARD " & $shard.id & "] Disconnecting with code: " & $code) await shard.ws.close(code) -proc reconnectShard(shard: Shard) {.async.} = +proc reconnectShard*(shard: Shard) {.async.} = shard.client.log.info("[SHARD " & $shard.id & "] Reconnecting...") shard.reconnecting = true - await shard.ws.close(1000) - shard.ws = await newAsyncWebsocketClient(shard.client.endpoint[6..shard.client.endpoint.high], Port 443, + waitFor shard.ws.close(1000) + + shard.ws = waitFor newAsyncWebsocketClient(shard.client.endpoint[6..shard.client.endpoint.high], Port 443, path = "/v=6&encoding=json", true) shard.reconnecting = false