diff --git a/Bot/IRC_Bot.cpp b/Bot/IRC_Bot.cpp index b776b7a..d7a923e 100644 --- a/Bot/IRC_Bot.cpp +++ b/Bot/IRC_Bot.cpp @@ -30,8 +30,10 @@ using namespace Jupiter::literals; IRC_Bot::IRC_Bot(const Jupiter::INIFile::Section *in_primary_section, const Jupiter::INIFile::Section *in_secondary_section) : Client(in_primary_section, in_secondary_section) { IRC_Bot::commandPrefix = this->readConfigValue("Prefix"_jrs); + for (size_t i = 0; i != IRCMasterCommandList->size(); i++) - IRC_Bot::addCommand(IRCMasterCommandList->get(i)->copy()); + IRC_Bot::commands.add(IRCMasterCommandList->get(i)->copy()); + IRC_Bot::setCommandAccessLevels(); } @@ -45,9 +47,10 @@ IRC_Bot::~IRC_Bot() IRC_Bot::commands.emptyAndDelete(); } -void IRC_Bot::addCommand(IRCCommand *cmd) +void IRC_Bot::addCommand(IRCCommand *in_command) { - IRC_Bot::commands.add(cmd); + IRC_Bot::commands.add(in_command); + IRC_Bot::setCommandAccessLevels(in_command); } bool IRC_Bot::freeCommand(const Jupiter::ReadableString &trigger) @@ -101,11 +104,11 @@ Jupiter::StringL IRC_Bot::getTriggers(Jupiter::ArrayList &cmds) return r; } -void IRC_Bot::setCommandAccessLevels() +void IRC_Bot::setCommandAccessLevels(IRCCommand *in_command) { - auto set_command_access_levels = [this](const Jupiter::ReadableString §ion_name) + auto set_command_access_levels = [this, in_command](const Jupiter::ReadableString §ion_name) { - Jupiter::INIFile::Section *section = g_config->getSection(section_name); + Jupiter::INIFile::Section *section = serverManager->getConfig().getSection(section_name); if (section != nullptr) { @@ -134,7 +137,7 @@ void IRC_Bot::setCommandAccessLevels() tmp_sub_key.shiftRight(5); // shift beyond "Type." command = this->getCommand(tmp_key); - if (command != nullptr) + if (command != nullptr && (in_command == nullptr || in_command == command)) command->setAccessLevel(tmp_sub_key.asInt(), pair->getValue().asInt()); } else if (tmp_sub_key.findi("Channel."_jrs) == 0) @@ -143,7 +146,7 @@ void IRC_Bot::setCommandAccessLevels() // Assign access level to command (if command exists) command = this->getCommand(tmp_key); - if (command != nullptr) + if (command != nullptr && (in_command == nullptr || in_command == command)) command->setAccessLevel(tmp_sub_key, pair->getValue().asInt()); } } @@ -151,7 +154,7 @@ void IRC_Bot::setCommandAccessLevels() { // Assign access level to command (if command exists) command = this->getCommand(pair->getKey()); - if (command != nullptr) + if (command != nullptr && (in_command == nullptr || in_command == command)) command->setAccessLevel(pair->getValue().asInt()); } } diff --git a/Bot/IRC_Bot.h b/Bot/IRC_Bot.h index 1842a7f..04d8c31 100644 --- a/Bot/IRC_Bot.h +++ b/Bot/IRC_Bot.h @@ -49,12 +49,12 @@ public: /** * @brief Pulls the configured access levels from the config and applies them. */ - void setCommandAccessLevels(); + void setCommandAccessLevels(IRCCommand *in_command = nullptr); /** * @brief Adds a command to the command list. */ - void addCommand(IRCCommand *cmd); + void addCommand(IRCCommand *in_command); /** * @brief Removes a command from the command list. diff --git a/Bot/IRC_Command.cpp b/Bot/IRC_Command.cpp index bf76546..e84ec96 100644 --- a/Bot/IRC_Command.cpp +++ b/Bot/IRC_Command.cpp @@ -135,12 +135,8 @@ GenericCommandWrapperIRCCommand::GenericCommandWrapperIRCCommand(GenericCommandW GenericCommandWrapperIRCCommand::m_command = in_command.m_command; // Copy triggers - size_t index = 0; - while (index != GenericCommandWrapperIRCCommand::m_command->getTriggerCount()) - { + for (size_t index = 0; index != GenericCommandWrapperIRCCommand::m_command->getTriggerCount(); ++index) this->addTrigger(GenericCommandWrapperIRCCommand::m_command->getTrigger(index)); - ++index; - } } GenericCommandWrapperIRCCommand::GenericCommandWrapperIRCCommand(Jupiter::GenericCommand &in_command) : IRCCommand() @@ -148,12 +144,8 @@ GenericCommandWrapperIRCCommand::GenericCommandWrapperIRCCommand(Jupiter::Generi GenericCommandWrapperIRCCommand::m_command = &in_command; // Copy triggers - size_t index = 0; - while (index != GenericCommandWrapperIRCCommand::m_command->getTriggerCount()) - { + for (size_t index = 0; index != GenericCommandWrapperIRCCommand::m_command->getTriggerCount(); ++index) this->addTrigger(GenericCommandWrapperIRCCommand::m_command->getTrigger(index)); - ++index; - } if (serverManager != nullptr) serverManager->addCommand(this); diff --git a/Bot/Main.cpp b/Bot/Main.cpp index 725538a..ab38a92 100644 --- a/Bot/Main.cpp +++ b/Bot/Main.cpp @@ -29,7 +29,6 @@ #include "Jupiter/Plugin.h" #include "Jupiter/Timer.h" #include "IRC_Bot.h" -#include "ServerManager.h" #include "Console_Command.h" #include "IRC_Command.h" @@ -87,19 +86,13 @@ void inputLoop() } } -int rehash_config() -{ - o_config.reload(); - serverManager->OnConfigRehash(); - return 0; -} - int main(int argc, const char **args) { atexit(onExit); std::set_terminate(onTerminate); std::thread inputThread(inputLoop); Jupiter::ReferenceString command, plugins_directory, configs_directory; + size_t index; srand(static_cast(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count())); puts(Jupiter::copyright); @@ -131,8 +124,6 @@ int main(int argc, const char **args) exit(0); } - Jupiter::addOnRehash(rehash_config); - puts("Config loaded."); if (plugins_directory.isEmpty()) @@ -159,8 +150,10 @@ int main(int argc, const char **args) puts("No plugins to load!"); else { + // initialize plugins unsigned int nPlugins = pluginList.wordCount(WHITESPACE); printf("Attempting to load %u plugins..." ENDL, nPlugins); + for (unsigned int i = 0; i < nPlugins; i++) { Jupiter::ReferenceString plugin = Jupiter::ReferenceString::getWord(pluginList, i, WHITESPACE); @@ -168,6 +161,10 @@ int main(int argc, const char **args) fprintf(stderr, "WARNING: Failed to load plugin \"%.*s\"!" ENDL, plugin.size(), plugin.ptr()); else printf("\"%.*s\" loaded successfully." ENDL, plugin.size(), plugin.ptr()); } + + // OnPostInitialize + for (index = 0; index != Jupiter::plugins->size(); ++index) + Jupiter::plugins->get(index)->OnPostInitialize(); } if (consoleCommands->size() > 0) @@ -175,20 +172,6 @@ int main(int argc, const char **args) if (IRCMasterCommandList->size() > 0) printf("%u IRC Commands have been loaded into the master list." ENDL, IRCMasterCommandList->size()); - puts("Retreiving network list..."); - const Jupiter::ReadableString &serverList = o_config.get(Jupiter::ReferenceString::empty, "Servers"_jrs); - if (serverList == nullptr) - puts("Unable to find network list."); - else - { - unsigned int nServers = serverList.wordCount(WHITESPACE); - printf("Attempting to connect to %u servers..." ENDL, nServers); - for (unsigned int index = 0; index < nServers; ++index) - serverManager->addServer(Jupiter::ReferenceString::getWord(serverList, index, WHITESPACE)); - } - - puts("Sockets established."); - size_t index; while (1) { index = 0; @@ -198,7 +181,6 @@ int main(int argc, const char **args) else ++index; Jupiter_checkTimers(); - serverManager->think(); if (console_input.input_mutex.try_lock()) { diff --git a/Bot/ServerManager.cpp b/Bot/ServerManager.cpp index 1db4775..f62e042 100644 --- a/Bot/ServerManager.cpp +++ b/Bot/ServerManager.cpp @@ -75,8 +75,8 @@ void ServerManager::OnConfigRehash() { server = ServerManager::servers.get(index); - server->setPrimaryConfigSection(g_config->getSection(server->getConfigSection())); - server->setSecondaryConfigSection(g_config->getSection("Defualt"_jrs)); + server->setPrimaryConfigSection(m_config->getSection(server->getConfigSection())); + server->setSecondaryConfigSection(m_config->getSection("Defualt"_jrs)); server->setCommandAccessLevels(); } } @@ -109,7 +109,7 @@ IRC_Bot *ServerManager::getServer(size_t serverIndex) bool ServerManager::addServer(const Jupiter::ReadableString &serverConfig) { - IRC_Bot *server = new IRC_Bot(g_config->getSection(serverConfig), g_config->getSection("Default"_jrs)); + IRC_Bot *server = new IRC_Bot(m_config->getSection(serverConfig), m_config->getSection("Default"_jrs)); if (server->connect()) { ServerManager::servers.add(server); diff --git a/Bot/ServerManager.h b/Bot/ServerManager.h index feb63fc..414688e 100644 --- a/Bot/ServerManager.h +++ b/Bot/ServerManager.h @@ -77,7 +77,7 @@ public: size_t removeCommand(const Jupiter::ReadableString &command); /** - * @brief Called when g_config is rehashed + * @brief Called when m_config is rehashed */ void OnConfigRehash(); @@ -142,6 +142,20 @@ public: */ size_t size(); + /** + * @brief Fetches the configuration file being used + * + * @return Configuration file being used + */ + inline Jupiter::INIFile &getConfig() const { return *this->m_config; }; + + /** + * @brief Sets the configuration file to use + * + * @param Reference to the config file to use + */ + inline void setConfig(Jupiter::INIFile &in_config) { this->m_config = &in_config; }; + /** * Destructor for the ServerManager class. */ @@ -150,6 +164,9 @@ public: private: /** Underlying ArrayList of servers */ Jupiter::ArrayList servers; + + /** Config to read data from */ + Jupiter::INIFile *m_config = g_config; }; /** Pointer to an instance of the server manager. Note: DO NOT DELETE OR FREE THIS POINTER. */ diff --git a/Config.ini b/Config.ini index 4bc1471..3598451 100644 --- a/Config.ini +++ b/Config.ini @@ -15,132 +15,11 @@ ; DO NOT INCLUDE A PLUGIN'S FILE EXTENSION (.dll or .so). ; ; Settings: -; Plugins=String (Format: Plugin1 Plugin2) -; Servers=String (Format: Server1 Server2) -; PluginsDirectory=String (Default: Plugins\) -; ConfigsDirectory=String (Default: Configs\) +; Plugins=String (Format: Plugin1 Plugin2 ...); list of plugins to load +; PluginsDirectory=String (Default: Plugins\); directory where plugin binaries are +; ConfigsDirectory=String (Default: Configs\); directory where plugin configs are ; -Plugins=CoreCommands PluginManager ExtraCommands RenX.Core RenX.Commands RenX.Logging RenX.Medals -Servers=CnCIRC - -; [Default] -; -; This block is referenced only when a setting is not -; specified in a server's block. If a value is located -; neither in the server's block nor this one, then a -; crash or other unexpected behavior may occur. It is -; therefore recommended to have some sort of default -; value for all possible settings. -; -; Channel Configuring: -; Channels are given "types", which can determine various things such -; as auto-parting. A Channel of type -1 will automatically part itself. -; Channels can be configured in two ways: Active and Passive. -; Active channels are joined automatically. Passive channels are not, -; but can still be configured. -; -; Active Channels: -; Channel.Integer=String (Format: #Example [Password]) -; Channel.Integer.Type=Integer (-1 is auto-part) -; -; Passive Channels: -; Channel.String.Type=Integer -; -; Client address and port: -; The client address and port settings are entirely optional. These are -; only used under very special circumstances, and should otherwise -; not be specified. Unless you have a valid reason to need to bind the -; client to a specific address/port (such as connection limiations on a -; per-IP basis), do not set these. -; -; Settings: -; Hostname=String ("irc.cncirc.net" if unspecified) -; Port=Positive Integer (194 or 994 if unspecified) -; SSL=Bool -; STARTTLS=Bool (True if unspecified) -; Certificate=String (No SSL certificate used if unspecified) -; Key=String (Certificate file used if unspecified) -; SASL.Password=String (SASL disabled if unspecified) -; SASL.Account=String (Nickname if unspecified) -; Nick=String ("Jupiter" if unspecified) -; AltNick=String -; RealName=String ("Jupiter IRC Client" if unspecified) -; Channel.Type=Integer -; RawData.Integer=String (Example: OPER UserName Password) -; LogFile=String -; AutoJoinOnKick=Bool -; AutoPartMessage=String -; AutoReconnectDelay=Integer (Measured in seconds) -; MaxReconnectAttempts=Integer -; PrintOutput=Bool -; Prefix=String -; ClientAddress=String (Unused if unspecified) -; ClientPort=Integer (Unused if above is unspecified; defaults to 0) -; - -[Default] -Port=6667 -Nick=Jupiter -AltNick=Jupiter` -RealName=Jupiter IRC Framework by Agent -AutoPartMessage=Auto-Parting Enabled -AutoReconnect=1 -MaxReconnectAttempts=3 -AutoReconnectDelay=5 -PrintOutput=1 -Channel.Type=-1 -Prefix=! - -; [(ServerName)] -; -; Anything which can be set within the Default block can -; also be applied here. Values here supercede any value -; which is set within the Default block. -; - -[CnCIRC] -; CnCIRC includes the Renegade X IRC server. :) -Hostname=irc.cncirc.net -Nick=RenXBot -AltNick=RXBot` -Channel.1=#RenX-IRC -Channel.1.Type=1 -Channel.2=#RenX-IRC.Admin -Channel.2.Type=2 -SASL.Password=your_NickServ_Password -LogFile=CnCIRC.txt - -[CT] -Hostname=irc.ConstructiveTyranny.com -Nick=RenXBot -Channel.1=#RenX-IRC -Channel.1.Type=1 -Channel.2=#RenX-IRC.Admin -Channel.2.Type=2 -RawData.1=PRIVMSG NickServ :IDENTIFY your_NickServ_Password -LogFile=CT.txt - -; [DefaultCommands] -; You can modify the access requirements for any command here. -; Values set here will be set across all servers that do not have -; server-specific values set. -; -; To disable a command, set its access requirement to -1. -; -; Syntax: CommandTrigger=AccessLevel -; - -[DefaultCommands] -msg=1 - -; [(ServerName)Commands] -; You can modify the access requirements for any command here, on a -; per-server basis. Values specified here supercede those which are set -; in the DefaultCommands block. -; - -[CnCIRCCommands] -msg=0 +Plugins=IRC.Core CoreCommands PluginManager ExtraCommands RenX.Core RenX.Commands RenX.Logging RenX.Medals ;EOF \ No newline at end of file diff --git a/Configs/IRC.Core.ini b/Configs/IRC.Core.ini new file mode 100644 index 0000000..7edfdb1 --- /dev/null +++ b/Configs/IRC.Core.ini @@ -0,0 +1,121 @@ +; File: IRC.Core.ini +; + +; Servers=String (Format: Server1 Server2 ...) +; Lists server sections to instantiate IRC connections with +Servers=CnCIRC + +; [Default] +; +; This block is referenced only when a setting is not +; specified in a server's block. If a value is located +; neither in the server's block nor this one, then a +; crash or other unexpected behavior may occur. It is +; therefore recommended to have some sort of default +; value for all possible settings. +; +; Channel Configuring: +; Channels are given "types", which can determine various things such +; as auto-parting. A Channel of type -1 will automatically part itself. +; Channels can be configured in two ways: Active and Passive. +; Active channels are joined automatically. Passive channels are not, +; but can still be configured. +; +; Active Channels: +; Channel.Integer=String (Format: #Example [Password]) +; Channel.Integer.Type=Integer (-1 is auto-part) +; +; Passive Channels: +; Channel.String.Type=Integer +; +; Client address and port: +; The client address and port settings are entirely optional. These are +; only used under very special circumstances, and should otherwise +; not be specified. Unless you have a valid reason to need to bind the +; client to a specific address/port (such as connection limiations on a +; per-IP basis), do not set these. +; +; Settings: +; Hostname=String ("irc.cncirc.net" if unspecified) +; Port=Positive Integer (194 or 994 if unspecified) +; SSL=Bool (Default: false) +; STARTTLS=Bool (Default: true) +; Certificate=String (No SSL certificate used if unspecified) +; Key=String (Certificate file used if unspecified) +; SASL.Password=String (SASL disabled if unspecified) +; SASL.Account=String (Nickname if unspecified) +; Nick=String (Default: Jupiter) +; AltNick=String (Unused if unspecified) +; RealName=String ("Jupiter IRC Client" if unspecified) +; Channel.Type=Integer (Default: 0) +; RawData.Integer=String (Example: OPER UserName Password) +; LogFile=String (Default: ) +; AutoJoinOnKick=Bool (Default: false) +; AutoPartMessage=String (Default: ) +; AutoReconnectDelay=Integer (Default: 0; Measured in seconds) +; MaxReconnectAttempts=Integer (Default: 0; Set to -1 for unlimited) +; PrintOutput=Bool (Default: false) +; Prefix=String (Unused if unspecified) +; ClientAddress=String (Unused if unspecified) +; ClientPort=Integer (Unused if above is unspecified; defaults to 0) +; + +[Default] +Port=6667 +Nick=RenXBot +AltNick=RenXBot` +RealName=Jupiter IRC Framework by Agent +AutoPartMessage=Auto-Parting Enabled +AutoReconnect=1 +MaxReconnectAttempts=3 +AutoReconnectDelay=5 +PrintOutput=1 +Channel.Type=-1 +Prefix=! + +; [(ServerName)] +; +; Anything which can be set within the Default block can +; also be applied here. Values here supercede any value +; which is set within the Default block. +; + +[CnCIRC] +; CnCIRC includes the Renegade X IRC server. :) +Hostname=irc.cncirc.net +Channel.1=#RenX-IRC +Channel.1.Type=1 +Channel.2=#RenX-IRC.Admin +Channel.2.Type=2 +SASL.Password=your_NickServ_Password + +[CT] +Hostname=irc.ConstructiveTyranny.com +Channel.1=#RenX-IRC +Channel.1.Type=1 +Channel.2=#RenX-IRC.Admin +Channel.2.Type=2 +RawData.1=PRIVMSG NickServ :IDENTIFY your_NickServ_Password + +; [DefaultCommands] +; You can modify the access requirements for any command here. +; Values set here will be set across all servers that do not have +; server-specific values set. +; +; To disable a command, set its access requirement to -1. +; +; Syntax: CommandTrigger=AccessLevel +; + +[DefaultCommands] +msg=0 + +; [(ServerName)Commands] +; You can modify the access requirements for any command here, on a +; per-server basis. Values specified here supercede those which are set +; in the DefaultCommands block. +; + +[CnCIRCCommands] + +;EOF \ No newline at end of file diff --git a/IRC.Core/IRC_Core.cpp b/IRC.Core/IRC_Core.cpp index ed12728..9307e56 100644 --- a/IRC.Core/IRC_Core.cpp +++ b/IRC.Core/IRC_Core.cpp @@ -21,11 +21,40 @@ #include "IRC_Command.h" #include "IRC_Core.h" +using namespace Jupiter::literals; + IRCCorePlugin::~IRCCorePlugin() { IRCCorePlugin::m_wrapped_commands.emptyAndDelete(); } +bool IRCCorePlugin::initialize() +{ + const Jupiter::ReadableString &serverList = this->config.get(Jupiter::ReferenceString::empty, "Servers"_jrs); + if (serverList != nullptr) + { + serverManager->setConfig(this->config); + + unsigned int server_count = serverList.wordCount(WHITESPACE); + for (unsigned int index = 0; index != server_count; ++index) + serverManager->addServer(Jupiter::ReferenceString::getWord(serverList, index, WHITESPACE)); + } + + return true; +} + +int IRCCorePlugin::OnRehash() +{ + serverManager->OnConfigRehash(); + return 0; +} + +int IRCCorePlugin::think() +{ + serverManager->think(); + return 0; +} + void IRCCorePlugin::OnGenericCommandAdd(Jupiter::GenericCommand &in_command) { IRCCorePlugin::m_wrapped_commands.add(new GenericCommandWrapperIRCCommand(in_command)); diff --git a/IRC.Core/IRC_Core.h b/IRC.Core/IRC_Core.h index 7dede25..935c725 100644 --- a/IRC.Core/IRC_Core.h +++ b/IRC.Core/IRC_Core.h @@ -25,6 +25,23 @@ class IRCCorePlugin : public Jupiter::Plugin { public: + /** + * @brief Initializes the plugin + */ + virtual bool initialize() override; + + /** + * @brief Called when there is a rehash + * + * @return 0 always. + */ + virtual int OnRehash() override; + + /** + * @brief Cycles through IRC servers for new data + */ + virtual int think() override; + /** * @brief This is called when a GenericCommand is instantiated. */ diff --git a/Jupiter b/Jupiter index 5966674..c378c17 160000 --- a/Jupiter +++ b/Jupiter @@ -1 +1 @@ -Subproject commit 5966674d67b66f380b73ba3028d6176c0d3af2cb +Subproject commit c378c178809fc77ad922298c0e9bb33d1fa55cb0 diff --git a/Release/Bot.lib b/Release/Bot.lib index 1218a4e..4e7876b 100644 Binary files a/Release/Bot.lib and b/Release/Bot.lib differ diff --git a/Release/Plugins/RenX.Core.lib b/Release/Plugins/RenX.Core.lib index c9d9e54..7074fe3 100644 Binary files a/Release/Plugins/RenX.Core.lib and b/Release/Plugins/RenX.Core.lib differ