vrobot3 is a chat bot for IRC and Discord.
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.

150 lines
4.6KB

  1. //-----------------------------------------------------------------------------
  2. //
  3. // Copyright © 2016 Project Golan
  4. //
  5. // See "LICENSE" for more information.
  6. //
  7. //-----------------------------------------------------------------------------
  8. //
  9. // Data for the Bot class.
  10. //
  11. //-----------------------------------------------------------------------------
  12. using System;
  13. using System.Threading.Tasks;
  14. using System.Collections.Generic;
  15. using System.Linq;
  16. namespace ProjectGolan.Vrobot3
  17. {
  18. // Delegate type for bot commands.
  19. public delegate void BotCommand(User usr, Channel channel, String msg);
  20. // Dictionary of bot commands.
  21. public class CommandDict : Dictionary<String, BotCommandStructure> {}
  22. public class CommandFuncDict :
  23. Dictionary<String, Tuple<IBotModule, BotCommandStructure>> {}
  24. public partial class Bot
  25. {
  26. private readonly Dictionary<ulong, String> lastLine;
  27. private readonly Client.IChatClient client;
  28. public List<IBotModule> modules {get; private set;}
  29. public CommandFuncDict cmdfuncs {get; private set;}
  30. public readonly BotInfo info;
  31. public Client.ClientInfo clientInfo => client.info;
  32. public Client.IChatClient getClient() => client;
  33. public Bot(BotInfo info)
  34. {
  35. this.info = info;
  36. this.lastLine = new Dictionary<ulong, String>();
  37. this.modules = new List<IBotModule>();
  38. this.cmdfuncs = new CommandFuncDict();
  39. switch(info.serverType)
  40. {
  41. case "IRC": this.client = new Client.ClientIRC(this); break;
  42. case "Discord": this.client = new Client.ClientDiscord(this); break;
  43. default: throw new BotConfigurationException("Invalid server type.");
  44. }
  45. var modClasses =
  46. from assembly in AppDomain.CurrentDomain.GetAssemblies()
  47. from type in assembly.GetTypes()
  48. where moduleIsValid(type)
  49. select type;
  50. foreach(var mod in modClasses)
  51. modules.Add(Activator.CreateInstance(mod, this) as IBotModule);
  52. foreach(var mod in modules)
  53. foreach(var kvp in mod.commands)
  54. cmdfuncs.Add(kvp.Key, Tuple.Create(mod, kvp.Value));
  55. }
  56. public void connect() => client.connect();
  57. public void action(Channel channel, String msg) =>
  58. client.sendAction(channel, msg);
  59. public void action(ulong id, String msg) =>
  60. client.sendAction(client.getChannel(id), msg);
  61. public void message(Channel channel, String msg) =>
  62. client.sendMessage(channel, msg);
  63. public void message(ulong id, String msg) =>
  64. client.sendMessage(client.getChannel(id), msg);
  65. public void messageRaw(Channel channel, String msg) =>
  66. client.sendMessageRaw(channel, msg);
  67. public void messageRaw(ulong id, String msg) =>
  68. client.sendMessageRaw(client.getChannel(id), msg);
  69. public void reply(User usr, Channel channel, String msg) =>
  70. message(channel, usr.name + ": " + msg);
  71. public void reply(User usr, ulong id, String msg) =>
  72. message(id, usr.name + ": " + msg);
  73. public void disconnect()
  74. {
  75. cmdfuncs.Clear();
  76. modules.Clear();
  77. client.disconnect();
  78. }
  79. private bool checkMod(Type mod, String modName)
  80. {
  81. const String modBase = "ProjectGolan.Vrobot3.Modules.";
  82. var modFull = modBase + modName.Substring(1);
  83. Type type;
  84. if(modName == "*") return true;
  85. else if(modName[0] == '@') type = Type.GetType(modFull);
  86. else type = Type.GetType(modName);
  87. return type == mod;
  88. }
  89. private bool procModPermissions(Type mod, String[] e, String[] d = null)
  90. {
  91. if(e == null)
  92. return false;
  93. bool ret = false;
  94. foreach(var modName in e)
  95. if(checkMod(mod, modName)) {ret = true; break;}
  96. if(d != null)
  97. foreach(var modName in d)
  98. if(checkMod(mod, modName)) return false;
  99. return ret;
  100. }
  101. public bool checkModPermissions(Channel channel, Type mod)
  102. {
  103. String[] e = null;
  104. String[] d = null;
  105. if( info.enables.ContainsKey("*")) e = info.enables["*"];
  106. if(info.disables.ContainsKey("*")) d = info.disables["*"];
  107. bool ret = procModPermissions(mod, e, d);
  108. String name = channel.name;
  109. e = info.enables.ContainsKey(name) ? info.enables[name] : null;
  110. d = info.disables.ContainsKey(name) ? info.disables[name] : null;
  111. return ret || procModPermissions(mod, e, d);
  112. }
  113. }
  114. }
  115. // EOF