Пример #1
0
 /// <summary>
 /// Gets a string from the primary or backup language file
 /// </summary>
 /// <param name="path">The path to the node</param>
 /// <returns></returns>
 public string GetString(string path)
 {
     if (primary == null && backup == null)
     {
         throw new ArgumentNullException();
     }
     try
     {
         return(plugin.language.primary.SelectToken(path).Value <string>());
     }
     // This exception means the node does not exist in the language file, the plugin attempts to find it in the backup file
     catch (Exception primaryException)
     {
         if (primaryException is NullReferenceException || primaryException is ArgumentNullException || primaryException is InvalidCastException || primaryException is JsonException)
         {
             plugin.Warn("Error reading dictionary '" + path + "' from primary language file, switching to backup...");
             try
             {
                 return(plugin.language.backup.SelectToken(path).Value <string>());
             }
             // The node also does not exist in the backup file
             catch (NullReferenceException e)
             {
                 plugin.Error("Error: Language config node '" + path + "' does not exist. Message can not be sent." + e);
                 throw;
             }
             catch (ArgumentNullException e)
             {
                 plugin.Error("Error: Language config node '" + path + "' does not exist. Message can not be sent." + e);
                 throw;
             }
             catch (InvalidCastException e)
             {
                 plugin.Error(e.ToString());
                 throw;
             }
             catch (JsonException e)
             {
                 plugin.Error(e.ToString());
                 throw;
             }
         }
         else
         {
             plugin.Error(primaryException.ToString());
             throw;
         }
     }
 }
Пример #2
0
        //This is a loop that keeps running and checks if the bot has been disconnected
        public StartConnectionWatchdog(SCPDiscordPlugin plugin)
        {
            while (true)
            {
                Thread.Sleep(2000);
                if (!plugin.clientSocket.Connected && plugin.hasConnectedOnce)
                {
                    plugin.clientSocket.Close();
                    plugin.Info("Not connected, trying to reconnect");
                    if (plugin.GetConfigBool("discord_verbose"))
                    {
                        plugin.Warn("Discord bot connection issue detected, attempting reconnect...");
                    }

                    try
                    {
                        plugin.clientSocket = new TcpClient(plugin.GetConfigString("discord_bot_ip"), plugin.GetConfigInt("discord_bot_port"));
                        plugin.Info("Reconnected to Discord bot.");
                        plugin.SendMessageToBot("default", "botmessages.reconnectedtobot");
                    }
                    catch (SocketException e)
                    {
                        if (plugin.GetConfigBool("discord_verbose"))
                        {
                            plugin.Info("Error occured while reconnecting to discord bot server.");
                            plugin.Debug(e.ToString());
                        }
                        Thread.Sleep(5000);
                    }
                    catch (ObjectDisposedException e)
                    {
                        if (plugin.GetConfigBool("discord_verbose"))
                        {
                            plugin.Info("TCP client was unexpectedly closed.");
                            plugin.Debug(e.ToString());
                        }
                        Thread.Sleep(5000);
                    }
                    catch (ArgumentOutOfRangeException e)
                    {
                        if (plugin.GetConfigBool("discord_verbose"))
                        {
                            plugin.Info("Invalid port.");
                            plugin.Debug(e.ToString());
                        }
                        Thread.Sleep(5000);
                    }
                    catch (ArgumentNullException e)
                    {
                        if (plugin.GetConfigBool("discord_verbose"))
                        {
                            plugin.Info("IP address is null.");
                            plugin.Debug(e.ToString());
                        }
                        Thread.Sleep(5000);
                    }
                }
            }
        }
Пример #3
0
        public AsyncMessage(SCPDiscordPlugin plugin, string channelID, string message)
        {
            if (message != null && message != "")
            {
                if (channelID == "default")
                {
                    channelID = "000000000000000000";
                }

                // Reconnect feature
                try
                {
                    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.");
                }
                catch (SocketException e)
                {
                    plugin.Info("Error occured while connecting to discord bot server.\n" + e.Message);
                    plugin.Info("Restarting plugin...");
                    plugin.clientSocket.Close();
                    plugin.OnEnable();
                }
                catch (ObjectDisposedException e)
                {
                    plugin.Info("TCP client was unexpectedly closed.\n" + e.Message);
                    plugin.Info("Restarting plugin...");
                    plugin.clientSocket.Close();
                    plugin.OnEnable();
                }
            }
            else
            {
                plugin.Warn("Tried to send empty message to discord.");
            }
        }
