void RecentCommand(CommandDetails command)
 {
     if (command.Arguments.Count == 0)
     {
         Chat(command.Channel.Name, command.Pinger + ColorGeneral + "That command is written as: " + ColorHighlightMajor + Prefixes[0] + command.Name + " <name>");
         Chat(command.Channel.Name, ColorGeneral + "For example, " + ColorHighlightMajor + Prefixes[0] + command.Name + " mcmonkey");
         return;
     }
     IRCUser user = new IRCUser(command.Arguments[0]);
     string seen = user.GetSeen(1);
     if (seen == null)
     {
         Chat(command.Channel.Name, command.Pinger + ColorGeneral + "I've never seen that user!");
         return;
     }
     Chat(command.Channel.Name, command.Pinger + ColorGeneral + "I last saw " + ColorHighlightMajor + user.Name + ColorGeneral + " at " + ColorHighlightMinor + seen, 3);
     for (int i = 2; i <= 5; i++)
     {
         seen = user.GetSeen(i);
         if (seen != null)
         {
             Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Previously, I saw " + ColorHighlightMajor + user.Name + ColorGeneral + " at " + ColorHighlightMinor + seen, 3);
         }
     }
 }
 public void MessageCommand(CommandDetails command)
 {
     if (command.Arguments.Count <= 1)
     {
         Chat(command.Channel.Name, command.Pinger + ColorGeneral + "That command is written as: " + ColorHighlightMajor + Prefixes[0] + command.Name + " <name> <message>");
         Chat(command.Channel.Name, ColorGeneral + "For example, " + ColorHighlightMajor + Prefixes[0] + command.Name + " mcmonkey Hi, how are you?");
         return;
     }
     if (!IRCUser.Exists(command.Arguments[0]))
     {
         Chat(command.Channel.Name, command.Pinger + ColorGeneral + "I have never seen that user.");
         return;
     }
     IRCUser user = new IRCUser(command.Arguments[0]);
     user.SendReminder(command.User.Name + ": " + Utilities.Concat(command.Arguments, 1), DateTime.Now);
     Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Message stored.");
 }
 public void ReminderCommand(CommandDetails command)
 {
     if (command.Arguments.Count <= 2)
     {
         Chat(command.Channel.Name, command.Pinger + ColorGeneral + "That command is written as: " + ColorHighlightMajor + Prefixes[0] + command.Name + " <name> <time> <message>");
         Chat(command.Channel.Name, ColorGeneral + "For example, " + ColorHighlightMajor + Prefixes[0] + command.Name + " mcmonkey 1d Download the code update");
         return;
     }
     if (!IRCUser.Exists(command.Arguments[0]))
     {
         Chat(command.Channel.Name, command.Pinger + ColorGeneral + "I have never seen that user.");
         return;
     }
     IRCUser user = new IRCUser(command.Arguments[0]);
     TimeSpan rel = Utilities.StringToDuration(command.Arguments[1]);
     user.SendReminder(command.User.Name + ": " + Utilities.Concat(command.Arguments, 2), DateTime.Now.Add(rel));
     Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Reminder stored.");
 }
 void SeenCommand(CommandDetails command)
 {
     if (command.Arguments.Count == 0)
     {
         Chat(command.Channel.Name, command.Pinger + ColorGeneral + "That command is written as: " + ColorHighlightMajor + Prefixes[0] + command.Name + " <name>");
         Chat(command.Channel.Name, ColorGeneral + "For example, " + ColorHighlightMajor + Prefixes[0] + command.Name +" mcmonkey");
         return;
     }
     IRCUser user = new IRCUser(command.Arguments[0]);
     string seen = user.GetSeen(1);
     if (seen == null)
     {
         Logger.Output(LogType.DEBUG, "Never before seen " + user.Name);
         Chat(command.Channel.Name, command.Pinger + ColorGeneral + "I've never seen that user!");
         return;
     }
     Chat(command.Channel.Name, command.Pinger + ColorGeneral + "I last saw " + ColorHighlightMajor + user.Name + ColorGeneral + " at " + ColorHighlightMinor + seen, 3);
 }
 void MCPingCommand(CommandDetails command)
 {
     if (command.Arguments.Count <= 0)
     {
         Chat(command.Channel.Name, command.Pinger + ColorGeneral + "That command is written as: " + ColorHighlightMajor + Prefixes[0] + command.Name + " <Minecraft server IP address>");
         return;
     }
     IRCUser user = new IRCUser(command.Arguments[0]);
     string IP = user.Settings.ReadString("general.minecraft_server_ip", null);
     if (IP == null)
     {
         IP = command.Arguments[0];
     }
     ushort port = 0;
     if (IP.Contains(':'))
     {
         string[] dat = IP.Split(new char[] { ':' }, 2);
         IP = dat[0];
         port = Utilities.StringToUShort(dat[1]);
     }
     if (port == 0)
     {
         try
         {
             DnsQueryRequest dqr = new DnsQueryRequest();
             DnsQueryResponse resp = dqr.Resolve("_minecraft._tcp." + IP, NsType.SRV, NsClass.ANY, ProtocolType.Tcp);
             if (resp != null)
             {
                 for (int i = 0; i < resp.AdditionalRRecords.Count; i++)
                 {
                     if (resp.AdditionalRRecords[i] is SrvRecord)
                     {
                         port = (ushort)((SrvRecord)resp.AdditionalRRecords[i]).Port;
                     }
                 }
                 for (int i = 0; i < resp.Answers.Length; i++)
                 {
                     if (resp.Answers[i] is SrvRecord)
                     {
                         port = (ushort)((SrvRecord)resp.Answers[i]).Port;
                     }
                 }
             }
             else
             {
                 Logger.Output(LogType.DEBUG, "Null SRV record.");
             }
             if (port == 0)
             {
                 port = (ushort)25565;
             }
         }
         catch (Exception ex)
         {
             Logger.Output(LogType.ERROR, "Pinging a SRV record for a minecraft server: " + ex.ToString());
             port = 25565;
         }
     }
     Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
     try
     {
         Stopwatch Timer = new Stopwatch();
         Timer.Reset();
         Timer.Start();
         sock.SendBufferSize = 8192;
         sock.ReceiveBufferSize = 8192 * 10;
         sock.ReceiveTimeout = 3000;
         sock.SendTimeout = 3000;
         IAsyncResult result = sock.BeginConnect(IP, port, null, null);
         bool timeout = !result.AsyncWaitHandle.WaitOne(5000, true);
         if (timeout)
         {
             throw new Exception("Connection timed out");
         }
         if (!sock.Connected)
         {
             throw new Exception("Failed to connect");
         }
         byte[] address = UTF8.GetBytes(IP);
         int packlen = 1 + 1 + 1 + address.Length + 2 + 1;
         byte[] send = new byte[1 + packlen + 1 + 1];
         byte[] portbytes = BitConverter.GetBytes(port).Reverse().ToArray();
         send[0] = (byte)packlen; // packet length
         send[1] = (byte)0x00; // Packet ID
         send[2] = (byte)0x04; // Protocol Version
         send[3] = (byte)address.Length; // Address string length
         address.CopyTo(send, 4); // Address string
         portbytes.CopyTo(send, address.Length + 4); // Port
         send[address.Length + 6] = (byte)0x01; // Next state
         send[address.Length + 7] = (byte)0x01; // Next packet length
         send[address.Length + 8] = (byte)0x00; // Empty state request packet ~ packet ID
         sock.Send(send);
         int length = 0;
         // Packet size -> packet ID -> JSON length
         for (int x = 0; x < 2; x++)
         {
             length = 0;
             int j = 0;
             while (true)
             {
                 byte[] recd = new byte[1];
                 sock.Receive(recd, 1, SocketFlags.None);
                 int k = recd[0];
                 length |= (k & 0x7F) << j++ * 7;
                 if (j > 5) throw new Exception("VarInt too big");
                 if ((k & 0x80) != 128) break;
                 if (Timer.ElapsedMilliseconds > 7000)
                     throw new Exception("Timeout while reading response");
             }
             if (x == 0)
             {
                 byte[] resp = new byte[1];
                 sock.Receive(resp, 1, SocketFlags.None);
             }
         }
         int gotten = 0;
         byte[] response = new byte[length];
         while (gotten < length)
         {
             byte[] gotbit = new byte[length - gotten];
             int newgot = sock.Receive(gotbit, length - gotten, SocketFlags.None);
             gotbit.CopyTo(response, gotten);
             gotten += newgot;
             if (Timer.ElapsedMilliseconds > 7000)
                 throw new Exception("Timeout while reading response");
         }
         string fullresponse = UTF8.GetString(response);
         int ind = fullresponse.IndexOf('{');
         if (ind < 0)
         {
             throw new Exception("Invalid response packet - is that an actual minecraft server?");
         }
         fullresponse = fullresponse.Substring(ind);
         Dictionary<string, dynamic> dict = new JavaScriptSerializer().Deserialize<Dictionary<string, dynamic>>(fullresponse.Trim());
         string version = dict["version"]["name"].ToString();
         string versionnum = dict["version"]["protocol"].ToString();
         string players_on = dict["players"]["online"].ToString();
         string players_max = dict["players"]["max"].ToString();
         string description;
         if (dict["description"] is Dictionary<String, Object>)
         {
             description = dict["description"]["text"].ToString();
         }
         else
         {
             description = dict["description"].ToString();
         }
         Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Server: " + IP + ":" + port.ToString() + ", MOTD: '"
             + Utilities.mctoirc(description) + ColorGeneral + "', players: " + players_on + "/" + players_max + ", version: " + Utilities.mctoirc(version));
     }
     catch (Exception ex)
     {
         Logger.Output(LogType.DEBUG, "Pinging minecraft server: " + ex.ToString());
         Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Couldn't ping server: internal exception: " + ex.Message);
     }
     finally
     {
         sock.Close();
     }
 }
 /// <summary>
 /// Connects to the IRC server and runs the bot.
 /// </summary>
 void ConnectAndRun()
 {
     Logger.Output(LogType.INFO, "Connecting to " + ServerAddress + ":" + ServerPort + " as user " + Name + "...");
     IRCSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
     IRCSocket.Connect(ServerAddress, ServerPort);
     Logger.Output(LogType.INFO, "Connected to " + IRCSocket.RemoteEndPoint.ToString());
     string host = Configuration.ReadString("dircbot.irc-servers." + ServerName + ".host", "unknown");
     SendCommand("USER", Name + " " + host + " " + host + " :" + Name);
     SendCommand("NICK", Name);
     string receivedAlready = string.Empty;
     while (true)
     {
         if ((DateTime.Now.Hour == 6 || DateTime.Now.Hour == 18) && DateTime.Now.Minute >= 29 && DateTime.Now.Minute <= 31
             && DateTime.Now.Subtract(Started).TotalMinutes > 10)
         {
             Restart();
         }
         long timePassed = 0;
         bool pinged = false;
         Stopwatch sw = new Stopwatch();
         sw.Start();
         while (IRCSocket.Available <= 0)
         {
             sw.Stop();
             timePassed += sw.ElapsedMilliseconds;
             if (timePassed > 60 * 1000 && !pinged)
             {
                 SendCommand("PING", Utilities.random.Next(10000).ToString());
                 pinged = true;
             }
             if (timePassed > 120 * 1000)
             {
                 throw new Exception("Ping timed out!");
             }
             sw.Reset();
             sw.Start();
             Thread.Sleep(1);
         }
         int avail = IRCSocket.Available;
         byte[] receivedNow = new byte[avail > 1024 ? 1024: avail];
         IRCSocket.Receive(receivedNow, receivedNow.Length, SocketFlags.None);
         string got = UTF8.GetString(receivedNow).Replace("\r", "");
         receivedAlready += got;
         while (receivedAlready.Contains('\n'))
         {
             int index = receivedAlready.IndexOf('\n');
             string message = receivedAlready.Substring(0, index);
             receivedAlready = receivedAlready.Substring(index + 1);
             Logger.Output(LogType.DEBUG, "Received message: " + message);
             List<string> data = message.Split(' ').ToList();
             string user = "";
             string command = data[0];
             if (command.StartsWith(":"))
             {
                 user = command.Substring(1);
                 data.RemoveAt(0);
                 if (data.Count > 0)
                 {
                     command = data[0];
                     data.RemoveAt(0);
                 }
                 else
                 {
                     command = "null";
                 }
             }
             try
             {
                 switch (command.ToLower())
                 {
                     case "ping": // Respond to server-given PING's
                         {
                             SendCommand("PONG", data.Count > 0 ? data[1] : null);
                         }
                         break;
                     case "433": // Nickname In Use
                         {
                             SendCommand("NICK", Name + "_" + Utilities.random.Next(999));
                             SendCommand("NS", "identify " + Name + " " + Configuration.Read("dircbot.irc-servers." + ServerName + ".nickserv.password", ""));
                             SendCommand("NS", "ghost " + Name);
                             SendCommand("NICK", Name);
                         }
                         break;
                     case "376": // End of MOTD -> Ready To Join And Identify
                         {
                             SendCommand("NS", "identify " + Configuration.Read("dircbot.irc-servers." + ServerName + ".nickserv.password", ""));
                             Channels.Clear();
                             foreach (string channel in BaseChannels)
                             {
                                 SendCommand("JOIN", "#" + channel);
                                 Logger.Output(LogType.INFO, "Join Channel: #" + channel.ToLower());
                                 IRCChannel chan = new IRCChannel() { Name = "#" + channel.ToLower() };
                                 Channels.Add(chan);
                             }
                         }
                         break;
                     case "477": // Error joining channel
                         resending = true;
                         Task.Factory.StartNew(() =>
                         {
                             Thread.Sleep(5000);
                             foreach (string channel in BaseChannels)
                             {
                                 SendCommand("JOIN", "#" + channel);
                             }
                             resending = false;
                         });
                         break;
                     case "332": // Topic for channel
                         {
                             if (!resending)
                             {
                                 Task.Factory.StartNew(() =>
                                 {
                                     Thread.Sleep(5000);
                                     foreach (string achannel in BaseChannels)
                                     {
                                         SendCommand("JOIN", "#" + achannel);
                                     }
                                     resending = false;
                                 });
                             }
                             resending = true;
                             string channel = data[1].ToLower();
                             string topic = Utilities.Concat(data, 2).Substring(1);
                             Logger.Output(LogType.INFO, "Topic for channel: " + channel);
                             foreach (IRCChannel chan in Channels)
                             {
                                 if (channel == chan.Name)
                                 {
                                     chan.Topic += topic;
                                     break;
                                 }
                             }
                         }
                         break;
                     case "topic": // Fresh topic set on channel
                         {
                             // TODO: RECORD
                         }
                         break;
                     case "join": // Someone joined
                         {
                             string channel = data[0].ToLower();
                             foreach (IRCChannel chan in Channels)
                             {
                                 if (channel == chan.Name)
                                 {
                                     IRCUser newuser = new IRCUser(user);
                                     SeenUser(newuser.Name, newuser.IP);
                                     chan.Users.Add(newuser);
                                     Logger.Output(LogType.DEBUG, "Recognizing join of " + newuser.Name + " into " + chan.Name);
                                     if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + chan.Name.Replace("#", "") + ".greet", "false").StartsWith("t"))
                                     {
                                         foreach (string msg in Configuration.ReadStringList("dircbot.irc-servers." + ServerName + ".channels." + chan.Name.Replace("#", "") + ".greeting"))
                                         {
                                             Notice(newuser.Name, msg.Replace("<BASE>", ColorGeneral).Replace("<MAJOR>", ColorHighlightMajor).Replace("<MINOR>", ColorHighlightMinor));
                                         }
                                     }
                                     break;
                                 }
                             }
                         }
                         break;
                     case "mode": // User mode set
                         {
                             // TODO: RECORD
                         }
                         break;
                     case "353": // User list for channel
                         {
                             string channel = data[2].ToLower();
                             List<string> users = new List<string>(data);
                             users.RemoveRange(0, 4);
                             Logger.Output(LogType.INFO, "User list for channel: " + channel);
                             foreach (IRCChannel chan in Channels)
                             {
                                 if (channel == chan.Name)
                                 {
                                     chan.Users.Add(new IRCUser(Name + "!" + Name + "@"));
                                     foreach (string usr in users)
                                     {
                                         Logger.Output(LogType.DEBUG, "Recognize user " + usr);
                                         chan.Users.Add(new IRCUser(usr));
                                     }
                                     break;
                                 }
                             }
                         }
                         break;
                     case "part": // Someone left the channel
                         {
                             string channel = data[0].ToLower();
                             foreach (IRCChannel chan in Channels)
                             {
                                 if (channel == chan.Name)
                                 {
                                     IRCUser quitter = new IRCUser(user);
                                     string name = quitter.Name.ToLower();
                                     for (int i = 0; i < chan.Users.Count; i++)
                                     {
                                         if (chan.Users[i].Name.ToLower() == name)
                                         {
                                             Logger.Output(LogType.DEBUG, "Recognizing leave of " + chan.Users[i].Name + " from " + chan.Name);
                                             chan.Users.RemoveAt(i--);
                                             break;
                                         }
                                     }
                                     break;
                                 }
                             }
                         }
                         break;
                         // TODO: Kick
                     case "quit": // Someone left the server
                         {
                             IRCUser quitter = new IRCUser(user);
                             string name = quitter.Name.ToLower();
                             // quitreason = concat(data, 0).substring(1);
                             foreach (IRCChannel chan in Channels)
                             {
                                 for (int i = 0; i < chan.Users.Count; i++)
                                 {
                                     if (chan.Users[i].Name.ToLower() == name)
                                     {
                                         Logger.Output(LogType.DEBUG, "Recognizing quit of " + chan.Users[i].Name + " from " + chan.Name);
                                         chan.Users.RemoveAt(i--);
                                         break;
                                     }
                                 }
                             }
                         }
                         break;
                     case "nick": // Someone changed their name
                         {
                             IRCUser renamer = new IRCUser(user);
                             string nicknew = data[0].Substring(1);
                             string name = renamer.Name.ToLower();
                             renamer.SetSeen("renaming to " + nicknew);
                             foreach (IRCChannel chan in Channels)
                             {
                                 for (int i = 0; i < chan.Users.Count; i++)
                                 {
                                     if (chan.Users[i].Name.ToLower() == name)
                                     {
                                         Logger.Output(LogType.DEBUG, "Recognizing rename of " + chan.Users[i].Name + " to " + nicknew);
                                         SeenUser(nicknew, renamer.IP);
                                         IRCUser theusr = chan.Users[i];
                                         chan.Users.RemoveAt(i--);
                                         chan.Users.Add(new IRCUser(nicknew + "!" + theusr.Ident + "@" + theusr.IP) { Voice = theusr.Voice, OP = theusr.OP, EverHadVoice = theusr.EverHadVoice });
                                         break;
                                     }
                                 }
                             }
                         }
                         break;
                     case "privmsg": // Chat message
                         {
                             string channel = data[0].ToLower();
                             data[1] = data[1].Substring(1);
                             string privmsg = Utilities.Concat(data, 1);
                             bool isPM = !channel.StartsWith("#");
                             Logger.Output(LogType.INFO, "User " + user + " spoke in channel " + channel + ", saying " + privmsg);
                             if (isPM && privmsg == actionchr + "VERSION" + actionchr)
                             {
                                 Notice(user.Substring(0, user.IndexOf('!')), actionchr.ToString() + "VERSION " + Configuration.Read("dircbot.version", "DenizenBot vMisconfigured") + actionchr.ToString());
                             }
                             else if (isPM && privmsg.StartsWith(actionchr + "PING "))
                             {
                                 Notice(user.Substring(0, user.IndexOf('!')), privmsg);
                             }
                             IRCChannel chan = null;
                             foreach (IRCChannel chann in Channels)
                             {
                                 if (chann.Name == channel)
                                 {
                                     chan = chann;
                                 }
                             }
                             if (chan == null)
                             {
                                 break;
                             }
                             IRCUser iuser = chan.GetUser(user);
                             OnMessage(channel, iuser.Name, privmsg);
                             if (privmsg.StartsWith(actionchr + "ACTION "))
                             {
                                 RecentMessages.Insert(0, new IRCMessage(chan, iuser, privmsg.Substring((actionchr + "ACTION ").Length, privmsg.Length - 1 - (actionchr + "ACTION ").Length), true));
                                 goto post_s;
                             }
                             Match match = Regex.Match(privmsg, "^s/([^/]+)/([^/]+)/?([^\\s/]+)?", RegexOptions.IgnoreCase);
                             if (match.Success)
                             {
                                 string value = match.Groups[1].Value;
                                 string s_user = match.Groups[3].Success ? match.Groups[3].Value : null;
                                 foreach (IRCMessage msg in RecentMessages)
                                 {
                                     if (msg.Channel.Name != chan.Name || (s_user != null && s_user.ToLower() != msg.User.Name.ToLower()))
                                     {
                                         continue;
                                     }
                                     if (Regex.Match(msg.Message, value, RegexOptions.IgnoreCase).Success)
                                     {
                                         msg.Message = Regex.Replace(msg.Message, value, match.Groups[2].Value, RegexOptions.IgnoreCase);
                                         string prefix = msg.Action ? "* " + msg.User.Name + " " : "<" + msg.User.Name + "> ";
                                         Chat(chan.Name, ColorGeneral + prefix + msg.Message);
                                         goto post_s;
                                     }
                                 }
                             }
                             RecentMessages.Insert(0, new IRCMessage(chan, iuser, privmsg));
                             post_s:
                             if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + chan.Name.Replace("#", "") + ".link_read", "false").StartsWith("t"))
                             {
                                 foreach (string str in data)
                                 {
                                     if (str.StartsWith("http://") || str.StartsWith("https://"))
                                     {
                                         Task.Factory.StartNew(() =>
                                         {
                                             try
                                             {
                                                 LowTimeoutWebclient ltwc = new LowTimeoutWebclient();
                                                 ltwc.Encoding = UTF8;
                                                 string web = ltwc.DownloadString(str);
                                                 if (web.Contains("<title>") && web.Contains("</title>"))
                                                 {
                                                     web = web.Substring(web.IndexOf("<title>") + 7);
                                                     web = web.Substring(0, web.IndexOf("</title>"));
                                                     web = web.Replace("\r", "").Replace("\n", "");
                                                     web = web.Replace("&lt;", "<").Replace("&gt;", ">");
                                                     web = web.Replace("&quot;", "\"").Replace("&amp;", (char)0x01 + "amp");
                                                     string webtitle = "";
                                                     bool flip = false;
                                                     for (int x = 0; x < web.Length; x++)
                                                     {
                                                         if (web[x] == '&')
                                                         {
                                                             flip = true;
                                                             continue;
                                                         }
                                                         else if (web[x] == ';')
                                                         {
                                                             if (flip)
                                                             {
                                                                 flip = false;
                                                                 continue;
                                                             }
                                                         }
                                                         else if (web[x] == ' ' && x > 0 && web[x - 1] == ' ')
                                                         {
                                                             continue;
                                                         }
                                                         if (!flip)
                                                         {
                                                             webtitle += web[x].ToString();
                                                         }
                                                     }
                                                     webtitle = webtitle.Trim().Replace((char)0x01 + "amp", "&");
                                                     Chat(chan.Name, ColorGeneral + "Title --> " + ColorHighlightMinor + webtitle.Trim(), 1);
                                                 }
                                             }
                                             catch (Exception ex)
                                             {
                                                 Logger.Output(LogType.DEBUG, "Failed to read webpage " + str + ": " + ex.ToString());
                                             }
                                         });
                                     }
                                 }
                             }
                             if (iuser == null)
                             {
                                 Logger.Output(LogType.INFO, "Null user sent message to channel!");
                                 break;
                             }
                             if (string.IsNullOrEmpty(iuser.IP))
                             {
                                 iuser.ParseMask(user);
                             }
                             CheckReminders(iuser, chan);
                             if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + chan.Name.Replace("#", "") + ".record_seen", "false").StartsWith("t"))
                             {
                                 Task.Factory.StartNew(() =>
                                 {
                                     try
                                     {
                                         iuser.SetSeen("in " + chan.Name + ", saying " + privmsg);
                                     }
                                     catch (Exception ex)
                                     {
                                         Logger.Output(LogType.ERROR, "SEEN user " + iuser.OriginalMask + ": " + ex.ToString());
                                     }
                                 });
                             }
                             if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + chan.Name.Replace("#", "") + ".has_log_page", "false").StartsWith("t"))
                             {
                                 Log(chan.Name, Utilities.FormatDate(DateTime.Now) + " <" + iuser.Name + "> " + privmsg);
                             }
                             bool cmd = false;
                             List<string> cmds = new List<string>(data);
                             cmds.RemoveAt(0);
                             string cmdlow = cmds[0].ToLower();
                             if (cmdlow.StartsWith(Name.ToLower()))
                             {
                                 Logger.Output(LogType.DEBUG, "Was pinged by " + cmdlow);
                                 cmd = true;
                                 cmds.RemoveAt(0);
                             }
                             else
                             {
                                 foreach (string prefix in Prefixes)
                                 {
                                     if (cmdlow.StartsWith(prefix.ToLower()))
                                     {
                                         cmd = true;
                                         cmds[0] = cmds[0].Substring(prefix.Length);
                                         Logger.Output(LogType.DEBUG, "Recognized " + prefix + " in " + cmds[0]);
                                         break;
                                     }
                                 }
                             }
                             if (cmd)
                             {
                                 CommandDetails details = new CommandDetails();
                                 details.Name = cmds[0];
                                 cmds.RemoveAt(0);
                                 details.Arguments = cmds;
                                 details.Channel = chan;
                                 details.User = iuser;
                                 details.Pinger = "";
                                 Logger.Output(LogType.INFO, "Try command " + details.Name + " for " + details.User.Name);
                                 if (cmds.Count > 0)
                                 {
                                     string cmdlast = cmds[cmds.Count - 1];
                                     if (cmdlast.Contains("@"))
                                     {
                                         string pingme = cmdlast.Replace("@", "");
                                         IRCUser usr = chan.GetUser(pingme);
                                         if (usr != null)
                                         {
                                             details.Pinger = usr.Name + ": ";
                                             cmds.RemoveAt(cmds.Count - 1);
                                         }
                                     }
                                 }
                                 new Task(() =>
                                 {
                                     try
                                     {
                                         TryCommand(details);
                                     }
                                     catch (Exception ex)
                                     {
                                         if (ex is ThreadAbortException)
                                         {
                                             throw ex;
                                         }
                                         Logger.Output(LogType.ERROR, "Command parsing of " + details.Name + ":: " + ex.ToString());
                                     }
                                 }).Start();
                             }
                         }
                         break;
                     case "notice": // NOTICE message
                         break;
                     default:
                         break;
                 }
             }
             catch (Exception ex)
             {
                 if (ex is SocketException)
                 {
                     throw ex;
                 }
                 Logger.Output(LogType.ERROR, "Error: " + ex.ToString());
             }
         }
     }
 }
