diff --git a/SCPDiscordBot/DiscordBot.js b/SCPDiscordBot/DiscordBot.js index 64ffb479..9a1a84d0 100644 --- a/SCPDiscordBot/DiscordBot.js +++ b/SCPDiscordBot/DiscordBot.js @@ -8,6 +8,8 @@ const Discord = require('discord.js'); const client = new Discord.Client(); +var messageQueue = []; + console.log('Binding TCP port...'); var net = require('net'); net.createServer(function (socket) diff --git a/SCPDiscordPlugin/AsyncTask.cs b/SCPDiscordPlugin/AsyncTask.cs index 628fc6e9..a96745a0 100644 --- a/SCPDiscordPlugin/AsyncTask.cs +++ b/SCPDiscordPlugin/AsyncTask.cs @@ -1,5 +1,7 @@ using Smod2; +using System; using System.Net.Sockets; +using System.Threading; namespace SCPDiscord { @@ -7,21 +9,122 @@ class AsyncMessage { public AsyncMessage(SCPDiscordPlugin plugin, string channelID, string message) { - if(message != null && message != "") + if(plugin.clientSocket == null || !plugin.clientSocket.Connected) + { + plugin.Warn("Error sending message '" + message + "' to discord: Not connected to bot yet."); + return; + } + if (message == null || message == "" || message == " " || message == ".") + { + plugin.Warn("Tried to send empty message to discord."); + return; + } + + //Change the default keyword to the bot's representation of it + if(channelID == "default") + { + channelID = "000000000000000000"; + } + + //Try to send the message to the bot + try { - if(channelID == "default") - { - channelID = "000000000000000000"; - } NetworkStream serverStream = plugin.clientSocket.GetStream(); byte[] outStream = System.Text.Encoding.ASCII.GetBytes(channelID + message + '\0'); serverStream.Write(outStream, 0, outStream.Length); plugin.Info("Sent message '" + message + "' to discord."); } - else + catch(InvalidOperationException e) { - plugin.Warn("Tried to send empty message to discord."); + plugin.Error("Error sending message '" + message + "' to discord: " + e.ToString()); + } + catch (ArgumentNullException e) + { + plugin.Error("Error sending message '" + message + "' to discord: " + e.ToString()); + } + } + } + class AsyncConnect + { + //This is ran once on the first time connecting to the bot + public AsyncConnect(SCPDiscordPlugin plugin) + { + Thread.Sleep(2000); + while (!plugin.clientSocket.Connected) + { + plugin.Info("Attempting Bot Connection..."); + try + { + plugin.Info("Your Bot IP: " + plugin.GetConfigString("discord_bot_ip") + ". Your Bot Port: " + plugin.GetConfigInt("discord_bot_port") + "."); + plugin.clientSocket.Connect(plugin.GetConfigString("discord_bot_ip"), plugin.GetConfigInt("discord_bot_port")); + } + catch (SocketException e) + { + plugin.Info("Error occured while connecting to discord bot server.\n" + e.ToString()); + Thread.Sleep(5000); + } + catch (ObjectDisposedException e) + { + plugin.Info("TCP client was unexpectedly closed.\n" + e.ToString()); + Thread.Sleep(5000); + } + catch (ArgumentOutOfRangeException e) + { + plugin.Info("Invalid port.\n" + e.ToString()); + Thread.Sleep(5000); + } + catch (ArgumentNullException e) + { + plugin.Info("IP address is null.\n" + e.ToString()); + Thread.Sleep(5000); + } + } + plugin.Info("Connected to Discord bot."); + plugin.SendMessageAsync("default", "Plugin Connected."); + plugin.hasConnectedOnce = true; + } + } + class AsyncConnectionWatchdog + { + //This is a loop that keeps running and checks if the bot has been disconnected + public AsyncConnectionWatchdog(SCPDiscordPlugin plugin) + { + while (true) + { + Thread.Sleep(200); + if(!plugin.clientSocket.Connected && plugin.hasConnectedOnce) + { + plugin.Info("Discord bot connection issue detected, attempting reconnect..."); + try + { + plugin.Info("Your Bot IP: " + plugin.GetConfigString("discord_bot_ip") + ". Your Bot Port: " + plugin.GetConfigInt("discord_bot_port") + "."); + plugin.clientSocket.Connect(plugin.GetConfigString("discord_bot_ip"), plugin.GetConfigInt("discord_bot_port")); + plugin.Info("Reconnected to Discord bot."); + plugin.SendMessageAsync("default", "Plugin Reconnected."); + } + catch (SocketException e) + { + plugin.Info("Error occured while reconnecting to discord bot server.\n" + e.ToString()); + Thread.Sleep(5000); + } + catch (ObjectDisposedException e) + { + plugin.Info("TCP client was unexpectedly closed.\n" + e.ToString()); + Thread.Sleep(5000); + } + catch (ArgumentOutOfRangeException e) + { + plugin.Info("Invalid port.\n" + e.ToString()); + Thread.Sleep(5000); + } + catch (ArgumentNullException e) + { + plugin.Info("IP address is null.\n" + e.ToString()); + Thread.Sleep(5000); + } + } + } } } diff --git a/SCPDiscordPlugin/SCPDiscord.cs b/SCPDiscordPlugin/SCPDiscord.cs index 0105a829..f55cf081 100644 --- a/SCPDiscordPlugin/SCPDiscord.cs +++ b/SCPDiscordPlugin/SCPDiscord.cs @@ -1,9 +1,6 @@ using Smod2; using Smod2.Attributes; -using Smod2.EventHandlers; -using Smod2.Events; -using System.Net; using System.Net.Sockets; using System; @@ -25,6 +22,7 @@ class SCPDiscordPlugin : Plugin { public TcpClient clientSocket = new TcpClient(); public readonly string GENERICMESSAGECHANNEL = "000000000000000000"; + public bool hasConnectedOnce = false; public override void Register() { @@ -35,6 +33,10 @@ public override void Register() this.AddEventHandlers(new EnvironmentEventHandler(this)); this.AddEventHandlers(new TeamEventHandler(this)); + //Connection settings + this.AddConfig(new Smod2.Config.ConfigSetting("discord_bot_ip", "127.0.0.1", Smod2.Config.SettingType.STRING, true, "IP of the discord bot.")); + this.AddConfig(new Smod2.Config.ConfigSetting("discord_bot_port", 8888, Smod2.Config.SettingType.NUMERIC, true, "Port of the discord bot.")); + //Round events this.AddConfig(new Smod2.Config.ConfigSetting("discord_channel_onroundstart", "off", Smod2.Config.SettingType.STRING, true, "Discord channel to post event messages in.")); this.AddConfig(new Smod2.Config.ConfigSetting("discord_channel_onconnect", "off", Smod2.Config.SettingType.STRING, true, "Discord channel to post event messages in.")); @@ -86,38 +88,14 @@ public override void Register() public override void OnEnable() { - //Connection settings - this.AddConfig(new Smod2.Config.ConfigSetting("discord_bot_ip", "127.0.0.1", Smod2.Config.SettingType.STRING, true, "IP of the discord bot.")); - this.AddConfig(new Smod2.Config.ConfigSetting("discord_bot_port", 8888, Smod2.Config.SettingType.NUMERIC, true, "Port of the discord bot.")); - - try - { - this.Info("Your Bot IP: " + this.GetConfigString("discord_bot_ip") + ". Your Bot Port: " + this.GetConfigInt("discord_bot_port") + "."); - clientSocket.Connect(this.GetConfigString("discord_bot_ip"), this.GetConfigInt("discord_bot_port")); - } - catch(SocketException e) - { - this.Info("Error occured while connecting to discord bot server.\n" + e.ToString()); - this.pluginManager.DisablePlugin(this); - } - catch (ObjectDisposedException e) - { - this.Info("TCP client was unexpectedly closed.\n" + e.ToString()); - this.pluginManager.DisablePlugin(this); - } - catch (ArgumentOutOfRangeException e) - { - this.Info("Invalid port.\n" + e.ToString()); - this.pluginManager.DisablePlugin(this); - } - catch (ArgumentNullException e) - { - this.Info("IP address is null.\n" + e.ToString()); - this.pluginManager.DisablePlugin(this); - } - this.Info("SCPDiscord enabled."); - SendMessageAsync("default", "Plugin Enabled."); + //Runs until the server has connected once + Thread connectionThread = new Thread(new ThreadStart(() => new AsyncConnect(this))); + connectionThread.Start(); + + //Keeps running to auto-reconnect if needed + Thread watchdogThread = new Thread(new ThreadStart(() => new AsyncConnectionWatchdog(this))); + watchdogThread.Start(); } public void SendMessageAsync(string channelID, string message)