Пример #4
0
        public RefreshBotActivity(SCPDiscordPlugin plugin)
        {
            var message = (plugin.pluginManager.Server.NumPlayers - 1) + " / " + plugin.GetConfigString("max_players");

            if (plugin.clientSocket == null || !plugin.clientSocket.Connected)
            {
                if (plugin.hasConnectedOnce && plugin.GetConfigBool("discord_verbose"))
                {
                    plugin.Warn("Error sending message '" + message + "' to bot: Not connected.");
                }
                return;
            }

            // Try to send the message to the bot
            try
            {
                NetworkStream serverStream = plugin.clientSocket.GetStream();
                byte[]        outStream    = System.Text.Encoding.UTF8.GetBytes("botactivity" + message + '\0');
                serverStream.Write(outStream, 0, outStream.Length);

                if (plugin.GetConfigBool("discord_verbose"))
                {
                    plugin.Info("Sent activity '" + message + "' to bot.");
                }
            }
            catch (InvalidOperationException e)
            {
                plugin.Error("Error sending activity '" + message + "' to bot.");
                plugin.Debug(e.ToString());
            }
            catch (ArgumentNullException e)
            {
                plugin.Error("Error sending activity '" + message + "' to bot.");
                plugin.Debug(e.ToString());
            }
        }
Пример #5
0
 /// <summary>
 /// Saves all default language files included in the .dll
 /// </summary>
 public static void SaveDefaultLanguages()
 {
     foreach (KeyValuePair <string, string> language in defaultLanguages)
     {
         if (!File.Exists(languagesPath + language.Key + ".yml"))
         {
             plugin.Info("Creating language file " + language.Key + ".yml...");
             try
             {
                 File.WriteAllText((languagesPath + language.Key + ".yml"), language.Value);
             }
             catch (DirectoryNotFoundException)
             {
                 plugin.Warn("Could not create language file: Language directory does not exist, attempting to create it... ");
                 Directory.CreateDirectory(languagesPath);
                 plugin.Info("Creating language file " + language.Key + ".yml...");
                 File.WriteAllText((languagesPath + language.Key + ".yml"), language.Value);
             }
         }
     }
 }