예제 #7
0
 public IRCMessage(IRCChannel channel, IRCUser user, string message, bool action = false)
 {
     Channel = channel;
     User = user;
     Message = message;
     Action = action;
 }
 public void CheckReminders(IRCUser user, IRCChannel channel)
 {
     List<string> rem = user.GetReminders();
     if (rem.Count > 30)
     {
         Chat(channel.Name, user.Name + ": You are about to receive " + rem.Count + " messages. Please tell an admin if you are being spammed!");
     }
     if (rem.Count > 0)
     {
         Chat(channel.Name, user.Name + ": I have messages for you!");
         Task.Factory.StartNew(() =>
         {
             for (int i = 0; i < rem.Count; i++)
             {
                 Notice(user.Name, rem[i]);
                 Thread.Sleep(500);
             }
         });
     }
 }
예제 #9
0
        void MCPingCommand(CommandDetails command)
        {
            if (command.Arguments.Count <= 0)
            {
                Chat(command.Channel.Name, command.Pinger + ColorGeneral + "That command is written as: " + ColorHighlightMajor + Prefixes[0] + command.Name + " <Minecraft server IP address>");
                return;
            }
            IRCUser user = new IRCUser(command.Arguments[0]);
            string  IP   = user.Settings.ReadString("general.minecraft_server_ip", null);

            if (IP == null)
            {
                IP = command.Arguments[0];
            }
            ushort port = 0;

            if (IP.Contains(':'))
            {
                string[] dat = IP.Split(new char[] { ':' }, 2);
                IP   = dat[0];
                port = Utilities.StringToUShort(dat[1]);
            }
            if (port == 0)
            {
                try
                {
                    DnsQueryRequest  dqr  = new DnsQueryRequest();
                    DnsQueryResponse resp = dqr.Resolve("_minecraft._tcp." + IP, NsType.SRV, NsClass.ANY, ProtocolType.Tcp);
                    if (resp != null)
                    {
                        for (int i = 0; i < resp.AdditionalRRecords.Count; i++)
                        {
                            if (resp.AdditionalRRecords[i] is SrvRecord)
                            {
                                port = (ushort)((SrvRecord)resp.AdditionalRRecords[i]).Port;
                            }
                        }
                        for (int i = 0; i < resp.Answers.Length; i++)
                        {
                            if (resp.Answers[i] is SrvRecord)
                            {
                                port = (ushort)((SrvRecord)resp.Answers[i]).Port;
                            }
                        }
                    }
                    else
                    {
                        Logger.Output(LogType.DEBUG, "Null SRV record.");
                    }
                    if (port == 0)
                    {
                        port = (ushort)25565;
                    }
                }
                catch (Exception ex)
                {
                    Logger.Output(LogType.ERROR, "Pinging a SRV record for a minecraft server: " + ex.ToString());
                    port = 25565;
                }
            }
            Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                Stopwatch Timer = new Stopwatch();
                Timer.Reset();
                Timer.Start();
                sock.SendBufferSize    = 8192;
                sock.ReceiveBufferSize = 8192 * 10;
                sock.ReceiveTimeout    = 3000;
                sock.SendTimeout       = 3000;
                IAsyncResult result  = sock.BeginConnect(IP, port, null, null);
                bool         timeout = !result.AsyncWaitHandle.WaitOne(5000, true);
                if (timeout)
                {
                    throw new Exception("Connection timed out");
                }
                if (!sock.Connected)
                {
                    throw new Exception("Failed to connect");
                }
                byte[] address   = UTF8.GetBytes(IP);
                int    packlen   = 1 + 1 + 1 + address.Length + 2 + 1;
                byte[] send      = new byte[1 + packlen + 1 + 1];
                byte[] portbytes = BitConverter.GetBytes(port).Reverse().ToArray();
                send[0] = (byte)packlen;                    // packet length
                send[1] = (byte)0x00;                       // Packet ID
                send[2] = (byte)0x04;                       // Protocol Version
                send[3] = (byte)address.Length;             // Address string length
                address.CopyTo(send, 4);                    // Address string
                portbytes.CopyTo(send, address.Length + 4); // Port
                send[address.Length + 6] = (byte)0x01;      // Next state
                send[address.Length + 7] = (byte)0x01;      // Next packet length
                send[address.Length + 8] = (byte)0x00;      // Empty state request packet ~ packet ID
                sock.Send(send);
                int length = 0;
                // Packet size -> packet ID -> JSON length
                for (int x = 0; x < 2; x++)
                {
                    length = 0;
                    int j = 0;
                    while (true)
                    {
                        byte[] recd = new byte[1];
                        sock.Receive(recd, 1, SocketFlags.None);
                        int k = recd[0];
                        length |= (k & 0x7F) << j++ *7;
                        if (j > 5)
                        {
                            throw new Exception("VarInt too big");
                        }
                        if ((k & 0x80) != 128)
                        {
                            break;
                        }
                        if (Timer.ElapsedMilliseconds > 7000)
                        {
                            throw new Exception("Timeout while reading response");
                        }
                    }
                    if (x == 0)
                    {
                        byte[] resp = new byte[1];
                        sock.Receive(resp, 1, SocketFlags.None);
                    }
                }
                int    gotten   = 0;
                byte[] response = new byte[length];
                while (gotten < length)
                {
                    byte[] gotbit = new byte[length - gotten];
                    int    newgot = sock.Receive(gotbit, length - gotten, SocketFlags.None);
                    gotbit.CopyTo(response, gotten);
                    gotten += newgot;
                    if (Timer.ElapsedMilliseconds > 7000)
                    {
                        throw new Exception("Timeout while reading response");
                    }
                }
                string fullresponse = UTF8.GetString(response);
                int    ind          = fullresponse.IndexOf('{');
                if (ind < 0)
                {
                    throw new Exception("Invalid response packet - is that an actual minecraft server?");
                }
                fullresponse = fullresponse.Substring(ind);
                Dictionary <string, dynamic> dict = new JavaScriptSerializer().Deserialize <Dictionary <string, dynamic> >(fullresponse.Trim());
                string version     = dict["version"]["name"].ToString();
                string versionnum  = dict["version"]["protocol"].ToString();
                string players_on  = dict["players"]["online"].ToString();
                string players_max = dict["players"]["max"].ToString();
                string description;
                if (dict["description"] is Dictionary <String, Object> )
                {
                    description = dict["description"]["text"].ToString();
                }
                else
                {
                    description = dict["description"].ToString();
                }
                Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Server: " + IP + ":" + port.ToString() + ", MOTD: '"
                     + Utilities.mctoirc(description) + ColorGeneral + "', players: " + players_on + "/" + players_max + ", version: " + Utilities.mctoirc(version));
            }
            catch (Exception ex)
            {
                Logger.Output(LogType.DEBUG, "Pinging minecraft server: " + ex.ToString());
                Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Couldn't ping server: internal exception: " + ex.Message);
            }
            finally
            {
                sock.Close();
            }
        }
