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.

Relay.cs 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. using Combot.IRCServices;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using Combot.IRCServices.Messaging;
  6. namespace Combot.Modules.Plugins
  7. {
  8. public class Relay : Module
  9. {
  10. public override void Initialize()
  11. {
  12. Bot.CommandReceivedEvent += HandleCommandEvent;
  13. Bot.IRC.Message.CTCPMessageReceivedEvent += CTCPRelayHandler;
  14. Bot.IRC.Message.CTCPNoticeReceivedEvent += CTCPRelayHandler;
  15. Bot.IRC.Message.ChannelMessageReceivedEvent += RelayChannelMessage;
  16. Bot.IRC.Message.PrivateMessageReceivedEvent += RelayPrivateMessage;
  17. Bot.IRC.Message.ChannelNoticeReceivedEvent += RelayChannelNotice;
  18. Bot.IRC.Message.PrivateNoticeReceivedEvent += RelayPrivateNotice;
  19. Bot.IRC.Message.ChannelModeChangeEvent += RelayChannelMode;
  20. Bot.IRC.Message.UserModeChangeEvent += RelayUserMode;
  21. Bot.IRC.Message.JoinChannelEvent += RelayChannelJoin;
  22. Bot.IRC.Message.InviteChannelEvent += RelayChannelInvite;
  23. Bot.IRC.Message.PartChannelEvent += RelayChannelPart;
  24. Bot.IRC.Message.KickEvent += RelayChannelKick;
  25. Bot.IRC.Message.QuitEvent += RelayQuit;
  26. }
  27. public override void ParseCommand(CommandMessage command)
  28. {
  29. Command foundCommand = Commands.Find(c => c.Triggers.Contains(command.Command));
  30. switch (foundCommand.Name)
  31. {
  32. case "Relay":
  33. string method = command.Arguments["Method"];
  34. switch (method.ToLower())
  35. {
  36. case "add":
  37. AddRelay(command);
  38. break;
  39. case "edit":
  40. EditRelay(command);
  41. break;
  42. case "delete":
  43. case "del":
  44. DeleteRelay(command);
  45. break;
  46. case "view":
  47. ViewRelay(command);
  48. break;
  49. }
  50. break;
  51. }
  52. }
  53. private void AddRelay(CommandMessage command)
  54. {
  55. string source = command.Arguments.ContainsKey("Source") ? command.Arguments["Source"] : command.Location;
  56. string target = command.Arguments.ContainsKey("Target") ? command.Arguments["Target"] : command.Nick.Nickname;
  57. string type = command.Arguments.ContainsKey("Type") ? command.Arguments["Type"] : "Message";
  58. string modes = command.Arguments.ContainsKey("Modes") ? command.Arguments["Modes"] : string.Empty;
  59. // verify access in source and target
  60. if (!CheckAccess(source, command.Nick.Nickname, command.Access))
  61. {
  62. string invalid = string.Format("You do not have permission to use '{0}' as a source.", source);
  63. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, invalid, true);
  64. return;
  65. }
  66. if (!CheckAccess(target, command.Nick.Nickname, command.Access))
  67. {
  68. string invalid = string.Format("You do not have permission to use '{0}' as a target.", source);
  69. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, invalid, true);
  70. return;
  71. }
  72. RelayType relayType = RelayType.Message;
  73. Enum.TryParse(type, out relayType);
  74. AddNick(command.Nick);
  75. string query = "INSERT INTO `relays` SET " +
  76. "`server_id` = (SELECT `id` FROM `servers` WHERE `name` = {0}), " +
  77. "`nick_id` = (SELECT `nicks`.`id` FROM `nicks` INNER JOIN `servers` ON `servers`.`id` = `nicks`.`server_id` WHERE `servers`.`name` = {1} && `nickname` = {2}), " +
  78. "`source` = {3}, " +
  79. "`target` = {4}, " +
  80. "`type` = {5}, " +
  81. "`modes` = {6}, " +
  82. "`date_added` = {7}";
  83. Bot.Database.Execute(query, new object[] { Bot.ServerConfig.Name, Bot.ServerConfig.Name, command.Nick.Nickname, source, target, (int)relayType, modes, command.TimeStamp });
  84. List<Dictionary<string, object>> results = GetRelayList(command.Nick.Nickname);
  85. string relayMessage = string.Format("Added relay from \u0002{0}\u0002 to \u0002{1}\u0002. You now have \u0002{2}\u0002 relays created.", source, target, results.Count);
  86. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, relayMessage);
  87. }
  88. private void EditRelay(CommandMessage command)
  89. {
  90. string source = command.Arguments.ContainsKey("Source") ? command.Arguments["Source"] : command.Location;
  91. string target = command.Arguments.ContainsKey("Target") ? command.Arguments["Target"] : command.Nick.Nickname;
  92. string type = command.Arguments.ContainsKey("Type") ? command.Arguments["Type"] : "Message";
  93. string modes = command.Arguments.ContainsKey("Modes") ? command.Arguments["Modes"] : string.Empty;
  94. // verify access in source and target
  95. if (!CheckAccess(source, command.Nick.Nickname, command.Access))
  96. {
  97. string invalid = string.Format("You do not have permission to use '{0}' as a source.", source);
  98. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, invalid, true);
  99. return;
  100. }
  101. if (!CheckAccess(target, command.Nick.Nickname, command.Access))
  102. {
  103. string invalid = string.Format("You do not have permission to use '{0}' as a target.", source);
  104. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, invalid, true);
  105. return;
  106. }
  107. RelayType relayType = RelayType.Message;
  108. Enum.TryParse(type, out relayType);
  109. int num = HasValidID(command);
  110. if (num > 0)
  111. {
  112. List<Dictionary<string, object>> results = GetRelayList(command.Nick.Nickname);
  113. int id = Convert.ToInt32(results[num - 1]["id"]);
  114. string query = "UPDATE `relays` SET " +
  115. "`source` = {0}, " +
  116. "`target` = {1}, " +
  117. "`type` = {2}, " +
  118. "`modes` = {3} " +
  119. "WHERE `id` = {4}";
  120. Bot.Database.Execute(query, new object[] { source, target, (int)relayType, modes, id });
  121. string relayMessage = string.Format("Updated relay \u0002{0}\u0002 to be from \u0002{1}\u0002 to \u0002{2}\u0002.", num, source, target);
  122. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, relayMessage);
  123. }
  124. else
  125. {
  126. string invalid = "Invalid relay ID.";
  127. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, invalid, true);
  128. }
  129. }
  130. private void DeleteRelay(CommandMessage command)
  131. {
  132. int num = HasValidID(command);
  133. if (num > 0)
  134. {
  135. List<Dictionary<string, object>> results = GetRelayList(command.Nick.Nickname);
  136. int id = Convert.ToInt32(results[num - 1]["id"]);
  137. string query = "DELETE FROM `relays` " +
  138. "WHERE `id` = {0}";
  139. Bot.Database.Execute(query, new object[] { id });
  140. string relayMessage = string.Format("Relay #\u0002{0}\u0002 has been deleted.", num);
  141. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, relayMessage);
  142. }
  143. else
  144. {
  145. string invalid = "Invalid relay ID.";
  146. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, invalid, true);
  147. }
  148. }
  149. private void ViewRelay(CommandMessage command)
  150. {
  151. List<Dictionary<string, object>> results = GetRelayList(command.Nick.Nickname);
  152. if (command.Arguments.ContainsKey("ID"))
  153. {
  154. int num = HasValidID(command);
  155. if (num > 0)
  156. {
  157. int relayInt = 0;
  158. Int32.TryParse(results[num - 1]["type"].ToString(), out relayInt);
  159. string relayMessage = string.Format("Relay #\u0002{0}\u0002 - Source: \u0002{1}\u0002 | Target: \u0002{2}\u0002 | Type: \u0002{3}\u0002",
  160. num, results[num - 1]["source"], results[num - 1]["target"], (RelayType)relayInt);
  161. if ((RelayType)relayInt == RelayType.Mode)
  162. {
  163. relayMessage = string.Format("{0} | Modes: \u0002{1}\u0002", relayMessage, results[num - 1]["modes"]);
  164. }
  165. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, relayMessage);
  166. }
  167. else
  168. {
  169. string invalid = "Invalid relay ID.";
  170. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, invalid, true);
  171. }
  172. }
  173. else
  174. {
  175. if (results.Any())
  176. {
  177. for (int i = 0; i < results.Count; i++)
  178. {
  179. int relayInt = 0;
  180. Int32.TryParse(results[i]["type"].ToString(), out relayInt);
  181. string relayMessage = string.Format("Relay #\u0002{0}\u0002 - Source: \u0002{1}\u0002 | Target: \u0002{2}\u0002 | Type: \u0002{3}\u0002",
  182. i + 1, results[i]["source"], results[i]["target"], (RelayType)relayInt);
  183. if ((RelayType)relayInt == RelayType.Mode)
  184. {
  185. relayMessage = string.Format("{0} | Modes: \u0002{1}\u0002", relayMessage, results[i]["modes"]);
  186. }
  187. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, relayMessage, true);
  188. }
  189. }
  190. else
  191. {
  192. string invalid = "You do not have any relays set.";
  193. SendResponse(command.MessageType, command.Location, command.Nick.Nickname, invalid, true);
  194. }
  195. }
  196. }
  197. private List<Dictionary<string, object>> GetRelayList(string nickname)
  198. {
  199. string search = "SELECT `relays`.`id`, `relays`.`source`, `relays`.`target`, `relays`.`type`, `relays`.`modes` FROM `relays` " +
  200. "INNER JOIN `nicks` " +
  201. "ON `relays`.`nick_id` = `nicks`.`id` " +
  202. "INNER JOIN `servers` " +
  203. "ON `nicks`.`server_id` = `servers`.`id` " +
  204. "WHERE `servers`.`name` = {0} AND `nicks`.`nickname` = {1}";
  205. return Bot.Database.Query(search, new object[] { Bot.ServerConfig.Name, nickname });
  206. }
  207. private List<Dictionary<string, object>> GetRelayList(string source, RelayType type)
  208. {
  209. string search = "SELECT `relays`.`target`, `relays`.`modes` FROM `relays` " +
  210. "INNER JOIN `servers` " +
  211. "ON `relays`.`server_id` = `servers`.`id` " +
  212. "WHERE `servers`.`name` = {0} AND `relays`.`source` = {1} AND `relays`.`type` = {2}";
  213. return Bot.Database.Query(search, new object[] { Bot.ServerConfig.Name, source, (int)type });
  214. }
  215. private bool CheckAccess(string source, string nick, List<AccessType> types)
  216. {
  217. // Owners get to have all the fun
  218. if (Bot.ServerConfig.Owners.Contains(nick))
  219. return true;
  220. // The source is a channel
  221. if (Bot.IRC.Channels.Exists(chan => chan.Name == source))
  222. {
  223. foreach (AccessType access in types)
  224. {
  225. bool valid = Bot.CheckChannelAccess(source, nick, AccessType.Operator);
  226. if (!valid)
  227. return false;
  228. }
  229. }
  230. // The source is a nickname
  231. else
  232. {
  233. if (source != nick)
  234. return false;
  235. }
  236. return true;
  237. }
  238. /* Returns the parsed ID field if valid, otherwise returns 0 */
  239. private int HasValidID(CommandMessage command)
  240. {
  241. int num = 0;
  242. int ret = 0;
  243. List<Dictionary<string, object>> results = GetRelayList(command.Nick.Nickname);
  244. if (int.TryParse(command.Arguments["ID"], out num))
  245. {
  246. if (results.Count >= num && num > 0)
  247. {
  248. ret = num;
  249. }
  250. }
  251. return ret;
  252. }
  253. private void ProcessRelay(string source, RelayType type, string message)
  254. {
  255. switch (type)
  256. {
  257. }
  258. }
  259. private void RelayQuit(object sender, QuitInfo e)
  260. {
  261. string msg = string.Format("{0} has quit. ({1})", e.Nick.Nickname, e.Message);
  262. ProcessRelay(e.Nick.Nickname, RelayType.Quit, msg);
  263. }
  264. private void RelayChannelKick(object sender, KickInfo e)
  265. {
  266. string msg = string.Format("[{0}] {1} has kicked {2} ({3})", e.Channel, e.Nick.Nickname, e.KickedNick.Nickname, e.Reason);
  267. ProcessRelay(e.Channel, RelayType.Kick, msg);
  268. }
  269. private void RelayChannelPart(object sender, PartChannelInfo e)
  270. {
  271. string msg = string.Format("[{0}] {1} has left.", e.Channel, e.Nick.Nickname);
  272. ProcessRelay(e.Channel, RelayType.Part, msg);
  273. }
  274. private void RelayChannelInvite(object sender, InviteChannelInfo e)
  275. {
  276. string msg = string.Format("[{0}] {1} invited {2}", e.Channel, e.Requester.Nickname, e.Recipient.Nickname);
  277. ProcessRelay(e.Channel, RelayType.Part, msg);
  278. }
  279. private void RelayChannelJoin(object sender, JoinChannelInfo e)
  280. {
  281. string msg = string.Format("[{0}] {1} ({2}) has joined.", e.Channel, e.Nick.Nickname, e.Nick.Host);
  282. ProcessRelay(e.Channel, RelayType.Part, msg);
  283. }
  284. private void RelayUserMode(object sender, UserModeChangeInfo e)
  285. {
  286. throw new NotImplementedException();
  287. }
  288. private void RelayChannelMode(object sender, ChannelModeChangeInfo e)
  289. {
  290. throw new NotImplementedException();
  291. }
  292. private void RelayPrivateNotice(object sender, PrivateNotice e)
  293. {
  294. throw new NotImplementedException();
  295. }
  296. private void RelayChannelNotice(object sender, ChannelNotice e)
  297. {
  298. throw new NotImplementedException();
  299. }
  300. private void RelayPrivateMessage(object sender, PrivateMessage e)
  301. {
  302. throw new NotImplementedException();
  303. }
  304. private void RelayChannelMessage(object sender, ChannelMessage e)
  305. {
  306. throw new NotImplementedException();
  307. }
  308. private void CTCPRelayHandler(object sender, CTCPMessage e)
  309. {
  310. throw new NotImplementedException();
  311. }
  312. }
  313. }