Пример #6
0
        public RefreshChannelTopic(SCPDiscordPlugin plugin, string channelID)
        {
            Dictionary <string, string> variables = new Dictionary <string, string>();

            try
            {
                Server server = plugin.pluginManager.Server;
                Dictionary <string, string> serverVariables;
                if (server != null)
                {
                    serverVariables = new Dictionary <string, string>
                    {
                        { "players", (server.NumPlayers - 1) + "" },
                        { "maxplayers", plugin.GetConfigString("max_players") },
                        { "ip", server.IpAddress },
                        { "port", server.Port + "" },
                        { "isvisible", server.Visible + "" },
                        { "isverified", server.Verified + "" },
                        { "uptime", (plugin.serverStartTime.ElapsedMilliseconds / 1000 / 60) + "" }
                    };
                }
                else
                {
                    serverVariables = new Dictionary <string, string>
                    {
                        { "players", "0" },
                        { "maxplayers", "0" },
                        { "ip", "---.---.---.---" },
                        { "port", "----" },
                        { "isvisible", "False" },
                        { "isverified", "False" },
                        { "uptime", "0" }
                    };
                }

                Dictionary <string, string> mapVariables;
                if (server != null && server.Map != null)
                {
                    mapVariables = new Dictionary <string, string>
                    {
                        { "warheaddetonated", server.Map.WarheadDetonated + "" },
                        { "decontaminated", server.Map.LCZDecontaminated + "" }
                    };
                }
                else
                {
                    mapVariables = new Dictionary <string, string>
                    {
                        { "warheaddetonated", "False" },
                        { "decontaminated", "False" }
                    };
                }

                Dictionary <string, string> roundVariables;
                if (server != null && server.Round != null)
                {
                    roundVariables = new Dictionary <string, string>
                    {
                        { "roundduration", (server.Round.Duration / 60) + "" },
                        { "dclassalive", server.Round.Stats.ClassDAlive + "" },
                        { "dclassdead", server.Round.Stats.ClassDDead + "" },
                        { "dclassescaped", server.Round.Stats.ClassDEscaped + "" },
                        { "dclassstart", server.Round.Stats.ClassDStart + "" },
                        { "mtfalive", server.Round.Stats.NTFAlive + "" },
                        { "scientistsalive", server.Round.Stats.ScientistsAlive + "" },
                        { "scientistsdead", server.Round.Stats.ScientistsDead + "" },
                        { "scientistsescaped", server.Round.Stats.ScientistsEscaped + "" },
                        { "scientistsstart", server.Round.Stats.ScientistsStart + "" },
                        { "scpalive", server.Round.Stats.SCPAlive + "" },
                        { "scpdead", server.Round.Stats.SCPDead + "" },
                        { "scpkills", server.Round.Stats.SCPKills + "" },
                        { "scpstart", server.Round.Stats.SCPStart + "" },
                        //{ "warheaddetonated",   server.Round.Stats.WarheadDetonated + ""      },
                        { "zombies", server.Round.Stats.Zombies + "" }
                    };
                }
                else
                {
                    roundVariables = new Dictionary <string, string>
                    {
                        { "roundduration", "0" },
                        { "dclassalive", "0" },
                        { "dclassdead", "0" },
                        { "dclassescaped", "0" },
                        { "dclassstart", "0" },
                        { "mtfalive", "0" },
                        { "scientistsalive", "0" },
                        { "scientistsdead", "0" },
                        { "scientistsescaped", "0" },
                        { "scientistsstart", "0" },
                        { "scpalive", "0" },
                        { "scpdead", "0" },
                        { "scpkills", "0" },
                        { "scpstart", "0" },
                        //{ "warheaddetonated",   "0"     },
                        { "zombies", "0" }
                    };
                }

                foreach (var entry in serverVariables)
                {
                    variables.Add(entry.Key, entry.Value);
                }

                foreach (var entry in mapVariables)
                {
                    variables.Add(entry.Key, entry.Value);
                }

                foreach (var entry in roundVariables)
                {
                    variables.Add(entry.Key, entry.Value);
                }


                var topic = plugin.GetConfigString("discord_server_status");

                topic = topic.Replace("\n", "");

                // Variable insertion
                foreach (KeyValuePair <string, string> variable in variables)
                {
                    topic = topic.Replace("<var:" + variable.Key + ">", variable.Value);
                }

                // Regex replacements
                Dictionary <string, string> regex = plugin.GetConfigDict("discord_server_status_regex");

                // Run the regex replacements
                foreach (KeyValuePair <string, string> entry in regex)
                {
                    topic = topic.Replace(entry.Key, entry.Value);
                }

                // 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
                {
                    NetworkStream serverStream = plugin.clientSocket.GetStream();
                    byte[]        outStream    = System.Text.Encoding.UTF8.GetBytes("channeltopic" + channelID + topic + '\0');
                    serverStream.Write(outStream, 0, outStream.Length);

                    if (plugin.GetConfigBool("discord_verbose"))
                    {
                        plugin.Info("Sent channel topic '" + topic + "' to bot.");
                    }
                }
                catch (InvalidOperationException e)
                {
                    plugin.Error("Error sending channel topic '" + topic + "' to bot.");
                    plugin.Debug(e.ToString());
                }
                catch (ArgumentNullException e)
                {
                    plugin.Error("Error sending channel topic '" + topic + "' to bot.");
                    plugin.Debug(e.ToString());
                }
            }
            catch (Exception e)
            {
                if (plugin.GetConfigBool("discord_verbose"))
                {
                    plugin.Warn(e.ToString());
                }
            }
        }
