diff --git a/Bot/Bot.vcxproj b/Bot/Bot.vcxproj
new file mode 100644
index 0000000..3ddd9a2
--- /dev/null
+++ b/Bot/Bot.vcxproj
@@ -0,0 +1,109 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {C188871B-5F32-4946-B301-24CA2EBB275D}
+ Win32Proj
+ IRCBotImp
+ Bot
+
+
+
+ Application
+ true
+ v120
+ Unicode
+
+
+ Application
+ false
+ v120
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ false
+ AllRules.ruleset
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;JUPITER_BOT_EXPORTS;%(PreprocessorDefinitions)
+ true
+ ..\Jupiter;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;JUPITER_BOT_EXPORTS;%(PreprocessorDefinitions)
+ true
+ Speed
+
+ ../Jupiter
+
+
+ Console
+ true
+ true
+ true
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Bot/Bot.vcxproj.filters b/Bot/Bot.vcxproj.filters
new file mode 100644
index 0000000..ceeff80
--- /dev/null
+++ b/Bot/Bot.vcxproj.filters
@@ -0,0 +1,56 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Resource Files
+
+
+
\ No newline at end of file
diff --git a/Bot/Console_Command.cpp b/Bot/Console_Command.cpp
new file mode 100644
index 0000000..0cd70db
--- /dev/null
+++ b/Bot/Console_Command.cpp
@@ -0,0 +1,49 @@
+/**
+ * Copyright (C) 2013-2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#include "Console_Command.h"
+
+Jupiter::ArrayList _consoleCommands;
+Jupiter::ArrayList *consoleCommands = &_consoleCommands;
+
+ConsoleCommand::ConsoleCommand()
+{
+ consoleCommands->add(this);
+}
+
+ConsoleCommand::~ConsoleCommand()
+{
+ for (size_t i = 0; i != consoleCommands->size(); i++)
+ {
+ if (consoleCommands->get(i) == this)
+ {
+ consoleCommands->remove(i);
+ break;
+ }
+ }
+}
+
+ConsoleCommand *getConsoleCommand(const Jupiter::ReadableString &trigger)
+{
+ for (size_t i = 0; i != consoleCommands->size(); i++)
+ {
+ ConsoleCommand *cmd = consoleCommands->get(i);
+ if (cmd->matches(trigger))
+ return cmd;
+ }
+ return nullptr;
+}
\ No newline at end of file
diff --git a/Bot/Console_Command.h b/Bot/Console_Command.h
new file mode 100644
index 0000000..94a5b00
--- /dev/null
+++ b/Bot/Console_Command.h
@@ -0,0 +1,107 @@
+/**
+ * Copyright (C) 2013-2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#if !defined _CONSOLE_COMMAND_H_HEADER
+#define _CONSOLE_COMMAND_H_HEADER
+
+/**
+* @file Console_Command.h
+* @brief Provides an extendable command system specialized for console-based commands.
+*/
+
+#include "Jupiter_Bot.h"
+#include "Jupiter/Command.h"
+#include "Jupiter/ArrayList.h"
+
+class Command;
+class ConsoleCommand;
+
+/*
+* Initial access level is always 0. Change this using setAccessLevel()
+* There are no default triggers. Add triggers using addTrigger(trigger)
+* When your command is triggered, trigger(parameters) will be called.
+* You must provide command-specific help for your command, through getHelp().
+* The first trigger added is the trigger which is displayed to the user in the help command.
+*/
+
+/** DLL Linkage Nagging */
+#if defined _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4251)
+#endif
+
+/** Console command list */
+JUPITER_BOT_API extern Jupiter::ArrayList *consoleCommands;
+
+/**
+* @brief Provides the basis for console commands.
+* Note: This will likely be moved to a separate file in the future.
+*/
+class JUPITER_BOT_API ConsoleCommand : public Jupiter::Command
+{
+public:
+ /**
+ * @brief Called when the command is to be executed.
+ *
+ * @param input Parameters passed to the command by the user.
+ */
+ virtual void trigger(const Jupiter::ReadableString &input) = 0;
+
+ /**
+ * @brief Default constructor for the console command class.
+ */
+ ConsoleCommand();
+
+ /**
+ * @brief Destructor for the console command class.
+ */
+ ~ConsoleCommand();
+};
+
+/**
+* @brief Fetches a console command based on its trigger.
+*
+* @param trigger Trigger of the command to fetch.
+* @return A console command if it exists, nullptr otherwise.
+*/
+JUPITER_BOT_API extern ConsoleCommand *getConsoleCommand(const Jupiter::ReadableString &trigger);
+
+/** Console Command Macros */
+
+/** Defines the core of a console command's declaration. This should be included in every console command. */
+#define BASE_CONSOLE_COMMAND(CLASS) \
+ public: \
+ CLASS(); \
+ void trigger(const Jupiter::ReadableString ¶meters); \
+ const Jupiter::ReadableString &getHelp(const Jupiter::ReadableString ¶meters);
+
+/** Expands to become the entire declaration for a console command. In most cases, this will be sufficient. */
+#define GENERIC_CONSOLE_COMMAND(CLASS) \
+class CLASS : public ConsoleCommand { \
+ BASE_CONSOLE_COMMAND(CLASS) \
+};
+
+/** Instantiates a console command. */
+#define CONSOLE_COMMAND_INIT(CLASS) \
+ CLASS CLASS ## _instance;
+
+/** Re-enable warnings */
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // _CONSOLE_COMMAND_H_HEADER
\ No newline at end of file
diff --git a/Bot/IRC_Bot.cpp b/Bot/IRC_Bot.cpp
new file mode 100644
index 0000000..5575979
--- /dev/null
+++ b/Bot/IRC_Bot.cpp
@@ -0,0 +1,204 @@
+/**
+ * Copyright (C) 2013-2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+/**
+ * Long term plan:
+ * Eventually, this file and its header will no longer be a part of this project.
+ * The features made available by this core will slowly be transferred away in pieces
+ * to other locations, such as the internal Jupiter library, or various plugins.
+ *
+ * There is a relatively thin line between what will go in Jupiter, and what will be
+ * pushed to plugins.
+ * Example: The "Command" and "Plugin" classes ended up in Jupiter; they're abstract concepts
+ * that doesn't put a specific behavior on any mechanisms. The "IRCCommand" class, however,
+ * alters the behavior of the IRC Client, and thus should be contained within a plugin.
+ */
+
+#include
+#include
+#include
+#include "Jupiter/INIFile.h"
+#include "Jupiter/Plugin.h"
+#include "Jupiter/Functions.h"
+#include "IRC_Bot.h"
+#include "IRC_Command.h"
+
+IRC_Bot::IRC_Bot(const Jupiter::ReadableString &configSection) : Client(configSection)
+{
+ IRC_Bot::commandPrefix = this->readConfigValue(STRING_LITERAL_AS_REFERENCE("Prefix"));
+ for (size_t i = 0; i != IRCMasterCommandList->size(); i++)
+ IRC_Bot::addCommand(IRCMasterCommandList->get(i)->copy());
+ IRC_Bot::setCommandAccessLevels();
+}
+
+IRC_Bot::~IRC_Bot()
+{
+ while (IRC_Bot::commands.size()) delete IRC_Bot::commands.remove(0);
+}
+
+void IRC_Bot::addCommand(IRCCommand *cmd)
+{
+ IRC_Bot::commands.add(cmd);
+}
+
+bool IRC_Bot::freeCommand(const Jupiter::ReadableString &trigger)
+{
+ for (size_t i = 0; i != IRC_Bot::commands.size(); i++)
+ {
+ if (IRC_Bot::commands.get(i)->matches(trigger))
+ {
+ delete IRC_Bot::commands.remove(i);
+ return true;
+ }
+ }
+ return false;
+}
+
+int IRC_Bot::getCommandIndex(const Jupiter::ReadableString &trigger) const
+{
+ for (size_t i = 0; i != IRC_Bot::commands.size(); i++)
+ if (IRC_Bot::commands.get(i)->matches(trigger))
+ return i;
+ return -1;
+}
+
+IRCCommand *IRC_Bot::getCommand(const Jupiter::ReadableString &trigger) const
+{
+ int i = IRC_Bot::getCommandIndex(trigger);
+ if (i < 0) return nullptr;
+ return IRC_Bot::commands.get(i);
+}
+
+Jupiter::ArrayList IRC_Bot::getAccessCommands(Jupiter::IRC::Client::Channel *chan, int access)
+{
+ Jupiter::ArrayList r;
+ for (size_t i = 0; i != IRC_Bot::commands.size(); i++)
+ {
+ IRCCommand *cmd = IRC_Bot::commands.get(i);
+ if (cmd->getAccessLevel(chan) == access)
+ r.add(cmd);
+ }
+ return r;
+}
+
+Jupiter::StringL IRC_Bot::getTriggers(Jupiter::ArrayList cmds)
+{
+ Jupiter::StringL r;
+ for (size_t i = 0; i < cmds.size(); i++)
+ {
+ r += cmds[i]->getTrigger();
+ r += ' ';
+ }
+ return r;
+}
+
+void IRC_Bot::setCommandAccessLevels()
+{
+ // Rewrite this later
+ // Note: Prepare for abstraction of configuration file type.
+ Jupiter::StringS commandSection = "DefaultCommands";
+
+ checkForCommands:
+ int sIndex = Config->getSectionIndex(commandSection);
+ if (sIndex >= 0)
+ {
+ int sLen = Config->getSectionLength(sIndex);
+ for (int i = 0; i < sLen; i++)
+ {
+ const Jupiter::ReadableString &key = Config->getKey(commandSection, i);
+ int pos = key.find('.');
+ if (pos != Jupiter::INVALID_INDEX)
+ {
+ Jupiter::ReferenceString command = Jupiter::ReferenceString(key.ptr(), pos);
+ if (command != nullptr)
+ {
+ IRCCommand *cmd = IRC_Bot::getCommand(command);
+ if (cmd != nullptr)
+ {
+ Jupiter::ReferenceString channelType(key.ptr() + pos + 1, key.size() - pos - 1);
+ if (isdigit(key[pos + 1]))
+ cmd->setAccessLevel(channelType.asInt(10), Config->getInt(commandSection, key));
+ else cmd->setAccessLevel(channelType.asInt(10), Config->getInt(commandSection, key));
+ }
+ else if (this->getPrintOutput()) printf("Unable to find command \"%.*s\"" ENDL, key.size(), key.ptr());
+ }
+ }
+ else
+ {
+ IRCCommand *cmd = IRC_Bot::getCommand(key);
+ if (cmd != nullptr) cmd->setAccessLevel(Config->getInt(commandSection, key));
+ else if (this->getPrintOutput()) printf("Unable to find command \"%.*s\"" ENDL, key.size(), key.ptr());
+ }
+ }
+ }
+ if (commandSection.equals("DefaultCommands"))
+ {
+ commandSection = this->getConfigSection();
+ commandSection += "Commands";
+ if (commandSection.equals("DefaultCommands") == false) goto checkForCommands;
+ }
+}
+
+int IRC_Bot::OnRehash()
+{
+ if (Config->reload() == Jupiter::ERROR_INDICATOR) return 1;
+ IRC_Bot::setCommandAccessLevels();
+ return 0;
+}
+
+void IRC_Bot::OnChat(const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &message)
+{
+ int chanIndex = this->getChannelIndex(channel);
+ if (chanIndex >= 0)
+ {
+ Channel *chan = this->getChannel(chanIndex);
+ if (chan->getType() >= 0)
+ {
+ Jupiter::ReferenceString msg = message;
+ while (msg.isEmpty() == false && isspace(msg[0]))
+ msg.shiftRight(1);
+
+ if (IRC_Bot::commandPrefix.size() <= msg.size())
+ {
+ bool matchesPrefix = true;
+ size_t i;
+ for (i = 0; i != IRC_Bot::commandPrefix.size(); i++)
+ {
+ if (toupper(msg.get(0)) != toupper(IRC_Bot::commandPrefix[i]))
+ {
+ matchesPrefix = false;
+ break;
+ }
+ msg.shiftRight(1);
+ }
+
+ if (matchesPrefix)
+ {
+ Jupiter::ReferenceString command = Jupiter::ReferenceString::getWord(msg, 0, WHITESPACE);;
+ Jupiter::ReferenceString parameters = Jupiter::ReferenceString::gotoWord(msg, 1, WHITESPACE);
+ IRCCommand *cmd = IRC_Bot::getCommand(command);
+ if (cmd != nullptr)
+ {
+ int cAccess = cmd->getAccessLevel(chan);
+ if (cAccess >= 0 && Jupiter::IRC::Client::getAccessLevel(channel, nick) >= cAccess) cmd->trigger(this, channel, nick, parameters);
+ else this->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Access Denied."));
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Bot/IRC_Bot.h b/Bot/IRC_Bot.h
new file mode 100644
index 0000000..6e07ea6
--- /dev/null
+++ b/Bot/IRC_Bot.h
@@ -0,0 +1,128 @@
+/**
+ * Copyright (C) 2013-2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#if !defined _IRC_BOT_H_HEADER
+#define _IRC_BOT_H_HEADER
+
+/**
+ * @file IRC_Bot.h
+ * @brief Provides extendable bot-like interfacing with the IRC client.
+ */
+
+#include "Jupiter_Bot.h"
+#include "Jupiter/IRC_Client.h"
+#include "Jupiter/ArrayList.h"
+#include "Jupiter/Rehash.h"
+#include "Jupiter/String.h"
+
+/** Forward Declaration */
+class IRCCommand;
+
+/** DLL Linkage Nagging */
+#if defined _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4251)
+#endif
+
+/**
+* @brief Provies extendable bot-like interfacing with the IRC client.
+*/
+class JUPITER_BOT_API IRC_Bot : public Jupiter::IRC::Client, public Jupiter::Rehashable
+{
+public:
+
+ /**
+ * @brief Pulls the configured access levels from the config and applies them.
+ */
+ void setCommandAccessLevels();
+
+ /**
+ * @brief Adds a command to the command list.
+ */
+ void addCommand(IRCCommand *cmd);
+
+ /**
+ * @brief Removes a command from the command list.
+ *
+ * @param trigger Trigger of the command to remove
+ * @return True if a command is removed, false otherwise.
+ */
+ bool freeCommand(const Jupiter::ReadableString &trigger);
+
+ /**
+ * @brief Gets the index of a command.
+ *
+ * @param trigger Trigger of the command to find.
+ * @return Index of the first match for the trigger if found, -1 otherwise.
+ */
+ int getCommandIndex(const Jupiter::ReadableString &trigger) const;
+
+ /**
+ * @return Gets a command.
+ *
+ * @param trigger Trigger of the command to find.
+ * @return First command using the specified trigger, nullptr otherwise.
+ */
+ IRCCommand *getCommand(const Jupiter::ReadableString &trigger) const;
+
+ /**
+ * @brief Creates and returns an ArrayList of IRC Commands with a specified access level.
+ *
+ * @param chan Channel which access levels are set.
+ * @param access Access level to match.
+ * @return An ArrayList containing pointers to all of the matching commands.
+ */
+ Jupiter::ArrayList getAccessCommands(Jupiter::IRC::Client::Channel *chan, int access);
+
+ /**
+ * @brief Gets the triggers of all the commands in an ArrayList, and adds them to a space-deliminated string.
+ *
+ * @param cmds Commands to construct the string with.
+ * @return A string containing the triggers of the commands in a space-deliminated list.
+ */
+ static Jupiter::StringL getTriggers(Jupiter::ArrayList cmds);
+
+ /**
+ * @brief Reloads some settings.
+ *
+ * @return 0 on success, 1 otherwise.
+ */
+ int OnRehash();
+
+ /** Constructor for IRC_Bot */
+ IRC_Bot(const Jupiter::ReadableString &configSection);
+
+ /** Destructor for IRC_Bot */
+ ~IRC_Bot();
+
+ /** Overloaded events from Jupiter::IRC::Client */
+protected:
+
+ void OnChat(const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &message);
+
+ /** Private members for internal usage */
+private:
+ Jupiter::ArrayList commands;
+ Jupiter::StringS commandPrefix;
+};
+
+/** Re-enable warnings */
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // _IRC_BOT_H_HEADER
\ No newline at end of file
diff --git a/Bot/IRC_Command.cpp b/Bot/IRC_Command.cpp
new file mode 100644
index 0000000..09ad1ba
--- /dev/null
+++ b/Bot/IRC_Command.cpp
@@ -0,0 +1,119 @@
+/**
+ * Copyright (C) 2013-2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#include "IRC_Command.h"
+
+Jupiter::ArrayList _IRCMasterCommandList;
+Jupiter::ArrayList *IRCMasterCommandList = &_IRCMasterCommandList;
+
+IRCCommand::IRCCommand()
+{
+ IRCCommand::access = 0;
+ IRCMasterCommandList->add(this);
+}
+
+IRCCommand::IRCCommand(const IRCCommand &command)
+{
+ IRCCommand::access = command.access;
+ size_t i;
+
+ for (i = 0; i < command.channels.size(); i++)
+ IRCCommand::channels.add(new IRCCommand::ChannelAccessPair(*command.channels.get(i)));
+
+ for (i = 0; i < command.types.size(); i++)
+ IRCCommand::types.add(new IRCCommand::TypeAccessPair(*command.types.get(i)));
+}
+
+IRCCommand::~IRCCommand()
+{
+ for (size_t i = 0; i != IRCMasterCommandList->size(); i++)
+ {
+ if (IRCMasterCommandList->get(i) == this)
+ {
+ serverManager->removeCommand(this);
+ IRCMasterCommandList->remove(i);
+ break;
+ }
+ }
+ IRCCommand::channels.emptyAndDelete();
+ IRCCommand::types.emptyAndDelete();
+}
+
+// IRC Command Functions
+
+int IRCCommand::getAccessLevel()
+{
+ return IRCCommand::access;
+}
+
+int IRCCommand::getAccessLevel(int type)
+{
+ for (size_t i = 0; i != IRCCommand::types.size(); i++)
+ if (IRCCommand::types.get(i)->type == type)
+ return IRCCommand::types.get(i)->access;
+ return IRCCommand::access;
+}
+
+int IRCCommand::getAccessLevel(const Jupiter::ReadableString &channel)
+{
+ IRCCommand::ChannelAccessPair *pair;
+ for (size_t i = 0; i != IRCCommand::channels.size(); i++)
+ {
+ pair = IRCCommand::channels.get(i);
+ if (pair->channel.equalsi(channel))
+ return pair->access;
+ }
+ return IRCCommand::access;
+}
+
+int IRCCommand::getAccessLevel(Jupiter::IRC::Client::Channel *channel)
+{
+ IRCCommand::ChannelAccessPair *pair;
+ for (size_t i = 0; i != IRCCommand::channels.size(); i++)
+ {
+ pair = IRCCommand::channels.get(i);
+ if (pair->channel.equalsi(channel->getName()))
+ return pair->access;
+ }
+
+ for (size_t i = 0; i != IRCCommand::types.size(); i++)
+ if (IRCCommand::types.get(i)->type == channel->getType())
+ return IRCCommand::types.get(i)->access;
+
+ return IRCCommand::access;
+}
+
+void IRCCommand::setAccessLevel(int accessLevel)
+{
+ IRCCommand::access = accessLevel;
+}
+
+void IRCCommand::setAccessLevel(int type, int accessLevel)
+{
+ IRCCommand::TypeAccessPair *pair = new IRCCommand::TypeAccessPair();
+ pair->type = type;
+ pair->access = accessLevel;
+ IRCCommand::types.add(pair);
+}
+
+void IRCCommand::setAccessLevel(const Jupiter::ReadableString &channel, int accessLevel)
+{
+ IRCCommand::ChannelAccessPair *pair = new IRCCommand::ChannelAccessPair();
+ pair->channel = channel;
+ pair->access = accessLevel;
+ IRCCommand::channels.add(pair);
+}
\ No newline at end of file
diff --git a/Bot/IRC_Command.h b/Bot/IRC_Command.h
new file mode 100644
index 0000000..209d1af
--- /dev/null
+++ b/Bot/IRC_Command.h
@@ -0,0 +1,197 @@
+/**
+ * Copyright (C) 2013-2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#if !defined _IRC_COMMAND_H_HEADER
+#define _IRC_COMMAND_H_HEADER
+
+/**
+* @file IRC_Command.h
+* @brief Provides an extendable command system specialized for IRC chat-based commands.
+*/
+
+#include "Jupiter/Command.h"
+#include "Jupiter/IRC_Client.h"
+#include "Jupiter/ArrayList.h"
+#include "Jupiter/String.h"
+#include "ServerManager.h"
+#include "Jupiter_Bot.h"
+
+class IRC_Bot;
+class IRCCommand;
+
+/*
+* Initial access level is always 0. Change this using setAccessLevel()
+* There are no default triggers. Add triggers using addTrigger(trigger)
+* When your command is triggered, trigger(channel, nick, parameters) will be called.
+* You must provide command-specific help for your command, through getHelp().
+* The first trigger added is the trigger which is displayed to the user in the help command.
+*/
+
+/** DLL Linkage Nagging */
+#if defined _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4251)
+#endif
+
+/** IRC Master Command List */
+JUPITER_BOT_API extern Jupiter::ArrayList *IRCMasterCommandList;
+
+/**
+* @brief Provides the basis for IRC commands.
+* Note: This will likely be moved to a separate file in the future.
+*/
+class JUPITER_BOT_API IRCCommand : public Jupiter::Command
+{
+public:
+ /**
+ * @brief Fetches a command's default access level.
+ *
+ * @return Default access level.
+ */
+ int getAccessLevel();
+
+ /**
+ * @brief Fetches a command's access level for a channel type.
+ *
+ * @return Access level.
+ */
+ int getAccessLevel(int type);
+
+ /**
+ * @brief Fetches a command's access level for a specific channel by name.
+ *
+ * @return Access level.
+ */
+ int getAccessLevel(const Jupiter::ReadableString &channel);
+
+ /**
+ * @brief Fetches a command's access level for a specific channel.
+ *
+ * @return Access level.
+ */
+ int getAccessLevel(Jupiter::IRC::Client::Channel *channel);
+
+ /**
+ * @brief Sets a command's default access level.
+ *
+ * @param accessLevel Access level.
+ */
+ void setAccessLevel(int accessLevel);
+
+ /**
+ * @brief Sets a command's access level for a channel type.
+ *
+ * @param type Type of channel for which to set access.
+ * @param accessLevel Access level.
+ */
+ void setAccessLevel(int type, int accessLevel);
+
+ /**
+ * @brief Sets a command's access level for a specific channel by name.
+ *
+ * @param channel Specific channel name for which to set access.
+ * @param accessLevel Access level.
+ */
+ void setAccessLevel(const Jupiter::ReadableString &channel, int accessLevel);
+
+ /**
+ * @brief Called when the command is to be executed.
+ *
+ * @param source IRC Server from which the command is being executed.
+ * @param channel Name of the channel from which the message originated.
+ * @param nick Nickname of the user who executed the command.
+ * @param parameters Parameters specified with the command.
+ */
+ virtual void trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters) = 0;
+
+ /**
+ * @brief Called when the command is intially created. Define triggers and access levels here.
+ */
+ virtual void create() = 0;
+
+ /**
+ * @brief Creates a copy of a command.
+ * Note: This is primarily for internal usage.
+ *
+ * @return Copy of the command.
+ */
+ virtual IRCCommand *copy() = 0;
+
+ /**
+ * @brief Default constructor for the IRC command class.
+ * Generally, this is called only for master commands.
+ */
+ IRCCommand();
+
+ /**
+ * @brief Copy constructor for the IRC command class.
+ * Generally, this is called only for slave commands.
+ */
+ IRCCommand(const IRCCommand &command);
+
+ /**
+ * @brief Destructor for the IRC command class.
+ */
+ virtual ~IRCCommand();
+
+ /** Private members */
+private:
+ int access; /** Default access level */
+
+ struct TypeAccessPair
+ {
+ int type;
+ int access;
+ };
+ Jupiter::ArrayList types; /** Access levels for channel types */
+
+ struct ChannelAccessPair
+ {
+ Jupiter::StringS channel;
+ int access;
+ };
+ Jupiter::ArrayList channels; /** Access levels for specific channels */
+};
+
+/** IRC Command Macros */
+
+/** Defines the core of an IRC command's declaration. This should be included in every IRC command. */
+#define BASE_IRC_COMMAND(CLASS) \
+ public: \
+ void trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters); \
+ const Jupiter::ReadableString &getHelp(const Jupiter::ReadableString ¶meters); \
+ CLASS *copy(); \
+ void create(); \
+ CLASS() { this->create(); if (serverManager != nullptr) serverManager->addCommand(this); }
+
+/** Expands to become the entire declaration for an IRC command. In most cases, this will be sufficient. */
+#define GENERIC_IRC_COMMAND(CLASS) \
+class CLASS : public IRCCommand { \
+ BASE_IRC_COMMAND(CLASS) \
+ CLASS(CLASS &c) : IRCCommand(c) { this->create(); } };
+
+/** Instantiates an IRC command, and also defines neccessary core functions for compatibility. */
+#define IRC_COMMAND_INIT(CLASS) \
+ CLASS CLASS ## _instance; \
+ CLASS *CLASS::copy() { return new CLASS(*this); }
+
+/** Re-enable warnings */
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // _IRC_COMMAND_H_HEADER
\ No newline at end of file
diff --git a/Bot/Jupiter_Bot.h b/Bot/Jupiter_Bot.h
new file mode 100644
index 0000000..4e360de
--- /dev/null
+++ b/Bot/Jupiter_Bot.h
@@ -0,0 +1,38 @@
+/**
+ * Copyright (C) 2013-2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#if !defined JUPITER_BOT_API
+
+/**
+* @file Jupiter_Bot.h
+* @brief Defines JUPITER_BOT_API.
+* On anything other than Windows, JUPITER_BOT_API is defined as nothing, to prevent compiler errors.
+*/
+
+#if defined _WIN32
+
+#if defined JUPITER_BOT_EXPORTS
+#define JUPITER_BOT_API __declspec(dllexport)
+#else // JUPITER_BOT_EXPORTS
+#define JUPITER_BOT_API __declspec(dllimport)
+#endif // JUPITER_BOT_EXPORTS
+
+#else // _WIN32
+#define JUPITER_BOT_API
+#endif // _WIN32
+
+#endif // JUPITER_BOT_API
\ No newline at end of file
diff --git a/Bot/Main.cpp b/Bot/Main.cpp
new file mode 100644
index 0000000..a9c9991
--- /dev/null
+++ b/Bot/Main.cpp
@@ -0,0 +1,154 @@
+/**
+ * Copyright (C) 2013-2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "Jupiter/Functions.h"
+#include "Jupiter/INIFile.h"
+#include "Jupiter/Queue.h"
+#include "Jupiter/Socket.h"
+#include "Jupiter/Plugin.h"
+#include "Jupiter/Timer.h"
+#include "IRC_Bot.h"
+#include "ServerManager.h"
+#include "Console_Command.h"
+#include "IRC_Command.h"
+
+Jupiter::Queue inputQueue;
+
+void onTerminate()
+{
+ puts("Terminate signal received...");
+}
+
+void onExit()
+{
+ puts("Exit signal received; Cleaning up...");
+ Jupiter::Socket::cleanup();
+ puts("Clean-up complete. Closing...");
+}
+
+void inputLoop()
+{
+ const size_t inputSize = 1024;
+ char *input = new char[inputSize];
+ while (ftell(stdin) != -1) // This can be expanded later to check for EBADF specifically.
+ {
+ fgets(input, inputSize, stdin);
+ input[strcspn(input, "\r\n")] = 0;
+ inputQueue.enqueue(input);
+ }
+ delete[] input;
+}
+
+int main(int argc, const char **args)
+{
+ atexit(onExit);
+ std::set_terminate(onTerminate);
+ std::thread inputThread(inputLoop);
+ srand((unsigned int) time(0));
+ puts(Jupiter::copyright);
+ const char *configFileName = CONFIG_INI;
+
+ for (int i = 1; i < argc; i++)
+ {
+ if (streqli(args[i], "-help"))
+ {
+ puts("Help coming soon, to a theatre near you!");
+ return 0;
+ }
+ else if (streqli(args[i], "-config") && ++i < argc) configFileName = args[i];
+ else if (streqli(args[i], "-pluginsdir") && ++i < argc) Jupiter::setPluginDirectory(Jupiter::ReferenceString(args[i]));
+ else if (streqli(args[i], "-configFormat") && ++i < argc) puts("Feature not yet supported!");
+ else printf("Warning: Unknown command line argument \"%s\" specified. Ignoring...", args[i]);
+ }
+
+ puts("Loading config file...");
+ if (!Jupiter::IRC::Client::Config->readFile(configFileName))
+ {
+ puts("Unable to read config file. Closing...");
+ exit(0);
+ }
+
+ fputs("Config loaded. ", stdout);
+ const Jupiter::ReadableString &pDir = Jupiter::IRC::Client::Config->get(STRING_LITERAL_AS_REFERENCE("Config"), STRING_LITERAL_AS_REFERENCE("PluginsDirectory"));
+ if (pDir.isEmpty() == false)
+ {
+ Jupiter::setPluginDirectory(pDir);
+ printf("Plugins will be loaded from \"%.*s\"." ENDL, pDir.size(), pDir.ptr());
+ }
+
+ puts("Loading plugins...");
+ const Jupiter::ReadableString &pluginList = Jupiter::IRC::Client::Config->get(STRING_LITERAL_AS_REFERENCE("Config"), STRING_LITERAL_AS_REFERENCE("Plugins"));
+ if (pluginList.isEmpty())
+ puts("No plugins to load!");
+ else
+ {
+ 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);
+ if (Jupiter::loadPlugin(plugin) == nullptr) fprintf(stderr, "WARNING: Failed to load plugin \"%.*s\"!" ENDL, plugin.size(), plugin.ptr());
+ else printf("\"%.*s\" loaded successfully." ENDL, plugin.size(), plugin.ptr());
+ }
+ }
+
+ if (consoleCommands->size() > 0)
+ printf("%u Console Commands have been initialized%s" ENDL, consoleCommands->size(), getConsoleCommand(STRING_LITERAL_AS_REFERENCE("help")) == nullptr ? "." : "; type \"help\" for more information.");
+ 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 = Jupiter::IRC::Client::Config->get(STRING_LITERAL_AS_REFERENCE("Config"), STRING_LITERAL_AS_REFERENCE("Servers"));
+ 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 i = 0; i < nServers; i++)
+ serverManager->addServer(Jupiter::ReferenceString::getWord(serverList, i, WHITESPACE));
+ }
+
+ puts("Sockets established.");
+ while (1)
+ {
+ for (size_t i = 0; i < Jupiter::plugins->size(); i++)
+ if (Jupiter::plugins->get(i)->think() != 0)
+ Jupiter::freePlugin(i);
+ Jupiter_checkTimers();
+ serverManager->think();
+ Jupiter::ReferenceString input = (const char *)inputQueue.dequeue();
+ if (input != nullptr)
+ {
+ Jupiter::ReferenceString command = input.getWord(0, WHITESPACE);
+
+ ConsoleCommand *cmd = getConsoleCommand(command);
+ if (cmd != nullptr)
+ cmd->trigger(input.gotoWord(1, WHITESPACE));
+ else
+ printf("Error: Command \"%.*s\" not found." ENDL, command.size(), command.ptr());
+ }
+ std::this_thread::sleep_for((std::chrono::milliseconds(1)));
+ }
+ return 0;
+}
\ No newline at end of file
diff --git a/Bot/ServerManager.cpp b/Bot/ServerManager.cpp
new file mode 100644
index 0000000..7bdb44b
--- /dev/null
+++ b/Bot/ServerManager.cpp
@@ -0,0 +1,154 @@
+/**
+ * Copyright (C) 2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#include "Jupiter/Functions.h"
+#include "ServerManager.h"
+#include "IRC_Bot.h"
+#include "IRC_Command.h"
+
+ServerManager _serverManager;
+ServerManager *serverManager = &_serverManager;
+
+int ServerManager::think()
+{
+ for (size_t i = 0; i < ServerManager::servers.size(); i++)
+ {
+ IRC_Bot *server = ServerManager::servers.get(i);
+ if (server->think() != 0) delete ServerManager::servers.remove(i);
+ }
+ return ServerManager::servers.size() != 0;
+}
+
+size_t ServerManager::addCommand(IRCCommand *command)
+{
+ for (size_t i = 0; i != ServerManager::servers.size(); i++)
+ {
+ IRC_Bot *server = ServerManager::servers.get(i);
+ server->addCommand(command->copy());
+ }
+ return ServerManager::servers.size();
+}
+
+size_t ServerManager::removeCommand(IRCCommand *command)
+{
+ size_t r = 0;
+ for (size_t i = 0; i != ServerManager::servers.size(); i++)
+ {
+ IRC_Bot *server = ServerManager::servers.get(i);
+ if (server->freeCommand(command->getTrigger())) r++;
+ }
+ return r;
+}
+
+size_t ServerManager::removeCommand(const Jupiter::ReadableString &command)
+{
+ size_t r = 0;
+ for (size_t i = 0; i != ServerManager::servers.size(); i++)
+ {
+ IRC_Bot *server = ServerManager::servers.get(i);
+ if (server->freeCommand(command)) r++;
+ }
+ return r;
+}
+
+size_t ServerManager::syncCommands()
+{
+ for (size_t i = 0; i != ServerManager::servers.size(); i++)
+ {
+ IRC_Bot *server = ServerManager::servers.get(i);
+ server->setCommandAccessLevels();
+ }
+ return ServerManager::servers.size();
+}
+
+IRC_Bot *ServerManager::getServer(const Jupiter::ReadableString &serverConfig)
+{
+ for (size_t i = 0; i != ServerManager::servers.size(); i++)
+ {
+ IRC_Bot *server = ServerManager::servers.get(i);
+ if (server->getConfigSection().equalsi(serverConfig)) return server;
+ }
+ return nullptr;
+}
+
+IRC_Bot *ServerManager::getServer(size_t serverIndex)
+{
+ if (serverIndex < ServerManager::servers.size()) return ServerManager::servers.get(serverIndex);
+ return nullptr;
+}
+
+bool ServerManager::addServer(const Jupiter::ReadableString &serverConfig)
+{
+ IRC_Bot *server = new IRC_Bot(serverConfig);
+ if (server->connect() == true)
+ {
+ ServerManager::servers.add(server);
+ return true;
+ }
+ else
+ {
+ delete server;
+ return false;
+ }
+}
+
+bool ServerManager::freeServer(size_t serverIndex)
+{
+ if (serverIndex < ServerManager::servers.size())
+ {
+ delete ServerManager::servers.remove(serverIndex);
+ return true;
+ }
+ return false;
+}
+
+bool ServerManager::freeServer(IRC_Bot *server)
+{
+ for (size_t i = 0; i != ServerManager::servers.size(); i++)
+ {
+ if (ServerManager::servers.get(i) == server)
+ {
+ delete ServerManager::servers.remove(i);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ServerManager::freeServer(const Jupiter::ReadableString &serverConfig)
+{
+ for (size_t i = 0; i != ServerManager::servers.size(); i++)
+ {
+ IRC_Bot *server = ServerManager::servers.get(i);
+ if (server->getConfigSection().equalsi(serverConfig))
+ {
+ delete ServerManager::servers.remove(i);
+ return true;
+ }
+ }
+ return false;
+}
+
+size_t ServerManager::size()
+{
+ return ServerManager::servers.size();
+}
+
+ServerManager::~ServerManager()
+{
+ ServerManager::servers.emptyAndDelete();
+}
\ No newline at end of file
diff --git a/Bot/ServerManager.h b/Bot/ServerManager.h
new file mode 100644
index 0000000..8644383
--- /dev/null
+++ b/Bot/ServerManager.h
@@ -0,0 +1,157 @@
+/**
+ * Copyright (C) 2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#if !defined _SERVERMANAGER_H_HEADER
+#define _SERVERMANAGER_H_HEADER
+
+/**
+ * @file ServerManager.h
+ * @brief Provides a system for controlling and affecting multiple IRC connections simultaneously.
+ */
+
+#include "Jupiter_Bot.h"
+#include "Jupiter/Thinker.h"
+#include "Jupiter/ArrayList.h"
+#include "Jupiter/Readable_String.h"
+
+/** Forward declarations */
+class IRC_Bot;
+class IRCCommand;
+
+/** DLL Linkage Nagging */
+#if defined _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4251)
+#endif
+
+/**
+* @brief Provides a system for controlling and affecting multiple IRC connections simultaneously.
+*/
+class JUPITER_BOT_API ServerManager : public Jupiter::Thinker
+{
+public:
+ /**
+ * @brief Calls think() on all of the managed connections.
+ *
+ * @return false if there are still active connections, true otherwise.
+ */
+ int think();
+
+ /**
+ * @brief Adds a copy of a command to each managed server.
+ *
+ * @param command Command to copy to each server.
+ * @return Number of servers copied to.
+ */
+ size_t addCommand(IRCCommand *command);
+
+ /**
+ * @brief Removes any command which matches an input command's primary trigger.
+ *
+ * @param command Command to get the trigger of.
+ * @return Number of servers which had a command removed.
+ */
+ size_t removeCommand(IRCCommand *command);
+
+ /**
+ * @brief Removes any command which matches a trigger.
+ *
+ * @param command Trigger to match against.
+ * @return Number of servers which had a command removed.
+ */
+ size_t removeCommand(const Jupiter::ReadableString &command);
+
+ /**
+ * @brief Syncs command access levels from the configuration file.
+ *
+ * @return Number of servers sync'd.
+ */
+ size_t syncCommands();
+
+ /**
+ * @brief Fetches a server based on its configuration section
+ *
+ * @param serverConfig Configuration section to match against.
+ * @return Pointer to a matching server instance on success, nullptr otherwise.
+ */
+ IRC_Bot *getServer(const Jupiter::ReadableString &serverConfig);
+
+ /**
+ * @brief Fetches a server based on its index.
+ *
+ * @param index Index of the server to fetch.
+ * @return Pointer to a server on success, nullptr otherwise.
+ */
+ IRC_Bot *getServer(size_t index);
+
+ /**
+ * @brief Adds a server based on its configuration section to the list.
+ *
+ * @return True if a socket connection was successfully established, false otherwise.
+ */
+ bool addServer(const Jupiter::ReadableString &serverConfig);
+
+ /**
+ * @brief Removes a server from the manager, based on its index.
+ *
+ * @param index Index of the server to remove.
+ * @return True if a server was removed, false otherwise.
+ */
+ bool freeServer(size_t index);
+
+ /**
+ * @brief Removes a server from the manager, based on its data.
+ *
+ * @param server Data of the server to remove.
+ * @return True if a server was removed, false otherwise.
+ */
+ bool freeServer(IRC_Bot *server);
+
+ /**
+ * @brief Removes a server from the manager, based on its configuration section.
+ *
+ * @param serverConfig Configuration section of the server to remove.
+ * @return True if a server was removed, false otherwise.
+ */
+ bool freeServer(const Jupiter::ReadableString &serverConfig);
+
+ /**
+ * @brief Returns the number of servers in the list.
+ *
+ * @return Number of servers in the list.
+ */
+ size_t size();
+
+ /**
+ * Destructor for the ServerManager class.
+ */
+ virtual ~ServerManager();
+
+private:
+ /** Underlying ArrayList of servers */
+ Jupiter::ArrayList servers;
+};
+
+/** Pointer to an instance of the server manager. Note: DO NOT DELETE OR FREE THIS POINTER. */
+JUPITER_BOT_API extern ServerManager *serverManager;
+
+/** Re-enable warnings */
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // _SERVERMANAGER_H_HEADER
\ No newline at end of file
diff --git a/CoreCommands/CoreCommands.cpp b/CoreCommands/CoreCommands.cpp
new file mode 100644
index 0000000..1441c53
--- /dev/null
+++ b/CoreCommands/CoreCommands.cpp
@@ -0,0 +1,228 @@
+/**
+ * Copyright (C) 2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#include
+#include "Jupiter/INIFile.h"
+#include "Jupiter/Functions.h"
+#include "Jupiter/ArrayList.h"
+#include "CoreCommands.h"
+#include "IRC_Bot.h"
+
+// Help Console Command
+
+HelpConsoleCommand::HelpConsoleCommand()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("help"));
+}
+
+void HelpConsoleCommand::trigger(const Jupiter::ReadableString ¶meters)
+{
+ if (parameters.isEmpty())
+ {
+ fputs("Supported commands:", stdout);
+ for (size_t i = 0; i != consoleCommands->size(); i++)
+ {
+ fputc(' ', stdout);
+ consoleCommands->get(i)->getTrigger().print(stdout);
+ }
+ printf(ENDL "%s - %s" ENDL, Jupiter::version, Jupiter::copyright);
+ puts("For command-specific help, use: help ");
+ }
+ else
+ {
+ Jupiter::ReferenceString command = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE);
+ ConsoleCommand *cmd = getConsoleCommand(command);
+ if (cmd != nullptr)
+ cmd->getHelp(Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE)).println(stdout);
+ else
+ printf("Error: Command \"%.*s\" not found." ENDL, command.size(), command.ptr());
+ }
+}
+
+const Jupiter::ReadableString &HelpConsoleCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Lists commands, or sends command-specific help. Syntax: help [command]");
+ return defaultHelp;
+}
+
+CONSOLE_COMMAND_INIT(HelpConsoleCommand)
+
+// Version Console Command
+
+VersionConsoleCommand::VersionConsoleCommand()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("version"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("versioninfo"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("copyright"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("copyrightinfo"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("client"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("clientinfo"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("info"));
+}
+
+void VersionConsoleCommand::trigger(const Jupiter::ReadableString ¶meters)
+{
+ printf("Version: %s" ENDL "%s" ENDL, Jupiter::version, Jupiter::copyright);
+}
+
+const Jupiter::ReadableString &VersionConsoleCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Displays version and copyright information");
+ return defaultHelp;
+}
+
+CONSOLE_COMMAND_INIT(VersionConsoleCommand)
+
+// Help Command.
+
+void HelpIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("help"));
+}
+
+void HelpIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ int cIndex = source->getChannelIndex(channel);
+ if (cIndex >= 0)
+ {
+ Jupiter::IRC::Client::Channel *chan = source->getChannel(cIndex);
+ int access = source->getAccessLevel(channel, nick);
+ if (parameters == nullptr)
+ {
+ for (int i = 0; i <= access; i++)
+ {
+ Jupiter::ArrayList cmds = source->getAccessCommands(chan, i);
+ if (cmds.size() != 0)
+ {
+ Jupiter::StringL &triggers = source->getTriggers(cmds);
+ if (triggers.size() >= 0)
+ source->sendNotice(nick, Jupiter::StringS::Format("Access level %d commands: %.*s", i, triggers.size(), triggers.ptr()));
+ }
+ }
+ source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("For command-specific help, use: help "));
+ }
+ else
+ {
+ IRCCommand *cmd = source->getCommand(Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE));
+ if (cmd)
+ {
+ if (access >= cmd->getAccessLevel(chan))
+ source->sendNotice(nick, cmd->getHelp(Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE)));
+ else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Access Denied."));
+ }
+ else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Command not found."));
+ }
+ }
+}
+
+const Jupiter::ReadableString &HelpIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Syntax: help [command]");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(HelpIRCCommand)
+
+// Version IRC Command
+
+void VersionIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("version"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("versioninfo"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("copyright"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("copyrightinfo"));
+}
+
+void VersionIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ source->sendMessage(channel, Jupiter::StringS::Format("Version: %s", Jupiter::version));
+ source->sendMessage(channel, Jupiter::ReferenceString(Jupiter::copyright));
+}
+
+const Jupiter::ReadableString &VersionIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Displays version and copyright information. Syntax: version");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(VersionIRCCommand)
+
+// Sync Command
+
+void SyncIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("sync"));
+ this->setAccessLevel(4);
+}
+
+void SyncIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ if (source->Config == nullptr) source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Unable to find Config data."));
+ else
+ {
+ bool r;
+ if (parameters.size() != 0)
+ r = source->Config->sync(parameters);
+ else r = source->Config->sync();
+ if (r) source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Config data synced to file successfully."));
+ else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Unable to sync Config data."));
+ }
+}
+
+const Jupiter::ReadableString &SyncIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Syncs the configuration data to a file. Syntax: sync [file]");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(SyncIRCCommand)
+
+// Rehash Command
+
+void RehashIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("rehash"));
+ this->setAccessLevel(4);
+}
+
+void RehashIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ if (source->Config == nullptr) source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Unable to find Config data."));
+ else
+ {
+ unsigned int r = Jupiter::rehash();
+ if (r == 0)
+ source->sendMessage(channel, Jupiter::StringS::Format("All %u objects were successfully rehashed.", Jupiter::getRehashableCount()));
+ else source->sendMessage(channel, Jupiter::StringS::Format("%u of %u objects failed to successfully rehash.", r, Jupiter::getRehashableCount()));
+ }
+}
+
+const Jupiter::ReadableString &RehashIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Rehashes configuration data from a file. Syntax: rehash [file]");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(RehashIRCCommand)
+
+// Plugin instantiation and entry point.
+CoreCommandsPlugin pluginInstance;
+
+extern "C" __declspec(dllexport) Jupiter::Plugin *getPlugin()
+{
+ return &pluginInstance;
+}
diff --git a/CoreCommands/CoreCommands.h b/CoreCommands/CoreCommands.h
new file mode 100644
index 0000000..b847192
--- /dev/null
+++ b/CoreCommands/CoreCommands.h
@@ -0,0 +1,41 @@
+/**
+ * Copyright (C) 2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#if !defined _CORECOMMANDS_H_HEADER
+#define _CORECOMMANDS_H_HEADER
+
+#include "Jupiter/Plugin.h"
+#include "Console_Command.h"
+#include "IRC_Command.h"
+
+class CoreCommandsPlugin : public Jupiter::Plugin
+{
+public:
+ const Jupiter::ReadableString &getName() override { return name; }
+
+private:
+ STRING_LITERAL_AS_NAMED_REFERENCE(name, "CoreCommands");
+};
+
+GENERIC_CONSOLE_COMMAND(HelpConsoleCommand)
+GENERIC_CONSOLE_COMMAND(VersionConsoleCommand)
+GENERIC_IRC_COMMAND(HelpIRCCommand)
+GENERIC_IRC_COMMAND(VersionIRCCommand)
+GENERIC_IRC_COMMAND(SyncIRCCommand)
+GENERIC_IRC_COMMAND(RehashIRCCommand)
+
+#endif // _CORECOMMANDS_H_HEADER
\ No newline at end of file
diff --git a/CoreCommands/CoreCommands.vcxproj b/CoreCommands/CoreCommands.vcxproj
new file mode 100644
index 0000000..9412988
--- /dev/null
+++ b/CoreCommands/CoreCommands.vcxproj
@@ -0,0 +1,85 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {55F71101-B302-4345-9F9F-3055E805422A}
+ PluginExample
+ CoreCommands
+
+
+
+ Application
+ true
+ v120
+ MultiByte
+
+
+ DynamicLibrary
+ false
+ v120
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+ $(SolutionDir)$(Configuration)\Plugins\
+ AllRules.ruleset
+
+
+
+ Level3
+ Disabled
+ true
+
+
+ true
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ ../Bot;../Jupiter
+ _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+
+
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CoreCommands/CoreCommands.vcxproj.filters b/CoreCommands/CoreCommands.vcxproj.filters
new file mode 100644
index 0000000..200b773
--- /dev/null
+++ b/CoreCommands/CoreCommands.vcxproj.filters
@@ -0,0 +1,35 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Resource Files
+
+
+ Resource Files
+
+
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/ExtraCommands/ExtraCommands.cpp b/ExtraCommands/ExtraCommands.cpp
new file mode 100644
index 0000000..04d8750
--- /dev/null
+++ b/ExtraCommands/ExtraCommands.cpp
@@ -0,0 +1,287 @@
+/**
+ * Copyright (C) 2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#include
+#include "Jupiter/Functions.h"
+#include "ExtraCommands.h"
+#include "IRC_Bot.h"
+
+// Raw Console Command
+
+RawConsoleCommand::RawConsoleCommand()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("raw"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("sendraw"));
+}
+
+void RawConsoleCommand::trigger(const Jupiter::ReadableString ¶meters)
+{
+ if (parameters.wordCount(WHITESPACE) < 2)
+ puts("Error: Too few parameters.");
+ else
+ {
+ Jupiter::ReferenceString network = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE);
+ Jupiter::ReferenceString message = Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE);
+ size_t total = 0;
+ for (size_t i = 0; i < serverManager->size(); i++)
+ {
+ IRC_Bot *server = serverManager->getServer(i);
+ if (server->getConfigSection().matchi(network))
+ {
+ server->send(message);
+ total++;
+ }
+ }
+ printf("%u packets sent." ENDL, total);
+ }
+}
+
+const Jupiter::ReadableString &RawConsoleCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Syntax: raw ");
+ return defaultHelp;
+}
+
+CONSOLE_COMMAND_INIT(RawConsoleCommand)
+
+// Message Console Command
+
+MessageConsoleCommand::MessageConsoleCommand()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("ircmsg"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("message"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("privmsg"));
+}
+
+void MessageConsoleCommand::trigger(const Jupiter::ReadableString ¶meters)
+{
+ if (parameters.wordCount(WHITESPACE) < 3)
+ puts("Error: Too few parameters.");
+ else
+ {
+ Jupiter::ReferenceString network = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE);
+ Jupiter::ReferenceString channel = Jupiter::ReferenceString::getWord(parameters, 1, WHITESPACE);
+ Jupiter::ReferenceString message = Jupiter::ReferenceString::gotoWord(parameters, 2, WHITESPACE);
+
+ size_t total = 0;
+ for (size_t i = 0; i < serverManager->size(); i++)
+ {
+ IRC_Bot *server = serverManager->getServer(i);
+ if (server->getConfigSection().matchi(network))
+ {
+ server->sendMessage(channel, message);
+ total++;
+ }
+ }
+ printf("%u messages sent." ENDL, total);
+ }
+}
+
+const Jupiter::ReadableString &MessageConsoleCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Sends a message to an IRC user/channel, on a specified network (accepts wildcards). Syntax: msg ");
+ return defaultHelp;
+}
+
+CONSOLE_COMMAND_INIT(MessageConsoleCommand)
+
+// Join Command
+
+void JoinIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("Join"));
+ this->setAccessLevel(3);
+}
+
+void JoinIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ if (parameters.size() != 0)
+ {
+ if (parameters.wordCount(WHITESPACE) == 1)
+ source->joinChannel(parameters);
+ else source->joinChannel(Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE), Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE));
+ }
+ else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: join [password]"));
+}
+
+const Jupiter::ReadableString &JoinIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Joins a channel. Syntax: join ");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(JoinIRCCommand)
+
+// Part Command
+
+void PartIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("Part"));
+ this->setAccessLevel(3);
+}
+
+void PartIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ if (parameters.size() != 0)
+ {
+ if (parameters.wordCount(WHITESPACE) == 1)
+ source->partChannel(parameters);
+ else source->partChannel(Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE), Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE));
+ }
+ else source->partChannel(channel);
+}
+
+const Jupiter::ReadableString &PartIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Parts from a channel. Syntax: part [channel=here] [message=empty]");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(PartIRCCommand)
+
+// Info Command
+
+void InfoIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("info"));
+ this->setAccessLevel(4);
+}
+
+void InfoIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ Jupiter::String msg;
+ msg.format("Outputing data for %u channels...", source->getChannelCount());
+ source->sendMessage(channel, msg);
+ for (unsigned int a = 0; a < source->getChannelCount(); a++)
+ {
+ Jupiter::IRC::Client::Channel *chan = source->getChannel(a);
+ if (chan != nullptr)
+ {
+ msg.format("Channel %.*s - Type: %d", chan->getName().size(), chan->getName().ptr(), chan->getType());
+ source->sendMessage(channel, msg);
+ for (unsigned int b = 0; b < chan->getUserCount(); b++)
+ {
+ Jupiter::IRC::Client::Channel::User *chanUser = chan->getUser(b);
+ Jupiter::IRC::Client::User *user = chanUser->getUser();
+ msg.format("PRIVMSG %.*s :User %.*s!%.*s@%.*s (prefix: %c) of channel %.*s (of %u shared)" ENDL, channel.size(), channel.ptr(), user->getNickname().size(), user->getNickname().ptr(), user->getUsername().size(), user->getUsername().ptr(), user->getHostname().size(), user->getHostname().ptr(), chan->getUserPrefix(b) ? chan->getUserPrefix(b) : ' ', chan->getName().size(), chan->getName().ptr(), user->getChannelCount());
+ source->send(msg);
+ }
+ }
+ }
+}
+
+const Jupiter::ReadableString &InfoIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "TEMPORARY COMMAND - Spits out some info about channels. Syntax: info");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(InfoIRCCommand)
+
+// Exit command
+
+void ExitIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("exit"));
+ this->setAccessLevel(5);
+}
+
+void ExitIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Bye!"));
+ exit(0);
+}
+
+const Jupiter::ReadableString &ExitIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Closes the bot's application process. Syntax: exit");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(ExitIRCCommand)
+
+// IRC Connect command
+
+void IRCConnectIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("IRCConnect"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("IRCReconnect"));
+ this->setAccessLevel(5);
+}
+
+void IRCConnectIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ if (parameters == nullptr)
+ source->disconnect(STRING_LITERAL_AS_REFERENCE("Connect command used; reconnecting..."), false);
+ else
+ {
+ IRC_Bot *server = serverManager->getServer(parameters);
+ if (server != nullptr)
+ {
+ source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Warning: Server already exists. Severing connection..."));
+ server->disconnect(true);
+ }
+ if (serverManager->addServer(parameters))
+ source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Connection successfully established; server added to server list."));
+ else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Unable to find configuration settings for server, or connection refused."));
+ }
+}
+
+const Jupiter::ReadableString &IRCConnectIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Connects/reconnects to an IRC server, based on config entry. Syntax: IRCConnect [server=here]");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(IRCConnectIRCCommand)
+
+// IRC Disconnect command
+
+void IRCDisconnectIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("IRCDisconnect"));
+ this->setAccessLevel(5);
+}
+
+void IRCDisconnectIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ if (parameters.isEmpty())
+ source->disconnect(STRING_LITERAL_AS_REFERENCE("Disconnect command used"), true);
+ else
+ {
+ IRC_Bot *server = serverManager->getServer(parameters);
+ if (server == nullptr)
+ source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Server not found."));
+ else server->disconnect(STRING_LITERAL_AS_REFERENCE("Disconnect command used remotely"), true);
+ }
+}
+
+const Jupiter::ReadableString &IRCDisconnectIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Disconnects from an IRC server, based on config entry. Syntax: IRCDisconnect [server=here]");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(IRCDisconnectIRCCommand)
+
+// Plugin instantiation and entry point.
+FunCommandsPlugin pluginInstance;
+
+extern "C" __declspec(dllexport) Jupiter::Plugin *getPlugin()
+{
+ return &pluginInstance;
+}
diff --git a/ExtraCommands/ExtraCommands.h b/ExtraCommands/ExtraCommands.h
new file mode 100644
index 0000000..08a80d2
--- /dev/null
+++ b/ExtraCommands/ExtraCommands.h
@@ -0,0 +1,43 @@
+/**
+ * Copyright (C) 2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#if !defined _FUNCOMMANDS_H_HEADER
+#define _FUNCOMMANDS_H_HEADER
+
+#include "Jupiter/Plugin.h"
+#include "Console_Command.h"
+#include "IRC_Command.h"
+
+class FunCommandsPlugin : public Jupiter::Plugin
+{
+public:
+ const Jupiter::ReadableString &getName() override { return name; }
+
+private:
+ STRING_LITERAL_AS_NAMED_REFERENCE(name, "ExtraCommands");
+};
+
+GENERIC_CONSOLE_COMMAND(RawConsoleCommand)
+GENERIC_CONSOLE_COMMAND(MessageConsoleCommand)
+GENERIC_IRC_COMMAND(JoinIRCCommand)
+GENERIC_IRC_COMMAND(PartIRCCommand)
+GENERIC_IRC_COMMAND(InfoIRCCommand)
+GENERIC_IRC_COMMAND(ExitIRCCommand)
+GENERIC_IRC_COMMAND(IRCConnectIRCCommand)
+GENERIC_IRC_COMMAND(IRCDisconnectIRCCommand)
+
+#endif // _EXTRACOMMANDS_H_HEADER
\ No newline at end of file
diff --git a/ExtraCommands/ExtraCommands.vcxproj b/ExtraCommands/ExtraCommands.vcxproj
new file mode 100644
index 0000000..7456408
--- /dev/null
+++ b/ExtraCommands/ExtraCommands.vcxproj
@@ -0,0 +1,84 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {85874531-681D-4F44-8A84-C8E939DA3FCB}
+ PluginExample
+
+
+
+ Application
+ true
+ v120
+ MultiByte
+
+
+ DynamicLibrary
+ false
+ v120
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+ $(SolutionDir)$(Configuration)\Plugins\
+ AllRules.ruleset
+
+
+
+ Level3
+ Disabled
+ true
+
+
+ true
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ ../Bot;../Jupiter
+ _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+
+
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ExtraCommands/ExtraCommands.vcxproj.filters b/ExtraCommands/ExtraCommands.vcxproj.filters
new file mode 100644
index 0000000..c81bd10
--- /dev/null
+++ b/ExtraCommands/ExtraCommands.vcxproj.filters
@@ -0,0 +1,35 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Resource Files
+
+
+ Resource Files
+
+
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/FunCommands/FunCommands.cpp b/FunCommands/FunCommands.cpp
new file mode 100644
index 0000000..21acab8
--- /dev/null
+++ b/FunCommands/FunCommands.cpp
@@ -0,0 +1,169 @@
+/**
+ * Copyright (C) 2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#include
+#include "Jupiter/Functions.h"
+#include "Jupiter/Socket.h"
+#include "Jupiter/CString.h"
+#include "FunCommands.h"
+#include "IRC_Bot.h"
+
+// 8ball
+
+void EightBallIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("8ball"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("8balls"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("eightBall"));
+}
+
+void EightBallIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ Jupiter::StringS msg;
+ unsigned short r = rand() % 20;
+ switch (r)
+ {
+ case 0:
+ msg.set("No.");
+ break;
+ case 1:
+ msg.set("Yes.");
+ break;
+ case 2:
+ msg.set("Maybe.");
+ break;
+ case 3:
+ msg.set("Seven.");
+ break;
+ case 4:
+ msg.set("Consider counseling.");
+ break;
+ case 5:
+ msg.set("Look into a realationship. A real one.");
+ break;
+ case 6:
+ msg.set("Quit asking me these deep questions, before I get deeply into you.");
+ break;
+ case 7:
+ msg.set("Fuck you.");
+ break;
+ case 8:
+ msg.set("Fuck me.");
+ break;
+ case 9:
+ msg.set("I'm sorry, I don't bend that way.");
+ break;
+ case 10:
+ msg.format("Hai %.*s ;)", nick.size(), nick.ptr());
+ break;
+ case 11:
+ msg.format("Let's ban %.*s!", nick.size(), nick.ptr());
+ break;
+ case 12:
+ msg.format("Sorry %.*s, but your IQ must be at least %d for me to care.", nick.size(), nick.ptr(), rand() % 50);
+ break;
+ case 13:
+ msg.set("Ask me those kind of questions in #Faggots");
+ break;
+ case 14:
+ msg.set("I don't talk to slut-mongers.");
+ break;
+ case 15:
+ msg.set("I only talk to slut-mongers.");
+ break;
+ case 16:
+ msg.set("Nuclear launch detected.");
+ break;
+ case 17:
+ msg.set("404 - Not found.");
+ break;
+ case 18:
+ msg.set("I hurr u liek mudkipz?");
+ break;
+ case 19:
+ msg.set("Walk this way, babycakes ;)");
+ break;
+ default:
+ msg.set("Nothingness. You suck. Go rot.");
+ break;
+ }
+ source->sendMessage(channel, msg);
+}
+
+const Jupiter::ReadableString &EightBallIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Accurately answers your question 60% of the time, EVERY time. Syntax: 8ball [question]");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(EightBallIRCCommand)
+
+// Resolve Command
+
+void ResolveIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("resolve"));
+}
+
+void ResolveIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ unsigned int count = parameters.wordCount(WHITESPACE);
+ if (count > 1)
+ {
+ Jupiter::ReferenceString command = Jupiter::ReferenceString::getWord(parameters, 0, WHITESPACE);
+ if (command.equalsi("hostname") || command.equalsi("host"))
+ {
+ Jupiter::ReferenceString resolved = Jupiter::Socket::resolveHostname(Jupiter::CStringS::gotoWord(parameters, 1, WHITESPACE).c_str(), 0);
+ if (resolved.isEmpty() == false)
+ source->sendMessage(channel, resolved);
+ else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Unable to resolve."));
+ }
+ else if (command.equalsi("ip"))
+ {
+ Jupiter::ReferenceString resolved = Jupiter::Socket::resolveAddress(Jupiter::CStringS::gotoWord(parameters, 1, WHITESPACE).c_str(), 0);
+ if (resolved.isEmpty() == false)
+ source->sendMessage(channel, resolved);
+ else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Unable to resolve."));
+ }
+ else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Invalid type. You can only resolve hostnames and IP addresses."));
+ }
+ else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Too few parameters. Syntax: resolve "));
+}
+
+const Jupiter::ReadableString &ResolveIRCCommand::getHelp(const Jupiter::ReadableString ¶meters)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Resolves an IP address or hostname. Syntax: resolve ");
+ static STRING_LITERAL_AS_NAMED_REFERENCE(hostHelp, "Resolves a hostname to an IP address. Syntax: resolve hostname ");
+ static STRING_LITERAL_AS_NAMED_REFERENCE(ipHelp, "Reverse-resolves an IP address to a hostname. Syntax: resolve ip ");
+
+ if (parameters.equalsi(STRING_LITERAL_AS_REFERENCE("hostname")) || parameters.equalsi(STRING_LITERAL_AS_REFERENCE("host")))
+ return hostHelp;
+ if (parameters.equalsi(STRING_LITERAL_AS_REFERENCE("ip")))
+ return ipHelp;
+
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(ResolveIRCCommand)
+
+// Plugin instantiation and entry point.
+ExtraCommandsPlugin pluginInstance;
+
+extern "C" __declspec(dllexport) Jupiter::Plugin *getPlugin()
+{
+ return &pluginInstance;
+}
diff --git a/FunCommands/FunCommands.h b/FunCommands/FunCommands.h
new file mode 100644
index 0000000..10afa1b
--- /dev/null
+++ b/FunCommands/FunCommands.h
@@ -0,0 +1,36 @@
+/**
+ * Copyright (C) 2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#if !defined _FUNCOMMANDS_H_HEADER
+#define _FUNCOMMANDS_H_HEADER
+
+#include "Jupiter/Plugin.h"
+#include "IRC_Command.h"
+
+class ExtraCommandsPlugin : public Jupiter::Plugin
+{
+public:
+ const Jupiter::ReadableString &getName() override { return name; }
+
+private:
+ STRING_LITERAL_AS_NAMED_REFERENCE(name, "FunCommands");
+};
+
+GENERIC_IRC_COMMAND(EightBallIRCCommand)
+GENERIC_IRC_COMMAND(ResolveIRCCommand)
+
+#endif // _FUNCOMMANDS_H_HEADER
\ No newline at end of file
diff --git a/FunCommands/FunCommands.vcxproj b/FunCommands/FunCommands.vcxproj
new file mode 100644
index 0000000..e24bb0f
--- /dev/null
+++ b/FunCommands/FunCommands.vcxproj
@@ -0,0 +1,84 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {80E38D71-CEC5-457F-88EC-24D3097C3470}
+ PluginExample
+
+
+
+ Application
+ true
+ v120
+ MultiByte
+
+
+ DynamicLibrary
+ false
+ v120
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+ $(SolutionDir)$(Configuration)\Plugins\
+ AllRules.ruleset
+
+
+
+ Level3
+ Disabled
+ true
+
+
+ true
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ ../Bot;../Jupiter
+ _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+
+
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FunCommands/FunCommands.vcxproj.filters b/FunCommands/FunCommands.vcxproj.filters
new file mode 100644
index 0000000..d37fcc3
--- /dev/null
+++ b/FunCommands/FunCommands.vcxproj.filters
@@ -0,0 +1,35 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Resource Files
+
+
+ Resource Files
+
+
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/Jupiter Bot.sln b/Jupiter Bot.sln
new file mode 100644
index 0000000..de02f01
--- /dev/null
+++ b/Jupiter Bot.sln
@@ -0,0 +1,176 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.30110.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bot", "Bot\Bot.vcxproj", "{C188871B-5F32-4946-B301-24CA2EBB275D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin.Example", "Plugin.Example\Plugin.Example.vcxproj", "{EA2C0100-5CC5-4416-8216-059833CAACE2}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin.Template", "Plugin.Template\Plugin.Template.vcxproj", "{1DD04156-F096-4C41-9E1C-5BFD3234E9FD}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginManager", "PluginManager\PluginManager.vcxproj", "{9D82C7EE-4167-4F5A-9764-B2C6B0EB9712}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SetJoin", "SetJoin\SetJoin.vcxproj", "{FDBEC4F9-AC8D-4197-BA6C-D042DF218A93}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FunCommands", "FunCommands\FunCommands.vcxproj", "{80E38D71-CEC5-457F-88EC-24D3097C3470}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExtraCommands", "ExtraCommands\ExtraCommands.vcxproj", "{85874531-681D-4F44-8A84-C8E939DA3FCB}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CoreCommands", "CoreCommands\CoreCommands.vcxproj", "{55F71101-B302-4345-9F9F-3055E805422A}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.Core", "RenX.Core\RenX.Core.vcxproj", "{9103DF3D-8B4A-48E5-A6B3-CBE2554630E2}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.Commands", "RenX.Commands\RenX.Commands.vcxproj", "{72B6B5A6-4267-4FED-9F96-917C7974CE25}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D}
+ {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} = {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.Plugin.Template", "RenX.Plugin.Template\RenX.Plugin.Template.vcxproj", "{6F575493-CF43-43CB-8062-9F3D0722A624}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D}
+ {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} = {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.Logging", "RenX.Logging\RenX.Logging.vcxproj", "{069D6053-F39A-4418-BAA3-FA8D260C83D1}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D}
+ {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} = {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.ExcessiveHeadshots", "RenX.ExcessiveHeadshots\RenX.ExcessiveHeadshots.vcxproj", "{0F71052A-A773-4AB5-AE2A-50DBDFB9CF9E}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D}
+ {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} = {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.ExtraLogging", "RenX.ExtraLogging\RenX.ExtraLogging.vcxproj", "{CEFD949E-BCF2-4EDB-8168-0920924FE2D8}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D}
+ {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} = {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.Announcements", "RenX.Announcements\RenX.Announcements.vcxproj", "{EF55A6DC-1861-4037-868A-9557ECAEBC27}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D}
+ {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} = {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2}
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{844CF9EF-70F3-449D-ACF3-A70D3501A775}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.Medals", "RenX.Medals\RenX.Medals.vcxproj", "{C295FFC2-8CE5-4387-B237-E4E1B1AB9987}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D}
+ {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} = {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.SetJoin", "RenX.SetJoin\RenX.SetJoin.vcxproj", "{0489F164-DC8F-433C-8CFA-F7EB2A3356F1}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D}
+ {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2} = {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C188871B-5F32-4946-B301-24CA2EBB275D}.Debug|Win32.ActiveCfg = Release|Win32
+ {C188871B-5F32-4946-B301-24CA2EBB275D}.Debug|Win32.Build.0 = Release|Win32
+ {C188871B-5F32-4946-B301-24CA2EBB275D}.Release|Win32.ActiveCfg = Release|Win32
+ {C188871B-5F32-4946-B301-24CA2EBB275D}.Release|Win32.Build.0 = Release|Win32
+ {EA2C0100-5CC5-4416-8216-059833CAACE2}.Debug|Win32.ActiveCfg = Debug|Win32
+ {EA2C0100-5CC5-4416-8216-059833CAACE2}.Debug|Win32.Build.0 = Debug|Win32
+ {EA2C0100-5CC5-4416-8216-059833CAACE2}.Release|Win32.ActiveCfg = Release|Win32
+ {EA2C0100-5CC5-4416-8216-059833CAACE2}.Release|Win32.Build.0 = Release|Win32
+ {1DD04156-F096-4C41-9E1C-5BFD3234E9FD}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1DD04156-F096-4C41-9E1C-5BFD3234E9FD}.Debug|Win32.Build.0 = Debug|Win32
+ {1DD04156-F096-4C41-9E1C-5BFD3234E9FD}.Release|Win32.ActiveCfg = Release|Win32
+ {1DD04156-F096-4C41-9E1C-5BFD3234E9FD}.Release|Win32.Build.0 = Release|Win32
+ {9D82C7EE-4167-4F5A-9764-B2C6B0EB9712}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9D82C7EE-4167-4F5A-9764-B2C6B0EB9712}.Debug|Win32.Build.0 = Debug|Win32
+ {9D82C7EE-4167-4F5A-9764-B2C6B0EB9712}.Release|Win32.ActiveCfg = Release|Win32
+ {9D82C7EE-4167-4F5A-9764-B2C6B0EB9712}.Release|Win32.Build.0 = Release|Win32
+ {FDBEC4F9-AC8D-4197-BA6C-D042DF218A93}.Debug|Win32.ActiveCfg = Debug|Win32
+ {FDBEC4F9-AC8D-4197-BA6C-D042DF218A93}.Debug|Win32.Build.0 = Debug|Win32
+ {FDBEC4F9-AC8D-4197-BA6C-D042DF218A93}.Release|Win32.ActiveCfg = Release|Win32
+ {FDBEC4F9-AC8D-4197-BA6C-D042DF218A93}.Release|Win32.Build.0 = Release|Win32
+ {80E38D71-CEC5-457F-88EC-24D3097C3470}.Debug|Win32.ActiveCfg = Debug|Win32
+ {80E38D71-CEC5-457F-88EC-24D3097C3470}.Debug|Win32.Build.0 = Debug|Win32
+ {80E38D71-CEC5-457F-88EC-24D3097C3470}.Release|Win32.ActiveCfg = Release|Win32
+ {80E38D71-CEC5-457F-88EC-24D3097C3470}.Release|Win32.Build.0 = Release|Win32
+ {85874531-681D-4F44-8A84-C8E939DA3FCB}.Debug|Win32.ActiveCfg = Debug|Win32
+ {85874531-681D-4F44-8A84-C8E939DA3FCB}.Debug|Win32.Build.0 = Debug|Win32
+ {85874531-681D-4F44-8A84-C8E939DA3FCB}.Release|Win32.ActiveCfg = Release|Win32
+ {85874531-681D-4F44-8A84-C8E939DA3FCB}.Release|Win32.Build.0 = Release|Win32
+ {55F71101-B302-4345-9F9F-3055E805422A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {55F71101-B302-4345-9F9F-3055E805422A}.Debug|Win32.Build.0 = Debug|Win32
+ {55F71101-B302-4345-9F9F-3055E805422A}.Release|Win32.ActiveCfg = Release|Win32
+ {55F71101-B302-4345-9F9F-3055E805422A}.Release|Win32.Build.0 = Release|Win32
+ {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2}.Debug|Win32.Build.0 = Debug|Win32
+ {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2}.Release|Win32.ActiveCfg = Release|Win32
+ {9103DF3D-8B4A-48E5-A6B3-CBE2554630E2}.Release|Win32.Build.0 = Release|Win32
+ {72B6B5A6-4267-4FED-9F96-917C7974CE25}.Debug|Win32.ActiveCfg = Debug|Win32
+ {72B6B5A6-4267-4FED-9F96-917C7974CE25}.Debug|Win32.Build.0 = Debug|Win32
+ {72B6B5A6-4267-4FED-9F96-917C7974CE25}.Release|Win32.ActiveCfg = Release|Win32
+ {72B6B5A6-4267-4FED-9F96-917C7974CE25}.Release|Win32.Build.0 = Release|Win32
+ {6F575493-CF43-43CB-8062-9F3D0722A624}.Debug|Win32.ActiveCfg = Debug|Win32
+ {6F575493-CF43-43CB-8062-9F3D0722A624}.Debug|Win32.Build.0 = Debug|Win32
+ {6F575493-CF43-43CB-8062-9F3D0722A624}.Release|Win32.ActiveCfg = Release|Win32
+ {6F575493-CF43-43CB-8062-9F3D0722A624}.Release|Win32.Build.0 = Release|Win32
+ {069D6053-F39A-4418-BAA3-FA8D260C83D1}.Debug|Win32.ActiveCfg = Debug|Win32
+ {069D6053-F39A-4418-BAA3-FA8D260C83D1}.Debug|Win32.Build.0 = Debug|Win32
+ {069D6053-F39A-4418-BAA3-FA8D260C83D1}.Release|Win32.ActiveCfg = Release|Win32
+ {069D6053-F39A-4418-BAA3-FA8D260C83D1}.Release|Win32.Build.0 = Release|Win32
+ {0F71052A-A773-4AB5-AE2A-50DBDFB9CF9E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0F71052A-A773-4AB5-AE2A-50DBDFB9CF9E}.Debug|Win32.Build.0 = Debug|Win32
+ {0F71052A-A773-4AB5-AE2A-50DBDFB9CF9E}.Release|Win32.ActiveCfg = Release|Win32
+ {0F71052A-A773-4AB5-AE2A-50DBDFB9CF9E}.Release|Win32.Build.0 = Release|Win32
+ {CEFD949E-BCF2-4EDB-8168-0920924FE2D8}.Debug|Win32.ActiveCfg = Debug|Win32
+ {CEFD949E-BCF2-4EDB-8168-0920924FE2D8}.Debug|Win32.Build.0 = Debug|Win32
+ {CEFD949E-BCF2-4EDB-8168-0920924FE2D8}.Release|Win32.ActiveCfg = Release|Win32
+ {CEFD949E-BCF2-4EDB-8168-0920924FE2D8}.Release|Win32.Build.0 = Release|Win32
+ {EF55A6DC-1861-4037-868A-9557ECAEBC27}.Debug|Win32.ActiveCfg = Debug|Win32
+ {EF55A6DC-1861-4037-868A-9557ECAEBC27}.Debug|Win32.Build.0 = Debug|Win32
+ {EF55A6DC-1861-4037-868A-9557ECAEBC27}.Release|Win32.ActiveCfg = Release|Win32
+ {EF55A6DC-1861-4037-868A-9557ECAEBC27}.Release|Win32.Build.0 = Release|Win32
+ {C295FFC2-8CE5-4387-B237-E4E1B1AB9987}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C295FFC2-8CE5-4387-B237-E4E1B1AB9987}.Debug|Win32.Build.0 = Debug|Win32
+ {C295FFC2-8CE5-4387-B237-E4E1B1AB9987}.Release|Win32.ActiveCfg = Release|Win32
+ {C295FFC2-8CE5-4387-B237-E4E1B1AB9987}.Release|Win32.Build.0 = Release|Win32
+ {0489F164-DC8F-433C-8CFA-F7EB2A3356F1}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0489F164-DC8F-433C-8CFA-F7EB2A3356F1}.Debug|Win32.Build.0 = Debug|Win32
+ {0489F164-DC8F-433C-8CFA-F7EB2A3356F1}.Release|Win32.ActiveCfg = Release|Win32
+ {0489F164-DC8F-433C-8CFA-F7EB2A3356F1}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/MakeRelease.bat b/MakeRelease.bat
new file mode 100644
index 0000000..8741cea
--- /dev/null
+++ b/MakeRelease.bat
@@ -0,0 +1,66 @@
+@ECHO OFF
+if NOT "%2" == "-scr" ECHO Copyright (C) 2014 Justin James. All rights reserved.
+ECHO.
+
+if "%1" == "/?" GOTO Help
+if "%1" == "-help" GOTO Help
+if "%1" == "--help" GOTO Help
+if "%1" == "-clean" GOTO CleanUp
+if "%1" == "-binary" GOTO BinaryCopy
+if "%1" == "-source" GOTO SourceCopy
+CALL %0 -clean -scr
+CALL %0 -binary -scr
+CALL %0 -source -scr
+if "%1" == "" GOTO Done
+GOTO EOF
+
+:Help:
+ECHO This is a convenience script to assist in build release.
+ECHO Usage: %0 [-clean/-binary/-source]
+ECHO.
+ECHO Clean: Deletes any contents from previous builds.
+ECHO Binary: Copies and ZIPS the essential binaries to run the applicaiton.
+ECHO Source: Copies and ZIPS the source code to run the application.
+ECHO.
+ECHO If no parameters are given, then all functions will be executed.
+ECHO.
+ECHO If a parameter other than "-clean", "-binary", or "-source" is given,
+ECHO then the program will execute all functions without pausing at the end.
+ECHO.
+ECHO Program execution order:
+ECHO Clean
+ECHO Binary
+ECHO Source
+ECHO.
+ECHO Dependencies:
+ECHO COPY, ROBOCOPY, DEL, RMDIR, PAUSE, ECHO, GOTO, IF, CALL
+GOTO EOF
+
+:CleanUp:
+RMDIR /S /Q "..\Jupiter Bot Binaries"
+RMDIR /S /Q "..\Jupiter Bot Source"
+DEL /F /Q "..\Jupiter Bot Binaries.zip"
+DEL /F /Q "..\Jupiter Bot.zip"
+GOTO EOF
+
+:BinaryCopy:
+ROBOCOPY "Release\\" "..\Jupiter Bot Binaries\\" *.dll *.exe ReadMe.txt /S
+COPY /Y "Release\Example Config.ini" "..\Jupiter Bot Binaries\Config.ini"
+COPY /Y "Release\Translations.ini" "..\Jupiter Bot Binaries\Translations.ini"
+"C:\Program Files\WinRAR\WinRAR.exe" a -r "..\Jupiter Bot Binaries.zip" "..\Jupiter Bot Binaries"
+GOTO EOF
+
+:SourceCopy:
+ROBOCOPY ".\\" "..\Jupiter Bot Source\\" *.* /S /XD Release
+ROBOCOPY "Release\\" "..\Jupiter Bot Source\Release\\" *.dll *.exe ReadMe.txt /S
+COPY /Y "Release\Example Config.ini" "..\Jupiter Bot Source\Release\Config.ini"
+COPY /Y "Release\Translations.ini" "..\Jupiter Bot Source\Release\Translations.ini"
+"C:\Program Files\WinRAR\WinRAR.exe" a -r "..\Jupiter Bot.zip" "..\Jupiter Bot Source"
+GOTO EOF
+
+:Done:
+ECHO Operations complete.
+PAUSE
+GOTO EOF
+
+:EOF:
\ No newline at end of file
diff --git a/Plugin.Example/Example.cpp b/Plugin.Example/Example.cpp
new file mode 100644
index 0000000..fa66aef
--- /dev/null
+++ b/Plugin.Example/Example.cpp
@@ -0,0 +1,44 @@
+/**
+ * This file is in the public domain, furnished "as is", without technical
+ * support, and with no warranty, express or implied, as to its usefulness for
+ * any purpose.
+ *
+ * Written by Justin James
+ */
+
+#include "Example.h"
+#include "IRC_Bot.h"
+
+void ExamplePlugin::OnConnect(Jupiter::IRC::Client *server)
+{
+ server->sendNotice(STRING_LITERAL_AS_REFERENCE("Agent"), STRING_LITERAL_AS_REFERENCE("Honey, I'm home!"));
+}
+
+// Example IRC Command Implementation
+
+void ExampleIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("example"));
+}
+
+void ExampleIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("This is an example command!"));
+}
+
+const Jupiter::ReadableString &ExampleIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(helpmsg, "This is just an example command. It takes no parameters!");
+ return helpmsg;
+}
+
+IRC_COMMAND_INIT(ExampleIRCCommand)
+
+
+// Plugin instantiation and entry point.
+ExamplePlugin pluginInstance;
+
+extern "C" __declspec(dllexport) Jupiter::Plugin *getPlugin()
+{
+ return &pluginInstance;
+}
diff --git a/Plugin.Example/Example.h b/Plugin.Example/Example.h
new file mode 100644
index 0000000..4c81968
--- /dev/null
+++ b/Plugin.Example/Example.h
@@ -0,0 +1,28 @@
+/**
+ * This file is in the public domain, furnished "as is", without technical
+ * support, and with no warranty, express or implied, as to its usefulness for
+ * any purpose.
+ *
+ * Written by Justin James
+ */
+
+#if !defined _EXAMPLE_H_HEADER
+#define _EXAMPLE_H_HEADER
+
+#include "Jupiter/Plugin.h"
+#include "IRC_Command.h"
+
+class ExamplePlugin : public Jupiter::Plugin
+{
+public:
+ void OnConnect(Jupiter::IRC::Client *server);
+ const Jupiter::ReadableString &getName() override { return this->name; }
+
+private:
+ STRING_LITERAL_AS_NAMED_REFERENCE(name, "ExamplePlugin");
+};
+
+// Example IRC Command Declaration
+GENERIC_IRC_COMMAND(ExampleIRCCommand)
+
+#endif // _EXAMPLE_H_HEADER
\ No newline at end of file
diff --git a/Plugin.Example/Plugin.Example.vcxproj b/Plugin.Example/Plugin.Example.vcxproj
new file mode 100644
index 0000000..0715b2c
--- /dev/null
+++ b/Plugin.Example/Plugin.Example.vcxproj
@@ -0,0 +1,84 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {EA2C0100-5CC5-4416-8216-059833CAACE2}
+ PluginExample
+
+
+
+ Application
+ true
+ v120
+ MultiByte
+
+
+ DynamicLibrary
+ false
+ v120
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+ $(SolutionDir)$(Configuration)\Plugins\
+ AllRules.ruleset
+
+
+
+ Level3
+ Disabled
+ true
+
+
+ true
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ ../Bot;../Jupiter
+ _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+
+
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Plugin.Example/Plugin.Example.vcxproj.filters b/Plugin.Example/Plugin.Example.vcxproj.filters
new file mode 100644
index 0000000..ab9ee24
--- /dev/null
+++ b/Plugin.Example/Plugin.Example.vcxproj.filters
@@ -0,0 +1,35 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+
+
+ Resource Files
+
+
+ Resource Files
+
+
+
\ No newline at end of file
diff --git a/Plugin.Template - Copy/Example.cpp b/Plugin.Template - Copy/Example.cpp
new file mode 100644
index 0000000..c0d7700
--- /dev/null
+++ b/Plugin.Template - Copy/Example.cpp
@@ -0,0 +1,11 @@
+#include "Example.h"
+
+
+
+// Plugin instantiation and entry point.
+TPlugin pluginInstance;
+
+extern "C" __declspec(dllexport) Jupiter::Plugin *getPlugin()
+{
+ return &pluginInstance;
+}
diff --git a/Plugin.Template - Copy/Example.h b/Plugin.Template - Copy/Example.h
new file mode 100644
index 0000000..6d2625b
--- /dev/null
+++ b/Plugin.Template - Copy/Example.h
@@ -0,0 +1,11 @@
+#if !defined _EXAMPLE_H_HEADER
+#define _EXAMPLE_H_HEADER
+
+#include "Plugin.h"
+
+class TPlugin : public Jupiter::Plugin
+{
+ const char *getName() { return "TemplatePlugin"; }
+};
+
+#endif // _EXAMPLE_H_HEADER
\ No newline at end of file
diff --git a/Plugin.Template - Copy/Plugin.Template.vcxproj b/Plugin.Template - Copy/Plugin.Template.vcxproj
new file mode 100644
index 0000000..955a247
--- /dev/null
+++ b/Plugin.Template - Copy/Plugin.Template.vcxproj
@@ -0,0 +1,83 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {1DD04156-F096-4C41-9E1C-5BFD3234E9FD}
+ PluginExample
+
+
+
+ Application
+ true
+ v120
+ MultiByte
+
+
+ DynamicLibrary
+ false
+ v120
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+ $(SolutionDir)$(Configuration)\Plugins\
+
+
+
+ Level3
+ Disabled
+ true
+
+
+ true
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ ../Bot;../Jupiter
+ _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+
+
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Plugin.Template - Copy/Plugin.Template.vcxproj.filters b/Plugin.Template - Copy/Plugin.Template.vcxproj.filters
new file mode 100644
index 0000000..ed05baa
--- /dev/null
+++ b/Plugin.Template - Copy/Plugin.Template.vcxproj.filters
@@ -0,0 +1,35 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+
+
+ Resource Files
+
+
+ Resource Files
+
+
+
\ No newline at end of file
diff --git a/Plugin.Template/Example.cpp b/Plugin.Template/Example.cpp
new file mode 100644
index 0000000..63c184b
--- /dev/null
+++ b/Plugin.Template/Example.cpp
@@ -0,0 +1,19 @@
+/**
+ * This file is in the public domain, furnished "as is", without technical
+ * support, and with no warranty, express or implied, as to its usefulness for
+ * any purpose.
+ *
+ * Written by Justin James
+ */
+
+#include "Example.h"
+
+
+
+// Plugin instantiation and entry point.
+TPlugin pluginInstance;
+
+extern "C" __declspec(dllexport) Jupiter::Plugin *getPlugin()
+{
+ return &pluginInstance;
+}
diff --git a/Plugin.Template/Example.h b/Plugin.Template/Example.h
new file mode 100644
index 0000000..be72a54
--- /dev/null
+++ b/Plugin.Template/Example.h
@@ -0,0 +1,24 @@
+/**
+ * This file is in the public domain, furnished "as is", without technical
+ * support, and with no warranty, express or implied, as to its usefulness for
+ * any purpose.
+ *
+ * Written by Justin James
+ */
+
+#if !defined _EXAMPLE_H_HEADER
+#define _EXAMPLE_H_HEADER
+
+#include "Jupiter/Plugin.h"
+#include "Jupiter/Reference_String.h"
+
+class TPlugin : public Jupiter::Plugin
+{
+public:
+ const Jupiter::ReadableString &getName() override { return name; }
+
+private:
+ STRING_LITERAL_AS_NAMED_REFERENCE(name, "TemplatePlugin");
+};
+
+#endif // _EXAMPLE_H_HEADER
\ No newline at end of file
diff --git a/Plugin.Template/Plugin.Template.vcxproj b/Plugin.Template/Plugin.Template.vcxproj
new file mode 100644
index 0000000..17971d7
--- /dev/null
+++ b/Plugin.Template/Plugin.Template.vcxproj
@@ -0,0 +1,84 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {1DD04156-F096-4C41-9E1C-5BFD3234E9FD}
+ PluginExample
+
+
+
+ Application
+ true
+ v120
+ MultiByte
+
+
+ DynamicLibrary
+ false
+ v120
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+ $(SolutionDir)$(Configuration)\Plugins\
+ AllRules.ruleset
+
+
+
+ Level3
+ Disabled
+ true
+
+
+ true
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ ../Bot;../Jupiter
+ _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+
+
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Plugin.Template/Plugin.Template.vcxproj.filters b/Plugin.Template/Plugin.Template.vcxproj.filters
new file mode 100644
index 0000000..ab9ee24
--- /dev/null
+++ b/Plugin.Template/Plugin.Template.vcxproj.filters
@@ -0,0 +1,35 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+
+
+ Resource Files
+
+
+ Resource Files
+
+
+
\ No newline at end of file
diff --git a/PluginManager/PluginManager.cpp b/PluginManager/PluginManager.cpp
new file mode 100644
index 0000000..4595882
--- /dev/null
+++ b/PluginManager/PluginManager.cpp
@@ -0,0 +1,172 @@
+/**
+ * Copyright (C) 2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#include
+#include "Jupiter/Functions.h"
+#include "PluginManager.h"
+#include "IRC_Bot.h"
+
+// Plugin Console Command
+PluginConsoleCommand::PluginConsoleCommand()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("plugin"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("plugins"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("module"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("modules"));
+}
+
+void PluginConsoleCommand::trigger(const Jupiter::ReadableString ¶meters)
+{
+ if (parameters.isEmpty() || parameters.matchi("list*"))
+ {
+ printf("There are %u plugins loaded." ENDL, Jupiter::plugins->size());
+ for (size_t i = 0; i != Jupiter::plugins->size(); i++) Jupiter::plugins->get(i)->getName().println(stdout);
+ }
+ else
+ {
+ if (parameters.matchi("load *"))
+ {
+ if (Jupiter::loadPlugin(Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE)) == nullptr)
+ puts("Error: Failed to load plugin.");
+ else
+ puts("Plugin successfully loaded.");
+ }
+ else if (parameters.matchi("unload *"))
+ {
+ Jupiter::ReferenceString pluginName = Jupiter::ReferenceString::gotoWord(parameters, 1, WHITESPACE);
+ if (Jupiter::getPlugin(pluginName) == nullptr)
+ puts("Error: Plugin does not exist.");
+ else if (Jupiter::freePlugin(pluginName) == false)
+ puts("Error: Failed to unload plugin.");
+ else
+ puts("Plugin successfully unloaded.");
+ }
+ else
+ puts("Error: Invalid Syntax. Syntax: plugin {[list], , }");
+ }
+}
+
+const Jupiter::ReadableString &PluginConsoleCommand::getHelp(const Jupiter::ReadableString ¶meters)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(loadHelp, "Loads a plugin by file name. Do not include a file extension. Syntax: plugin load ");
+ static STRING_LITERAL_AS_NAMED_REFERENCE(unloadHelp, "Unloads a plugin by name. Syntax: plugin unload ");
+ static STRING_LITERAL_AS_NAMED_REFERENCE(listHelp, "Lists all of the plugins currently loaded. Syntax: plugin [list]");
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Manages plugins. Syntax: plugin {[list], , }");
+
+ if (parameters.equalsi(STRING_LITERAL_AS_REFERENCE("load")))
+ return loadHelp;
+ if (parameters.equalsi(STRING_LITERAL_AS_REFERENCE("unload")))
+ return unloadHelp;
+ if (parameters.equalsi(STRING_LITERAL_AS_REFERENCE("list")))
+ return listHelp;
+
+ return defaultHelp;
+}
+
+CONSOLE_COMMAND_INIT(PluginConsoleCommand)
+
+// Load Plugin
+
+void LoadPluginIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("loadplugin"));
+ this->setAccessLevel(5);
+}
+
+void LoadPluginIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ if (parameters != nullptr)
+ {
+ if (Jupiter::getPlugin(parameters) != nullptr) source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Plugin already exists. You must first unload the plugin."));
+ else
+ {
+ if (Jupiter::loadPlugin(parameters) == nullptr) source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Failed to load plugin."));
+ else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Plugin successfully loaded."));
+ }
+ }
+ else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: loadPlugin "));
+}
+
+const Jupiter::ReadableString &LoadPluginIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Dynamically loads a plugin. Syntax: loadPlugin ");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(LoadPluginIRCCommand)
+
+// Free Plugin
+
+void FreePluginIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("freeplugin"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("unloadplugin"));
+ this->setAccessLevel(5);
+}
+
+void FreePluginIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ if (parameters != nullptr)
+ {
+ if (Jupiter::getPlugin(parameters) == nullptr) source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Plugin does not exist."));
+ else if (Jupiter::freePlugin(parameters) == false) source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Failed to unload plugin."));
+ else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Plugin successfully unloaded."));
+ }
+ else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: freePlugin "));
+}
+
+const Jupiter::ReadableString &FreePluginIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Dynamically unloads a plugin. Syntax: freePlugin ");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(FreePluginIRCCommand)
+
+// List Plugins
+
+void ListPluginIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("listplugin"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("listplugins"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("pluginlist"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("pluginslist"));
+ this->setAccessLevel(4);
+}
+
+void ListPluginIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ source->sendMessage(channel, Jupiter::StringS::Format("%u plugins loaded:", Jupiter::plugins->size()));
+ for (size_t i = 0; i != Jupiter::plugins->size(); i++)
+ source->sendMessage(channel, Jupiter::plugins->get(i)->getName());
+}
+
+const Jupiter::ReadableString &ListPluginIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Lists the currently loaded plugins. Syntax: pluginlist");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(ListPluginIRCCommand)
+
+// Plugin instantiation and entry point.
+PluginManager pluginInstance;
+
+extern "C" __declspec(dllexport) Jupiter::Plugin *getPlugin()
+{
+ return &pluginInstance;
+}
diff --git a/PluginManager/PluginManager.h b/PluginManager/PluginManager.h
new file mode 100644
index 0000000..44ec003
--- /dev/null
+++ b/PluginManager/PluginManager.h
@@ -0,0 +1,39 @@
+/**
+ * Copyright (C) 2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#if !defined _PLUGINMANAGER_H_HEADER
+#define _PLUGINMANAGER_H_HEADER
+
+#include "Jupiter/Plugin.h"
+#include "Console_Command.h"
+#include "IRC_Command.h"
+
+class PluginManager : public Jupiter::Plugin
+{
+public:
+ const Jupiter::ReadableString &getName() override { return name; }
+
+private:
+ STRING_LITERAL_AS_NAMED_REFERENCE(name, "PluginManager");
+};
+
+GENERIC_CONSOLE_COMMAND(PluginConsoleCommand)
+GENERIC_IRC_COMMAND(LoadPluginIRCCommand)
+GENERIC_IRC_COMMAND(FreePluginIRCCommand)
+GENERIC_IRC_COMMAND(ListPluginIRCCommand)
+
+#endif // _PLUGINMANAGER_H_HEADER
\ No newline at end of file
diff --git a/PluginManager/PluginManager.vcxproj b/PluginManager/PluginManager.vcxproj
new file mode 100644
index 0000000..eb4d059
--- /dev/null
+++ b/PluginManager/PluginManager.vcxproj
@@ -0,0 +1,85 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {9D82C7EE-4167-4F5A-9764-B2C6B0EB9712}
+ PluginExample
+ PluginManager
+
+
+
+ Application
+ true
+ v120
+ MultiByte
+
+
+ DynamicLibrary
+ false
+ v120
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+ $(SolutionDir)$(Configuration)\Plugins\
+ AllRules.ruleset
+
+
+
+ Level3
+ Disabled
+ true
+
+
+ true
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ ../Bot;../Jupiter
+ _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+
+
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PluginManager/PluginManager.vcxproj.filters b/PluginManager/PluginManager.vcxproj.filters
new file mode 100644
index 0000000..1e0686a
--- /dev/null
+++ b/PluginManager/PluginManager.vcxproj.filters
@@ -0,0 +1,35 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Resource Files
+
+
+ Resource Files
+
+
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/Release/Bot.lib b/Release/Bot.lib
new file mode 100644
index 0000000..5ba44af
Binary files /dev/null and b/Release/Bot.lib differ
diff --git a/Release/Plugins/RenX.Core.lib b/Release/Plugins/RenX.Core.lib
new file mode 100644
index 0000000..a3aad3f
Binary files /dev/null and b/Release/Plugins/RenX.Core.lib differ
diff --git a/RenX.Announcements/RenX.Announcements.vcxproj b/RenX.Announcements/RenX.Announcements.vcxproj
new file mode 100644
index 0000000..4d96eb9
--- /dev/null
+++ b/RenX.Announcements/RenX.Announcements.vcxproj
@@ -0,0 +1,85 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {EF55A6DC-1861-4037-868A-9557ECAEBC27}
+ PluginExample
+
+
+
+ Application
+ true
+ v120
+ MultiByte
+
+
+ DynamicLibrary
+ false
+ v120
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+ $(SolutionDir)$(Configuration)\Plugins\
+ AllRules.ruleset
+
+
+
+ Level3
+ Disabled
+ true
+
+
+ true
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ ../Bot;../Jupiter;../RenX.Core
+ _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+
+
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/RenX.Announcements/RenX.Announcements.vcxproj.filters b/RenX.Announcements/RenX.Announcements.vcxproj.filters
new file mode 100644
index 0000000..9ff9780
--- /dev/null
+++ b/RenX.Announcements/RenX.Announcements.vcxproj.filters
@@ -0,0 +1,38 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Resource Files
+
+
+ Resource Files
+
+
+ Resource Files
+
+
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/RenX.Announcements/RenX_Announcements.cpp b/RenX.Announcements/RenX_Announcements.cpp
new file mode 100644
index 0000000..b6723c8
--- /dev/null
+++ b/RenX.Announcements/RenX_Announcements.cpp
@@ -0,0 +1,73 @@
+/**
+ * Copyright (C) 2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#include "Jupiter/IRC_Client.h"
+#include "Jupiter/INIFile.h"
+#include "RenX_Announcements.h"
+#include "RenX_Core.h"
+#include "RenX_Server.h"
+
+RenX_AnnouncementsPlugin pluginInstance;
+
+void announce(unsigned int)
+{
+ if (pluginInstance.random == false)
+ {
+ pluginInstance.lastLine++;
+ if (pluginInstance.lastLine == pluginInstance.announcementsFile.getLineCount()) pluginInstance.lastLine = 0;
+ }
+ else
+ {
+ unsigned int trand;
+ do trand = rand() % pluginInstance.announcementsFile.getLineCount();
+ while (trand == pluginInstance.lastLine);
+ pluginInstance.lastLine = trand;
+ }
+ const Jupiter::ReadableString &announcement = pluginInstance.announcementsFile.getLine(pluginInstance.lastLine);
+ RenX::Core *core = RenX::getCore();
+ RenX::Server *server;
+ for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
+ {
+ server = core->getServer(i);
+ if (server->players.size() != 0)
+ server->sendMessage(announcement);
+ }
+}
+
+RenX_AnnouncementsPlugin::RenX_AnnouncementsPlugin()
+{
+ RenX_AnnouncementsPlugin::announcementsFile.load(Jupiter::IRC::Client::Config->get(STRING_LITERAL_AS_REFERENCE("RenX.Announcements"), STRING_LITERAL_AS_REFERENCE("File"), STRING_LITERAL_AS_REFERENCE("Announcements.txt")));
+ if (RenX_AnnouncementsPlugin::announcementsFile.getLineCount() != 0)
+ {
+ RenX_AnnouncementsPlugin::random = Jupiter::IRC::Client::Config->getBool(STRING_LITERAL_AS_REFERENCE("RenX.Announcements"), STRING_LITERAL_AS_REFERENCE("Random"));
+ time_t delay = Jupiter::IRC::Client::Config->getInt(STRING_LITERAL_AS_REFERENCE("RenX.Announcements"), STRING_LITERAL_AS_REFERENCE("Delay"), 60);
+ RenX_AnnouncementsPlugin::timer = new Jupiter::Timer(0, delay, announce);
+ if (RenX_AnnouncementsPlugin::random == false) RenX_AnnouncementsPlugin::lastLine = RenX_AnnouncementsPlugin::announcementsFile.getLineCount() - 1;
+ }
+ else fputs("[RenX.Announcements] ERROR: No announcements loaded." ENDL, stderr);
+}
+
+RenX_AnnouncementsPlugin::~RenX_AnnouncementsPlugin()
+{
+ RenX_AnnouncementsPlugin::timer->kill();
+ RenX_AnnouncementsPlugin::announcementsFile.unload();
+}
+
+extern "C" __declspec(dllexport) Jupiter::Plugin *getPlugin()
+{
+ return &pluginInstance;
+}
diff --git a/RenX.Announcements/RenX_Announcements.h b/RenX.Announcements/RenX_Announcements.h
new file mode 100644
index 0000000..5a43a00
--- /dev/null
+++ b/RenX.Announcements/RenX_Announcements.h
@@ -0,0 +1,43 @@
+/**
+ * Copyright (C) 2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#if !defined _RENX_ANNOUNCEMENTS_H_HEADER
+#define _RENX_ANNOUNCEMENTS_H_HEADER
+
+#include "Jupiter/Plugin.h"
+#include "Jupiter/Timer.h"
+#include "Jupiter/File.h"
+#include "RenX_Plugin.h"
+
+class RenX_AnnouncementsPlugin : public RenX::Plugin
+{
+public:
+ const Jupiter::ReadableString &getName() override { return name; }
+ RenX_AnnouncementsPlugin();
+ ~RenX_AnnouncementsPlugin();
+
+public:
+ Jupiter::File announcementsFile;
+ bool random;
+ unsigned int lastLine;
+
+private:
+ STRING_LITERAL_AS_NAMED_REFERENCE(name, "RenX.Announcements");
+ Jupiter::Timer *timer;
+};
+
+#endif // _RENX_ANNOUNCEMENTS_H_HEADER
\ No newline at end of file
diff --git a/RenX.Commands/RenX.Commands.vcxproj b/RenX.Commands/RenX.Commands.vcxproj
new file mode 100644
index 0000000..b7ad2b8
--- /dev/null
+++ b/RenX.Commands/RenX.Commands.vcxproj
@@ -0,0 +1,87 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {72B6B5A6-4267-4FED-9F96-917C7974CE25}
+ PluginExample
+
+
+
+ Application
+ true
+ v120
+ MultiByte
+
+
+ DynamicLibrary
+ false
+ v120
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+ $(SolutionDir)$(Configuration)\Plugins\
+ AllRules.ruleset
+
+
+
+ Level3
+ Disabled
+ true
+
+
+ true
+
+
+
+
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ ../Bot;../Jupiter;../RenX.Core
+ _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+
+
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+ Document
+
+
+
+
+
+
\ No newline at end of file
diff --git a/RenX.Commands/RenX.Commands.vcxproj.filters b/RenX.Commands/RenX.Commands.vcxproj.filters
new file mode 100644
index 0000000..fc45530
--- /dev/null
+++ b/RenX.Commands/RenX.Commands.vcxproj.filters
@@ -0,0 +1,38 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Resource Files
+
+
+ Resource Files
+
+
+ Resource Files
+
+
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/RenX.Commands/RenX_Commands.cpp b/RenX.Commands/RenX_Commands.cpp
new file mode 100644
index 0000000..f14c92c
--- /dev/null
+++ b/RenX.Commands/RenX_Commands.cpp
@@ -0,0 +1,1357 @@
+/**
+ * Copyright (C) 2014 Justin James.
+ *
+ * This license must be preserved.
+ * Any applications, libraries, or code which make any use of any
+ * component of this program must not be commercial, unless explicit
+ * permission is granted from the original author. The use of this
+ * program for non-profit purposes is permitted.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * In the event that this license restricts you from making desired use of this program, contact the original author.
+ * Written by Justin James
+ */
+
+#include "Jupiter/Functions.h"
+#include "IRC_Bot.h"
+#include "RenX_Commands.h"
+#include "RenX_Core.h"
+#include "RenX_Server.h"
+#include "RenX_PlayerInfo.h"
+#include "RenX_Functions.h"
+
+inline bool togglePhasing(RenX::Server *server, bool newState)
+{
+ server->varData.set(STRING_LITERAL_AS_REFERENCE("RenX.Commands"), STRING_LITERAL_AS_REFERENCE("phasing"), newState ? STRING_LITERAL_AS_REFERENCE("true") : STRING_LITERAL_AS_REFERENCE("false"));
+ return newState;
+}
+
+inline bool togglePhasing(RenX::Server *server)
+{
+ return togglePhasing(server, !server->varData.getBool(STRING_LITERAL_AS_REFERENCE("RenX.Commands"), STRING_LITERAL_AS_REFERENCE("phasing"), false));
+}
+
+inline void onDie(RenX::Server *server, const RenX::PlayerInfo *player)
+{
+ if (player->isBot && server->varData.getBool(STRING_LITERAL_AS_REFERENCE("RenX.Commands"), STRING_LITERAL_AS_REFERENCE("phasing"), false)) server->kickPlayer(player);
+}
+
+void RenX_CommandsPlugin::RenX_OnSuicide(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &)
+{
+ onDie(server, player);
+}
+
+void RenX_CommandsPlugin::RenX_OnKill(RenX::Server *server, const RenX::PlayerInfo *, const RenX::PlayerInfo *victim, const Jupiter::ReadableString &)
+{
+ onDie(server, victim);
+}
+
+void RenX_CommandsPlugin::RenX_OnDie(RenX::Server *server, const RenX::PlayerInfo *player, const Jupiter::ReadableString &)
+{
+ onDie(server, player);
+}
+
+/** Console Commands */
+
+// RCON Console Command
+
+RCONConsoleCommand::RCONConsoleCommand()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("rcon"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("renx"));
+}
+
+void RCONConsoleCommand::trigger(const Jupiter::ReadableString ¶meters)
+{
+ int i = RenX::getCore()->getServerCount();
+ if (i == 0)
+ puts("Error: Not connected to any Renegade X servers.");
+ else if (parameters != nullptr)
+ {
+ RenX::Server *server;
+ while (--i >= 0)
+ {
+ server = RenX::getCore()->getServer(i);
+ RenX::getCore()->send(server, parameters);
+ }
+ }
+ else
+ puts("Error: Too Few Parameters. Syntax: rcon ");
+}
+
+const Jupiter::ReadableString &RCONConsoleCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Sends data to the Renegade X server's rcon. Syntax: rcon ");
+ return defaultHelp;
+}
+
+CONSOLE_COMMAND_INIT(RCONConsoleCommand)
+
+/** IRC Commands */
+
+// Msg IRC Command
+
+void MsgIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("msg"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("say"));
+}
+
+void MsgIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ if (parameters.isEmpty() == false)
+ {
+ Jupiter::StringL msg = "say ";
+ msg += source->getChannel(channel)->getUserPrefix(nick);
+ msg += nick;
+ msg += "@IRC: ";
+ msg += parameters;
+ if (RenX::getCore()->send(source->getChannel(channel)->getType(), msg) == 0)
+ source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
+ }
+ else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: Msg "));
+}
+
+const Jupiter::ReadableString &MsgIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Sends a message in - game.Syntax: Msg ");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(MsgIRCCommand)
+
+// Host Msg IRC Command
+
+void HostMsgIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("hmsg"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("hsay"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("hostmessage"));
+ this->setAccessLevel(4);
+}
+
+void HostMsgIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ if (parameters.isEmpty() == false)
+ {
+ if (RenX::getCore()->send(source->getChannel(channel)->getType(), Jupiter::StringS::Format("say %.*s", parameters.size(), parameters.ptr())) == 0)
+ source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
+ }
+ else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: hmsg "));
+}
+
+const Jupiter::ReadableString &HostMsgIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Sends a message in-game. Syntax: hmsg ");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(HostMsgIRCCommand)
+
+// Players IRC Command
+
+void PlayersIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("players"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("pl"));
+}
+
+const size_t STRING_LENGTH = 240;
+
+void PlayersIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &)
+{
+ int type = source->getChannel(channel)->getType();
+
+ // Team colors
+ const Jupiter::ReadableString &gTeamColor = RenX::getTeamColor(RenX::TeamType::GDI);
+ const Jupiter::ReadableString &nTeamColor = RenX::getTeamColor(RenX::TeamType::Nod);
+ const Jupiter::ReadableString &oTeamColor = RenX::getTeamColor(RenX::TeamType::Other);
+
+ // Team names
+ const Jupiter::ReadableString &gTeam = RenX::getTeamName(RenX::TeamType::GDI);
+ const Jupiter::ReadableString &nTeam = RenX::getTeamName(RenX::TeamType::Nod);
+ const Jupiter::ReadableString &oTeam = RenX::getTeamName(RenX::TeamType::Other);
+
+ bool noServers = true;
+ for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
+ {
+ RenX::Server *server = RenX::getCore()->getServer(i);
+ if (server->isLogChanType(type))
+ {
+ noServers = false;
+ if (server->players.size() != 0)
+ {
+ // End string containers
+ Jupiter::DLList gStrings;
+ Jupiter::DLList nStrings;
+ Jupiter::DLList oStrings;
+
+ Jupiter::StringL *gCurrent = nullptr;
+ Jupiter::StringL *nCurrent = nullptr;
+ Jupiter::StringL *oCurrent = nullptr;
+
+ // Team player counters
+ unsigned int gTotal = 0;
+ unsigned int nTotal = 0;
+ unsigned int oTotal = 0;
+
+ // Bot counters
+ unsigned int gBots = 0;
+ unsigned int nBots = 0;
+ unsigned int oBots = 0;
+
+ for (Jupiter::DLList::Node *node = server->players.getNode(0); node != nullptr; node = node->next)
+ {
+ if (node->data != nullptr)
+ {
+ Jupiter::String &name = RenX::getFormattedPlayerName(node->data);
+ if (name.size() > STRING_LENGTH - 32) continue; // Name will be too long to send.
+
+ switch (node->data->team)
+ {
+ case RenX::TeamType::Nod:
+ if (nCurrent == nullptr || nCurrent->size() + name.size() > STRING_LENGTH)
+ {
+ nCurrent = new Jupiter::StringL(STRING_LENGTH);
+ nCurrent->format(IRCCOLOR "%.*s[%.*s]: " IRCBOLD "%.*s" IRCBOLD, nTeamColor.size(), nTeamColor.ptr(), nTeam.size(), nTeam.ptr(), name.size(), name.ptr());
+ nStrings.add(nCurrent);
+ }
+ else nCurrent->aformat(IRCCOLOR ", " IRCBOLD "%.*s" IRCBOLD, name.size(), name.ptr());
+ nTotal++;
+ if (node->data->isBot)
+ nBots++;
+ break;
+ case RenX::TeamType::GDI:
+ if (gCurrent == nullptr || gCurrent->size() + name.size() > STRING_LENGTH)
+ {
+ gCurrent = new Jupiter::StringL(STRING_LENGTH);
+ gCurrent->format(IRCCOLOR "%.*s[%.*s]: " IRCBOLD "%.*s" IRCBOLD, gTeamColor.size(), gTeamColor.ptr(), gTeam.size(), gTeam.ptr(), name.size(), name.ptr());
+ gStrings.add(gCurrent);
+ }
+ else gCurrent->aformat(IRCCOLOR ", " IRCBOLD "%.*s" IRCBOLD, name.size(), name.ptr());
+ gTotal++;
+ if (node->data->isBot)
+ gBots++;
+ break;
+ default:
+ if (oCurrent == nullptr || oCurrent->size() + name.size() > STRING_LENGTH)
+ {
+ oCurrent = new Jupiter::StringL(STRING_LENGTH);
+ oCurrent->format(IRCCOLOR "%.*s[%.*s]: " IRCBOLD "%.*s" IRCBOLD, oTeamColor.size(), oTeamColor.ptr(), oTeam.size(), oTeam.ptr(), name.size(), name.ptr());
+ oStrings.add(oCurrent);
+ }
+ else oCurrent->aformat(IRCCOLOR ", " IRCBOLD "%.*s" IRCBOLD, name.size(), name.ptr());
+ oTotal++;
+ if (node->data->isBot)
+ oBots++;
+ break;
+ }
+ }
+ }
+ Jupiter::StringL *outString;
+ while (gStrings.size() != 0)
+ {
+ outString = gStrings.remove(0U);
+ source->sendMessage(channel, *outString);
+ delete outString;
+ }
+ while (nStrings.size() != 0)
+ {
+ outString = nStrings.remove(0U);
+ source->sendMessage(channel, *outString);
+ delete outString;
+ }
+ while (oStrings.size() != 0)
+ {
+ outString = oStrings.remove(0U);
+ source->sendMessage(channel, *outString);
+ delete outString;
+ }
+
+ Jupiter::StringL out;
+ out.format(IRCCOLOR "03Total Players" IRCCOLOR ": %u", server->players.size());
+ if (gBots + nBots + oBots > 0)
+ out.aformat(" (%u bots)", gBots + nBots + oBots);
+ if (gTotal > 0)
+ {
+ out.aformat(IRCCOLOR "02 | " IRCCOLOR "%.*s%.*s" IRCCOLOR ": %u", gTeamColor.size(), gTeamColor.ptr(), gTeam.size(), gTeam.ptr(), gTotal);
+ if (gBots > 0)
+ out.aformat(" (%u bots)", gBots);
+ }
+ if (nTotal > 0)
+ {
+ out.aformat(IRCCOLOR "02 | " IRCCOLOR "%.*s%.*s" IRCCOLOR ": %u", nTeamColor.size(), nTeamColor.ptr(), nTeam.size(), nTeam.ptr(), nTotal);
+ if (nBots > 0)
+ out.aformat(" (%u bots)", nBots);
+ }
+ if (oTotal > 0)
+ {
+ out.aformat(IRCCOLOR "02 | " IRCCOLOR "%.*s%.*s" IRCCOLOR ": %u", oTeamColor.size(), oTeamColor.ptr(), oTeam.size(), oTeam.ptr(), oTotal);
+ if (oBots > 0)
+ out.aformat(" (%u bots)", oBots);
+ }
+ source->sendMessage(channel, out);
+ }
+ else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("No players are in-game."));
+ }
+ }
+ if (noServers)
+ source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
+}
+
+const Jupiter::ReadableString &PlayersIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Lists the players currently in-game. Syntax: Players");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(PlayersIRCCommand)
+
+// PlayerInfo IRC Command
+
+void PlayerInfoIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("playerinfo"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("pi"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("player"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("pinfo"));
+ this->setAccessLevel(2);
+}
+
+void PlayerInfoIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ if (parameters.size() != 0)
+ {
+ Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
+ if (chan != nullptr)
+ {
+ int type = chan->getType();
+ RenX::PlayerInfo *player;
+ Jupiter::StringL msg;
+ for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
+ {
+ RenX::Server *server = RenX::getCore()->getServer(i);
+ if (server->isLogChanType(type) && server->players.size() != 0)
+ {
+ for (Jupiter::DLList::Node *node = server->players.getNode(0); node != nullptr; node = node->next)
+ {
+ player = node->data;
+ if (player->name.findi(parameters) != Jupiter::INVALID_INDEX)
+ {
+ const Jupiter::ReadableString &teamColor = RenX::getTeamColor(player->team);
+ const Jupiter::ReadableString &teamName = RenX::getFullTeamName(player->team);
+ msg.format(IRCCOLOR "03[Player Info]" IRCCOLOR "%.*s Name: " IRCBOLD "%.*s" IRCBOLD " - ID: %d - Team: " IRCBOLD "%.*s" IRCBOLD " - Vehicle Kills: %u - Defence Kills: %u - Building Kills: %u - Kills: %u (%u headshots) - Deaths: %u (%u suicides) - KDR: %.2f", teamColor.size(), teamColor.ptr(), player->name.size(), player->name.ptr(), player->id, teamName.size(), teamName.ptr(), player->vehicleKills, player->defenceKills, player->buildingKills, player->kills, player->headshots, player->deaths, player->suicides, ((float)player->kills) / (player->deaths == 0 ? 1.0 : (float)player->deaths));
+ if (source->getAccessLevel(channel, nick) > 1)
+ {
+ msg += " - IP: " IRCBOLD;
+ if (player->ip.size() != 0)
+ {
+ msg += player->ip;
+ msg += IRCBOLD;
+ }
+ else msg += "IP Not Found" IRCBOLD;
+ }
+ if (player->steamid.size() != 0)
+ {
+ msg += " - Steam ID: " IRCBOLD;
+ msg += player->steamid;
+ msg += IRCBOLD;
+ }
+ if (player->adminType.size() != 0)
+ {
+ msg += " - Admin Type: " IRCBOLD;
+ msg += player->adminType;
+ msg += IRCBOLD;
+ }
+ source->sendMessage(channel, msg);
+ }
+ }
+ }
+ }
+ if (msg.isEmpty()) source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
+ }
+ }
+ else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: PlayerInfo "));
+}
+
+const Jupiter::ReadableString &PlayerInfoIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Gets information about a player. Syntax: PlayerInfo ");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(PlayerInfoIRCCommand)
+
+// Steam IRC Command
+
+void SteamIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("steam"));
+ this->setAccessLevel(1);
+}
+
+void SteamIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
+ if (chan != nullptr)
+ {
+ int type = chan->getType();
+ RenX::PlayerInfo *player;
+ if (parameters.size() != 0)
+ {
+ Jupiter::StringL msg;
+ for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
+ {
+ RenX::Server *server = RenX::getCore()->getServer(i);
+ if (server->isLogChanType(type) && server->players.size() != 0)
+ {
+ for (Jupiter::DLList::Node *node = server->players.getNode(0); node != nullptr; node = node->next)
+ {
+ player = node->data;
+ if (player->name.findi(parameters) != Jupiter::INVALID_INDEX)
+ {
+ Jupiter::String &playerName = RenX::getFormattedPlayerName(player);
+ msg.format(IRCCOLOR "03[Steam] " IRCCOLOR "%.*s (ID: %d) ", playerName.size(), playerName.ptr(), player->id);
+ if (player->steamid.size() != 0)
+ {
+ msg += "is using steam ID " IRCBOLD;
+ msg += player->steamid;
+ msg += IRCBOLD;
+ }
+ else msg += "is not using steam.";
+ source->sendMessage(channel, msg);
+ }
+ }
+ }
+ }
+ if (msg.isEmpty())
+ source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
+ }
+ else
+ {
+ unsigned int total = 0;
+ unsigned int realPlayers = 0;
+ for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
+ {
+ RenX::Server *server = RenX::getCore()->getServer(i);
+ if (server->isLogChanType(type) && server->players.size() != 0)
+ {
+ for (Jupiter::DLList::Node *node = server->players.getNode(0); node != nullptr; node = node->next)
+ {
+ player = node->data;
+ if (player->isBot == false)
+ {
+ realPlayers++;
+ if (player->steamid.size() != 0) total++;
+ }
+ }
+ }
+ if (realPlayers != 0)
+ source->sendMessage(channel, Jupiter::StringS::Format("%.2f%% (%u/%u) of players are using Steam.", ((double)total * 100) / ((double)realPlayers), total, realPlayers));
+ else source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("No players are in-game."));
+ }
+ }
+ }
+}
+
+const Jupiter::ReadableString &SteamIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Fetches steam usage information. Syntax: Steam [Player]");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(SteamIRCCommand)
+
+// Kill-Death Ratio IRC Command
+
+void KillDeathRatioIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("kills"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("deaths"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("kdr"));
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("killdeathraio"));
+}
+
+void KillDeathRatioIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ if (parameters.size() != 0)
+ {
+ Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
+ if (chan != nullptr)
+ {
+ int type = chan->getType();
+ RenX::PlayerInfo *player;
+ Jupiter::StringL msg;
+ for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
+ {
+ RenX::Server *server = RenX::getCore()->getServer(i);
+ if (server->isLogChanType(type) && server->players.size() != 0)
+ {
+ for (Jupiter::DLList::Node *node = server->players.getNode(0); node != nullptr; node = node->next)
+ {
+ player = node->data;
+ if (player->name.findi(parameters) != Jupiter::INVALID_INDEX)
+ {
+ Jupiter::String &playerName = RenX::getFormattedPlayerName(player);
+ msg.format(IRCBOLD "%.*s" IRCBOLD IRCCOLOR ": Kills: %u - Deaths: %u - KDR: %.2f", playerName.size(), playerName.ptr(), player->kills, player->deaths, ((float)player->kills) / (player->deaths == 0 ? 1.0 : (float)player->deaths));
+ source->sendMessage(channel, msg);
+ }
+ }
+ }
+ }
+ if (msg.isEmpty())
+ source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Player not found."));
+ }
+ }
+ else source->sendNotice(nick, STRING_LITERAL_AS_REFERENCE("Error: Too Few Parameters. Syntax: Kills "));
+}
+
+const Jupiter::ReadableString &KillDeathRatioIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Gets a player's kills and deaths. Syntax: Kills ");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(KillDeathRatioIRCCommand)
+
+// ShowMods IRC Command
+
+void ShowModsIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("showmods"));
+}
+
+extern ModsGameCommand ModsGameCommand_instance;
+
+void ShowModsIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
+ if (chan != nullptr)
+ {
+ int type = chan->getType();
+ bool sent = false;
+ for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
+ {
+ RenX::Server *server = RenX::getCore()->getServer(i);
+ if (server->isLogChanType(type))
+ {
+ ModsGameCommand_instance.trigger(server, nullptr, Jupiter::ReferenceString::empty);
+ sent = true;
+ }
+ }
+ if (sent == false)
+ source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
+ }
+}
+
+const Jupiter::ReadableString &ShowModsIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Sends a message, displaying the in-game moderators. Syntax: showmods");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(ShowModsIRCCommand)
+
+// Mods IRC Command
+
+void ModsIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("mods"));
+}
+
+void ModsIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ if (parameters.equalsi("show")) ShowModsIRCCommand_instance.trigger(source, channel, nick, parameters);
+ else
+ {
+ Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
+ if (chan != nullptr)
+ {
+ int type = chan->getType();
+ RenX::PlayerInfo *player;
+ Jupiter::StringL msg;
+ for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
+ {
+ RenX::Server *server = RenX::getCore()->getServer(i);
+ if (server->isLogChanType(type))
+ {
+ msg = "";
+ if (server->players.size() != 0)
+ {
+ for (Jupiter::DLList::Node *node = server->players.getNode(0); node != nullptr; node = node->next)
+ {
+ player = node->data;
+ if (player->adminType.size() != 0)
+ {
+ if (msg.size() != 0) msg += ", ";
+ else msg += "Moderators in-game: ";
+ msg += player->name;
+ }
+ }
+ }
+ if (msg.size() == 0) msg = "No moderators are in-game.";
+ source->sendMessage(channel, msg);
+ }
+ }
+ if (msg.size() == 0) source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
+ }
+ }
+}
+
+const Jupiter::ReadableString &ModsIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Sends a message, displaying the in-game moderators. Syntax: mods [show]");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(ModsIRCCommand)
+
+// ShowRules IRC Command
+
+void ShowRulesIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("showrules"));
+}
+
+void ShowRulesIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
+ if (chan != nullptr)
+ {
+ int type = chan->getType();
+ Jupiter::StringL msg;
+ for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
+ {
+ RenX::Server *server = RenX::getCore()->getServer(i);
+ if (server->isLogChanType(type))
+ {
+ msg = "Rules: ";
+ msg += server->getRules();
+ server->sendMessage(msg);
+ }
+ }
+ if (msg.size() == 0) source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
+ }
+}
+
+const Jupiter::ReadableString &ShowRulesIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Sends a message, displaying the in-game rules. Syntax: showrules");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(ShowRulesIRCCommand)
+
+// Rules IRC Command
+
+void RulesIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("rules"));
+}
+
+void RulesIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ if (parameters.equalsi("show")) ShowRulesIRCCommand_instance.trigger(source, channel, nick, parameters);
+ else
+ {
+ Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
+ if (chan != nullptr)
+ {
+ int type = chan->getType();
+ Jupiter::StringL msg;
+ for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
+ {
+ RenX::Server *server = RenX::getCore()->getServer(i);
+ if (server->isLogChanType(type))
+ {
+ msg = IRCCOLOR "11[Rules]" IRCCOLOR " ";
+ msg += server->getRules();
+ source->sendMessage(channel, msg);
+ }
+ }
+ if (msg.size() == 0) source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
+ }
+ }
+}
+
+const Jupiter::ReadableString &RulesIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Displays the in-game rules. Syntax: rules [show]");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(RulesIRCCommand)
+
+// SetRules IRC Command
+
+void SetRulesIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("setrules"));
+ this->setAccessLevel(4);
+}
+
+void SetRulesIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ if (parameters.size() != 0)
+ {
+ unsigned int r = 0;
+ Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
+ if (chan != nullptr)
+ {
+ int type = chan->getType();
+ for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
+ {
+ RenX::Server *server = RenX::getCore()->getServer(i);
+ if (server->isLogChanType(type))
+ {
+ server->setRules(parameters);
+ r++;
+ }
+ }
+ if (r == 0)
+ source->sendMessage(channel, STRING_LITERAL_AS_REFERENCE("Error: Channel not attached to any connected Renegade X servers."));
+ }
+ }
+}
+
+const Jupiter::ReadableString &SetRulesIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Sets the in-game rules. Syntax: setrules [show]");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(SetRulesIRCCommand)
+
+// Reconnect IRC Command
+
+void ReconnectIRCCommand::create()
+{
+ this->addTrigger(STRING_LITERAL_AS_REFERENCE("reconnect"));
+ this->setAccessLevel(4);
+}
+
+void ReconnectIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString &)
+{
+ Jupiter::IRC::Client::Channel *chan = source->getChannel(channel);
+ if (chan != nullptr)
+ {
+ int type = chan->getType();
+ Jupiter::StringS msg;
+ for (unsigned int i = 0; i != RenX::getCore()->getServerCount(); i++)
+ {
+ RenX::Server *server = RenX::getCore()->getServer(i);
+ if (server->isLogChanType(type))
+ {
+ if (server->reconnect()) msg.format("Connection established");
+ else msg.format("[RenX] ERROR: Failed to connect to %.*s on port %u." ENDL, server->getHostname().size(), server->getHostname().ptr(), server->getPort());
+ source->sendMessage(channel, msg);
+ }
+ }
+ if (msg.isEmpty())
+ {
+ // We didn't connect anywhere!!
+ msg.format("ERROR: No servers found to connect to.");
+ source->sendMessage(channel, msg);
+ }
+ }
+}
+
+const Jupiter::ReadableString &ReconnectIRCCommand::getHelp(const Jupiter::ReadableString &)
+{
+ static STRING_LITERAL_AS_NAMED_REFERENCE(defaultHelp, "Gets information about a player. Syntax: Reconnect");
+ return defaultHelp;
+}
+
+IRC_COMMAND_INIT(ReconnectIRCCommand)
+
+// RestartMap IRC Command
+
+/*void RestartMapIRCCommand::create()
+{
+ this->addTrigger("restartmap");
+ this->setAccessLevel(2);
+}
+
+void RestartMapIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ int r = RenX::getCore()->send(source->getChannel(channel.c_str())->getType(), "adminrestartmap");
+ if (r > 0)
+ {
+ char t[256];
+ sprintf(t, "Command sent to %d servers.", r);
+ source->sendMessage(channel.c_str(), t);
+ }
+ else source->sendMessage(channel.c_str(), "Error: Channel not attached to any connected Renegade X servers.");
+}
+
+const char *RestartMapIRCCommand::getHelp()
+{
+ return "Restarts the current map. Syntax: RestartMap";
+}
+
+IRC_COMMAND_INIT(RestartMapIRCCommand)
+
+// SetMap IRC Command
+
+void SetMapIRCCommand::create()
+{
+ this->addTrigger("setmap");
+ this->setAccessLevel(3);
+}
+
+void SetMapIRCCommand::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters)
+{
+ if (parameters != nullptr)
+ {
+ Jupiter::StringL cmd = "adminrestartmap ";
+ cmd += parameters;
+ int r = RenX::getCore()->send(source->getChannel(channel.c_str())->getType(), cmd.c_str());
+ if (r > 0)
+ {
+ char t[256];
+ sprintf(t, "Command sent to %d servers.", r);
+ source->sendMessage(channel.c_str(), t);
+ }
+ else source->sendMessage(channel.c_str(), "Error: Channel not attached to any connected Renegade X servers.");
+ }
+ else source->sendNotice(nick.c_str(), "Error: Too Few Parameters. Syntax: SetMap