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.

Bot.cs 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Net;
  6. using System.Reflection;
  7. using System.Threading.Tasks;
  8. using Combot.IRCServices;
  9. using Combot.Configurations;
  10. using Combot.IRCServices.Messaging;
  11. using Combot.Modules;
  12. using Module = Combot.Modules.Module;
  13. namespace Combot
  14. {
  15. public class Bot
  16. {
  17. public event Action<CommandMessage> CommandReceivedEvent;
  18. public event Action<BotError> ErrorEvent;
  19. public ServerConfig ServerConfig;
  20. public IRC IRC;
  21. public bool Connected = false;
  22. public static Dictionary<PrivilegeMode, AccessType> AccessTypeMapping = new Dictionary<PrivilegeMode, AccessType>() { { PrivilegeMode.v, AccessType.Voice }, { PrivilegeMode.h, AccessType.HalfOperator }, { PrivilegeMode.o, AccessType.Operator }, { PrivilegeMode.a, AccessType.SuperOperator }, { PrivilegeMode.q, AccessType.Founder } };
  23. private List<Module> _Modules;
  24. public Bot(ServerConfig serverConfig)
  25. {
  26. IRC = new IRC();
  27. _Modules = new List<Module>();
  28. ServerConfig = serverConfig;
  29. IRC.ConnectEvent += HandleConnectEvent;
  30. IRC.DisconnectEvent += HandleDisconnectEvent;
  31. IRC.Message.ServerReplyEvent += HandleReplyEvent;
  32. IRC.Message.ChannelMessageReceivedEvent += HandleChannelMessageReceivedEvent;
  33. LoadModules();
  34. }
  35. /// <summary>
  36. /// Trys to connect to one of the IPs of the given hostname. If the connection was successful, it will login the nick.
  37. /// </summary>
  38. public void Connect()
  39. {
  40. bool serverConnected = false;
  41. int i = 0;
  42. do
  43. {
  44. if (ServerConfig.Hosts.Count > i)
  45. {
  46. IPAddress[] ipList = Dns.GetHostAddresses(ServerConfig.Hosts[i].Host);
  47. foreach (IPAddress ip in ipList)
  48. {
  49. serverConnected = IRC.Connect(ip, ServerConfig.Hosts[i].Port, 5000);
  50. if (serverConnected)
  51. {
  52. break;
  53. }
  54. }
  55. i++;
  56. }
  57. else
  58. {
  59. break;
  60. }
  61. }
  62. while (!serverConnected);
  63. if (serverConnected)
  64. {
  65. IRC.Login(ServerConfig.Name, new Nick() { Nickname = ServerConfig.Nickname, Host = Dns.GetHostName(), Realname = ServerConfig.Realname, Username = ServerConfig.Username });
  66. }
  67. }
  68. /// <summary>
  69. /// Disconnects from the current server.
  70. /// </summary>
  71. public void Disconnect()
  72. {
  73. IRC.Disconnect();
  74. Connected = false;
  75. }
  76. public void LoadModules()
  77. {
  78. foreach (Module module in ServerConfig.Modules)
  79. {
  80. if (module.Enabled && !_Modules.Exists(mod => mod.ClassName == module.ClassName))
  81. {
  82. Module loadedModule = module.CreateInstance(this);
  83. if (loadedModule.Loaded)
  84. {
  85. _Modules.Add(loadedModule);
  86. }
  87. }
  88. }
  89. }
  90. private void HandleConnectEvent()
  91. {
  92. Connected = true;
  93. }
  94. private void HandleDisconnectEvent()
  95. {
  96. Connected = false;
  97. }
  98. private void HandleReplyEvent(object sender, IReply e)
  99. {
  100. if (e.GetType() == typeof(ServerReplyMessage))
  101. {
  102. ServerReplyMessage reply = (ServerReplyMessage)e;
  103. // If the reply is Welcome, that means we are fully connected to the server and can now join the auto-join channels.
  104. if (reply.ReplyCode == IRCReplyCode.RPL_WELCOME && Connected)
  105. {
  106. foreach (ChannelConfig channel in ServerConfig.Channels)
  107. {
  108. IRC.SendJoin(channel.Name, channel.Key);
  109. }
  110. }
  111. }
  112. }
  113. private void HandleChannelMessageReceivedEvent(object sender, ChannelMessage e)
  114. {
  115. // The message was a command
  116. if (e.Message.StartsWith(ServerConfig.CommandPrefix))
  117. {
  118. if (!ServerConfig.ChannelBlacklist.Contains(e.Channel)
  119. && !ServerConfig.NickBlacklist.Contains(e.Sender.Nickname)
  120. )
  121. {
  122. ParseCommandMessage(e.TimeStamp, e.Message, e.Sender, e.Channel, LocationType.Channel);
  123. }
  124. }
  125. }
  126. private void ParseCommandMessage(DateTime timestamp, string message, Nick sender, string location, LocationType locationType)
  127. {
  128. // Extract command and arguments
  129. string[] msgArgs = message.Split(new[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries);
  130. string command = msgArgs[0].Remove(0, ServerConfig.CommandPrefix.Length);
  131. List<string> argsOnly = msgArgs.ToList();
  132. argsOnly.RemoveAt(0);
  133. Module module = _Modules.Find(mod => mod.Commands.Exists(c => c.Triggers.Contains(command)) && mod.Loaded);
  134. if (module != null)
  135. {
  136. Command cmd = module.Commands.Find(c => c.Triggers.Contains(command));
  137. if (cmd != null)
  138. {
  139. CommandMessage newCommand = new CommandMessage();
  140. newCommand.Nick.Copy(sender);
  141. IRC.Channels.ForEach(channel => channel.Nicks.ForEach(nick =>
  142. {
  143. if (nick.Nickname == newCommand.Nick.Nickname)
  144. {
  145. newCommand.Nick.AddPrivileges(nick.Privileges);
  146. }
  147. }));
  148. newCommand.TimeStamp = timestamp;
  149. newCommand.Location = location;
  150. newCommand.LocationType = locationType;
  151. newCommand.Command = command;
  152. if (argsOnly.Count > 0)
  153. {
  154. string[] argSplit = argsOnly.First()
  155. .Split(new[] {' '}, cmd.Arguments.Count + 1, StringSplitOptions.RemoveEmptyEntries);
  156. for (int i = 0; i < cmd.Arguments.Count; i++)
  157. {
  158. newCommand.Arguments.Add(argSplit[i]);
  159. }
  160. }
  161. if (CommandReceivedEvent != null)
  162. {
  163. CommandReceivedEvent(newCommand);
  164. }
  165. }
  166. }
  167. }
  168. }
  169. }