Пример #7
0
        public SendMessageToBot(SCPDiscordPlugin plugin, string channelID, string messagePath, Dictionary <string, string> variables = null)
        {
            // Get unparsed message from config
            string message = "";

            try
            {
                message = plugin.language.GetString(messagePath + ".message");
            }
            catch (Exception e)
            {
                if (!(e is NullReferenceException))
                {
                    plugin.Error("Error reading base message" + e);
                }
                return;
            }

            // Abort on empty message
            if (message == null || message == "" || message == " " || message == ".")
            {
                plugin.Error("Tried to send empty message " + messagePath + " to discord. Verify your language file.");
                return;
            }

            // Abort if client is dead
            if (plugin.clientSocket == null || !plugin.clientSocket.Connected)
            {
                if (plugin.hasConnectedOnce && plugin.GetConfigBool("discord_verbose"))
                {
                    plugin.Warn("Error sending message '" + message + "' to bot: Not connected.");
                }
                return;
            }

            // Add time stamp
            if (plugin.GetConfigString("discord_formatting_date") != "off")
            {
                message = "[" + DateTime.Now.ToString(plugin.GetConfigString("discord_formatting_date")) + "]: " + message;
            }

            // Change the default keyword to the bot's representation of it
            if (channelID == "default")
            {
                channelID = "000000000000000000";
            }

            // Re-add newlines
            message = message.Replace("\\n", "\n");

            // Add variables //////////////////////////////
            if (variables != null)
            {
                // Variable insertion
                foreach (KeyValuePair <string, string> variable in variables)
                {
                    // Wait until after the regex replacements to add the player names
                    if (variable.Key == "servername" || variable.Key == "name" || variable.Key == "attackername" || variable.Key == "playername" || variable.Key == "adminname" || variable.Key == "feedback")
                    {
                        continue;
                    }
                    message = message.Replace("<var:" + variable.Key + ">", variable.Value);
                }
            }
            ///////////////////////////////////////////////

            // Global regex replacements //////////////////
            Dictionary <string, string> globalRegex = new Dictionary <string, string>();

            try
            {
                globalRegex = plugin.language.GetRegexDictionary("global_regex");
            }
            catch (Exception e)
            {
                plugin.Error("Error reading global regex" + e);
                return;
            }
            // Run the global regex replacements
            foreach (KeyValuePair <string, string> entry in globalRegex)
            {
                message = message.Replace(entry.Key, entry.Value);
            }
            ///////////////////////////////////////////////

            // Local regex replacements ///////////////////
            Dictionary <string, string> localRegex = new Dictionary <string, string>();

            try
            {
                localRegex = plugin.language.GetRegexDictionary(messagePath + ".regex");
            }
            catch (Exception e)
            {
                plugin.Error("Error reading local regex" + e);
                return;
            }
            // Run the local regex replacements
            foreach (KeyValuePair <string, string> entry in localRegex)
            {
                message = message.Replace(entry.Key, entry.Value);
            }
            ///////////////////////////////////////////////

            if (variables != null)
            {
                // Add names/command feedback to the message //
                foreach (KeyValuePair <string, string> variable in variables)
                {
                    if (variable.Key == "servername" || variable.Key == "name" || variable.Key == "attackername" || variable.Key == "playername" || variable.Key == "adminname" || variable.Key == "feedback")
                    {
                        message = message.Replace("<var:" + variable.Key + ">", EscapeDiscordFormatting(variable.Value));
                    }
                }
                ///////////////////////////////////////////////

                // Final regex replacements ///////////////////
                Dictionary <string, string> finalRegex = new Dictionary <string, string>();
                try
                {
                    finalRegex = plugin.language.GetRegexDictionary("final_regex");
                }
                catch (Exception e)
                {
                    plugin.Error("Error reading final regex" + e);
                    return;
                }
                // Run the final regex replacements
                foreach (KeyValuePair <string, string> entry in finalRegex)
                {
                    message = message.Replace(entry.Key, entry.Value);
                }
                ///////////////////////////////////////////////
            }

            // Try to send the message to the bot
            try
            {
                NetworkStream serverStream = plugin.clientSocket.GetStream();
                byte[]        outStream    = System.Text.Encoding.UTF8.GetBytes(channelID + message + '\0');
                serverStream.Write(outStream, 0, outStream.Length);

                if (plugin.GetConfigBool("discord_verbose"))
                {
                    plugin.Info("Sent message '" + message + "' to bot.");
                }
            }
            catch (InvalidOperationException e)
            {
                plugin.Error("Error sending message '" + message + "' to bot.");
                plugin.Debug(e.ToString());
            }
            catch (ArgumentNullException e)
            {
                plugin.Error("Error sending message '" + message + "' to bot.");
                plugin.Debug(e.ToString());
            }
        }
