Example #1
0
        /// <summary>
        /// Outputs help to an IRC user (should be used threaded).
        /// </summary>
        /// <param name="o">Set by Thread instance, the nickname</param>
        public void SendHelp(object o)
        {
            string[] param = (string[])o;
            string nick = param[0];
            string hostmask = param[1];
            string prefix = param[2];
            Botop check = new Botop();

            Notice(nick, "Bot commands:");
            Notice(nick, "Everything in <> is necessary and everything in [] are optional.");

            DelayNotice(nick, prefix + "help -- This command.");
            if (IsOwner(hostmask)) DelayNotice(nick, prefix + "mode <mode> -- Sets a mode the current channel.");
            if (IsOwner(hostmask)) DelayNotice(nick, prefix + "topic [topic] -- Tells the current topic OR sets the channel's topic to [topic]");
            if (IsOwner(hostmask)) DelayNotice(nick, prefix + "config <list|edit> [<variable> <value>] -- Tells current config.");
            if (IsOwner(hostmask)) DelayNotice(nick, prefix + "join <chan> -- Joins the bot to a channel");
            if (IsOwner(hostmask)) DelayNotice(nick, prefix + "part <chan> [reason] -- Parts the bot from a channel");
            if (IsOwner(hostmask) || (check.isBotOp(nick) && (check.GetLevel(nick) >= 3))) DelayNotice(nick, prefix + "kick <nick> [reason] -- Kicks <nick> from the current channel for [reason], or, if [reason] is not specified, kicks user with one of the kick lines in the kicks database.");
            if (IsOwner(hostmask)) DelayNotice(nick, prefix + "kicklines <add|clear|read|total> <kickmessage|(do nothing)|number|(do nothing)> -- Does various actions to the kicklines database.");
            if (IsOwner(hostmask)) DelayNotice(nick, prefix + "reset -- Clears the config and restarts the bot");
            if (IsOwner(hostmask)) DelayNotice(nick, prefix + "restart -- Restarts the bot");
            if (IsOwner(hostmask)) DelayNotice(nick, prefix + "clean -- Clears the config and kills the bot");
            if (IsOwner(hostmask)) DelayNotice(nick, prefix + "die [quitmessage] -- Kills the bot, with optional [quitmessage]");
            DelayNotice(nick, prefix + "time [<+|-> <number>] -- Tells the time in GMT/UTC, with the offset you specify.");
            DelayNotice(nick, prefix + "uptime -- Tells the time, which the bot is running now without crash or shutdown.");
            if (IsOwner(hostmask)) DelayNotice(nick, prefix + "addbotop <nick> [level] -- Add a BotOp user, where nick is the nickname of the user you want to add and level is the access level of the user you want to add");
            if (IsOwner(hostmask)) DelayNotice(nick, prefix + "delbotop <nick> -- Delete a BotOp user, where nick is the nickname of the user you want to Delete");
            if (IsOwner(hostmask)) DelayNotice(nick, prefix + "amibotop -- Tells you if you are a BotOp");
            if (IsOwner(hostmask)) DelayNotice(nick, prefix + "setbotop <nick> <level> -- Sets the level of a BotOP");
        }
