All pastes #979368 Raw Edit

GET IT!?

public text v1 · immutable
·published 2008-04-10 09:39 UTC
rendered paste body
////////
// 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<Channel> channels = new List<Channel>();
		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<string> logBuffer;
			public int countLines;
			public List<GetItCandidate> candidates;
			public string lastGotItNick;
			public int lastGotItLine;

			public Channel(string name) {
				this.name = name;
				logBuffer = new List<string>();
				countLines = 0;
				candidates = new List<GetItCandidate>();
				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<GetItKeyword> keywords = new List<GetItKeyword>();

		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());
			}
		}
	}
}