Пример #8
0
        public BotListener(SCPDiscordPlugin plugin)
        {
            this.plugin = plugin;
            while (true)
            {
                //Listen for connections
                if (plugin.clientSocket.Connected && plugin.hasConnectedOnce)
                {
                    Thread.Sleep(200);
                    try
                    {
                        //Discord messages can be up to 2000 chars long, UTF8 chars can be up to 4 bytes long.
                        byte[] data = new byte[8000];

                        NetworkStream stream = null;
                        try
                        {
                            stream = plugin.clientSocket.GetStream();
                        }
                        catch (Exception ex)
                        {
                            if (ex is IOException)
                            {
                                plugin.Error("Could not get stream from socket.");
                            }
                            else
                            {
                                plugin.Error("BotListener Error: " + ex.ToString());
                            }
                        }

                        if (stream == null)
                        {
                            return;
                        }

                        string incomingData = "";
                        try
                        {
                            int lengthOfData = stream.Read(data, 0, data.Length);
                            incomingData = Encoding.UTF8.GetString(data, 0, lengthOfData);
                        }
                        catch (Exception ex)
                        {
                            if (ex is IOException)
                            {
                                plugin.Error("Could not read from socket.");
                            }
                            else
                            {
                                plugin.Error("BotListener Error: " + ex.ToString());
                            }
                        }
                        List <string> messages = new List <string>(incomingData.Split('\n'));

                        //If several messages come in at the same time, process all of them
                        while (messages.Count > 0)
                        {
                            if (messages[0].Length == 0)
                            {
                                messages.RemoveAt(0);
                                continue;
                            }
                            string[] words = messages[0].Split(' ');

                            bool     isCommand = words[0] == "command";
                            string   command   = words[1];
                            string[] arguments = new string[0];
                            if (words.Length >= 3)
                            {
                                arguments = words.Skip(2).ToArray();
                            }

                            //A verification that message is a command and not some left over string in the socket
                            if (isCommand)
                            {
                                if (command == "ban")
                                {
                                    //Check if the command has enough arguments
                                    if (arguments.Length >= 2)
                                    {
                                        BanCommand(arguments[0], arguments[1], MergeReason(arguments.Skip(2).ToArray()));
                                    }
                                    else
                                    {
                                        Dictionary <string, string> variables = new Dictionary <string, string>
                                        {
                                            { "command", messages[0] }
                                        };
                                        plugin.SendMessageToBot(Config.channels.statusmessages, "botresponses.missingarguments", variables);
                                    }
                                }
                                else if (command == "kick")
                                {
                                    //Check if the command has enough arguments
                                    if (arguments.Length >= 1)
                                    {
                                        KickCommand(arguments[0], MergeReason(arguments.Skip(1).ToArray()));
                                    }
                                    else
                                    {
                                        Dictionary <string, string> variables = new Dictionary <string, string>
                                        {
                                            { "command", messages[0] }
                                        };
                                        plugin.SendMessageToBot(Config.channels.statusmessages, "botresponses.missingarguments", variables);
                                    }
                                }
                                else if (command == "kickall")
                                {
                                    KickallCommand(MergeReason(arguments));
                                }
                                else if (command == "unban")
                                {
                                    //Check if the command has enough arguments
                                    if (arguments.Length >= 1)
                                    {
                                        UnbanCommand(arguments[0]);
                                    }
                                    else
                                    {
                                        Dictionary <string, string> variables = new Dictionary <string, string>
                                        {
                                            { "command", messages[0] }
                                        };
                                        plugin.SendMessageToBot(Config.channels.statusmessages, "botresponses.missingarguments", variables);
                                    }
                                }
                                else if (command == "list")
                                {
                                    var message = "```md\n# Players online:\n";
                                    foreach (Player player in plugin.Server.GetPlayers())
                                    {
                                        string line = player.Name.PadRight(32);
                                        line += player.SteamId;
                                        line += "\n";
                                    }
                                    message += "```";

                                    if (plugin.clientSocket == null || !plugin.clientSocket.Connected)
                                    {
                                        if (plugin.hasConnectedOnce && Config.settings.verbose)
                                        {
                                            plugin.Warn("Error sending message '" + message + "' to bot: Not connected.");
                                        }
                                        return;
                                    }

                                    // Try to send the message to the bot
                                    try
                                    {
                                        NetworkStream serverStream = plugin.clientSocket.GetStream();
                                        byte[]        outStream    = System.Text.Encoding.UTF8.GetBytes("000000000000000000" + message + '\0');
                                        serverStream.Write(outStream, 0, outStream.Length);

                                        if (Config.settings.verbose)
                                        {
                                            plugin.Info("Sent activity '" + message + "' to bot.");
                                        }
                                    }
                                    catch (InvalidOperationException e)
                                    {
                                        plugin.Error("Error sending activity '" + message + "' to bot.");
                                        plugin.Debug(e.ToString());
                                    }
                                    catch (ArgumentNullException e)
                                    {
                                        plugin.Error("Error sending activity '" + message + "' to bot.");
                                        plugin.Debug(e.ToString());
                                    }
                                }
                                else if (command == "exit")
                                {
                                    plugin.SendMessageToBot(Config.channels.statusmessages, "botresponses.exit");
                                }
                                else if (command == "help")
                                {
                                    plugin.SendMessageToBot(Config.channels.statusmessages, "botresponses.help");
                                }
                                else if (command == "hidetag" || command == "showtag")
                                {
                                    if (plugin.pluginManager.GetEnabledPlugin("karlofduty.toggletag") != null)
                                    {
                                        if (arguments.Length > 0)
                                        {
                                            command = "console_" + command;
                                            string response = ConsoleCommand(plugin.pluginManager.Server, command, arguments);

                                            Dictionary <string, string> variables = new Dictionary <string, string>
                                            {
                                                { "feedback", response }
                                            };
                                            plugin.SendMessageToBot(Config.channels.statusmessages, "botresponses.consolecommandfeedback", variables);
                                        }
                                        else
                                        {
                                            Dictionary <string, string> variables = new Dictionary <string, string>
                                            {
                                                { "command", command }
                                            };
                                            plugin.SendMessageToBot(Config.channels.statusmessages, "botresponses.missingarguments", variables);
                                        }
                                    }
                                    else
                                    {
                                        plugin.SendMessageToBot(Config.channels.statusmessages, "botresponses.toggletag.notinstalled");
                                    }
                                }
                                else if (command == "vs_enable" || command == "vs_disable" || command == "vs_whitelist" || command == "vs_reload")
                                {
                                    if (plugin.pluginManager.GetEnabledPlugin("karlofduty.vpnshield") != null)
                                    {
                                        string response = ConsoleCommand(plugin.pluginManager.Server, command, arguments);

                                        Dictionary <string, string> variables = new Dictionary <string, string>
                                        {
                                            { "feedback", response }
                                        };
                                        plugin.SendMessageToBot(Config.channels.statusmessages, "botresponses.consolecommandfeedback", variables);
                                    }
                                    else
                                    {
                                        plugin.SendMessageToBot(Config.channels.statusmessages, "botresponses.vpnshield.notinstalled");
                                    }
                                }
                                else
                                {
                                    string response = ConsoleCommand(plugin.pluginManager.Server, command, arguments);

                                    Dictionary <string, string> variables = new Dictionary <string, string>
                                    {
                                        { "feedback", response }
                                    };
                                    plugin.SendMessageToBot(Config.channels.statusmessages, "botresponses.consolecommandfeedback", variables);
                                }
                            }
                            plugin.Info("From discord: " + messages[0]);
                            messages.RemoveAt(0);
                        }
                    }
                    catch (Exception ex)
                    {
                        if (ex is IOException)
                        {
                            plugin.Error("BotListener Error: " + ex.ToString());
                        }
                        plugin.Error("BotListener Error: " + ex.ToString());
                    }
                }
                else
                {
                    Thread.Sleep(2000);
                }
            }
        }