The easy to use and full featured Irc Bot everyone is talking about!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Custom_Commands.cs 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics.Eventing.Reader;
  4. using System.Linq;
  5. using System.Text.RegularExpressions;
  6. using Combot.IRCServices;
  7. using Combot.IRCServices.Messaging;
  8. namespace Combot.Modules.Plugins
  9. {
  10. public class Custom_Commands : Module
  11. {
  12. public override void Initialize()
  13. {
  14. Bot.CommandReceivedEvent += HandleCommandEvent;
  15. Bot.IRC.Message.ChannelMessageReceivedEvent += HandleChannelMessage;
  16. Bot.IRC.Message.PrivateMessageReceivedEvent += HandlePrivateMessage;
  17. Bot.IRC.Message.ChannelNoticeReceivedEvent += HandleChannelNotice;
  18. Bot.IRC.Message.PrivateNoticeReceivedEvent += HandlePrivateNotice;
  19. }
  20. public override void ParseCommand(CommandMessage command)
  21. {
  22. Command foundCommand = Commands.Find(c => c.Triggers.Contains(command.Command));
  23. switch (foundCommand.Name)
  24. {
  25. case "Custom Command":
  26. string action = command.Arguments["Action"];
  27. switch (action.ToLower())
  28. {
  29. case "add":
  30. string addType = command.Arguments["Type"];
  31. string addPermission = command.Arguments["Permission"];
  32. string addChannels = (command.Arguments.ContainsKey("Channels")) ? command.Arguments["Channels"] : string.Empty;
  33. string addNicknames = (command.Arguments.ContainsKey("Nicknames")) ? command.Arguments["Nicknames"] : string.Empty;
  34. string addTrigger = command.Arguments["Trigger"];
  35. string addResponse = command.Arguments["Response"];
  36. AddCommand(command, addType, addPermission, addChannels, addNicknames, addTrigger, addResponse);
  37. break;
  38. case "del":
  39. DeleteCommand(command);
  40. break;
  41. case "edit":
  42. string editType = command.Arguments["Type"];
  43. string editPermission = command.Arguments["Permission"];
  44. string editChannels = (command.Arguments.ContainsKey("Channels")) ? command.Arguments["Channels"] : string.Empty;
  45. string editNicknames = (command.Arguments.ContainsKey("Nicknames")) ? command.Arguments["Nicknames"] : string.Empty;
  46. string editTrigger = command.Arguments["Trigger"];
  47. string editResponse = command.Arguments["Response"];
  48. EditCommand(command, editType, editPermission, editChannels, editNicknames, editTrigger, editResponse);
  49. break;
  50. case "view":
  51. if (command.Arguments.ContainsKey("Trigger"))
  52. {
  53. ViewTrigger(command, command.Arguments["Trigger"]);
  54. }
  55. else
  56. {
  57. ViewTriggers(command);
  58. }
  59. break;
  60. }
  61. break;
  62. }
  63. }
  64. private void HandleChannelMessage(object sender, ChannelMessage message)
  65. {
  66. if (Enabled && !Bot.IsCommand(message.Message))
  67. {
  68. string command = Bot.GetCommand(message.Message);
  69. if (!string.IsNullOrEmpty(command))
  70. {
  71. List<Dictionary<string, object>> foundTriggers = GetTrigger(message.Sender, null, message.Channel, message.Sender.Nickname, command);
  72. if (foundTriggers.Any())
  73. {
  74. foreach (Dictionary<string, object> foundTrigger in foundTriggers)
  75. {
  76. ExecuteCommand(MessageType.Channel, message.Channel, message.Sender, foundTrigger);
  77. }
  78. }
  79. }
  80. }
  81. }
  82. private void HandlePrivateMessage(object sender, PrivateMessage message)
  83. {
  84. if (Enabled && !Bot.IsCommand(message.Message))
  85. {
  86. string command = Bot.GetCommand(message.Message);
  87. if (!string.IsNullOrEmpty(command))
  88. {
  89. List<Dictionary<string, object>> foundTriggers = GetTrigger(message.Sender, null, null, message.Sender.Nickname, command);
  90. if (foundTriggers.Any())
  91. {
  92. foreach (Dictionary<string, object> foundTrigger in foundTriggers)
  93. {
  94. ExecuteCommand(MessageType.Query, message.Sender.Nickname, message.Sender, foundTrigger);
  95. }
  96. }
  97. }
  98. }
  99. }
  100. private void HandleChannelNotice(object sender, ChannelNotice message)
  101. {
  102. if (Enabled && !Bot.IsCommand(message.Message))
  103. {
  104. string command = Bot.GetCommand(message.Message);
  105. if (!string.IsNullOrEmpty(command))
  106. {
  107. List<Dictionary<string, object>> foundTriggers = GetTrigger(message.Sender, null, message.Channel, null, command);
  108. if (foundTriggers.Any())
  109. {
  110. foreach (Dictionary<string, object> foundTrigger in foundTriggers)
  111. {
  112. ExecuteCommand(MessageType.Notice, message.Channel, message.Sender, foundTrigger);
  113. }
  114. }
  115. }
  116. }
  117. }
  118. private void HandlePrivateNotice(object sender, PrivateNotice message)
  119. {
  120. if (Enabled && !Bot.IsCommand(message.Message))
  121. {
  122. string command = Bot.GetCommand(message.Message);
  123. if (!string.IsNullOrEmpty(command))
  124. {
  125. List<Dictionary<string, object>> foundTriggers = GetTrigger(message.Sender, null, null, message.Sender.Nickname, command);
  126. if (foundTriggers.Any())
  127. {
  128. foreach (Dictionary<string, object> foundTrigger in foundTriggers)
  129. {
  130. ExecuteCommand(MessageType.Notice, message.Sender.Nickname, message.Sender, foundTrigger);
  131. }
  132. }
  133. }
  134. }
  135. }
  136. /* Returns the parsed ID field if valid, otherwise returns 0 */
  137. private int HasValidCommandID(CommandMessage command)
  138. {
  139. int num = 0;
  140. int ret = 0;
  141. List<Dictionary<string, object>> foundTriggers = GetTrigger(command.Nick, "Self", string.Empty, string.Empty, null, true);
  142. if (int.TryParse(command.Arguments["ID"], out num))
  143. {
  144. if (foundTriggers.Count >= num && num > 0)
  145. {
  146. ret = num;
  147. }
  148. }
  149. return ret;
  150. }
  151. private void AddCommand(CommandMessage command, string type, string permission, string channels, string nicknames, string trigger, string response)
  152. {
  153. if (!Bot.IsCommand(trigger))
  154. {
  155. int maxTriggers = Convert.ToInt32(GetOptionValue("Max Commands"));
  156. List<Dictionary<string, object>> currentCommands = GetTrigger(command.Nick, "Self", string.Empty, string.Empty, null, true);
  157. if (currentCommands.Count < maxTriggers)
  158. {
  159. List<Dictionary<string, object>> foundTriggers = GetTrigger(command.Nick, null, channels, nicknames, trigger, false);
  160. if (!foundTriggers.Any())
  161. {
  162. AddNick(command.Nick);
  163. string query = "INSERT INTO `customcommands` SET " +
  164. "`server_id` = (SELECT `id` FROM `servers` WHERE `name` = {0}), " +
  165. "`nick_id` = (SELECT `nicks`.`id` FROM `nicks` INNER JOIN `servers` ON `servers`.`id` = `nicks`.`server_id` WHERE `servers`.`name` = {1} && `nicks`.`nickname` = {2}), " +
  166. "`type` = {3}, " +
  167. "`permission` = {4}, " +
  168. "`channels` = {5}, " +
  169. "`nicknames` = {6}, " +
  170. "`trigger` = {7}, " +
  171. "`response` = {8}, " +
  172. "`date_added` = {9}";
  173. Bot.Database.Execute(query, new object[] {Bot.ServerConfig.Name, Bot.ServerConfig.Name, command.Nick.Nickname, type, permission, channels, nicknames, trigger, response, command.TimeStamp});
  174. string message = string.Format("You now have \u0002{0}\u0002 custom commands set.", currentCommands.Count + 1);
  175. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, message);
  176. }
  177. else
  178. {
  179. string errorMessage = string.Format("\u0002{0}\u0002 is already set as a command you can access.", trigger);
  180. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, errorMessage, true);
  181. }
  182. }
  183. else
  184. {
  185. string errorMessage = string.Format("You can not have more than \u0002{0}\u0002 custom commands set. Please delete one before adding another.", maxTriggers);
  186. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, errorMessage, true);
  187. }
  188. }
  189. else
  190. {
  191. string errorMessage = string.Format("There is already a command for \u0002{0}\u0002.", trigger);
  192. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, errorMessage, true);
  193. }
  194. }
  195. private void DeleteCommand(CommandMessage command)
  196. {
  197. List<Dictionary<string, object>> foundTriggers = GetTrigger(command.Nick, "Self", string.Empty, string.Empty, null, true);
  198. int triggerIndex = HasValidCommandID(command);
  199. if (triggerIndex > 0)
  200. {
  201. string query = "DELETE FROM `customcommands` " +
  202. "WHERE `id` = {0}";
  203. Bot.Database.Execute(query, new object[] { foundTriggers[triggerIndex - 1]["id"] });
  204. string message = string.Format("Command \u0002{0}\u0002 has been deleted.", triggerIndex);
  205. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, message);
  206. }
  207. else
  208. {
  209. string errorMessage = string.Format("\u0002{0}\u0002 is not a valid command number.", command.Arguments["ID"]);
  210. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, errorMessage, true);
  211. }
  212. }
  213. private void EditCommand(CommandMessage command, string type, string permission, string channels, string nicknames, string trigger, string response)
  214. {
  215. List<Dictionary<string, object>> foundTriggers = GetTrigger(command.Nick, "Self", string.Empty, string.Empty, null, true);
  216. int triggerIndex = HasValidCommandID(command);
  217. if (triggerIndex > 0)
  218. {
  219. string query = "UPDATE `customcommands` SET " +
  220. "`type` = {0}, " +
  221. "`permission` = {1}, " +
  222. "`channels` = {2}, " +
  223. "`nicknames` = {3}, " +
  224. "`trigger` = {4}, " +
  225. "`response` = {5} " +
  226. "WHERE `id` = {6}";
  227. Bot.Database.Execute(query, new object[] { type, permission, channels, nicknames, trigger, response, foundTriggers[triggerIndex - 1]["id"] });
  228. string message = string.Format("\u0002{0}\u0002 now has the response: {1}", trigger, response);
  229. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, message);
  230. }
  231. else
  232. {
  233. string errorMessage = string.Format("\u0002{0}\u0002 is not a valid command number.", command.Arguments["ID"]);
  234. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, errorMessage, true);
  235. }
  236. }
  237. private void ViewTriggers(CommandMessage command)
  238. {
  239. List<Dictionary<string, object>> foundTriggers = GetTrigger(command.Nick, "Self", string.Empty, string.Empty, null, true);
  240. if (foundTriggers.Any())
  241. {
  242. int index = 1;
  243. foreach (Dictionary<string, object> foundTrigger in foundTriggers)
  244. {
  245. string allowed = string.Empty;
  246. switch (foundTrigger["permission"].ToString().ToLower())
  247. {
  248. case "channels":
  249. allowed = " " + foundTrigger["channels"];
  250. break;
  251. case "nicks":
  252. allowed = " " + foundTrigger["nicknames"];
  253. break;
  254. }
  255. string response = string.Format("Command #{0} [{1}{2}] \u0002{3}{4}\u0002: {5}", index, foundTrigger["permission"], allowed, Bot.ServerConfig.CommandPrefix, foundTrigger["trigger"], foundTrigger["response"]);
  256. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, response, true);
  257. index++;
  258. }
  259. }
  260. else
  261. {
  262. string errorMessage = "There are no custom commands for you.";
  263. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, errorMessage, true);
  264. }
  265. }
  266. private void ViewTrigger(CommandMessage command, string trigger)
  267. {
  268. List<Dictionary<string, object>> foundTriggers = GetTrigger(command.Nick, null, command.Location, command.Nick.Nickname, trigger);
  269. if (foundTriggers.Any())
  270. {
  271. foreach (Dictionary<string, object> foundTrigger in foundTriggers)
  272. {
  273. string allowed = string.Empty;
  274. switch (foundTrigger["permission"].ToString().ToLower())
  275. {
  276. case "channels":
  277. allowed = " " + foundTrigger["channels"];
  278. break;
  279. case "nicks":
  280. allowed = " " + foundTrigger["nicknames"];
  281. break;
  282. }
  283. string response = string.Format("[{0}{1}] \u0002{2}{3}\u0002: {4}", foundTrigger["permission"], allowed, Bot.ServerConfig.CommandPrefix, foundTrigger["trigger"], foundTrigger["response"]);
  284. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, response, true);
  285. }
  286. }
  287. else
  288. {
  289. string errorMessage = string.Format("\u0002{0}\u0002 is not set as a custom command for that search.", trigger);
  290. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, errorMessage, true);
  291. }
  292. }
  293. private List<Dictionary<string, object>> GetTrigger(Nick caller, string permission, string channels, string nicknames, string trigger = null, bool edit = false)
  294. {
  295. string search = "SELECT * FROM `customcommands`" +
  296. " WHERE" +
  297. " `server_id` = (SELECT `id` FROM `servers` WHERE `name` = {0})";
  298. int argCount = 1;
  299. List<object> arguments = new List<object>();
  300. arguments.Add(Bot.ServerConfig.Name);
  301. if (!string.IsNullOrEmpty(trigger))
  302. {
  303. search += " AND `trigger` = {" + argCount++ + "}";
  304. arguments.Add(trigger);
  305. }
  306. search += " AND ";
  307. string combine = "AND";
  308. if (string.IsNullOrEmpty(permission))
  309. {
  310. search += "(";
  311. combine = "OR";
  312. }
  313. if (!string.IsNullOrEmpty(channels) && (string.IsNullOrEmpty(permission) || permission.ToLower() == "channels"))
  314. {
  315. Regex channelRegex = new Regex(@"(?<Prefix>[\#]+)?(?<Prefix>[\&]+)?(?<Channel>[^\#|^\&|^,]+)");
  316. MatchCollection matches = channelRegex.Matches(channels);
  317. if (matches.Count > 0)
  318. {
  319. search += "(";
  320. foreach (Match match in matches)
  321. {
  322. if (match.Success)
  323. {
  324. search += "`channels` REGEXP {" + argCount++ + "} OR ";
  325. arguments.Add(string.Format(@"{0}[[:<:]]{1}[[:>:]]", string.Join(@"\\", match.Groups["Prefix"].ToString().ToCharArray()), match.Groups["Channel"]));
  326. }
  327. }
  328. search += "`nick_id` = (SELECT `nicks`.`id` FROM `nicks` INNER JOIN `servers` ON `servers`.`id` = `nicks`.`server_id` WHERE `servers`.`name` = {" + argCount++ + "} && `nickname` = {" + argCount++ + "})";
  329. search += (edit) ? ")" : " OR `permission` = 'all')";
  330. arguments.Add(Bot.ServerConfig.Name);
  331. arguments.Add(caller.Nickname);
  332. }
  333. }
  334. if (!string.IsNullOrEmpty(nicknames) && (string.IsNullOrEmpty(permission) || permission.ToLower() == "nicks"))
  335. {
  336. if (!string.IsNullOrEmpty(channels) && string.IsNullOrEmpty(permission))
  337. search += " " + combine + " ";
  338. Regex nickRegex = new Regex(@"(?<Nickname>[^,]+)");
  339. MatchCollection matches = nickRegex.Matches(nicknames);
  340. if (matches.Count > 0)
  341. {
  342. search += "(";
  343. foreach (Match match in matches)
  344. {
  345. if (match.Success)
  346. {
  347. search += "`nicknames` REGEXP {" + argCount++ + "} OR ";
  348. arguments.Add(string.Format(@"[[:<:]]{0}[[:>:]]", match.Groups["Nickname"]));
  349. }
  350. }
  351. search += "`nick_id` = (SELECT `nicks`.`id` FROM `nicks` INNER JOIN `servers` ON `servers`.`id` = `nicks`.`server_id` WHERE `servers`.`name` = {" + argCount++ + "} && `nickname` = {" + argCount++ + "})";
  352. search += (edit) ? ")" : " OR `permission` = 'all')";
  353. arguments.Add(Bot.ServerConfig.Name);
  354. arguments.Add(caller.Nickname);
  355. }
  356. }
  357. if (string.IsNullOrEmpty(permission) || permission.ToLower() == "self")
  358. {
  359. if (!string.IsNullOrEmpty(channels) || !string.IsNullOrEmpty(nicknames))
  360. search += " " + combine + " ";
  361. search += "(`nick_id` = (SELECT `nicks`.`id` FROM `nicks` INNER JOIN `servers` ON `servers`.`id` = `nicks`.`server_id` WHERE `servers`.`name` = {" + argCount++ + "} && `nickname` = {" + argCount++ + "})";
  362. search += (edit) ? ")" : " OR `permission` = 'all')";
  363. arguments.Add(Bot.ServerConfig.Name);
  364. arguments.Add(caller.Nickname);
  365. }
  366. if (string.IsNullOrEmpty(permission))
  367. {
  368. search += ")";
  369. }
  370. return Bot.Database.Query(search, arguments.ToArray());
  371. }
  372. private void ExecuteCommand(MessageType messageType, string location, Nick nick, Dictionary<string, object> trigger)
  373. {
  374. string type = trigger["type"].ToString();
  375. string message = trigger["response"].ToString();
  376. switch (type.ToLower())
  377. {
  378. case "response":
  379. message = "\u200B" + message;
  380. SendResponse(messageType, location, nick.Nickname, message);
  381. break;
  382. case "command":
  383. Bot.ExecuteCommand(Bot.ServerConfig.CommandPrefix + message, location, messageType, nick);
  384. break;
  385. case "list":
  386. // todo handle list commands
  387. break;
  388. }
  389. }
  390. }
  391. }