예제 #10
0
 public void ReadLogs()
 {
     string[] logsets = Directory.GetFileSystemEntries(Environment.CurrentDirectory + "/data/logs");
     foreach (string channel in logsets)
     {
         Logger.Output(LogType.DEBUG, "Found channel: " + channel);
         string[] years = Directory.GetFileSystemEntries(channel);
         foreach (string str_year in years)
         {
             Logger.Output(LogType.DEBUG, "Found year: " + str_year);
             string[] months = Directory.GetFileSystemEntries(str_year);
             foreach (string str_month in months)
             {
                 Logger.Output(LogType.DEBUG, "Found month: " + str_month);
                 string[] days = Directory.GetFileSystemEntries(str_month);
                 foreach (string str_day in days)
                 {
                     try
                     {
                         Logger.Output(LogType.DEBUG, "Found day: " + str_day);
                         string file = File.ReadAllText(str_day);
                         string[] file_split = file.Split('\n');
                         bool reading = false;
                         for (int i = 0; i < file_split.Length; i++)
                         {
                             if (!reading && file_split[i].Trim() == "")
                             {
                                 reading = true;
                             }
                             else if (reading)
                             {
                                 string data = file_split[i];
                                 bool is_old = data.StartsWith(C_S_COLOR + "");
                                 for (int x = 0; x < 16; x++)
                                 {
                                     data = data.Replace(C_S_COLOR + Utilities.FormatNumber(x), "");
                                 }
                                 string[] splits = data.Replace(" AM", "").Replace(" PM", "").Split(new char[] { ' ' }, 4);
                                 if (splits.Length == 4)
                                 {
                                     string[] date = splits[0].Split('/');
                                     string[] time = splits[1].Split(':');
                                     if (time.Length != 3)
                                     {
                                         Logger.Output(LogType.DEBUG, "Found " + splits[1] + " instead of a 3-length timestamp");
                                     }
                                     else if (splits[2].StartsWith("<") && splits[2].EndsWith(">") && !splits[3].StartsWith("*"))
                                     {
                                         string name = splits[2].Substring(1, splits[2].Length - 2);
                                         string message = splits[3];
                                         IRCUser user = new IRCUser(name);
                                         string sy = str_year.Substring(str_year.LastIndexOf('\\') + 1).Replace(".log", "");
                                         sy = sy.Substring(sy.LastIndexOf('/') + 1);
                                         string sm = str_month.Substring(str_month.LastIndexOf('\\') + 1).Replace(".log", "");
                                         sm = sm.Substring(sm.LastIndexOf('/') + 1);
                                         string sd = str_day.Substring(str_day.LastIndexOf('\\') + 1).Replace(".log", "");
                                         sd = sd.Substring(sd.LastIndexOf('/') + 1);
                                         int y = Utilities.StringToInt(sy);
                                         int m = Utilities.StringToInt(sm);
                                         int d = Utilities.StringToInt(sd);
                                         DateTime dt = new DateTime(y, m, d, Utilities.StringToInt(time[0]), Utilities.StringToInt(time[1]), Utilities.StringToInt(time[2]));
                                         string ch = channel.Substring(channel.LastIndexOf('\\') + 1);
                                         ch = ch.Substring(ch.LastIndexOf('/') + 1);
                                         user.SetSeen("in #" + ch + ", saying " + message, dt);
                                     }
                                     else if (splits[2] == "*" && splits[3].EndsWith(") joined."))
                                     {
                                         int ind = splits[3].IndexOf(' ');
                                         string name = splits[3].Substring(0, ind);
                                         string ip = splits[3].Substring(ind + 1, ((splits[3].Length - ") joined.".Length) - ind) - 1);
                                         SeenUser(name, ip, false);
                                     }
                                 }
                             }
                         }
                     }
                     catch (Exception ex)
                     {
                         Logger.Output(LogType.ERROR, "Failed to read " + str_year + "/" + str_month + "/" + str_day + ": " + ex.ToString());
                     }
                 }
             }
         }
     }
     saveSeenList();
     Chat("#monkeybot", ColorGeneral + "Finished reading log files.");
 }