/// <summary> /// Constructor for MoronBot. /// This is where: /// - All of the Bot's Functions are loaded. /// - Settings is initialized from xml. /// - The initial connection to the server is made. /// </summary> public MoronBot() { if (!LoadXML("settings.xml")) { SaveXML("settings.xml"); } LoadFunctions(); //PluginLoader.WatchDirectory(Settings.Instance.FunctionPath, FuncDirChanged); Nick = Settings.Instance.Nick; cwIRC = CwIRC.Interface.Instance; cwIRC.MessageReceived += CwIRC_MessageReceived; cwIRC.Connect(Settings.Instance.Server, Settings.Instance.Port); cwIRC.NICK(Nick); cwIRC.USER(Nick, "Nope", "Whatever", "MoronBot 0.1.6"); cwIRC.SendData("PASS mOrOnBoTuS"); Say("identify mOrOnBoTuS", "NickServ"); cwIRC.JOIN(Settings.Instance.Channel); connectionTimer.Elapsed += new System.Timers.ElapsedEventHandler(connectionTimer_Elapsed); connectionTimer.Interval = 120000; connectionTimer.Enabled = true; }
/// <summary> /// Processes messages from the server. Most of the main 'bot' functions are in here. /// NOTE: Should probably be split off into separate modules, for easier modification. /// FURTHER-NOTE: Have now split off all of the bot's main functions (the ones listed by |commands), should maybe continue with the rest. /// </summary> /// <param name="p_message">The message received from the server.</param> void ProcessMessage(BotMessage message) { if (message.Type == "PING") { cwIRC.SendData("PONG " + message.MessageString); return; } string parameter = message.MessageList[2].TrimStart(':'); string logText = ""; switch (message.Type) { // First, a load of message types we don't care about case "NOTICE": case "001": // Welcome case "002": // Server you're on, IRC server software version case "003": // Server creation date case "004": // Server name, version, user modes, channel modes case "005": // Stuff supported by the server case "251": // Number of users on the servers case "252": // Number of OPs on the servers case "253": // Number of unregistered connections case "254": // Number of channels formed case "255": // Number of local connections, I think case "265": // Number of local users case "266": // Number of global users case "315": // End of WHO reply case "329": // Channel creation time case "333": // Who set the current topic, and when case "366": // End of NAMES reply case "372": // MOTD line case "375": // Start of MOTD case "451": // Bot not marked as registered yet case "474": // Bot banned from channel break; case "010": // Server full, connect to another cwIRC.Disconnect(); cwIRC.Connect(message.MessageList[3], Int32.Parse(message.MessageList[4])); cwIRC.NICK(Nick); cwIRC.USER(Nick, "Nope", "Whatever", "MoronBot 0.1.6"); break; case "324": // Channel modes ChannelList.Parse324(message); break; case "332": // Current topic ChannelList.Parse332(message); break; case "352": // WHO reply ChannelList.Parse352(message); break; case "353": // NAMES reply ChannelList.Parse353(message); break; case "376": // End of MOTD (Used as 'Nick Accepted') Nick = message.MessageList[2]; cwIRC.JOIN(Settings.Instance.Channel); break; case "433": // Nick In Use nickUsedCount++; Nick = Settings.Instance.Nick + nickUsedCount; cwIRC.NICK(Nick); break; case "NICK": List <string> channels = ChannelList.ParseNICK(message); if (message.User.Name == Nick) { Nick = parameter; } logText = string.Format("{0} is now known as {1}", message.User.Name, parameter); foreach (string chan in channels) { Log(logText, chan.ToLowerInvariant()); } break; case "JOIN": ChannelList.ParseJOIN(message); if (message.User.Name == Nick) { cwIRC.SendData("MODE " + message.MessageList[2].TrimStart(':')); } ExecuteFunctionList(RegexFunctions, message); ExecuteFunctionList(UserListFunctions, message); ExecuteFunctionList(CommandFunctions, message); SendQueue(); //cwIRC.SendData("WHO " + message.MessageList[2].TrimStart(':')); //cwIRC.SendData("NAMES " + message.MessageList[2].TrimStart(':')); Log(string.Format(" >> {0} ({1}@{2}) joined {3}", message.User.Name, message.User.User, message.User.Hostmask, parameter), parameter.ToLowerInvariant()); break; case "PART": ChannelList.ParsePART(message, message.User.Name == Nick); string partMsg = (message.MessageList.Count > 3 ? ", message: " + String.Join(" ", message.MessageList.ToArray(), 3, message.MessageList.Count - 3).Substring(1) : ""); Log(string.Format(" << {0} ({1}@{2}) left {3}{4}", message.User.Name, message.User.User, message.User.Hostmask, parameter, partMsg), parameter.ToLowerInvariant()); break; case "QUIT": List <string> quittedChannels = ChannelList.ParseQUIT(message); string quitMsg = (message.MessageList.Count > 2 ? ", message: " + String.Join(" ", message.MessageList.ToArray(), 2, message.MessageList.Count - 2).Substring(1) : ""); logText = string.Format(" << {0} ({1}@{2}) quit{3}", message.User.Name, message.User.User, message.User.Hostmask, quitMsg); foreach (string chan in quittedChannels) { Log(logText, chan.ToLowerInvariant()); } break; case "KICK": ChannelList.ParsePART(message, message.MessageList[3] == Nick); if (message.MessageList[3] == Nick) { cwIRC.JOIN(message.MessageList[2]); } string kickMsg = (message.MessageList.Count > 4 ? ", message: " + String.Join(" ", message.MessageList.ToArray(), 4, message.MessageList.Count - 4).Substring(1) : ""); logText = string.Format("!<< {0} kicked {1}{2}", message.User.Name, message.MessageList[3], kickMsg); Log(logText, parameter.ToLowerInvariant()); break; case "MODE": ChannelList.ParseMODE(message); string setter = message.User.Name.TrimStart(':'); string modes = message.MessageList[3].TrimStart(':'); string targets = ""; string channel = message.MessageList[2].ToLowerInvariant(); if (channel.StartsWith("#")) { if (message.MessageList.Count > 4) { for (int i = 4; i < message.MessageList.Count; ++i) { if (i < message.MessageList.Count - 1) { targets += message.MessageList[i] + " "; } else { targets += message.MessageList[i]; } } } else { targets = message.MessageList[2]; } } Log(string.Format("# {0} set mode: {1} {2}", setter, modes, targets), channel.ToLowerInvariant()); break; case "TOPIC": ChannelList.ParseTOPIC(message); Log(string.Format("# {0} changed the topic to: {1}", message.User.Name, message.MessageString), message.ReplyTo); break; case "PRIVMSG": // User messages char ctcpChar = Convert.ToChar((byte)1); string action = ctcpChar + "ACTION "; if (message.MessageString.StartsWith(action)) { Log(string.Format("*{0} {1}*", message.User.Name, message.MessageString.Replace(action, "").TrimEnd(ctcpChar)), message.ReplyTo); } else { Log(string.Format("<{0}> {1}", message.User.Name, message.MessageString), message.ReplyTo); } ExecuteFunctionList(UserListFunctions, message); SendQueue(); if (Settings.Instance.IgnoreList.Contains(message.User.Name.ToUpper())) { return; } ExecuteFunctionList(RegexFunctions, message); SendQueue(); Match match = Regex.Match(message.MessageString, @"^(\||" + Nick + @"(,|:)?[ ])", RegexOptions.IgnoreCase); if (match.Success) { ExecuteFunctionList(CommandFunctions, message); SendQueue(); // Intrinsic functions // These are here because they are either too linked with the bot to extract, // or too simple to be worth making a Function dll for. if (message.User.Name == Settings.Instance.Owner) { if (Regex.IsMatch(message.Command, "^(pass)$", RegexOptions.IgnoreCase)) { cwIRC.SendData("PASS mOrOnBoTuS"); } else if (Regex.IsMatch(message.Command, "^(unload)$", RegexOptions.IgnoreCase)) { UnloadFunction(message); } else if (Regex.IsMatch(message.Command, "^(load)$", RegexOptions.IgnoreCase)) { LoadFunction(message); } } } SendQueue(); break; default: Log(message.RawMessage, "-unknown"); break; } }