From f6964219d8ebd613b557b2b874d00072864127a3 Mon Sep 17 00:00:00 2001 From: Uncled1023 Date: Tue, 3 Feb 2015 00:56:19 -0800 Subject: [PATCH] Added weather commands. Added timed bans. --- Combot/Combot.csproj | 1 + Combot/Modules/ModuleClasses/Moderation.cs | 45 +++++++ Combot/Modules/ModuleClasses/Weather.cs | 196 +++++++++++++++++++++++++++++ 3 files changed, 242 insertions(+) create mode 100755 Combot/Modules/ModuleClasses/Weather.cs diff --git a/Combot/Combot.csproj b/Combot/Combot.csproj index 4c6011b..8e00300 100755 --- a/Combot/Combot.csproj +++ b/Combot/Combot.csproj @@ -74,6 +74,7 @@ + diff --git a/Combot/Modules/ModuleClasses/Moderation.cs b/Combot/Modules/ModuleClasses/Moderation.cs index 5799d64..12e2e69 100755 --- a/Combot/Modules/ModuleClasses/Moderation.cs +++ b/Combot/Modules/ModuleClasses/Moderation.cs @@ -1,15 +1,22 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using Combot.IRCServices; using Combot.IRCServices.Messaging; +using Timer = System.Timers.Timer; namespace Combot.Modules.ModuleClasses { public class Moderation : Module { + private List unbanTimers; + private ReaderWriterLockSlim listLock; + public override void Initialize() { + unbanTimers = new List(); + listLock = new ReaderWriterLockSlim(); Bot.CommandReceivedEvent += HandleCommandEvent; } @@ -351,7 +358,45 @@ namespace Combot.Modules.ModuleClasses private void TimedBan(Command curCommand, CommandMessage command) { + double timeout; + if (double.TryParse(command.Arguments["Time"], out timeout)) + { + BanNick(true, curCommand, command); + Timer unban_trigger = new Timer(); + unban_trigger.Interval = (timeout * 1000.0); + unban_trigger.Enabled = true; + unban_trigger.AutoReset = false; + unban_trigger.Elapsed += (sender, e) => TimedUnBan(sender, e, curCommand, command); + listLock.EnterWriteLock(); + unbanTimers.Add(unban_trigger); + listLock.ExitWriteLock(); + } + else + { + string noAccessMessage = "Please enter a valid time."; + switch (command.MessageType) + { + case MessageType.Channel: + Bot.IRC.SendPrivateMessage(command.Location, noAccessMessage); + break; + case MessageType.Query: + Bot.IRC.SendPrivateMessage(command.Nick.Nickname, noAccessMessage); + break; + case MessageType.Notice: + Bot.IRC.SendNotice(command.Nick.Nickname, noAccessMessage); + break; + } + } + } + private void TimedUnBan(object sender, EventArgs e, Command curCommand, CommandMessage command) + { + Timer unbanTimer = (Timer)sender; + unbanTimer.Enabled = false; + BanNick(false, curCommand, command); + listLock.EnterWriteLock(); + unbanTimers.Remove(unbanTimer); + listLock.ExitWriteLock(); } private void KickNick(Command curCommand, CommandMessage command) diff --git a/Combot/Modules/ModuleClasses/Weather.cs b/Combot/Modules/ModuleClasses/Weather.cs new file mode 100755 index 0000000..224352f --- /dev/null +++ b/Combot/Modules/ModuleClasses/Weather.cs @@ -0,0 +1,196 @@ +using System; +using System.Xml; + +namespace Combot.Modules.ModuleClasses +{ + public class Weather : Module + { + public override void Initialize() + { + Bot.CommandReceivedEvent += HandleCommandEvent; + } + + public override void ParseCommand(CommandMessage command) + { + Command foundCommand = Commands.Find(c => c.Triggers.Contains(command.Command)); + switch (foundCommand.Name) + { + case "Weather": + getWeather(command); + break; + case "Forecast": + getForecast(command); + break; + } + } + + private void getForecast(CommandMessage command) + { + int days = 6; + if (command.Arguments.ContainsKey("Days")) + { + if (!int.TryParse(command.Arguments["Days"], out days)) + { + days = 6; + } + } + XmlDocument doc2 = new XmlDocument(); + + // Load data + doc2.Load("http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=" + command.Arguments["Location"]); + + // Get forecast with XPath + XmlNodeList nodes2 = doc2.SelectNodes("/current_observation"); + + string location = ""; + if (nodes2.Count > 0) + { + foreach (XmlNode node2 in nodes2) + { + XmlNodeList sub_node2 = doc2.SelectNodes("/current_observation/display_location"); + foreach (XmlNode xn2 in sub_node2) + { + location = xn2["full"].InnerText; + } + } + } + + XmlDocument doc = new XmlDocument(); + // Load data + doc.Load("http://api.wunderground.com/auto/wui/geo/ForecastXML/index.xml?query=" + command.Arguments["Location"]); + + // Get forecast with XPath + XmlNodeList nodes = doc.SelectNodes("/forecast/simpleforecast"); + + string weekday = string.Empty; + string highf = string.Empty; + string lowf = string.Empty; + string highc = string.Empty; + string lowc = string.Empty; + string conditions = string.Empty; + if (location != ", " && !String.IsNullOrEmpty(location)) + { + if (nodes != null && nodes.Count > 0) + { + string startMsg = string.Format("{0} day forecast for {1}", days, command.Arguments["Location"]); + if (command.MessageType == MessageType.Channel || command.MessageType == MessageType.Notice) + { + Bot.IRC.SendNotice(command.Nick.Nickname, startMsg); + } + else + { + Bot.IRC.SendPrivateMessage(command.Nick.Nickname, startMsg); + } + int index = 0; + foreach (XmlNode node in nodes) + { + foreach (XmlNode sub_node in node) + { + if (index < days) + { + weekday = sub_node["date"].SelectSingleNode("weekday").InnerText; + highf = sub_node["high"].SelectSingleNode("fahrenheit").InnerText; + highc = sub_node["high"].SelectSingleNode("celsius").InnerText; + lowf = sub_node["low"].SelectSingleNode("fahrenheit").InnerText; + lowc = sub_node["low"].SelectSingleNode("celsius").InnerText; + conditions = sub_node["conditions"].InnerText; + string forecastMsg = string.Format("{0}: {1} with a high of {2} F ({3} C) and a low of {4} F ({5} C).", weekday, conditions, highf, highc, lowf, lowc); + if (command.MessageType == MessageType.Channel || command.MessageType == MessageType.Notice) + { + Bot.IRC.SendNotice(command.Nick.Nickname, forecastMsg); + } + else + { + Bot.IRC.SendPrivateMessage(command.Nick.Nickname, forecastMsg); + } + } + index++; + } + } + } + else + { + string noWeather = string.Format("No weather information available for \u0002{0}\u000F", command.Arguments["Location"]); + if (command.MessageType == MessageType.Channel || command.MessageType == MessageType.Notice) + { + Bot.IRC.SendNotice(command.Nick.Nickname, noWeather); + } + else + { + Bot.IRC.SendPrivateMessage(command.Nick.Nickname, noWeather); + } + } + } + else + { + string noWeather = string.Format("No weather information available for \u0002{0}\u000F", command.Arguments["Location"]); + if (command.MessageType == MessageType.Channel || command.MessageType == MessageType.Notice) + { + Bot.IRC.SendNotice(command.Nick.Nickname, noWeather); + } + else + { + Bot.IRC.SendPrivateMessage(command.Nick.Nickname, noWeather); + } + } + } + + private void getWeather(CommandMessage command) + { + XmlDocument doc = new XmlDocument(); + + // Load data + doc.Load("http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=" + command.Arguments["Location"]); + + // Get forecast with XPath + XmlNodeList nodes = doc.SelectNodes("/current_observation"); + string weatherMsg = string.Empty; + string location = string.Empty; + string temp = string.Empty; + string weather = string.Empty; + string humidity = string.Empty; + string wind_dir = string.Empty; + string wind_mph = string.Empty; + if (nodes != null && nodes.Count > 0) + { + foreach (XmlNode node in nodes) + { + XmlNodeList sub_node = doc.SelectNodes("/current_observation/display_location"); + foreach (XmlNode xn in sub_node) + { + location = xn["full"].InnerText; + } + temp = node["temperature_string"].InnerText; + weather = node["weather"].InnerText; + humidity = node["relative_humidity"].InnerText; + wind_dir = node["wind_dir"].InnerText; + wind_mph = node["wind_mph"].InnerText; + } + if (location != ", ") + { + weatherMsg = string.Format("{0} is currently {1} with a temperature of {2}. The humidity is {3} with winds blowing {4} at {5} mph", location, weather, temp, humidity, wind_dir, wind_mph); + } + else + { + weatherMsg = string.Format("No weather information available for \u0002{0}\u000F", command.Arguments["Location"]); + } + } + else + { + weatherMsg = string.Format("No weather information available for \u0002{0}\u000F", command.Arguments["Location"]); + } + if (command.MessageType == MessageType.Channel) + { + Bot.IRC.SendPrivateMessage(command.Location, weatherMsg); + } + else if (command.MessageType == MessageType.Notice) + { + Bot.IRC.SendNotice(command.Nick.Nickname, weatherMsg); + } + else if (command.MessageType == MessageType.Query) + { + Bot.IRC.SendPrivateMessage(command.Nick.Nickname, weatherMsg); + } + } + } +} \ No newline at end of file