using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using System.Diagnostics; namespace MuteBot { struct IrcUser { public string nick; public string user; public string host; public string channel; public double unMuteTime; } class MainClass { private static List punishees = new List(); private static StreamWriter swrite; private static StreamReader sread; public static void Main (string[] args) { // Configurable bot vars string nickname = "NiiForcer"; string server = "127.0.0.1"; int port = 1025; // Socket vars NetworkStream sstream; TcpClient irc; // Generic bot vars bool botOn = true; string line; // incoming line string[] splitLine; // array of line, expoded by \s string fucker = "KickedByA"; try { // Connect irc = new TcpClient(server, port); sstream = irc.GetStream(); sread = new StreamReader(sstream); swrite = new StreamWriter(sstream); } catch (Exception e) { Console.WriteLine("Error connecting to {0}: {1}", server, e); return; } // Identify swrite.WriteLine("USER {0} {0} {0} :{1}", nickname, nickname); swrite.WriteLine("NICK {0}", nickname); //auth to znc swrite.Flush(); while (botOn) { if ((line = sread.ReadLine()) != null) { Console.WriteLine(line); splitLine = line.Split(' '); if(splitLine[0].StartsWith(":GlaD0S!") || splitLine[0].StartsWith(":NiiForcer!")) { Console.WriteLine("Line ignored!"); continue; } if (splitLine.Length > 0) { switch (splitLine[1]) { case "366": Console.WriteLine("Connected to ponychat :)"); break; case "MODE": if (splitLine[3] == "-v") { MuteUser(splitLine[4], splitLine[2], MakeUserFromString(line).nick); Console.WriteLine("MUTER: " + MakeUserFromString(line).nick); } else if (splitLine[3] == "+v") { UnMuteUser(splitLine[4], MakeUserFromString(line).nick); } break; case "JOIN": if(AllowVoiceUser(line)) { SendLine("MODE {0} +v {1}", new object[] {splitLine[2].Substring(1), MakeUserFromString(line).nick}); Console.WriteLine("User {0} voiced", MakeUserFromString(line).nick); } else { //SendLine("NOTICE {0} :Please ask a mod to be voiced. in #tulpa.mods", MakeUserFromString(line).nick); //SendLine("PRIVMSG #tulpa.mods :mod mods admin swashy Purlox Shockk Tesseract: {0} has evaded a mute. ", MakeUserFromString(line).nick); } swrite.Flush(); break; } //CheckExpiredMutes(); if (splitLine[0] == "PING") { SendLine("PONG {0}", splitLine[1]); swrite.Flush(); } } //CheckExpiredMutes(); } else { //CheckExpiredMutes(); } //CheckExpiredMutes(); } // Clean up swrite.Close(); sread.Close(); irc.Close(); } private static string GetSpokenLine(string line) { if (line.Split(':').Length >= 2) return line.Split(':')[2]; return ""; } private static IrcUser MakeUserFromString (string user) { IrcUser ret = new IrcUser(); user = user.Split(' ')[0]; int bang, at; bang = user.IndexOf("!"); at = user.IndexOf("@"); ret.nick = user.Substring(1,bang-1); ret.user = user.Substring(bang+1, (at-bang)-1); ret.host = user.Substring(at+1); return ret; } private static bool AllowVoiceUser (string line) { IrcUser joinee = MakeUserFromString (line); foreach (IrcUser user in punishees) { if (user.host.Equals (joinee.host)) { return false; } } return true; } private static IrcUser DoWhoisLookupOnUser (string nick) { IrcUser lookup = new IrcUser (); lookup.nick = nick; SendLine ("WHO {0}", nick); string whoLine = sread.ReadLine (); sread.ReadLine (); Console.Out.WriteLine ("Who: " + whoLine); string[] whoLineSplit = whoLine.Split (' '); if (whoLineSplit [2].Equals ("MODE")) { return DoWhoisLookupOnUser (nick); } try { lookup.user = whoLineSplit [4]; lookup.host = whoLineSplit [5]; } catch (Exception e) { e.ToString(); return DoWhoisLookupOnUser(nick); } return lookup; } private static void SendLine(string line) { swrite.WriteLine(line); swrite.Flush(); Console.WriteLine(">>> " + line); } private static void SendLine (string line, object thing) { SendLine(String.Format(line, new object[] {thing})); } private static void SendLine(string line, object[] stuff) { SendLine(String.Format(line, stuff)); } private bool SameUser(IrcUser a, IrcUser b) { return (a.host.Equals(b.host)); } private static void MuteUser (string nick, string channel, string muter) { IrcUser punishee = new IrcUser (); punishee.nick = nick; punishee.channel = channel; punishee = DoWhoisLookupOnUser (punishee.nick); if (punishees.Contains (punishee)) { SendLine("PRIVMSG #tulpa_moderation :{3} nearly tried to double mute {0}!{1}@{2} :< Report this bug to Niichan please", new object[] { punishee.nick, punishee.user, punishee.host, muter }); return; } punishee.unMuteTime = unix_timestamp() + 300; punishees.Add(punishee); SendLine("NOTICE {0} :You have been devoiced, you may not speak in {1} until a moderator revoices you", new object[] {punishee.nick, channel}); SendLine("MODE {1} -v {0}", new object[] {nick, channel}); SendLine("PRIVMSG #tulpa_moderation :{0}!{1}@{2} added to devoice list by {3}.", new object[] { punishee.nick, punishee.user, punishee.host, muter }); Console.WriteLine("{0}!{1}@{2} added to devoice list\n", new object[] { punishee.nick, punishee.user, punishee.host }); } private static void UnMuteUser (string nick, string muter) { int i = 0; IrcUser toDelete = new IrcUser(); toDelete.nick = nick; toDelete = DoWhoisLookupOnUser(toDelete.nick); foreach (IrcUser user in punishees) { if(user.host.Equals(toDelete.host)) { punishees.RemoveAt(i); SendLine("NOTICE {0} :You have been revoiced, you may speak again in #tulpa_ot", user.nick); SendLine("PRIVMSG #tulpa_moderation :{0}!{1}@{2} removed from devoice list by {3}.", new object[] { user.nick, user.user, user.host, muter }); break; } i++; } } public static double unix_timestamp() { TimeSpan unix_time = (System.DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)); return unix_time.TotalSeconds; } } }