//////// // a GET IT!? bot // by flamingspinach // date: a long ass time ago // released into oh I dunno licensing scheme // change whatever you want, it'd be nice if you credit me somewhere though // sorry there's not a ton of comments at all because I didn't think anyone would use this ever // also a lot of stuff is hardcoded which is gay lol // (oops) // hmm looking through this it looks like there is a total of one (1) comment haha // well I guess ".... deal with it......." :/ //////// using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Threading; using System.Windows.Forms; using Meebey.SmartIrc4net; namespace GetItBot { class Program { static void Main (string[] args) { // IrcClient client = new IrcClient(); // client.ActiveChannelSyncing = true; // client.AutoRejoin = true; // client.AutoReconnect = true; // client.AutoRelogin = true; // client.AutoRetry = true; // client.CtcpVersion = "GI:IRC v0.1"; // // client.Connect("popn.cjb.net", 4400); // client.Login("flamingspinach", "LocT", 0, "LocT"); // // client.RfcJoin("#test"); // client.SendMessage(SendType.Action, "#test", "is hilariously ill atm"); // client.Listen(); // GetItBotObject bot = new GetItBotObject("popn.cjb.net", 4400, "#bemaniso"); string server; short port; string[] channelNames; if(args.Length > 2) { server = args[0]; port = Convert.ToInt16(args[1]); channelNames = new string[args.Length - 2]; for (int c = 2; c < args.Length; ++c) channelNames[c - 2] = args[c]; } else { server = "popn.cjb.net"; port = 4400; channelNames = new string[2] { "#machogang", "#test" }; } GetItBotObject testbot = new GetItBotObject(server, port, channelNames, true); testbot.Start(); } } class GetItBotObject { private IrcClient client = new IrcClient(); public bool saveLogs = false; private string server = ""; private short port = 6667; private List channels = new List(); private readonly int logBufferLength; private Random randomNumberGenerator = new Random(); class GetItCandidate { public int lineNumber; public DateTime time; public GetItKeyword keyword; public static int curUniqueID = 0; public int uniqueID; public string originalText; public GetItCandidate(int lineNumber, GetItKeyword keyword, string originalText) { this.lineNumber = lineNumber; time = DateTime.Now; this.keyword = keyword; uniqueID = ++curUniqueID; this.originalText = originalText; } } class Channel { public string name; public List logBuffer; public int countLines; public List candidates; public string lastGotItNick; public int lastGotItLine; public Channel(string name) { this.name = name; logBuffer = new List(); countLines = 0; candidates = new List(); lastGotItNick = ""; lastGotItLine = 0; } public void ResetCandidates (string nick) { lastGotItNick = nick; lastGotItLine = countLines; candidates.Clear(); } } class GetItKeyword { public string pattern; public string response; public double weight; public DateTime lastUse = DateTime.MinValue; public GetItKeyword (string pattern, string response, double weight) { this.pattern = pattern; this.response = response; this.weight = weight; } public GetItKeyword (string[] values) : this(values[0], values[1], Convert.ToDouble(values[2])) {} public GetItKeyword (string values) : this(values.Split(':')) {} } private static List keywords = new List(); static GetItBotObject () { StreamReader input = new StreamReader("data.txt"); while (!input.EndOfStream) { keywords.Add(new GetItKeyword(input.ReadLine())); } } public GetItBotObject (string server, short port, string[] channelNames, bool saveLogs, int logBufferLength) { this.saveLogs = saveLogs; this.logBufferLength = logBufferLength; foreach (string x in channelNames) { channels.Add(new Channel(x)); } this.server = server; this.port = port; } public GetItBotObject (string server, short port, string[] channelNames, bool saveLogs) : this(server, port, channelNames, saveLogs, 100) {} public GetItBotObject (string server, short port, string[] channelNames) : this(server, port, channelNames, false) {} public void Start() { client.ActiveChannelSyncing = true; client.AutoReconnect = true; client.AutoRejoin = true; client.AutoRelogin = true; client.AutoRetry = true; client.CtcpVersion = "spacedream WIP"; client.Connect(server, port); client.Login("LocT", "location test", 0, "spacedream"); foreach(Channel x in channels) { client.RfcJoin(x.name); } client.OnCtcpRequest += new IrcEventHandler(OnCtcp); client.OnChannelAction += new ActionEventHandler(OnChannelMessage); client.OnChannelMessage += new IrcEventHandler(OnChannelMessage); new MethodInvoker(ReadRaw).BeginInvoke(null, null); client.Listen(); } private Channel FindChannel (string name) { foreach (Channel x in channels) { if (x.name == name) return x; } lock (channels) { channels.Add(new Channel(name)); return channels[channels.Count - 1]; } } private delegate void GetItAnnounce_delegate (GetItCandidate candidate, Channel channel); private void OnChannelMessage (object sender, IrcEventArgs e) { Channel channel = FindChannel(e.Data.Channel); DateTime curDateTime = DateTime.Now; string formattedLine = ""; // increment line count channel.countLines++; // save the new line to the log buffer if (saveLogs) { switch (e.Data.Type) { case ReceiveType.ChannelAction: formattedLine = String.Format("{0}. {1} * {2} {3}", channel.countLines, Timestamp(curDateTime), e.Data.Nick, e.Data.Message); break; case ReceiveType.ChannelMessage: formattedLine = String.Format("{0}. {1} <{2}> {3}", channel.countLines, Timestamp(curDateTime), e.Data.Nick, e.Data.Message); break; default: // this shouldn't happen formattedLine = String.Format("{0}. {1} {2}", channel.countLines, Timestamp(curDateTime), e.Data.RawMessage); break; } LogNewLine(channel, formattedLine); } // check if preempted by sMaRt PpLz if (e.Data.Message.Contains("GET IT")) { channel.ResetCandidates(e.Data.Nick); } // facilitate pattern matching string messageTest = " " + e.Data.Message + " "; // check for potential GET IT!!??!? foreach (GetItKeyword x in keywords) { if (messageTest.ToLower().Contains(x.pattern)) { LogNewLine(channel, "+---- POTENTIAL GET IT DETECTED !!! -------------------------------------------+"); LogNewLine(channel, "| Pattern match: '" + x.pattern + "'" + "".PadRight(79 - 19 - x.pattern.Length) + "|"); if (DateTime.Now < x.lastUse + new TimeSpan(2, 0, 0)) { LogNewLine(channel, "| Oops! Last GOT this pattern too recently to GET it again. |"); LogNewLine(channel, "+------------------------------------------------------------------------------+"); } else { double randomNumber = randomNumberGenerator.NextDouble(); LogNewLine(channel, "| Probability calc: [" + "".PadRight((int)(50*x.weight), '+').PadRight(50) + "] |"); LogNewLine(channel, "| " + "^".PadLeft((int)(50*randomNumber) + 1).PadRight(50) + " |"); if (randomNumber <= x.weight) { string quote = formattedLine.Substring(formattedLine.IndexOf(']') + 2) + " "; quote = quote.Insert(quote.ToLower().IndexOf(x.pattern), ((char)2).ToString()); quote = quote.Insert(quote.ToLower().IndexOf(x.pattern) + x.pattern.Length, ((char)2).ToString()); GetItCandidate candidate = new GetItCandidate(channel.countLines, x, quote); channel.candidates.Add(candidate); LogNewLine(channel, "| SUCCESS! Will we be the first to call it? Only time will tell! |"); LogNewLine( channel, "| Candidate added to queue with unique ID ".Insert(42, candidate.uniqueID.ToString()).PadRight(79) + "|"); LogNewLine(channel, "+------------------------------------------------------------------------------+"); // launch a thread that waits a while and then tries to announce a GET IT!?!???!? new GetItAnnounce_delegate(GetItAnnounce).BeginInvoke(candidate, channel, null, null); } else { LogNewLine(channel, "| FAILURE! Lying low for now... |"); LogNewLine(channel, "+------------------------------------------------------------------------------+"); } } break; } } } private void GetItAnnounce (GetItCandidate candidate, Channel channel) { string response = candidate.keyword.response; if (response == "") { // create random GET IT!??!??!?? response = "GET IT"; int interrobangCount = randomNumberGenerator.Next(9) + 3; for (int c = 0; c < interrobangCount; ++c) { switch (randomNumberGenerator.Next(2)) { case 0: response += "?"; break; case 1: response += "!"; break; } } } // update the last usage of this GET IT keyword candidate.keyword.lastUse = DateTime.Now; // wait a while to not be obnoxious Thread.Sleep(4000 + randomNumberGenerator.Next(10000)); if (!channel.candidates.Contains(candidate)) { LogNewLine(channel, "+---- PREEMPTED !!! -----------------------------------------------------------+"); LogNewLine(channel, "| GET IT candidate ID: ".Insert(23, candidate.uniqueID.ToString()).PadRight(79) + "|"); LogNewLine(channel, "| GET IT candidate line number: ".Insert(32, candidate.lineNumber.ToString()).PadRight(79) + "|"); LogNewLine(channel, "| Nimble Jack: ".Insert(15, channel.lastGotItNick.ToString()).PadRight(79) + "|"); LogNewLine(channel, "+------------------------------------------------------------------------------+"); } else { if (channel.countLines > candidate.lineNumber) { client.SendMessage(SendType.Message, channel.name, candidate.originalText); LogNewLine(channel, String.Format("{0}. {1} <{2}> {3}", ++channel.countLines, Timestamp(DateTime.Now), client.Nickname, candidate.originalText)); } client.SendMessage(SendType.Message, channel.name, response); LogNewLine(channel, String.Format("{0}. {1} <{2}> {3}", ++channel.countLines, Timestamp(DateTime.Now), client.Nickname, response)); LogNewLine(channel, "+---- GOT IT !!! --------------------------------------------------------------+"); LogNewLine(channel, "| GET IT candidate ID: ".Insert(23, candidate.uniqueID.ToString()).PadRight(79) + "|"); LogNewLine(channel, "| GET IT candidate line number: ".Insert(32, candidate.lineNumber.ToString()).PadRight(79) + "|"); LogNewLine(channel, "+------------------------------------------------------------------------------+"); } } private void LogNewLine (Channel channel, string line) { if (!saveLogs) return; channel.logBuffer.Add(line); Console.WriteLine(channel.name + ": " + line); if (channel.logBuffer.Count >= logBufferLength) { StreamWriter output = new StreamWriter("log." + channel.name + ".txt", true); foreach (string x in channel.logBuffer) { output.WriteLine(x); } output.Close(); output.Dispose(); channel.logBuffer.Clear(); } } // hardcoded because I'm a bastard static string Timestamp (DateTime time) { return time.ToString("'['yyyy-MM-dd HH:mm:ss']'"); } void OnCtcp(object sender, IrcEventArgs e) { if (e.Data.Message.ToLower() == "finger") { client.SendMessage(SendType.Notice, e.Data.Nick, "Yep, you guessed it, I'm a GET IT!??!?? bot ;> Have fun!"); LogNewLine(FindChannel("status"), Timestamp(DateTime.Now) + " *** Received CTCP FINGER from " + e.Data.Nick); } } void ReadRaw() { while(true) { client.WriteLine(Console.ReadLine()); } } } }