void OLDdScriptCommand(CommandDetails command) { string outp = scriptcommand_base(command); if (outp == null) { return; } Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Scanning " + ColorHighlightMajor + (Utilities.CountChar(outp, '\n') + 1) + ColorGeneral + " lines..."); try { YamlStream ys = new YamlStream(); ys.Load(new StringReader(outp)); int nodes = 0; for (int i = 0; i < ys.Documents.Count; i++) { nodes += ys.Documents[i].AllNodes.ToArray().Length; } } catch (Exception ex) { Chat(command.Channel.Name, ColorGeneral + "Error in your YAML: " + ColorHighlightMajor + ex.Message); } List<string> warnings = dsCheck(outp); Chat(command.Channel.Name, ColorGeneral + "Found " + ColorHighlightMajor + warnings.Count + ColorGeneral + " potential issues."); for (int i = 0; i < warnings.Count && i < 8; i++) { Chat(command.Channel.Name, ColorHighlightMinor + "- " + i + ") " + warnings[i]); } }
void dScriptCommand(CommandDetails command) { string outp = scriptcommand_base(command); if (outp == null) { return; } Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Scanning " + ColorHighlightMajor + (Utilities.CountChar(outp, '\n') + 1) + ColorGeneral + " lines..."); int start = 0; if (command.Arguments.Count >= 2) { start = Math.Abs(Utilities.StringToInt(command.Arguments[1])); } try { List<string> errors = dScriptCheck(outp); Chat(command.Channel.Name, ColorGeneral + "Found " + ColorHighlightMajor + errors.Count + ColorGeneral + " potential issues."); int i = start; while (i < start + 8 && i < errors.Count) { Chat(command.Channel.Name, ColorHighlightMinor + "- " + (i + 1) + ") " + errors[i]); i++; } if (i < errors.Count) { Chat(command.Channel.Name, ColorGeneral + "And " + (errors.Count - i) + " more... type " + ColorHighlightMajor + Prefixes[0] + command.Name + " <link> " + i + ColorGeneral + " to see the rest."); } } catch (Exception ex) { Logger.Output(LogType.ERROR, ex.ToString()); Chat(command.Channel.Name, ColorGeneral + "Internal error processing script: " + ex.GetType().ToString() + ": " + ex.Message); } }
void IPStalkCommand(CommandDetails command) { if (IPHistory == null) { IPHistory = new YAMLConfiguration(File.ReadAllText("data/iphistory.yml")); } if (command.Arguments.Count < 1) { return; } List<string> data = IPHistory.ReadStringList(getippath(command.Arguments[0])); if (data == null || data.Count == 0) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Nope, nothing for " + getippath(command.Arguments[0])); return; } StringBuilder sb = new StringBuilder(); foreach (string dat in data) { sb.Append(dat).Append(", "); } string dater = sb.ToString(); dater = dater.Substring(0, dater.Length - 2); Chat(command.Channel.Name, command.Pinger + ColorGeneral + "I've seen that IP as: " + dater, 3); }
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."); }
void GitHubCommand(CommandDetails command) { if (command.Arguments.Count < 2 || command.Arguments[0].ToLower() != "info") { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "That command is written " + ColorHighlightMajor + Prefixes[0] + command.Name + " [info <repo>]"); return; } string name = command.Arguments[1].ToLower(); if (GitHub.Repositories.ContainsKey(name)) { Repository repo = GitHub.Repositories[name]; Chat(command.Channel.Name, command.Pinger + ColorGeneral + repo.HtmlUrl + " (" + repo.FullName + "): Issues(" + repo.HasIssues + ")"); } else { int minDist = int.MaxValue; string closest = ""; if (name.Contains('/')) { foreach (string repoName in GitHub.Repositories.Keys) { int distance = Utilities.GetLevenshteinDistance(name, repoName); if (minDist > distance) { minDist = distance; closest = repoName; } } } else { foreach (Repository repository in GitHub.Repositories.Values) { int distance = Utilities.GetLevenshteinDistance(name, repository.Name.ToLower()); if (minDist > distance) { minDist = distance; closest = repository.FullName; } } } Repository repo = GitHub.Repositories[closest.ToLower()]; Chat(command.Channel.Name, command.Pinger + ColorGeneral + repo.HtmlUrl + " (" + repo.FullName + "): Issues(" + repo.HasIssues + ")"); } }
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."); }
string scriptcommand_base(CommandDetails command) { if (command.Arguments.Count < 1) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "That command is written as: " + ColorHighlightMajor + Prefixes[0] + command.Name + " <link to a" + ColorLink + " http://mcmonkey.org/haste " + ColorGeneral + "paste>"); return null; } string cmd = command.Arguments[0]; if (!cmd.StartsWith("http://one.denizenscript.com/haste/") && !cmd.StartsWith("http://one.denizenscript.com/paste/") && !cmd.StartsWith("https://one.denizenscript.com/haste/") && !cmd.StartsWith("https://one.denizenscript.com/paste/")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "I am only trained to read pastes from" + ColorLink + " http://one.denizenscript.com/haste"); return null; } if (!cmd.EndsWith(".txt")) { cmd = cmd + ".txt"; } if (cmd.StartsWith("https://")) { cmd = "http://" + cmd.Substring("https://".Length); } string outp = null; try { LowTimeoutWebclient ltwc = new LowTimeoutWebclient(); outp = ltwc.DownloadString(cmd); } catch (Exception) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Failed to read that link - is the paste too long, or is there an error with the site?"); return null; } if (outp == null) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Failed to read that link - is the paste too long, or is there an error with the site?"); } return outp; }
void MyIPCommand(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; } command.User.Settings.Set("general.minecraft_server_ip", command.Arguments[0]); command.User.Save(); Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Recorded your server IP. Use " + ColorHighlightMajor + Prefixes[0] + "mcping <name> " + ColorGeneral + "to ping a player's server!"); }
/// <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("<", "<").Replace(">", ">"); web = web.Replace(""", "\"").Replace("&", (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()); } } } }
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(); } }
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 ListdObject <T>(CommandDetails command, List <T> cobjects, List <T> xobjects, List <T> bobjects, string objecttype) where T : dObject { StringBuilder sb = new StringBuilder(); sb.Append("Core " + objecttype + "s: "); foreach (T obj in cobjects) { sb.Append(obj.BasicName).Append(' '); } int limit = Chat(command.Channel.Name, command.Pinger + ColorGeneral + sb.ToString(), 7); sb = new StringBuilder(); sb.Append("Bukkit " + objecttype + "s: "); foreach (T obj in bobjects) { sb.Append(obj.BasicName).Append(' '); } limit = Chat(command.Channel.Name, command.Pinger + ColorGeneral + sb.ToString(), limit); sb = new StringBuilder(); sb.Append("External " + objecttype + "s: "); foreach (T obj in xobjects) { sb.Append(obj.BasicName).Append(' '); } limit = Chat(command.Channel.Name, command.Pinger + ColorGeneral + sb.ToString(), limit); }
void MojangStatusCommand(CommandDetails command) { WebRequest request = WebRequest.Create(STATUS_API); using (WebResponse response = request.GetResponse()) { using (Stream stream = response.GetResponseStream()) { List <Dictionary <string, string> > status = Json.Deserialize <List <Dictionary <string, string> > >(new StreamReader(stream, Encoding.UTF8).ReadToEnd()); Dictionary <string, string> allStatus = new Dictionary <string, string>(); foreach (Dictionary <string, string> dictionary in status) { foreach (string key in dictionary.Keys) { allStatus.Add(key, dictionary[key]); } } Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Website: " + TranslateStatus(allStatus[WEBSITE]) + "; " + "Session: " + TranslateStatus(allStatus[SESSION]) + "; " + "Account: " + TranslateStatus(allStatus[ACCOUNT]) + "; " + "Auth: " + TranslateStatus(allStatus[AUTH]) + "; " + "Skins: " + TranslateStatus(allStatus[SKINS]) + "; " + "Auth Server: " + TranslateStatus(allStatus[AUTH_SERVER]) + "; " + "Session Server: " + TranslateStatus(allStatus[SESSION_SERVER]) + "; " + "API: " + TranslateStatus(allStatus[API]) + "; " + "Textures: " + TranslateStatus(allStatus[TEXTURES])); } } }
void CmdCommand(CommandDetails command) { if (!MetaCommandIntro(command, "command", "cmds", AllMeta.Commands, CoreMeta.Commands, ExternalMeta.Commands, BukkitMeta.Commands, true, true)) { return; } }
void MechCommand(CommandDetails command) { if (!MetaCommandIntro(command, "mechanism", "mecs", AllMeta.Mechanisms, CoreMeta.Mechanisms, ExternalMeta.Mechanisms, BukkitMeta.Mechanisms, true, false)) { return; } }
void IPStalkCommand(CommandDetails command) { if (IPHistory == null) { IPHistory = new YAMLConfiguration(File.ReadAllText("data/iphistory.yml")); } if (command.Arguments.Count < 1) { return; } List <string> data = IPHistory.ReadStringList(getippath(command.Arguments[0])); if (data == null || data.Count == 0) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Nope, nothing for " + getippath(command.Arguments[0])); return; } StringBuilder sb = new StringBuilder(); foreach (string dat in data) { sb.Append(dat).Append(", "); } string dater = sb.ToString(); dater = dater.Substring(0, dater.Length - 2); Chat(command.Channel.Name, command.Pinger + ColorGeneral + "I've seen that IP as: " + dater, 3); }
void TutCommand(CommandDetails command) { if (!MetaCommandIntro(command, "tutorial", "tuts", AllMeta.Tutorials, CoreMeta.Tutorials, ExternalMeta.Tutorials, BukkitMeta.Tutorials, true, true)) { return; } }
void LangCommand(CommandDetails command) { if (!MetaCommandIntro(command, "language explanation", "lngs", AllMeta.Languages, CoreMeta.Languages, ExternalMeta.Languages, BukkitMeta.Languages, true, true)) { return; } }
void OLDdScriptCommand(CommandDetails command) { string outp = scriptcommand_base(command); if (outp == null) { return; } Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Scanning " + ColorHighlightMajor + (Utilities.CountChar(outp, '\n') + 1) + ColorGeneral + " lines..."); try { YamlStream ys = new YamlStream(); ys.Load(new StringReader(outp)); int nodes = 0; for (int i = 0; i < ys.Documents.Count; i++) { nodes += ys.Documents[i].AllNodes.ToArray().Length; } } catch (Exception ex) { Chat(command.Channel.Name, ColorGeneral + "Error in your YAML: " + ColorHighlightMajor + ex.Message); } List <string> warnings = dsCheck(outp); Chat(command.Channel.Name, ColorGeneral + "Found " + ColorHighlightMajor + warnings.Count + ColorGeneral + " potential issues."); for (int i = 0; i < warnings.Count && i < 8; i++) { Chat(command.Channel.Name, ColorHighlightMinor + "- " + i + ") " + warnings[i]); } }
public virtual void ShowToChannel(dIRCBot bot, CommandDetails command) { if (!string.IsNullOrEmpty(Group)) { bot.Chat(command.Channel.Name, bot.ColorGeneral + ":: In group: " + bot.ColorHighlightMajor + Group, 1); } if (!string.IsNullOrEmpty(Plugin)) { bot.Chat(command.Channel.Name, bot.ColorGeneral + ":: Requires the plugin(s): " + bot.ColorHighlightMajor + Plugin, 1); } if (!string.IsNullOrEmpty(Warning)) { bot.Chat(command.Channel.Name, bot.ColorGeneral + ":: WARNING: " + bot.ColorHighlightMajor + Warning, 2); } if (!string.IsNullOrEmpty(Deprecated)) { bot.Chat(command.Channel.Name, bot.ColorGeneral + ":: DEPRECATED: " + bot.ColorHighlightMajor + Deprecated, 2); } if (!string.IsNullOrEmpty(Video)) { bot.Chat(command.Channel.Name, bot.ColorGeneral + ":: Video on the subject:" + bot.ColorLink + " " + Video, 1); } if (command.Arguments.Count >= 2 && command.Arguments[1].ToLower().StartsWith("f")) { bot.Chat(command.Channel.Name, bot.ColorGeneral + ":: Found in internal file: " + FileName, 2); } }
void TagCommand(CommandDetails command) { if (!MetaCommandIntro(command, "tag", "tags", AllMeta.Tags, CoreMeta.Tags, ExternalMeta.Tags, BukkitMeta.Tags, true, false)) { return; } // TODO: Advanced tag search }
void FireCommand(CommandDetails command) { if (command.Arguments.Count < 1) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "That command is written as: " + ColorHighlightMajor + Prefixes[0] + command.Name + " <target>"); return; } lock (LaserLock) { if (!LasersCharged) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "PEW! PEW PEW! " + ColorHighlightMajor + command.User.Name + ColorGeneral + " fires at themself for " + ColorHighlightMajor + "0" + ColorGeneral + " damage!"); return; } FireTime.Value++; string target = command.Arguments[0]; if (command.Channel.GetUser(target) == null) { target = command.Channel.Users[Utilities.random.Next(command.Channel.Users.Count)].Name; } LasersCharged = false; double lpower = LaserPower * (Math.Min((DateTime.Now.Subtract(LasersChargedAt).TotalMinutes), 5) - 0.5); string hit = LaserFood[Utilities.random.Next(LaserFood.Count)].Target; if (lpower <= 0) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Poo! " + ColorHighlightMajor + hit + ColorGeneral + " is consumed!"); Chat(command.Channel.Name, ColorGeneral + "Wow! " + ColorHighlightMajor + command.User.Name + ColorGeneral + " just caught fire for some reason!"); } else if (lpower <= 5 && Utilities.random.NextDouble() <= 0.5) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Pew! " + ColorHighlightMajor + hit + ColorGeneral + " is consumed!"); Chat(command.Channel.Name, ColorGeneral + "Wow! " + ColorHighlightMajor + command.Channel.Users[Utilities.random.Next(command.Channel.Users.Count)].Name + ColorGeneral + " is hit by a small but painful beam!"); } else if (lpower <= 5) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Pew! " + ColorHighlightMajor + hit + ColorGeneral + " is consumed!"); Chat(command.Channel.Name, ColorGeneral + "Wow! " + ColorHighlightMajor + target + ColorGeneral + " is hit by a small but painful beam!"); } else if (lpower <= 10) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Pew! Pew Pew! " + ColorHighlightMajor + hit + ColorGeneral + " is consumed!"); Chat(command.Channel.Name, ColorGeneral + "Wow! " + ColorHighlightMajor + target + ColorGeneral + " is hit by a deadly beam!"); } else { string pew = ColorGeneral + "P" + ColorHighlightMajor + "E" + ColorHighlightMinor + "W" + ColorGeneral + "! "; string pew2 = ColorHighlightMajor + "P" + ColorHighlightMinor + "E" + ColorGeneral + "W" + ColorHighlightMajor + "! "; string pew3 = ColorHighlightMinor + "P" + ColorGeneral + "E" + ColorHighlightMajor + "W" + ColorHighlightMinor + "! "; Chat(command.Channel.Name, command.Pinger + ColorGeneral + pew + pew2 + pew3 + ColorHighlightMajor + hit + ColorGeneral + " is consumed!"); Chat(command.Channel.Name, ColorGeneral + "Wow! " + ColorHighlightMajor + target + ColorGeneral + " is entirely obliterated! Hit for " + Math.Round(lpower * 1000) + " damage!"); } } }
public override void ShowToChannel(dIRCBot bot, CommandDetails command) { bot.Chat(command.Channel.Name, command.Pinger + bot.ColorGeneral + "Found: " + bot.ColorHighlightMajor + Name + ": " + Short, 2); bot.Chat(command.Channel.Name, bot.ColorGeneral + "Syntax: " + bot.ColorHighlightMajor + Info, 2); // TODO Highlight correctly! string arg = command.Arguments.Count >= 2 ? command.Arguments[1].ToLower() : ""; if (arg.StartsWith("a")) { bot.Chat(command.Channel.Name, bot.ColorGeneral + "Author: " + bot.ColorHighlightMajor + Author, 1); } if (arg.StartsWith("d")) { if (bot.Chat(command.Channel.Name, bot.ColorGeneral + "Description: " + bot.ColorHighlightMajor + Description, 3) == 0) { bot.Chat(command.Channel.Name, bot.ColorGeneral + "And more..." + bot.ColorLink + " http://mcmonkey.org/denizen/cmds" + Name); } } if (arg.StartsWith("s")) { bot.Chat(command.Channel.Name, bot.ColorGeneral + "Stability: " + bot.ColorHighlightMajor + Stable, 1); } if (arg.StartsWith("r")) { bot.Chat(command.Channel.Name, bot.ColorGeneral + "Required Arguments: " + bot.ColorHighlightMajor + Reqs, 1); } if (arg.StartsWith("t")) { int limit = 5; foreach (string str in Tags) { // TODO: Dig up tag help short description limit = bot.Chat(command.Channel.Name, bot.ColorGeneral + "Tag: " + str, limit); } if (limit == 0) { bot.Chat(command.Channel.Name, bot.ColorGeneral + "And more..." + bot.ColorLink + " http://mcmonkey.org/denizen/cmds" + Name); } } if (arg.StartsWith("u")) { int limit = 5; foreach (string str in Usage) { foreach (string use in str.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)) { limit = bot.Chat(command.Channel.Name, bot.ColorGeneral + "Usage: " + use, limit); } } if (limit == 0) { bot.Chat(command.Channel.Name, bot.ColorGeneral + "And more..." + bot.ColorLink + " http://mcmonkey.org/denizen/cmds" + Name); } } base.ShowToChannel(bot, command); }
void RateLimitCommand(CommandDetails command) { GitHub.FetchRateLimit(); Notice(command.User.Name, ColorGeneral + "Max rate limit: " + GitHub.RateLimit.Limit); Notice(command.User.Name, ColorGeneral + "Remaining rate limit: " + GitHub.RateLimit.Remaining); TimeSpan span = GitHub.RateLimit.NextReset.Subtract(DateTime.UtcNow); int minutes = span.Minutes; Notice(command.User.Name, ColorGeneral + "Next reset: " + (minutes > 0 ? minutes + " minutes, " : "") + span.Seconds + " seconds"); }
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); }
string scriptcommand_base(CommandDetails command) { if (command.Arguments.Count < 1) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "That command is written as: " + ColorHighlightMajor + Prefixes[0] + command.Name + " <link to a" + ColorLink + " http://mcmonkey.org/haste " + ColorGeneral + "paste>"); return(null); } string cmd = command.Arguments[0]; if (!cmd.StartsWith("http://one.denizenscript.com/haste/") && !cmd.StartsWith("http://one.denizenscript.com/paste/") && !cmd.StartsWith("https://one.denizenscript.com/haste/") && !cmd.StartsWith("https://one.denizenscript.com/paste/")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "I am only trained to read pastes from" + ColorLink + " http://one.denizenscript.com/haste"); return(null); } if (!cmd.EndsWith(".txt")) { cmd = cmd + ".txt"; } if (cmd.StartsWith("https://")) { cmd = "http://" + cmd.Substring("https://".Length); } string outp = null; try { LowTimeoutWebclient ltwc = new LowTimeoutWebclient(); outp = ltwc.DownloadString(cmd); } catch (Exception) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Failed to read that link - is the paste too long, or is there an error with the site?"); return(null); } if (outp == null) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Failed to read that link - is the paste too long, or is there an error with the site?"); } return(outp); }
void dScriptCommand(CommandDetails command) { string outp = scriptcommand_base(command); if (outp == null) { return; } Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Scanning " + ColorHighlightMajor + (Utilities.CountChar(outp, '\n') + 1) + ColorGeneral + " lines..."); int start = 0; if (command.Arguments.Count >= 2) { start = Math.Abs(Utilities.StringToInt(command.Arguments[1])); } try { List <string> errors = dScriptCheck(outp); Chat(command.Channel.Name, ColorGeneral + "Found " + ColorHighlightMajor + errors.Count + ColorGeneral + " potential issues."); int i = start; while (i < start + 8 && i < errors.Count) { Chat(command.Channel.Name, ColorHighlightMinor + "- " + (i + 1) + ") " + errors[i]); i++; } if (i < errors.Count) { Chat(command.Channel.Name, ColorGeneral + "And " + (errors.Count - i) + " more... type " + ColorHighlightMajor + Prefixes[0] + command.Name + " <link> " + i + ColorGeneral + " to see the rest."); } } catch (Exception ex) { Logger.Output(LogType.ERROR, ex.ToString()); Chat(command.Channel.Name, ColorGeneral + "Internal error processing script: " + ex.GetType().ToString() + ": " + ex.Message); } }
void YAMLCommand(CommandDetails command) { string outp = scriptcommand_base(command); if (outp == null) { return; } try { YamlStream ys = new YamlStream(); ys.Load(new StringReader(outp)); int nodes = 0; for (int i = 0; i < ys.Documents.Count; i++) { nodes += ys.Documents[i].AllNodes.ToArray().Length; } Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Successfully read a YAML file with " + ColorHighlightMajor + nodes + ColorGeneral + " nodes!"); } catch (Exception ex) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Error in your YAML: " + ColorHighlightMajor + ex.Message); } }
void BotsnackCommand(CommandDetails command) { if (command.Arguments.Count < 1) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "That command is written " + ColorHighlightMajor + Prefixes[0] + command.Name + " <food item>"); return; } BotSnack snack = new BotSnack(); lock (LaserLock) { int givenSnacks = 0; string ulow = command.User.Name.ToLower(); for (int i = 0; i < RecentSnacks.Count; i++) { if (RecentSnacks[i].Giver == ulow) { givenSnacks++; } } if (givenSnacks >= 3) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "You trying to fatten me up? Cook me for a meal? HUH? I ain't conforming to your AGENDA! D:<"); return; } if (RecentSnacks.Count > 30) { RecentSnacks.RemoveAt(0); } RecentSnacks.Add(snack); } snack.Giver = command.User.Name.ToLower(); snack.TimeGiven = DateTime.Now; snack.Target = command.Arguments[0]; double delic; if (TasteForSnacks.TryGetValue(snack.Target.ToLower(), out delic)) { snack.Deliciousness = delic; } else { snack.Deliciousness = Utilities.random.NextDouble() * 10 - 3; TasteForSnacks.Add(snack.Target.ToLower(), snack.Deliciousness); } if (TasteForSnacks.Count > 500) { TasteForSnacks.Remove(TasteForSnacks.Keys.First()); } if (snack.Deliciousness <= 0) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Gross, I hate the taste of " + ColorHighlightMajor + snack.Target); } else if (snack.Deliciousness <= 3) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Thanks, I can't complain about a little " + ColorHighlightMajor + snack.Target); } else if (snack.Deliciousness <= 6) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Thanks! I really enjoyed that " + ColorHighlightMajor + snack.Target); } else { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "WOW THAT " + ColorHighlightMajor + snack.Target + ColorGeneral + " WAS THE BEST SNACK I'VE EVER HAD!"); } }
public void TryCommand(CommandDetails command) { switch (command.Name.ToLower()) { case "hello": case "allo": case "ello": case "hi": case "ohai": case "helo": case "halo": case "hai": case "howdy": case "website": case "web": case "site": case "link": case "url": case "greet": { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Hello! I am a bot designed to assist with Denizen Scripting! I have a website too, at" + ColorLink + " http://mcmonkey.org/logs " + ColorGeneral + "!"); } break; case "delay": { int delay = Utilities.random.Next(9) + 1; Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Delaying for " + ColorHighlightMajor + delay + ColorGeneral + " seconds!"); Thread.Sleep(1000 * delay); Chat(command.Channel.Name, ColorGeneral + "Done delaying for " + ColorHighlightMajor + delay); } break; case "regex": { // TODO } break; case "regexvalue": { // TODO } break; case "bs": case "botsnack": case "snack": { BotsnackCommand(command); } break; case "lasers": case "lzrbms": case "laserbeams": { LaserbeamsCommand(command); } break; case "fire": case "fiyar": case "fiar": { FireCommand(command); } break; case "seen": { SeenCommand(command); } break; case "recent": case "recentseen": case "seenrecently": case "recently": case "recentlyseen": { RecentCommand(command); } break; case "msg": case "send": case "tell": case "mail": case "message": { MessageCommand(command); } break; case "remind": case "rem": case "remember": case "tellmelater": case "delayedmsg": case "delayedmessage": { ReminderCommand(command); } break; case "ts": case "ts3": case "teamspeak": case "teamspeak3": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + "Denizen users are all welcome to voice chat together at the TeamSpeak3 server ts3.mcmonkey.org in the channel 'Denizen'!"); } else { Chat(command.Channel.Name, command.Pinger + "All bot users are all welcome to voice chat together at the TeamSpeak3 server ts3.mcmonkey.org!"); } break; case "please": case "pls": case "plz": case "plox": case "pl0x": case "sir": case "sir,": case "sir:": case "do": case "say": { if (command.Arguments.Count > 0) { CommandDetails cmddet = new CommandDetails(); cmddet.Name = command.Arguments[0].ToLower(); cmddet.Arguments = new List<string>(command.Arguments); cmddet.Arguments.RemoveAt(0); cmddet.Pinger = command.Pinger; cmddet.User = command.User; cmddet.Channel = command.Channel; TryCommand(cmddet); } } break; case "command": case "cmd": case "commands": case "cmds": case "c": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { CmdCommand(command); } break; case "evt": case "evts": case "event": case "events": case "e": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { // TODO } break; case "mec": case "mecs": case "mech": case "mechs": case "mechanism": case "mechanisms": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { MechCommand(command); } break; case "language": case "languages": case "info": case "infos": case "explanation": case "explanations": case "lng": case "lngs": case "text": case "texts": case "helps": case "lang": case "langs": case "lingo": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { LangCommand(command); } break; case "tutorial": case "tut": case "tutorials": case "tuts": case "example": case "examples": case "ex": case "exs": case "exam": case "exams": case "examp": case "examps": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { TutCommand(command); } break; case "tag": case "tags": case "t": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { TagCommand(command); } break; case "vid": case "vids": case "v": case "video": case "videos": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { // TODO } break; case "act": case "acts": case "action": case "actions": case "a": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { // TODO } break; case "item": case "items": case "itm": case "itms": case "mat": case "material": case "mats": case "materials": case "i": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { // TODO } break; case "m": case "math": case "maths": case "mathematic": case "mathematics": case "calculate": case "calc": { if (command.Arguments.Count > 0) { string input = Utilities.Concat(command.Arguments); string err; List<MathOperation> calc = MonkeyMath.Parse(input, out err); if (err != null) { Chat(command.Channel.Name, ColorGeneral + "Failed: " + err); return; } if (!MonkeyMath.Verify(calc, MonkeyMath.BaseFunctions, out err)) { Chat(command.Channel.Name, ColorGeneral + "Failed to verify: " + err); return; } Chat(command.Channel.Name, ColorGeneral + input + " = " + MonkeyMath.Calculate(calc, MonkeyMath.BaseFunctions)); } } break; case "wolfram": case "advancedmath": case "wolframalpha": case "alpha": case "wa": { if (command.Arguments.Count > 0) { WolframAlpha.QueryResult output = WolframAlpha.Query(string.Join(" ", command.Arguments), command.User.IP); string result = output.Result; if (output.Error || !output.Success || result == null) { if (output.Suggestion != null) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Sorry, I don't know the definition of that. Did you mean '" + output.Suggestion + "'?"); } else { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "There was an error while parsing that statement."); } } else { if (output.SpellCheck != null) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + output.SpellCheck); } Chat(command.Channel.Name, command.Pinger + ColorGeneral + output.Input + " = " + output.Result); } } } break; case "g": case "google": case "ggl": { if (command.Arguments.Count > 0) { GoogleResponse response = GoogleSearch.Search(Utilities.Concat(command.Arguments)); if (response == null) { Chat(command.Channel.Name, command.Pinger + ColorHighlightMajor + "Error! Response not found."); } else if (response.items.Count == 0) { Chat(command.Channel.Name, command.Pinger + ColorHighlightMinor + "No search results found."); } else { GoogleSearchInfo searchInfo = response.searchInformation; List<GoogleResponseItem> items = response.items; GoogleResponseItem result = items[0]; String snippet = result.snippet.Replace("\\n", ""); Chat(command.Channel.Name, command.Pinger + ColorGeneral + "[Result found in " + searchInfo.formattedSearchTime + "] " + snippet + " -- " + result.link); } } } break; case "u": case "urban": { if (command.Arguments.Count > 0) { UrbanResponse response = UrbanDictionary.Search(Utilities.Concat(command.Arguments)); if (response == null) { Chat(command.Channel.Name, command.Pinger + ColorHighlightMajor + "Error! Response not found."); } else if (response.result_type == "no_results" || response.list.Count == 0) { Chat(command.Channel.Name, command.Pinger + ColorHighlightMinor + "No search results found."); } else { int num = Utilities.random.Next(response.list.Count); UrbanDefinition definition = response.list[num]; string defString = definition.definition.Replace("\n\n", " ").Replace("\n", " ").Replace("\r", ""); string exampleString = definition.example.Replace("\n\n", " ").Replace("\n", " ").Replace("\r", ""); Chat(command.Channel.Name, command.Pinger + ColorGeneral + definition.word + " (" + definition.defid + "): " + defString); Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Example: " + exampleString); } } } break; case "rate": case "ratelimit": { RateLimitCommand(command); } break; case "git": case "github": { GitHubCommand(command); } break; case "repository": case "repo": case "repos": case "repositories": case "scripts": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Check out scripts made by other users -" + ColorLink + " " + "http://mcmonkey.org/denizen/repo/list"); Chat(command.Channel.Name, ColorGeneral + "Old repo -" + ColorLink + " http://bit.ly/19lCpfV"); } break; case "issue": case "issues": case "iss": { if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Post Denizen issues here:" + ColorLink + " https://github.com/DenizenScript/Denizen-For-Bukkit/issues"); } if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".citizens_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Post Citizens issues here:" + ColorLink + " https://github.com/CitizensDev/Citizens2/issues"); } } break; case "enchant": case "enchantment": case "enchants": case "enchantments": case "ench": case "enches": case "enchs": { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "A list of all valid bukkit enchantments is available here:" + ColorLink + " https://hub.spigotmc.org/javadocs/spigot/org/bukkit/enchantments/Enchantment.html"); Chat(command.Channel.Name, ColorGeneral + "They do not follow the same naming conventions as they do in game, so be careful."); } break; case "entity": case "entitys": case "entities": case "entitie": case "entitytype": case "entitytypes": { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "A list of all Entity types is available here:" + ColorLink + " http://bit.ly/1sos3dT"); } break; case "thank": case "thanks": case "thanks!": case "thanks.": case "thankyou!": case "thankyou.": case "thankyou": case "donate": case "don": { Chat(command.Channel.Name, ColorGeneral + "Donate to fullwall (Head of the Citizens project) at:" + ColorLink + " http://bit.ly/19UVDtp"); Chat(command.Channel.Name, ColorGeneral + "Donate to mcmonkey (Current head of Denizen development) at:" + ColorLink + " http://mcmonkey.org/donate"); Chat(command.Channel.Name, ColorGeneral + "Donate to Morphan1 (Denizen developer and head of Depenizen) at:" + ColorLink + " http://morphanone.com/donate"); } break; case "potion": case "potions": case "effect": case "effects": { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "A list of all Bukkit Potion Effects is available here:" + ColorLink + " http://bit.ly/1LnDvvv"); } break; case "test": case "tet": case "tes": case "tst": case "?": { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "All systems functional!"); } break; case "help": case "halp": case "hlp": case "hep": case "hap": { string prefix = Prefixes[0]; if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Hello, I am DenizenBot, a bot dedicated to assisting you in maximizing your Denizen scripting potential." + " If you're new to Denizen, type " + ColorHighlightMinor + prefix + "getstarted"); Chat(command.Channel.Name, ColorGeneral + "To check your script for errors, type " + ColorHighlightMinor + prefix + "script"); Chat(command.Channel.Name, ColorGeneral + "Available meta search commands: " + ColorHighlightMinor + prefix + "cmds " + prefix + "tags " + prefix + "events " + prefix + "requirements " + prefix + "languages " + prefix + "tutorials " + prefix + "mechanisms " + prefix + "actions " + prefix + "items " + prefix + "skins " + prefix + "search " + prefix + "videos"); Chat(command.Channel.Name, ColorGeneral + "Available informational commands: " + ColorHighlightMinor + prefix + "repo " + prefix + "enchantments " + prefix + "entities " + prefix + "anchors " + prefix + "tags " + prefix + "potions " + prefix + "assignments " + prefix + "update " + prefix + "newconfig " + prefix + "wiki " + prefix + "sounds " + prefix + "handbook " + prefix + "debug " + prefix + "mcve "); } Chat(command.Channel.Name, ColorGeneral + "Available interactive commands: " + ColorHighlightMinor + prefix + "seen " + prefix + "message " + prefix + "hello " + prefix + "showoff " + prefix + "math " + prefix + "mcping " + prefix + "help " + prefix + "paste " + prefix + "logs " + prefix + "yaml " + prefix + "yes " + prefix + "reload " + prefix + "voice " + prefix + "quote " + prefix + "savelog " + prefix + "botsnack " + prefix + "regex " + prefix + "regexvalue "); } break; case "skins": case "skin": case "skinssearch": case "skinsearch": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".citizens_meta", "false").StartsWith("t")) { if (command.Arguments.Count > 1) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "A list of matching skins for your NPCs is at:" + ColorLink + " " + "http://mcmonkey.org/denizen/skin/" + command.Arguments[1]); } else { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Your can search for skins for your NPCs at:" + ColorLink + " " + "http://mcmonkey.org/denizen/skin"); } } break; case "hastebin": case "haste": case "hastee": case "hastie": case "hastey": case "hastes": case "hastebins": case "pastebin": case "pastebins": case "pastey": case "pastests": case "pastie": case "pastee": case "paste": { // TODO } break; case "debug": case "db": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Need help with a script issue or server error? " + "- Help us help you by pasting your script to" + ColorLink + " " + "http://mcmonkey.org/haste " + ColorGeneral + "- From there, save the page and paste the link back in this channel."); Chat(command.Channel.Name, ColorGeneral + "In-game, type '" + ColorHighlightMajor + "/denizen debug -r" + ColorGeneral + "', then run through the broken parts of the script, then type '" + ColorHighlightMajor + "/denizen submit" + ColorGeneral + "'. Open the link it gives you, and paste that link back in this channel as well."); Chat(command.Channel.Name, ColorGeneral + "For more information on how to read debug, see " + ColorLink + " http://mcmonkey.org/denizen/vids/debug"); } break; case "update": case "latest": case "new": case "newest": case "build": case "builds": case "spigot": case "spig": case "sp": { if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Due to the nature of our project, Denizen is always built against the " + ColorHighlightMajor + "development" + ColorGeneral + " builds of Spigot and Citizens." + " Most errors can be fixed by updating them all."); } if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, ColorGeneral + S_BOLD + "Denizen-" + S_NORMAL + ColorLink + " http://ci.citizensnpcs.co/job/Denizen/lastSuccessfulBuild"); Chat(command.Channel.Name, ColorGeneral + S_BOLD + "Denizen (Developmental)-" + S_NORMAL + ColorLink + " http://ci.mineconomy.org/job/Denizen_Developmental/lastSuccessfulBuild/"); } if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".citizens_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, ColorGeneral + S_BOLD + "Citizens-" + S_NORMAL + ColorLink + " http://ci.citizensnpcs.co/job/Citizens2/lastSuccessfulBuild"); } if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, ColorGeneral + S_BOLD + "Spigot-" + S_NORMAL + ColorLink + " http://bit.ly/15RZsn6"); Chat(command.Channel.Name, ColorGeneral + S_BOLD + "Depenizen (Optional)- " + S_NORMAL + ColorLink + " http://ci.citizensnpcs.co/job/Depenizen/lastSuccessfulBuild/"); } } break; case "nc": case "newconfig": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "If you are having issues or are unable to find a setting, you may be using the old config file."); Chat(command.Channel.Name, ColorGeneral + "You can easily generate a new one by deleteing your current config.yml file in the Denizen folder."); } break; case "wiki": { if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".citizens_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Citizens Wiki:" + ColorLink + " http://wiki.citizensnpcs.co"); } if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, ColorGeneral + "Denizen Wiki:" + ColorLink + " http://wiki.citizensnpcs.co/Denizen"); Chat(command.Channel.Name, ColorGeneral + "Depenizen Wiki:" + ColorLink + " http://wiki.citizensnpcs.co/Depenizen"); Chat(command.Channel.Name, ColorGeneral + "dIRCBot Wiki:" + ColorLink + " http://wiki.citizensnpcs.co/dIRCBot"); } } break; case "ipstalk": if (command.User.OP && Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".admin", "false").StartsWith("t")) { IPStalkCommand(command); } break; case "log": case "logs": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".has_log_page", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Full logs of this channel are available at" + ColorLink + " http://mcmonkey.org/denizen/logs/" + command.Channel.Name.Replace("#", "")); } break; case "voice": if (command.User.EverHadVoice && command.Channel.GetUser(Name).OP) { SendCommand("MODE", command.Channel.Name + " " + (command.User.Voice ? "-" : "+") + "v " + command.User.Name); } else { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "I'm sorry, " + ColorHighlightMajor + command.User.Name + ColorGeneral + ", I can't do that."); } break; case "yml": case "yaml": { YAMLCommand(command); } break; case "dscript": case "ds": case "script": case "ch": case "check": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { dScriptCommand(command); } break; case "olddscript": case "oldds": case "oldscript": case "oldch": case "oldcheck": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { OLDdScriptCommand(command); } break; case "search": case "find": case "get": case "locate": case "what": case "where": case "how": case "s": case "f": case "w": case "meta": case "metainfo": case "docs": case "doc": case "documentation": case "document": case "documents": case "documentations": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { // TODO } break; case "sounds": case "sound": { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Here is the list of all valid bukkit sounds -" + ColorLink + " http://bit.ly/1AfW8wu"); } break; case "gs": case "getstarted": case "start": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, ColorGeneral + "If you're trying to use Denizen for the first time, these web resources will help you (in addition to help received here on this IRC)"); Chat(command.Channel.Name, ColorGeneral + "Tutorial Videos[Updated] -" + ColorLink + " " + "http://mcmonkey.org/denizen/vids"); Chat(command.Channel.Name, ColorGeneral + "Script Repo[Varies] -" + ColorLink + " " + "http://mcmonkey.org/denizen/repo/list"); Chat(command.Channel.Name, ColorGeneral + "Old Script Repo[Outdated] -" + ColorLink + " http://bit.ly/19lCpfV"); Chat(command.Channel.Name, ColorGeneral + "Denizen Wiki[Semi-recent] -" + ColorLink + " http://bit.ly/14o3kdq"); Chat(command.Channel.Name, ColorGeneral + "Denizen Handbook[Outdated] -" + ColorLink + " http://bit.ly/XaWBLN"); Chat(command.Channel.Name, ColorGeneral + "Beginner's Guide[Outdated] -" + ColorLink + " http://bit.ly/1bHkByR"); } break; case "yes": { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Yes. Si. Ja. Oui. Da."); } break; case "mcve": case "minimal": case "min": case "complete": case "comp": { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Please create a Minimal, Complete, and Verifiable Example:" + ColorLink + " https://stackoverflow.com/help/mcve"); } break; case "myip": case "pingip": { MyIPCommand(command); } break; case "ping": case "mcping": { MCPingCommand(command); } break; case "mojang": case "mojangstatus": case "mcstatus": case "minecraftstatus": { // TODO } break; case "d": case "def": case "define": case "definition": // TODO break; case "reload": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { LoadMeta(command.Arguments.Count > 0 && command.Arguments[0].ToLower().Contains("monkey")); Chat(command.Channel.Name, command.Pinger + ColorGeneral + "I have reloaded the source files and now have " + ColorHighlightMajor + AllMeta.Commands.Count + ColorGeneral + " commands (" + ExternalMeta.Commands.Count + " external, " + CoreMeta.Commands.Count + " core), " + ColorHighlightMajor + AllMeta.Events.Count + ColorGeneral + " events (" + ExternalMeta.Events.Count + " external, " + CoreMeta.Events.Count + " core), " + ColorHighlightMajor + AllMeta.Tags.Count + ColorGeneral + " tags (" + ExternalMeta.Tags.Count + " external, " + CoreMeta.Tags.Count + " core), " + ColorHighlightMajor + AllMeta.Mechanisms.Count + ColorGeneral + " mechanisms (" + ExternalMeta.Mechanisms.Count + " external, " + CoreMeta.Mechanisms.Count + " core), " + ColorHighlightMajor + AllMeta.Tutorials.Count + ColorGeneral + " tutorials (" + ExternalMeta.Tutorials.Count + " external, " + CoreMeta.Tutorials.Count + " core), " + ColorHighlightMajor + AllMeta.Languages.Count + ColorGeneral + " language infos (" + ExternalMeta.Languages.Count + " external, " + CoreMeta.Languages.Count + " core), " + ColorHighlightMajor + AllMeta.Actions.Count + ColorGeneral + " actions (" + ExternalMeta.Actions.Count + " external, " + CoreMeta.Actions.Count + " core) all loaded!"); } break; case "quotes": case "quote": case "qs": case "q": // TODO break; case "roll": case "dice": { if (command.Arguments.Count == 0) { Chat(command.Channel.Name, ColorGeneral + "That command is written as: " + Prefixes[0] + "roll <count>d[sides] <operations>"); break; } string input = Utilities.Concat(command.Arguments).ToLowerInvariant(); Match match = Regex.Match(input, @"(\d+)?d(\d+)"); if (match.Success) { while (match.Success) { int dice = 1; if (match.Groups[1].Success) { dice = Utilities.StringToInt(match.Groups[1].Value); } int sides = Utilities.StringToInt(match.Groups[2].Value); if (dice > 100 || sides > 100) { Chat(command.Channel.Name, ColorGeneral + "Maximum roll is 100d100."); break; } StringBuilder sb = new StringBuilder(); if (dice > 1) { sb.Append("("); } for (int i = 0; i < dice; i++) { int roll = (int)(Utilities.random.NextDouble() * sides) + 1; sb.Append(roll).Append(" + "); } sb.Remove(sb.Length - 3, 3); if (dice > 1) { sb.Append(")"); } string final = sb.Length == 0 ? "0" : sb.ToString(); input = input.Substring(0, match.Index) + final + input.Substring(match.Index + match.Length); match = Regex.Match(input, @"(\d+)?d(\d+)"); } string err; List<MathOperation> calc = MonkeyMath.Parse(input, out err); if (err != null) { Chat(command.Channel.Name, ColorGeneral + "Failed: " + err); break; } Chat(command.Channel.Name, ColorGeneral + "You rolled: " + input); if (!MonkeyMath.Verify(calc, MonkeyMath.BaseFunctions, out err)) { Chat(command.Channel.Name, ColorGeneral + "Failed to verify: " + err); return; } Chat(command.Channel.Name, ColorGeneral + "Total roll: " + MonkeyMath.Calculate(calc, MonkeyMath.BaseFunctions)); } else { Chat(command.Channel.Name, ColorGeneral + "You must specify at least set of dice to roll!"); } } break; case "readlogs": if (!command.User.OP || !Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".admin", "false").StartsWith("t")) { Chat(command.Channel.Name, ColorGeneral + "You can't do that!"); } else { ReadLogs(); } break; case "debugtoggle": if (!command.User.OP || !Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".admin", "false").StartsWith("t")) { Chat(command.Channel.Name, ColorGeneral + "You can't do that!"); } else { Logger.Debugging = !Logger.Debugging; Chat(command.Channel.Name, ColorGeneral + "Debugging now " + ColorHighlightMajor + (Logger.Debugging ? "ON" : "OFF")); } break; case "restart": if (!command.User.OP || !Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".admin", "false").StartsWith("t")) { Chat(command.Channel.Name, ColorGeneral + "You can't do that!"); } else { Chat(command.Channel.Name, ColorGeneral + "Restarting..."); Restart(); Thread.Sleep(1000); Chat(command.Channel.Name, ColorGeneral + "Well! That didn't seem to work."); } break; default: // Unknown command. break; } }
bool MetaCommandIntro <T>(CommandDetails command, string type, string shorttype, List <T> aobjects, List <T> cobjects, List <T> xobjects, List <T> bobjects, bool autoSearch, bool allowList) where T : dObject { if (command.Arguments.Count < 1) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "That command is written as: " + ColorHighlightMajor + Prefixes[0] + command.Name + " <" + type + " to find, 'all', or 'list'> <optional information request>"); return(false); } string arg = command.Arguments[0].ToLower(); if (arg == "all") { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "A list of all " + type + "s is available at" + ColorLink + " http://mcmonkey.org/denizen/" + shorttype); return(false); } if (arg == "list") { if (!allowList) { return(true); } else { ListdObject(command, cobjects, xobjects, bobjects, type); } return(false); } if (autoSearch) { List <T> found = new List <T>(); foreach (T obj in aobjects) { string bn = obj.BasicName.ToLower(); if (bn == arg) { found = new List <T>(); found.Add(obj); break; } else if (bn.Contains(arg)) { found.Add(obj); } } if (found.Count == 0) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Could not find any matches."); } else if (found.Count == 1) { showdObject(command, found[0]); } else { StringBuilder sb = new StringBuilder(); sb.Append("Found " + found.Count + " possible " + type + "s... "); foreach (T obj in found) { sb.Append(obj.BasicName).Append(", "); } string toret = sb.ToString().Substring(0, sb.Length - 2); Chat(command.Channel.Name, command.Pinger + ColorGeneral + toret); } } return(true); }
void LaserbeamsCommand(CommandDetails command) { lock (LaserLock) { if (LasersCharged) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Pew! ... Just kidding, I won't charge my lasers twice, unless you want something to explode :o"); return; } if (RecentSnacks.Count < 4) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Do I look like a magician?! I can't charge lasers without snacks!"); return; } FireTime.Value++; int ftime = FireTime.Value; Task.Factory.StartNew(() => { Thread.Sleep((int)(5 * 60 * 1000 * (Utilities.random.NextDouble() / 2 + 0.5))); lock (LaserLock) { if (FireTime.Value == ftime) { Chat(command.Channel.Name, ColorGeneral + "UH OH! " + ColorHighlightMinor + "LASER BEAMS OVERCHARGED! " + ColorGeneral + " VOIDING NOW!"); string target = command.Channel.Users[Utilities.random.Next(command.Channel.Users.Count)].Name; Chat(command.Channel.Name, ColorGeneral + "Wow! " + ColorHighlightMajor + target + ColorGeneral + " is hit for " + ColorHighlightMajor + Math.Round(LaserPower * 1000) + ColorGeneral + " damage!"); LasersCharged = false; FireTime.Value++; } } }); int count = Utilities.random.Next(4) + 1; LasersCharged = true; LasersChargedAt = DateTime.Now; LaserFood = new List <BotSnack>(); LaserPower = 0; for (int i = 0; i < count; i++) { int choice = Utilities.random.Next(RecentSnacks.Count); BotSnack food = RecentSnacks[choice]; RecentSnacks.RemoveAt(choice); LaserFood.Add(food); LaserPower += food.Deliciousness; } if (LaserPower <= 0) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Lasers are now charged as good as they'll ever be."); } else if (LaserPower <= 5) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Mini-beam charging, as ordered!"); } else if (LaserPower <= 10) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Laser-beam charging, as ordered!"); } else { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Just hypothetically speaking, what would you say if I were to, oh I don't know, charge 5 laser beams at once?"); } } }
public void TryCommand(CommandDetails command) { switch (command.Name.ToLower()) { case "hello": case "allo": case "ello": case "hi": case "ohai": case "helo": case "halo": case "hai": case "howdy": case "website": case "web": case "site": case "link": case "url": case "greet": { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Hello! I am a bot designed to assist with Denizen Scripting! I have a website too, at" + ColorLink + " http://mcmonkey.org/logs " + ColorGeneral + "!"); } break; case "delay": { int delay = Utilities.random.Next(9) + 1; Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Delaying for " + ColorHighlightMajor + delay + ColorGeneral + " seconds!"); Thread.Sleep(1000 * delay); Chat(command.Channel.Name, ColorGeneral + "Done delaying for " + ColorHighlightMajor + delay); } break; case "regex": { // TODO } break; case "regexvalue": { // TODO } break; case "bs": case "botsnack": case "snack": { BotsnackCommand(command); } break; case "lasers": case "lzrbms": case "laserbeams": { LaserbeamsCommand(command); } break; case "fire": case "fiyar": case "fiar": { FireCommand(command); } break; case "seen": { SeenCommand(command); } break; case "recent": case "recentseen": case "seenrecently": case "recently": case "recentlyseen": { RecentCommand(command); } break; case "msg": case "send": case "tell": case "mail": case "message": { MessageCommand(command); } break; case "remind": case "rem": case "remember": case "tellmelater": case "delayedmsg": case "delayedmessage": { ReminderCommand(command); } break; case "ts": case "ts3": case "teamspeak": case "teamspeak3": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + "Denizen users are all welcome to voice chat together at the TeamSpeak3 server ts3.mcmonkey.org in the channel 'Denizen'!"); } else { Chat(command.Channel.Name, command.Pinger + "All bot users are all welcome to voice chat together at the TeamSpeak3 server ts3.mcmonkey.org!"); } break; case "please": case "pls": case "plz": case "plox": case "pl0x": case "sir": case "sir,": case "sir:": case "do": case "say": { if (command.Arguments.Count > 0) { CommandDetails cmddet = new CommandDetails(); cmddet.Name = command.Arguments[0].ToLower(); cmddet.Arguments = new List <string>(command.Arguments); cmddet.Arguments.RemoveAt(0); cmddet.Pinger = command.Pinger; cmddet.User = command.User; cmddet.Channel = command.Channel; TryCommand(cmddet); } } break; case "command": case "cmd": case "commands": case "cmds": case "c": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { CmdCommand(command); } break; case "evt": case "evts": case "event": case "events": case "e": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { // TODO } break; case "mec": case "mecs": case "mech": case "mechs": case "mechanism": case "mechanisms": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { MechCommand(command); } break; case "language": case "languages": case "info": case "infos": case "explanation": case "explanations": case "lng": case "lngs": case "text": case "texts": case "helps": case "lang": case "langs": case "lingo": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { LangCommand(command); } break; case "tutorial": case "tut": case "tutorials": case "tuts": case "example": case "examples": case "ex": case "exs": case "exam": case "exams": case "examp": case "examps": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { TutCommand(command); } break; case "tag": case "tags": case "t": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { TagCommand(command); } break; case "vid": case "vids": case "v": case "video": case "videos": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { // TODO } break; case "act": case "acts": case "action": case "actions": case "a": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { // TODO } break; case "item": case "items": case "itm": case "itms": case "mat": case "material": case "mats": case "materials": case "i": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { // TODO } break; case "m": case "math": case "maths": case "mathematic": case "mathematics": case "calculate": case "calc": { if (command.Arguments.Count > 0) { string input = Utilities.Concat(command.Arguments); string err; List <MathOperation> calc = MonkeyMath.Parse(input, out err); if (err != null) { Chat(command.Channel.Name, ColorGeneral + "Failed: " + err); return; } if (!MonkeyMath.Verify(calc, MonkeyMath.BaseFunctions, out err)) { Chat(command.Channel.Name, ColorGeneral + "Failed to verify: " + err); return; } Chat(command.Channel.Name, ColorGeneral + input + " = " + MonkeyMath.Calculate(calc, MonkeyMath.BaseFunctions)); } } break; case "wolfram": case "advancedmath": case "wolframalpha": case "alpha": case "wa": { if (command.Arguments.Count > 0) { WolframAlpha.QueryResult output = WolframAlpha.Query(string.Join(" ", command.Arguments), command.User.IP); string result = output.Result; if (output.Error || !output.Success || result == null) { if (output.Suggestion != null) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Sorry, I don't know the definition of that. Did you mean '" + output.Suggestion + "'?"); } else { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "There was an error while parsing that statement."); } } else { if (output.SpellCheck != null) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + output.SpellCheck); } Chat(command.Channel.Name, command.Pinger + ColorGeneral + output.Input + " = " + output.Result); } } } break; case "g": case "google": case "ggl": { if (command.Arguments.Count > 0) { GoogleResponse response = GoogleSearch.Search(Utilities.Concat(command.Arguments)); if (response == null) { Chat(command.Channel.Name, command.Pinger + ColorHighlightMajor + "Error! Response not found."); } else if (response.items.Count == 0) { Chat(command.Channel.Name, command.Pinger + ColorHighlightMinor + "No search results found."); } else { GoogleSearchInfo searchInfo = response.searchInformation; List <GoogleResponseItem> items = response.items; GoogleResponseItem result = items[0]; String snippet = result.snippet.Replace("\\n", ""); Chat(command.Channel.Name, command.Pinger + ColorGeneral + "[Result found in " + searchInfo.formattedSearchTime + "] " + snippet + " -- " + result.link); } } } break; case "u": case "urban": { if (command.Arguments.Count > 0) { UrbanResponse response = UrbanDictionary.Search(Utilities.Concat(command.Arguments)); if (response == null) { Chat(command.Channel.Name, command.Pinger + ColorHighlightMajor + "Error! Response not found."); } else if (response.result_type == "no_results" || response.list.Count == 0) { Chat(command.Channel.Name, command.Pinger + ColorHighlightMinor + "No search results found."); } else { int num = Utilities.random.Next(response.list.Count); UrbanDefinition definition = response.list[num]; string defString = definition.definition.Replace("\n\n", " ").Replace("\n", " ").Replace("\r", ""); string exampleString = definition.example.Replace("\n\n", " ").Replace("\n", " ").Replace("\r", ""); Chat(command.Channel.Name, command.Pinger + ColorGeneral + definition.word + " (" + definition.defid + "): " + defString); Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Example: " + exampleString); } } } break; case "rate": case "ratelimit": { RateLimitCommand(command); } break; case "git": case "github": { GitHubCommand(command); } break; case "repository": case "repo": case "repos": case "repositories": case "scripts": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Check out scripts made by other users -" + ColorLink + " " + "http://mcmonkey.org/denizen/repo/list"); Chat(command.Channel.Name, ColorGeneral + "Old repo -" + ColorLink + " http://bit.ly/19lCpfV"); } break; case "issue": case "issues": case "iss": { if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Post Denizen issues here:" + ColorLink + " https://github.com/DenizenScript/Denizen-For-Bukkit/issues"); } if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".citizens_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Post Citizens issues here:" + ColorLink + " https://github.com/CitizensDev/Citizens2/issues"); } } break; case "enchant": case "enchantment": case "enchants": case "enchantments": case "ench": case "enches": case "enchs": { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "A list of all valid bukkit enchantments is available here:" + ColorLink + " https://hub.spigotmc.org/javadocs/spigot/org/bukkit/enchantments/Enchantment.html"); Chat(command.Channel.Name, ColorGeneral + "They do not follow the same naming conventions as they do in game, so be careful."); } break; case "entity": case "entitys": case "entities": case "entitie": case "entitytype": case "entitytypes": { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "A list of all Entity types is available here:" + ColorLink + " http://bit.ly/1sos3dT"); } break; case "thank": case "thanks": case "thanks!": case "thanks.": case "thankyou!": case "thankyou.": case "thankyou": case "donate": case "don": { Chat(command.Channel.Name, ColorGeneral + "Donate to fullwall (Head of the Citizens project) at:" + ColorLink + " http://bit.ly/19UVDtp"); Chat(command.Channel.Name, ColorGeneral + "Donate to mcmonkey (Current head of Denizen development) at:" + ColorLink + " http://mcmonkey.org/donate"); Chat(command.Channel.Name, ColorGeneral + "Donate to Morphan1 (Denizen developer and head of Depenizen) at:" + ColorLink + " http://morphanone.com/donate"); } break; case "potion": case "potions": case "effect": case "effects": { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "A list of all Bukkit Potion Effects is available here:" + ColorLink + " http://bit.ly/1LnDvvv"); } break; case "test": case "tet": case "tes": case "tst": case "?": { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "All systems functional!"); } break; case "help": case "halp": case "hlp": case "hep": case "hap": { string prefix = Prefixes[0]; if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Hello, I am DenizenBot, a bot dedicated to assisting you in maximizing your Denizen scripting potential." + " If you're new to Denizen, type " + ColorHighlightMinor + prefix + "getstarted"); Chat(command.Channel.Name, ColorGeneral + "To check your script for errors, type " + ColorHighlightMinor + prefix + "script"); Chat(command.Channel.Name, ColorGeneral + "Available meta search commands: " + ColorHighlightMinor + prefix + "cmds " + prefix + "tags " + prefix + "events " + prefix + "requirements " + prefix + "languages " + prefix + "tutorials " + prefix + "mechanisms " + prefix + "actions " + prefix + "items " + prefix + "skins " + prefix + "search " + prefix + "videos"); Chat(command.Channel.Name, ColorGeneral + "Available informational commands: " + ColorHighlightMinor + prefix + "repo " + prefix + "enchantments " + prefix + "entities " + prefix + "anchors " + prefix + "tags " + prefix + "potions " + prefix + "assignments " + prefix + "update " + prefix + "newconfig " + prefix + "wiki " + prefix + "sounds " + prefix + "handbook " + prefix + "debug " + prefix + "mcve "); } Chat(command.Channel.Name, ColorGeneral + "Available interactive commands: " + ColorHighlightMinor + prefix + "seen " + prefix + "message " + prefix + "hello " + prefix + "showoff " + prefix + "math " + prefix + "mcping " + prefix + "help " + prefix + "paste " + prefix + "logs " + prefix + "yaml " + prefix + "yes " + prefix + "reload " + prefix + "voice " + prefix + "quote " + prefix + "savelog " + prefix + "botsnack " + prefix + "regex " + prefix + "regexvalue "); } break; case "skins": case "skin": case "skinssearch": case "skinsearch": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".citizens_meta", "false").StartsWith("t")) { if (command.Arguments.Count > 1) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "A list of matching skins for your NPCs is at:" + ColorLink + " " + "http://mcmonkey.org/denizen/skin/" + command.Arguments[1]); } else { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Your can search for skins for your NPCs at:" + ColorLink + " " + "http://mcmonkey.org/denizen/skin"); } } break; case "hastebin": case "haste": case "hastee": case "hastie": case "hastey": case "hastes": case "hastebins": case "pastebin": case "pastebins": case "pastey": case "pastests": case "pastie": case "pastee": case "paste": { // TODO } break; case "debug": case "db": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Need help with a script issue or server error? " + "- Help us help you by pasting your script to" + ColorLink + " " + "http://mcmonkey.org/haste " + ColorGeneral + "- From there, save the page and paste the link back in this channel."); Chat(command.Channel.Name, ColorGeneral + "In-game, type '" + ColorHighlightMajor + "/denizen debug -r" + ColorGeneral + "', then run through the broken parts of the script, then type '" + ColorHighlightMajor + "/denizen submit" + ColorGeneral + "'. Open the link it gives you, and paste that link back in this channel as well."); Chat(command.Channel.Name, ColorGeneral + "For more information on how to read debug, see " + ColorLink + " http://mcmonkey.org/denizen/vids/debug"); } break; case "update": case "latest": case "new": case "newest": case "build": case "builds": case "spigot": case "spig": case "sp": { if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Due to the nature of our project, Denizen is always built against the " + ColorHighlightMajor + "development" + ColorGeneral + " builds of Spigot and Citizens." + " Most errors can be fixed by updating them all."); } if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, ColorGeneral + S_BOLD + "Denizen-" + S_NORMAL + ColorLink + " http://ci.citizensnpcs.co/job/Denizen/lastSuccessfulBuild"); Chat(command.Channel.Name, ColorGeneral + S_BOLD + "Denizen (Developmental)-" + S_NORMAL + ColorLink + " http://ci.mineconomy.org/job/Denizen_Developmental/lastSuccessfulBuild/"); } if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".citizens_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, ColorGeneral + S_BOLD + "Citizens-" + S_NORMAL + ColorLink + " http://ci.citizensnpcs.co/job/Citizens2/lastSuccessfulBuild"); } if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, ColorGeneral + S_BOLD + "Spigot-" + S_NORMAL + ColorLink + " http://bit.ly/15RZsn6"); Chat(command.Channel.Name, ColorGeneral + S_BOLD + "Depenizen (Optional)- " + S_NORMAL + ColorLink + " http://ci.citizensnpcs.co/job/Depenizen/lastSuccessfulBuild/"); } } break; case "nc": case "newconfig": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "If you are having issues or are unable to find a setting, you may be using the old config file."); Chat(command.Channel.Name, ColorGeneral + "You can easily generate a new one by deleteing your current config.yml file in the Denizen folder."); } break; case "wiki": { if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".citizens_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Citizens Wiki:" + ColorLink + " http://wiki.citizensnpcs.co"); } if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, ColorGeneral + "Denizen Wiki:" + ColorLink + " http://wiki.citizensnpcs.co/Denizen"); Chat(command.Channel.Name, ColorGeneral + "Depenizen Wiki:" + ColorLink + " http://wiki.citizensnpcs.co/Depenizen"); Chat(command.Channel.Name, ColorGeneral + "dIRCBot Wiki:" + ColorLink + " http://wiki.citizensnpcs.co/dIRCBot"); } } break; case "ipstalk": if (command.User.OP && Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".admin", "false").StartsWith("t")) { IPStalkCommand(command); } break; case "log": case "logs": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".has_log_page", "false").StartsWith("t")) { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Full logs of this channel are available at" + ColorLink + " http://mcmonkey.org/denizen/logs/" + command.Channel.Name.Replace("#", "")); } break; case "voice": if (command.User.EverHadVoice && command.Channel.GetUser(Name).OP) { SendCommand("MODE", command.Channel.Name + " " + (command.User.Voice ? "-" : "+") + "v " + command.User.Name); } else { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "I'm sorry, " + ColorHighlightMajor + command.User.Name + ColorGeneral + ", I can't do that."); } break; case "yml": case "yaml": { YAMLCommand(command); } break; case "dscript": case "ds": case "script": case "ch": case "check": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { dScriptCommand(command); } break; case "olddscript": case "oldds": case "oldscript": case "oldch": case "oldcheck": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { OLDdScriptCommand(command); } break; case "search": case "find": case "get": case "locate": case "what": case "where": case "how": case "s": case "f": case "w": case "meta": case "metainfo": case "docs": case "doc": case "documentation": case "document": case "documents": case "documentations": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { // TODO } break; case "sounds": case "sound": { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Here is the list of all valid bukkit sounds -" + ColorLink + " http://bit.ly/1AfW8wu"); } break; case "gs": case "getstarted": case "start": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { Chat(command.Channel.Name, ColorGeneral + "If you're trying to use Denizen for the first time, these web resources will help you (in addition to help received here on this IRC)"); Chat(command.Channel.Name, ColorGeneral + "Tutorial Videos[Updated] -" + ColorLink + " " + "http://mcmonkey.org/denizen/vids"); Chat(command.Channel.Name, ColorGeneral + "Script Repo[Varies] -" + ColorLink + " " + "http://mcmonkey.org/denizen/repo/list"); Chat(command.Channel.Name, ColorGeneral + "Old Script Repo[Outdated] -" + ColorLink + " http://bit.ly/19lCpfV"); Chat(command.Channel.Name, ColorGeneral + "Denizen Wiki[Semi-recent] -" + ColorLink + " http://bit.ly/14o3kdq"); Chat(command.Channel.Name, ColorGeneral + "Denizen Handbook[Outdated] -" + ColorLink + " http://bit.ly/XaWBLN"); Chat(command.Channel.Name, ColorGeneral + "Beginner's Guide[Outdated] -" + ColorLink + " http://bit.ly/1bHkByR"); } break; case "yes": { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Yes. Si. Ja. Oui. Da."); } break; case "mcve": case "minimal": case "min": case "complete": case "comp": { Chat(command.Channel.Name, command.Pinger + ColorGeneral + "Please create a Minimal, Complete, and Verifiable Example:" + ColorLink + " https://stackoverflow.com/help/mcve"); } break; case "myip": case "pingip": { MyIPCommand(command); } break; case "ping": case "mcping": { MCPingCommand(command); } break; case "mojang": case "mojangstatus": case "mcstatus": case "minecraftstatus": { MojangStatusCommand(command); } break; case "d": case "def": case "define": case "definition": // TODO break; case "reload": if (Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".denizen_meta", "false").StartsWith("t")) { LoadMeta(command.Arguments.Count > 0 && command.Arguments[0].ToLower().Contains("monkey")); Chat(command.Channel.Name, command.Pinger + ColorGeneral + "I have reloaded the source files and now have " + ColorHighlightMajor + AllMeta.Commands.Count + ColorGeneral + " commands (" + ExternalMeta.Commands.Count + " external, " + CoreMeta.Commands.Count + " core), " + ColorHighlightMajor + AllMeta.Events.Count + ColorGeneral + " events (" + ExternalMeta.Events.Count + " external, " + CoreMeta.Events.Count + " core), " + ColorHighlightMajor + AllMeta.Tags.Count + ColorGeneral + " tags (" + ExternalMeta.Tags.Count + " external, " + CoreMeta.Tags.Count + " core), " + ColorHighlightMajor + AllMeta.Mechanisms.Count + ColorGeneral + " mechanisms (" + ExternalMeta.Mechanisms.Count + " external, " + CoreMeta.Mechanisms.Count + " core), " + ColorHighlightMajor + AllMeta.Tutorials.Count + ColorGeneral + " tutorials (" + ExternalMeta.Tutorials.Count + " external, " + CoreMeta.Tutorials.Count + " core), " + ColorHighlightMajor + AllMeta.Languages.Count + ColorGeneral + " language infos (" + ExternalMeta.Languages.Count + " external, " + CoreMeta.Languages.Count + " core), " + ColorHighlightMajor + AllMeta.Actions.Count + ColorGeneral + " actions (" + ExternalMeta.Actions.Count + " external, " + CoreMeta.Actions.Count + " core) all loaded!"); } break; case "quotes": case "quote": case "qs": case "q": // TODO break; case "roll": case "dice": { if (command.Arguments.Count == 0) { Chat(command.Channel.Name, ColorGeneral + "That command is written as: " + Prefixes[0] + "roll <count>d[sides] <operations>"); break; } string input = Utilities.Concat(command.Arguments).ToLowerInvariant(); Match match = Regex.Match(input, @"(\d+)?d(\d+)"); if (match.Success) { while (match.Success) { int dice = 1; if (match.Groups[1].Success) { dice = Utilities.StringToInt(match.Groups[1].Value); } int sides = Utilities.StringToInt(match.Groups[2].Value); if (dice > 100 || sides > 100) { Chat(command.Channel.Name, ColorGeneral + "Maximum roll is 100d100."); break; } StringBuilder sb = new StringBuilder(); if (dice > 1) { sb.Append("("); } for (int i = 0; i < dice; i++) { int roll = (int)(Utilities.random.NextDouble() * sides) + 1; sb.Append(roll).Append(" + "); } sb.Remove(sb.Length - 3, 3); if (dice > 1) { sb.Append(")"); } string final = sb.Length == 0 ? "0" : sb.ToString(); input = input.Substring(0, match.Index) + final + input.Substring(match.Index + match.Length); match = Regex.Match(input, @"(\d+)?d(\d+)"); } string err; List <MathOperation> calc = MonkeyMath.Parse(input, out err); if (err != null) { Chat(command.Channel.Name, ColorGeneral + "Failed: " + err); break; } Chat(command.Channel.Name, ColorGeneral + "You rolled: " + input); if (!MonkeyMath.Verify(calc, MonkeyMath.BaseFunctions, out err)) { Chat(command.Channel.Name, ColorGeneral + "Failed to verify: " + err); return; } Chat(command.Channel.Name, ColorGeneral + "Total roll: " + MonkeyMath.Calculate(calc, MonkeyMath.BaseFunctions)); } else { Chat(command.Channel.Name, ColorGeneral + "You must specify at least set of dice to roll!"); } } break; case "readlogs": if (!command.User.OP || !Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".admin", "false").StartsWith("t")) { Chat(command.Channel.Name, ColorGeneral + "You can't do that!"); } else { ReadLogs(); } break; case "debugtoggle": if (!command.User.OP || !Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".admin", "false").StartsWith("t")) { Chat(command.Channel.Name, ColorGeneral + "You can't do that!"); } else { Logger.Debugging = !Logger.Debugging; Chat(command.Channel.Name, ColorGeneral + "Debugging now " + ColorHighlightMajor + (Logger.Debugging ? "ON" : "OFF")); } break; case "restart": if (!command.User.OP || !Configuration.ReadString("dircbot.irc-servers." + ServerName + ".channels." + command.Channel.Name.Replace("#", "") + ".admin", "false").StartsWith("t")) { Chat(command.Channel.Name, ColorGeneral + "You can't do that!"); } else { Chat(command.Channel.Name, ColorGeneral + "Restarting..."); Restart(); Thread.Sleep(1000); Chat(command.Channel.Name, ColorGeneral + "Well! That didn't seem to work."); } break; default: // Unknown command. break; } }
/// <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, 2); 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("<", "<").Replace(">", ">"); web = web.Replace(""", "\"").Replace("&", (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()); } } } }
void showdObject(CommandDetails command, dObject obj) { obj.ShowToChannel(this, command); }
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(); } }