/// <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"); }
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 } }