Example #2
0
        public void Run()
        {
            string inputline;

            start: // This is the point at which the bot restarts on errors
            if (!File.Exists(XmlFileName))
                Thread.CurrentThread.IsBackground = false;

            if (ProgramRestart == true)
            {
                Console.WriteLine("");
                HostmaskRegex = null;
                ProgramRestart = false;
            }

            if (Thread.CurrentThread.IsBackground == false)
            {
                config = new XmlConfiguration();
                check = new Botop();

                // Configuration
                if (!File.Exists(XmlFileName))
                {
                    DoFirstUseSetup();
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.Blue;
                    Console.WriteLine("Loading configuration...");
                    try
                    {
                        config.Load(XmlFileName);
                    }
                    catch (Exception e)
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine("Configuration has NOT been loaded. Please check if the configuration is valid and try again.");
                        if (DebuggingEnabled == true)
                        {
                            Console.ForegroundColor = ConsoleColor.DarkRed;
                            Console.WriteLine(e.ToString());
                            Console.WriteLine(e.StackTrace);
                            Console.ForegroundColor = ConsoleColor.DarkCyan;
                            Console.WriteLine(e.Message);
                        }
                        Console.WriteLine("Enter something to exit.");
                        Console.ReadKey();
                        return;
                    }
                }

                // Make this thread do not block the main thread
                botThread = new Thread(new ThreadStart(Run));
                botThread.IsBackground = true;
                botThread.Start();
                return;
            }

            // Liveserver
            /*
            if (!IsLiveserverAcknowledged())
            {
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("WARNING: CSharpBot has now the ability to be accessed over the implemented \"LiveServer\".");
                Console.WriteLine("You'll need to reset the configuration to use the server.");
                Console.WriteLine();
            }
            if (!IsLiveserverConfigured())
            {
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine("Liveserver disabled.");
                Console.ResetColor();
                Console.WriteLine();
            }
            else
            {
                StartLiveserver();
                Console.WriteLine("Liveserver started.");
            }
             */

            // Configuration check to be implemented - Icedream
            server = new CMDServer();
            server.SetupCertificate(".\\ca.cer");
            server.Port = 3000;
            server.Address = IPAddress.Any;
            server.Start();

            this.NumericReplyReceived += new NumericReplyReceivedHandler(CSharpBot_NumericReplyReceived);
            this.Kicked += new KickedHandler(CSharpBot_Kicked);

            // IRC
            try
            {
                Console.WriteLine();
                Connect();

                string whoistarget;
                int replycode;
                while ((inputline = reader.ReadLine()) != null)
                {
                    string[] cmd = inputline.Split(' ');

                    if (DebuggingEnabled)
                    {
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        if (!cmd[0].Equals("PING"))
                            Functions.Log("RECV: " + inputline);
                        Console.ResetColor();
                    }

                    // Automatic PING reply
                    if (cmd[0].Equals("PING"))
                    {
                        if (DebuggingEnabled == true)
                        {
                            Console.ForegroundColor = ConsoleColor.Yellow;
                            Functions.Log("Ping? Pong!");
                            Console.ResetColor();
                        }
                        Functions.WriteData("PONG " + cmd[1]);
                    }

                    // Numeric replies
                    else if (int.TryParse(cmd[1], out replycode))
                    {
                        IrcNumericReplyLine reply = new IrcNumericReplyLine(inputline);
                        this.OnNumericReplyReceived(reply);
                    }

                    // Capabilities
                    else if (cmd[1].Equals("CAP"))
                    {
                        if (cmd[3].Equals("LS"))
                        {
                            Functions.Log("Received capabitilites list.");
                            string[] capabilities = string.Join(" ", cmd.Skip(4).ToArray()).Substring(1).ToLower().Split(' ');

                            if (capabilities.Contains("tls") && config.StartTLS)
                            {
                                Functions.Log("Trying STARTTLS...");
                                Functions.WriteData("STARTTLS");
                                while (true)
                                {
                                    inputline = reader.ReadLine();
                                    try
                                    {
                                        IrcNumericReplyLine reply = new IrcNumericReplyLine(inputline);
                                        if (reply.ReplyCode == IrcReplyCode.RPL_STARTTLSSUCCESSFUL)
                                        {
                                            Functions.Log("StartTLS successful. Switching to SSL...");
                                            ssl = new SslStream(stream, false, new RemoteCertificateValidationCallback(CheckCertificate), null);
                                            Functions.Log("Negotiating...");
                                            ssl.AuthenticateAsClient(config.Server);
                                            Functions.WriteData("CAP END");
                                            reader = new StreamReader(ssl);
                                            writer = new StreamWriter(ssl);
                                        }
                                        else if (reply.ReplyCode == IrcReplyCode.ERR_STARTTLSFAILED)
                                        {
                                            Functions.Log("StartTLS initialization failed server-side. Disconnecting...");
                                            Shutdown("StartTLS failed", false);
                                        }
                                    }
                                    catch (Exception)
                                    {
                                        continue;
                                    }
                                }
                            }

                            if (capabilities.Contains("identify-msg"))
                            {
                                Console.WriteLine("Server supports IDENTIFY message, but it is currently not implemented in the bot.");
                            }

                            Functions.WriteData("CAP END");
                        }
                    }

                    // Kick
                    else if (cmd[1].Equals("KICK"))
                    {
                        if (cmd[3] == NICK)
                            OnKicked(cmd[0], cmd[2]);
                        else
                            OnUserKicked(cmd[0], cmd[2], cmd[3]);
                    }

                    // Handling incoming messages
                    IrcMessageLine msg = null;
                    try
                    {
                        msg = new IrcMessageLine(inputline, config);
                    }
                    catch (Exception)
                    {
                        // Do nothing. DON'T DELETE THIS LINE! It prevents errors during compilation.
                    }

                    if (msg != null)
                    {
                        #region PRIVMSG
                        if (msg.MessageType == IrcMessageType.PrivateMessage)
                        {
                            if (msg.Target.StartsWith("#") && msg.IsBotCommand)
                            // Source is really a channel
                            {

                                // Execute commands
                                Functions.Log(msg.SourceNickname + " issued " + prefix + msg.BotCommandName + " with " + msg.BotCommandParams.Count() + " parameters.");
                                switch (msg.BotCommandName.ToLower())
                                {
                                    case "test":
                                        Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": I think your test works ;-)");
                                        break;
                                    case "amiowner":
                                        Functions.PrivateMessage(msg.Target, "The answer is: " + (Functions.IsOwner(msg.SourceHostmask) ? "Yes!" : "No!"));
                                        break;
                                    case "addbotop":
                                        if (Functions.IsOwner(msg.SourceHostmask))
                                        {
                                            Botop add = new Botop();

                                            if (cmd.Length > 5)
                                            {
                                                try
                                                {
                                                    add.AddBotOp(cmd[4], Convert.ToInt32(cmd[5]));
                                                    Functions.PrivateMessage(msg.Target, "Done!");
                                                }
                                                catch (Exception)
                                                {
                                                    Functions.PrivateMessage(msg.Target, "I'm Sorry, " + msg.SourceNickname + ", but I'm afraid I can't do that.");
                                                    if (add.isBotOp(cmd[4]))
                                                    {
                                                        Functions.PrivateMessage(msg.Target, "The user is already in the DB.");
                                                    }
                                                    try
                                                    {
                                                        Convert.ToInt32(cmd[5]);
                                                    }
                                                    catch (Exception)
                                                    {
                                                        Functions.PrivateMessage(msg.Target, "The Access Level Number Is Invalid.");
                                                    }

                                                }
                                            }
                                            else if (cmd.Length > 4)
                                            {
                                                add.AddBotOp(cmd[4]);
                                                Functions.PrivateMessage(msg.Target, "Done!");
                                            }
                                        }
                                        else
                                        {
                                            Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": You aren't my owner!");
                                        }
                                        break;

                                    case "setbotop":
                                        if (Functions.IsOwner(msg.SourceHostmask))
                                        {
                                            Botop add = new Botop();

                                            if (cmd.Length > 5)
                                            {
                                                try
                                                {
                                                    if (!add.SetLevel(cmd[4], Convert.ToInt32(cmd[5])))
                                                    {
                                                        throw new IrcException("NO SUCH NICK");
                                                    }
                                                    Functions.PrivateMessage(msg.Target, "Done!");
                                                }
                                                catch (Exception e)
                                                {
                                                    Functions.PrivateMessage(msg.Target, "I'm Sorry, " + msg.SourceNickname + ", but I'm afraid I can't do that.");
                                                    if (e.Message == "NO SUCH NICK")
                                                    {
                                                        Functions.PrivateMessage(msg.Target, "The user is not in the DB.");
                                                    }

                                                    try
                                                    {
                                                        Convert.ToInt32(cmd[5]);
                                                    }
                                                    catch (Exception)
                                                    {
                                                        Functions.PrivateMessage(msg.Target, "The Access Level Number Is Invalid.");
                                                    }

                                                }
                                            }

                                        }
                                        else
                                        {
                                            Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": You aren't my owner!");
                                        }
                                        break;

                                    case "delbotop":
                                        if (Functions.IsOwner(msg.SourceHostmask))
                                        {

                                            Botop del = new Botop();
                                            if (cmd.Length > 4)
                                            {
                                                Functions.Log(msg.SourceNickname + " issued " + prefix + "delbotop");
                                                del.DelBotOp(cmd[4]);
                                                Functions.PrivateMessage(msg.Target, "Done!");
                                            }

                                        }
                                        else
                                        {
                                            Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": You aren't my owner!");
                                        }
                                        break;
                                    case "amibotop":
                                        Botop test = new Botop();
                                        Functions.Log(msg.SourceNickname + " issued " + prefix + "amibotop");
                                        Functions.PrivateMessage(msg.Target, "The answer is: " + (test.isBotOp(msg.SourceNickname) ? "Yes!" : "No!"));
                                        if (test.isBotOp(msg.SourceNickname))
                                        {

                                            Functions.PrivateMessage(msg.Target, "You are a level " + test.GetLevel(msg.SourceNickname).ToString() + " BotOP");
                                        }

                                        break;
                                    case "uptime":
                                        TimeSpan ts = DateTime.Now - startupTime;
                                        Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": The bot is now running " + ts.ToString());
                                        break;
                                    case "time":
                                        // UTC hours addition (#time +1 makes UTC+1 for example)
                                        double hoursToAdd = 0;
                                        string adds = "";
                                        if (cmd.Length > 4)
                                            double.TryParse(cmd[4], out hoursToAdd);
                                        if (hoursToAdd != 0)
                                            adds = hoursToAdd.ToString();
                                        if (hoursToAdd > 0)
                                            adds = "+" + adds;

                                        Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": It's " + DateTime.UtcNow.AddHours(hoursToAdd).ToString() + "(UTC" + adds + ")");
                                        break;
                                    case "mynick":
                                        Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": Your nick is \x02" + msg.SourceNickname + "\x02");
                                        break;
                                    case "myhost":
                                        Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": Your host is \x02" + msg.SourceHost + "\x02");
                                        break;
                                    case "myident":
                                        Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": Your ident/username is \x02" + msg.SourceUsername + "\x02");
                                        break;
                                    case "myfullmask":
                                        Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": Your full hostmask is \x02" + msg.SourceHostmask + "\x02");
                                        break;
                                    case "die":
                                        if (Functions.IsOwner(msg.SourceHostmask))
                                        {
                                            if (msg.BotCommandParams.Length == 0)
                                            {
                                                this.Shutdown();
                                            }
                                            else
                                            {
                                                this.Shutdown(string.Join(" ", msg.BotCommandParams));
                                            }

                                        }

                                        else
                                        {
                                            Functions.Log(msg.SourceNickname + " attempted to use " + prefix + "die");
                                            Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": You are not my owner!");
                                        }
                                        break;
                                    case "clean":
                                        if (Functions.IsOwner(msg.SourceHostmask))
                                        {
                                            FileInfo fi = new FileInfo("CSharpBot.xml");
                                            fi.Delete();
                                            Functions.Log(msg.SourceNickname + " issued " + prefix + "clean");
                                            Functions.Quit("Cleaned!");
                                        }
                                        else
                                        {
                                            Functions.Log(msg.SourceNickname + " attempted to use " + prefix + "clean");
                                            Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": You are not my owner!");
                                        }
                                        break;
                                    case "raw":
                                        if ((Functions.IsOwner(msg.SourceHostmask) | check.isBotOp(msg.SourceNickname)) && (check.GetLevel(msg.SourceNickname) >= 4))
                                        {
                                            if (msg.BotCommandParams.Length > 0)
                                                Functions.Raw(string.Join(" ", msg.BotCommandParams));
                                        }
                                        else
                                        {
                                            Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": You are not my owner!");
                                        }
                                        break;
                                    case "config":
                                        if (!Functions.IsOwner(msg.SourceHostmask))
                                        {
                                            Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": You are not my owner!");
                                        }
                                        else if (cmd[4] == "list")
                                        {
                                            Regex search = new Regex("^(.*)$");
                                            if (cmd.Length > 5)
                                                search = new Regex(!cmd[5].StartsWith("regex:") ? "(" + cmd[5].Replace(".", "\\.") + ")" : cmd[5].Substring(6));
                                            foreach (XmlNode node in config.ConfigFile.ChildNodes)
                                            {
                                                // Main settings
                                                if (node.InnerText.Trim() != ""
                                                    && (config.NickServPassword != "" ? !node.InnerText.Contains(config.NickServPassword) : true)
                                                    && (config.ServerPassword != "" ? !node.InnerText.Contains(config.ServerPassword) : true)
                                                    && search.Match(node.Name).Success
                                                    )
                                                    Functions.Notice(msg.SourceNickname, node.Name + " = " + node.InnerText);
                                                if (node.HasChildNodes)
                                                {

                                                    // Sub settings, if any (might be useful for plugins)
                                                    foreach (XmlNode sub in node.ChildNodes)
                                                    {
                                                        if (sub.Name != "#text" && sub.InnerText.Trim() != ""
                                                        && (config.NickServPassword != "" ? !sub.InnerText.Contains(config.NickServPassword) : true)
                                                        && (config.ServerPassword != "" ? !sub.InnerText.Contains(config.ServerPassword) : true)
                                                        && search.Match(node.Name).Success
                                                        )
                                                            Functions.Notice(msg.SourceNickname, node.Name + "." + sub.Name + " = " + sub.InnerText);
                                                    }
                                                }
                                            }
                                        }
                                        else if (msg.BotCommandParams[0] == "set")
                                        {
                                            string[] nodes = msg.BotCommandParams[1].Split('.');
                                            XmlNodeList xmlnodes = config.ConfigFile.SelectNodes("child::" + nodes[0]);
                                            if (xmlnodes.Count == 0)
                                            {
                                                Functions.Notice(msg.SourceNickname, "Sorry, but configuration node \x02" + nodes[0] + "\x02 could not be found.");
                                            }
                                            else
                                            {
                                                if (nodes.Length > 1)
                                                {
                                                    xmlnodes = xmlnodes[0].SelectNodes("child::" + nodes[1]);
                                                    if (xmlnodes.Count == 0)
                                                    {
                                                        Functions.Notice(msg.SourceNickname, "Sorry, but configuration node \x02" + nodes[1] + "\x02 (in " + nodes[0] + ") could not be found.");
                                                    }
                                                    else
                                                    {
                                                        xmlnodes[0].InnerText = msg.BotCommandParams[2];
                                                        Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": Configuration edited. You may need to restart the bot to apply.");
                                                    }
                                                }
                                                else
                                                {
                                                    xmlnodes[0].InnerText = msg.BotCommandParams[2];
                                                    Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": Configuration edited. Restart to apply.");
                                                }
                                            }
                                        }
                                        break;
                                    case "topic":
                                        if (msg.BotCommandParams.Length > 0)
                                        {
                                            msg.BotCommandParams[0] = msg.BotCommandParams[0] == "reset" ? "" : msg.BotCommandParams[0]; // !topic reset = set topic to ""

                                            // Set topic if is owner
                                            if (Functions.IsOwner(msg.SourceHostmask))
                                            {
                                                Functions.Topic(msg.Target, string.Join(" ", cmd.Skip(4).ToArray()));
                                                Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": Topic has been set.");
                                            }
                                            else
                                            {
                                                Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": You are not my owner!");
                                            }
                                        }
                                        else
                                        {
                                            Functions.WriteData("TOPIC " + msg.Target);

                                            bool foundTopic = false;
                                            string topic = "";
                                            while (!foundTopic)
                                            {
                                                topic = reader.ReadLine();
                                                if (DebuggingEnabled == true)
                                                {
                                                    Console.ForegroundColor = ConsoleColor.Yellow;
                                                    Functions.Log(topic);
                                                    Console.ResetColor();
                                                }
                                                if (topic.Contains("331"))
                                                {
                                                    topic = "No topic is set for this channel.";
                                                    foundTopic = true;
                                                }
                                                else if (topic.Contains("332"))
                                                {
                                                    topic = "The topic is: " + string.Join(":", topic.Split(':').Skip(2).ToArray());
                                                    foundTopic = true;
                                                }
                                            }
                                            Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": " + topic);
                                        }
                                        break;
                                    case "kicklines":
                                        if (Functions.IsOwner(msg.SourceHostmask))
                                        {
                                            if (msg.BotCommandParams.Length > 0)
                                            {
                                                if (msg.BotCommandParams[0].Equals("add") && msg.BotCommandParams.Length > 1)
                                                {
                                                    string theline = string.Join(" ", cmd.Skip(5).ToArray());
                                                    if (File.Exists("Kicks.txt"))
                                                    {
                                                        List<string> kicklist = new List<string>();
                                                        kicklist.Add(theline);
                                                        kicklist.AddRange(File.ReadAllLines("Kicks.txt"));
                                                        //string[] text = { string.Join(" ", cmd.Skip(5).ToArray() + "\r\n") + " " + string.Join(" ", pretext.Skip(0).ToArray()) + "\r\n" };
                                                        File.WriteAllLines("Kicks.txt", kicklist.ToArray());
                                                        kicklist = null;
                                                    }
                                                    else
                                                        File.WriteAllText("Kicks.txt", theline); // could it be more simple?
                                                    Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": Done. Added line " + IrcFormatting.BoldText(string.Join(" ", cmd.Skip(5).ToArray())) + " to kicks database.");
                                                }
                                                if (msg.BotCommandParams[0].Equals("clear"))
                                                {
                                                    if (File.Exists("Kicks.txt"))
                                                    {
                                                        File.Delete("Kicks.txt");
                                                        Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": Done. Deleted kicks database.");
                                                    }
                                                    else Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": Kicks database already deleted.");
                                                }
                                                if (msg.BotCommandParams[0].Equals("total") && File.Exists("Kicks.txt"))
                                                {
                                                    int i = 0;
                                                    string line;
                                                    System.IO.StreamReader file = new System.IO.StreamReader("Kicks.txt");
                                                    while ((line = file.ReadLine()) != null)
                                                    {
                                                        i++;
                                                    }
                                                    file.Close();
                                                    Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": " + i + " lines.");
                                                }
                                                if (msg.BotCommandParams[0].Equals("read") && msg.BotCommandParams.Length > 1)
                                                {
                                                    if (File.Exists("Kicks.txt"))
                                                    {
                                                        int i = 0;
                                                        int x;
                                                        string line;
                                                        if (!int.TryParse(cmd[5], out x))
                                                        {
                                                            Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": This isn't a valid number.");
                                                        }
                                                        else
                                                        {
                                                            x--;
                                                            if (x < 0)
                                                            {
                                                                Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": This isn't a valid number.");
                                                            }
                                                            else
                                                            {
                                                                System.IO.StreamReader file = new System.IO.StreamReader("Kicks.txt");
                                                                while ((line = file.ReadLine()) != null && i != x)
                                                                {
                                                                    i++;
                                                                }
                                                                if (i == x)
                                                                {
                                                                    if (line != null)
                                                                    {
                                                                        Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": " + line);
                                                                    }
                                                                    else
                                                                    {
                                                                        Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": No kickline for this number.");
                                                                    }
                                                                }
                                                                file.Close();
                                                            }
                                                        }
                                                    }
                                                    else
                                                    {
                                                        Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": There is no kicks database!");
                                                    }
                                                }
                                            }
                                        }
                                        else
                                        {
                                            Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": You are not my owner!");
                                        }
                                        break;
                                    case "kick":
                                        if (cmd.Length > 4)
                                        {

                                            if (Functions.IsOwner(msg.SourceHostmask) | (check.isBotOp(msg.SourceNickname) && (check.GetLevel(msg.SourceNickname) >= 3)))
                                            {
                                                if (cmd.Length > 5)
                                                {
                                                    Functions.WriteData("KICK " + msg.Target + " " + cmd[4] + " :" + string.Join(" ", cmd.Skip(5).ToArray()));
                                                }
                                                else if (File.Exists("Kicks.txt"))
                                                {
                                                    string[] lines = File.ReadAllLines("Kicks.txt");
                                                    Random rand = new Random();
                                                    Functions.WriteData("KICK " + msg.Target + " " + cmd[4] + " :" + lines[rand.Next(lines.Length)]);
                                                }
                                                else
                                                {
                                                    Functions.WriteData("KICK " + msg.Target + " " + cmd[4] + " :Goodbye! You just got kicked by " + msg.SourceNickname + ".");
                                                }
                                                //  Functions.WriteData("KICK " + msg.Target + " " + cmd[4] + " Gotcha! You just got ass-kicked by " + nick + "."); // might also be an idea ;D
                                            }
                                            else
                                            {
                                                Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": You don't have enough permissions!");
                                            }
                                        }
                                        break;
                                    case "join":
                                        if (Functions.IsOwner(msg.SourceHostmask) && msg.BotCommandParams.Length > 0)
                                        {
                                            Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": Joining " + cmd[4] + "...");
                                            Functions.WriteData("JOIN " + cmd[4]);
                                        }
                                        else if (!Functions.IsOwner(msg.SourceHostmask))
                                            Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": You are not my owner!");
                                        break;
                                    case "help": // async help
                                        Thread HelpThread = new Thread(new ParameterizedThreadStart(Functions.SendHelp));
                                        HelpThread.IsBackground = true;
                                        string[] param = { msg.SourceNickname, msg.SourceHostmask, prefix };
                                        HelpThread.Start(param);
                                        break;
                                    case "mode":
                                        if (Functions.IsOwner(msg.SourceHostmask))
                                        {
                                            if (cmd.Length > 5)
                                            {
                                                Functions.WriteData("MODE " + msg.Target + " " + string.Join(" ", cmd.Skip(4).ToArray()));
                                            }
                                            else if (cmd.Length > 4)
                                            {
                                                Functions.WriteData("MODE " + msg.Target + " " + cmd[4]);
                                            }
                                        }
                                        else if (!Functions.IsOwner(msg.SourceHostmask))
                                        {
                                            if (cmd.Length > 5)
                                            {
                                                Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": You are not my owner!");
                                            }
                                            else if (cmd.Length > 4)
                                            {
                                                Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": You are not my owner!");
                                            }
                                        }
                                        break;
                                    case "part":
                                        if (Functions.IsOwner(msg.SourceHostmask) && cmd.Length > 4)
                                        {
                                            if (cmd.Length > 5)
                                                cmd[5] = ":" + cmd[5];
                                            Functions.WriteData("PART " + string.Join(" ", cmd.Skip(4).ToArray()));
                                        }
                                        else if (!Functions.IsOwner(msg.SourceHostmask))
                                            Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": You are not my owner!");
                                        break;
                                    case "reset":
                                        if (Functions.IsOwner(msg.SourceHostmask))
                                        {
                                            config.Reset();
                                            config.Delete();
                                            Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": Configuration reset. The bot will now restart.");
                                            Functions.Quit("Resetting!");
                                            ProgramRestart = true;
                                            goto start;
                                        }
                                        else
                                        {
                                            Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": You are not my owner!");
                                        }
                                        break;
                                    case "action":
                                        Functions.Action(msg.Target, string.Join(" ", cmd.Skip(4).ToArray()));
                                        break;
                                    case "restart":
                                        if (Functions.IsOwner(msg.SourceHostmask))
                                        {
                                            Functions.Quit("Restarting!");
                                            ProgramRestart = true;
                                            goto start;
                                        }
                                        else
                                        {
                                            Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": You are not my owner!");
                                        }
                                        break;
                                    case "hostmask":
                                        if (msg.BotCommandParams.Length > 0)
                                        {
                                            whoistarget = msg.BotCommandParams[0];
                                            inputline = reader.ReadLine();
                                            cmd = inputline.Split(' ');
                                            IrcNumericReplyLine reply = new IrcNumericReplyLine(inputline);
                                            if (reply.ReplyCode == IrcReplyCode.RPL_WHOISUSER)
                                            {
                                                // WHOIS reply
                                                if (cmd.Length > 6)
                                                {
                                                    if (DebuggingEnabled == true)
                                                    {
                                                        Console.ForegroundColor = ConsoleColor.Yellow;
                                                        Functions.Log("Reading WHOIS to get hostmask of " + whoistarget + " for " + msg.SourceNickname + "...");
                                                        Console.ForegroundColor = ConsoleColor.White;
                                                    }
                                                    Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": " + whoistarget + "'s hostmask is " + cmd[5]);
                                                    Functions.Log("Found the hostmask that " + msg.SourceNickname + " called for, of " + whoistarget + "'s hostmask, which is: " + cmd[5]);
                                                }
                                            }
                                        }
                                        break;
                                    case "math":
                                        Functions.PrivateMessage(msg.Target, cmd[4] + " = " + MathParser.Parse(cmd[4]));
                                        break;
                                    case "saymodule":
                                        if (Functions.IsOwner(msg.SourceHostmask))
                                        {
                                            ProcessStartInfo start = new ProcessStartInfo();
                                            try
                                            {
                                                if (cmd.Length > 4)
                                                {
                                                    //  if (cmd[4].StartsWith("\"") && cmd.Last().EndsWith("\""))
                                                    //    start.FileName = string.Join(" ", cmd.Skip(4)).Remove('"');
                                                    // else
                                                    start.FileName = String.Join(" ", cmd.Skip(4).ToArray());
                                                    start.UseShellExecute = false;
                                                    start.RedirectStandardOutput = true;
                                                    bool ok = false;
                                                    try
                                                    {
                                                        ok = Functions.CheckEXE(start.FileName);
                                                    }
                                                    catch (Exception)
                                                    {
                                                        ok = false;
                                                    }
                                                    if (ok)
                                                    {
                                                        using (Process process = Process.Start(start))
                                                        {
                                                            using (StreamReader sreader = process.StandardOutput)
                                                            {
                                                                string output = sreader.ReadToEnd();
                                                                cwin.textBox3.Text = output;
                                                                string[] split = cwin.textBox3.Text.Split('\n');
                                                                foreach (string s in split)
                                                                {
                                                                    Functions.PrivateMessage(msg.Target, s);
                                                                }
                                                            }
                                                        }
                                                    }
                                                    else
                                                    {
                                                        Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": I'm sorry, but the file you have attempted to run is not a valid CSB executable.");
                                                    }
                                                }
                                                else
                                                {
                                                    Functions.PrivateMessage(msg.Target, "Usage: " + prefix + "saymodule <path_to_csbfile.exe>");
                                                }
                                            }
                                            catch (FileNotFoundException)
                                            {
                                                Functions.PrivateMessage(msg.Target, "That file doesn't exist :(");
                                            }
                                            catch (System.ComponentModel.Win32Exception)
                                            {
                                                Functions.PrivateMessage(msg.Target, "That file doesn't exist :(");
                                            }
                                            catch (Exception ex)
                                            {
                                                Functions.PrivateMessage(msg.Target, ex.ToString());
                                                string[] st = ex.StackTrace.Split('\n');
                                                foreach (string s in st)
                                                {
                                                    Functions.PrivateMessage(msg.Target, s);
                                                }
                                            }
                                        }
                                        break;
                                    case "version":
                                        Functions.SendCTCP(msg.SourceNickname, "VERSION");
                                        while (msg.MessageType != IrcMessageType.CtcpReply)
                                        {
                                            inputline = reader.ReadLine();
                                            IrcMessageLine cmsg = new IrcMessageLine(inputline, config);
                                            if (cmsg.MessageType == IrcMessageType.CtcpReply)
                                            {
                                                string[] ctcpSplit = cmsg.Message.Split(' ');
                                                if (ctcpSplit[0].ToUpper() == "VERSION")
                                                {
                                                    Functions.PrivateMessage(msg.Target, msg.SourceNickname + ": Your chat client says, that it is " + IrcFormatting.BoldText(string.Join(" ", ctcpSplit.Skip(1).ToArray())));
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                }
                                if (Regex.Match(msg.BotCommandName, "^(g|d)(voice|bot|halfop|op|admin|protect|owner)$").Success)
                                {
                                    string pre = msg.BotCommandName.StartsWith("g") ? "+" : "-";
                                    string cdmode = msg.BotCommandName.ToLower();
                                    if (Functions.IsOwner(msg.SourceHostmask))
                                    {
                                        if (msg.BotCommandParams.Length > 0)
                                        {
                                            cdmode = cdmode.Substring(1);
                                            if (cdmode.Equals("voice"))
                                            {
                                                Functions.Mode(msg.Target, pre + "v " + msg.BotCommandParams[0]);
                                            }
                                            else if (cdmode.Equals("bot"))
                                            {
                                                Functions.Mode(msg.Target, pre + "V " + msg.BotCommandParams[0]);
                                            }
                                            else if (cdmode.Equals("halfop"))
                                            {
                                                Functions.Mode(msg.Target, pre + "h " + msg.BotCommandParams[0]);
                                            }
                                            else if (cdmode.Equals("op"))
                                            {
                                                Functions.Mode(msg.Target, pre + "o " + msg.BotCommandParams[0]);
                                            }
                                            else if (cdmode.Equals(Regex.Match(cdmode, "^(admin|protect)$").Value))
                                            {
                                                Functions.Mode(msg.Target, pre + "a " + msg.BotCommandParams[0]);
                                            }
                                            else if (cdmode.Equals("owner"))
                                            {
                                                Functions.Mode(msg.Target, pre + "q " + msg.BotCommandParams[0]);
                                            }
                                        }
                                    }
                                }
                                if (msg.Message.StartsWith("GTFO "))
                                {
                                    if (cmd.Length > 4)
                                    {
                                        if (Functions.IsOwner(msg.SourceHostmask))
                                        {
                                            Functions.Log(msg.SourceNickname + " told " + cmd[4] + " to GTFO of " + msg.Target + ", so I kicked " + cmd[4]);
                                            Functions.WriteData("KICK " + msg.Target + " " + cmd[4] + " :GTFO!");
                                        }
                                        else
                                        {
                                            Functions.Log(msg.SourceNickname + " told " + cmd[4] + " to GTFO of " + msg.Target + ", so I kicked " + msg.SourceNickname + " for being mean.");
                                            Functions.WriteData("KICK " + msg.Target + " " + msg.SourceNickname + " :NO, U!");
                                        }
                                    }
                                }

                            }
                        }
                        #endregion
                        #region NOTICE
                        else if (msg.MessageType == IrcMessageType.Notice)
                        {
                            //Console.WriteLine("Notice from " + msg.SourceNickname + " to " + msg.Target + ": " + msg.Message);

                            if (msg.SourceNickname.ToUpper() == "NICKSERV")
                                Functions.Log("NickServ info: " + msg.Message);

                            if (msg.SourceNickname.ToUpper() == "CHANSERV")
                                Functions.Log("ChanServ info: " + msg.Message);

                            if (msg.Target.ToUpper() == "AUTH")
                                Functions.Log("Auth message: " + msg.Message);

                        }
                        #endregion
                        #region CTCP Request
                        else
                            if (msg.MessageType == IrcMessageType.CtcpRequest)
                            {
                                Functions.Log("CTCP by " + msg.SourceNickname + ".");
                                // CTCP request

                                string[] spl = msg.Message.Split(' ');
                                string ctcpCmd = spl[0];
                                string[] ctcpParams = spl.Skip(1).ToArray();

                                if (ctcpCmd == "VERSION")
                                {
                                    if (DebuggingEnabled == true)
                                    {
                                        Console.ForegroundColor = ConsoleColor.Yellow;
                                        Functions.Log("Sent CTCP VERSION reply to " + msg.SourceNickname + ".");
                                    }
                                    Functions.WriteData("NOTICE " + msg.SourceNickname + " :\x01VERSION MerbosMagic CSharpBot " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString() + "\x01");
                                }
                                else if (ctcpCmd == "PING")
                                {
                                    if (DebuggingEnabled == true)
                                    {
                                        Console.ForegroundColor = ConsoleColor.Yellow;
                                        Functions.Log("Sent CTCP PING reply to " + msg.SourceNickname + ".");
                                    }
                                    if (ctcpParams.Length == 0) ctcpParams = new string[] {
                                    Convert.ToString(DateTime.UtcNow.ToBinary(), 16)
                                };
                                    Functions.WriteData("NOTICE " + msg.SourceNickname + " :\x01PING " + string.Join(" ", ctcpParams) + "\x01");
                                }
                            }
                        #endregion
                    }
                }
            }
            catch (Exception e)
            {
                Functions.PrivateMessage(CHANNEL, "Error! Error: " + e.ToString());
                Functions.PrivateMessage(CHANNEL, "Error! StackTrace: " + e.StackTrace);
                Functions.Quit("Exception: " + e.ToString());

                Console.ForegroundColor = ConsoleColor.Red;
                Functions.Log("The bot generated an error:");
                Functions.Log(e.ToString());
                Functions.Log("Restarting in 5 seconds...");
                Console.ResetColor();

                Thread.Sleep(5000);

                ProgramRestart = true;
                goto start; // restart
                //Environment.Exit(0); // you might also use return
            }
        }