diff --git a/Bot/Bot.vcxproj b/Bot/Bot.vcxproj
index 5d7b0e5..29a4484 100644
--- a/Bot/Bot.vcxproj
+++ b/Bot/Bot.vcxproj
@@ -88,6 +88,7 @@
+
@@ -95,6 +96,7 @@
+
diff --git a/Bot/Bot.vcxproj.filters b/Bot/Bot.vcxproj.filters
index e11e6f6..9478b74 100644
--- a/Bot/Bot.vcxproj.filters
+++ b/Bot/Bot.vcxproj.filters
@@ -30,6 +30,9 @@
Source Files
+
+ Source Files
+
@@ -47,6 +50,9 @@
Header Files
+
+ Header Files
+
diff --git a/Bot/Console_Command.h b/Bot/Console_Command.h
index 94a5b00..e7955ae 100644
--- a/Bot/Console_Command.h
+++ b/Bot/Console_Command.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2013-2014 Justin James.
+ * Copyright (C) 2013-2015 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
@@ -23,21 +23,13 @@
* @brief Provides an extendable command system specialized for console-based commands.
*/
-#include "Jupiter_Bot.h"
#include "Jupiter/Command.h"
#include "Jupiter/ArrayList.h"
+#include "Jupiter_Bot.h"
+#include "Generic_Command.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)
@@ -49,7 +41,10 @@ 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.
+* 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 "help" commands.
*/
class JUPITER_BOT_API ConsoleCommand : public Jupiter::Command
{
@@ -99,6 +94,28 @@ class CLASS : public ConsoleCommand { \
#define CONSOLE_COMMAND_INIT(CLASS) \
CLASS CLASS ## _instance;
+/** Generates a console command implementation from a generic command. */
+#define GENERIC_COMMAND_AS_CONSOLE_COMMAND_IMPL(CLASS) \
+ CLASS ## _AS_CONSOLE_COMMAND :: CLASS ## _AS_CONSOLE_COMMAND() { \
+ size_t index = 0; \
+ while (index != CLASS ## _instance.getTriggerCount()) this->addTrigger(CLASS ## _instance.getTrigger(index++)); } \
+ void CLASS ## _AS_CONSOLE_COMMAND :: trigger(const Jupiter::ReadableString ¶meters) { \
+ GenericCommand::ResponseLine *del; \
+ GenericCommand::ResponseLine *ret = CLASS ## _instance.trigger(parameters); \
+ while (ret != nullptr) { \
+ ret->response.println(ret->type == GenericCommand::DisplayType::PublicError || ret->type == GenericCommand::DisplayType::PrivateError ? stderr : stdout); \
+ del = ret; ret = ret->next; delete del; } } \
+ const Jupiter::ReadableString & CLASS ## _AS_CONSOLE_COMMAND :: getHelp(const Jupiter::ReadableString ¶meters) { \
+ return CLASS ## _instance.getHelp(parameters); } \
+ CONSOLE_COMMAND_INIT(CLASS ## _AS_CONSOLE_COMMAND)
+
+/** Generates a console command from a generic command. */
+#define GENERIC_COMMAND_AS_CONSOLE_COMMAND(CLASS) \
+ GENERIC_CONSOLE_COMMAND(CLASS ## _AS_CONSOLE_COMMAND) \
+ GENERIC_COMMAND_AS_CONSOLE_COMMAND_IMPL(CLASS);
+
+
+
/** Re-enable warnings */
#if defined _MSC_VER
#pragma warning(pop)
diff --git a/Bot/Generic_Command.cpp b/Bot/Generic_Command.cpp
new file mode 100644
index 0000000..64b526b
--- /dev/null
+++ b/Bot/Generic_Command.cpp
@@ -0,0 +1,62 @@
+/**
+ * Copyright (C) 2015 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 "Generic_Command.h"
+
+Jupiter::ArrayList _genericCommands;
+Jupiter::ArrayList *genericCommands = &_genericCommands;
+
+GenericCommand::GenericCommand()
+{
+ _genericCommands.add(this);
+}
+
+GenericCommand::~GenericCommand()
+{
+ size_t count = _genericCommands.size();
+ while (count != 0)
+ if (_genericCommands.get(--count) == this)
+ {
+ _genericCommands.remove(count);
+ break;
+ }
+}
+
+GenericCommand *getGenericCommand(const Jupiter::ReadableString &trigger)
+{
+ size_t count = _genericCommands.size();
+ while (count != 0)
+ {
+ GenericCommand *cmd = _genericCommands.get(--count);
+ if (cmd->matches(trigger))
+ return cmd;
+ }
+ return nullptr;
+}
+
+GenericCommand::ResponseLine::ResponseLine(const Jupiter::ReadableString &response_, GenericCommand::DisplayType type_)
+{
+ GenericCommand::ResponseLine::response = response_;
+ GenericCommand::ResponseLine::type = type_;
+}
+
+GenericCommand::ResponseLine *GenericCommand::ResponseLine::set(const Jupiter::ReadableString &response_, GenericCommand::DisplayType type_)
+{
+ GenericCommand::ResponseLine::response = response_;
+ GenericCommand::ResponseLine::type = type_;
+ return this;
+}
\ No newline at end of file
diff --git a/Bot/Generic_Command.h b/Bot/Generic_Command.h
new file mode 100644
index 0000000..824f6bf
--- /dev/null
+++ b/Bot/Generic_Command.h
@@ -0,0 +1,125 @@
+/**
+ * Copyright (C) 2015 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 _GENERIC_COMMAND_H_HEADER
+#define _GENERIC_COMMAND_H_HEADER
+
+/**
+* @file Generic_Command.h
+* @brief Provides an extendable command system.
+*/
+
+#include "Jupiter/Command.h"
+#include "Jupiter/String.h"
+#include "Jupiter_Bot.h"
+
+class GenericCommand;
+
+/** DLL Linkage Nagging */
+#if defined _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4251)
+#endif
+
+/** Generic command list */
+JUPITER_BOT_API extern Jupiter::ArrayList *genericCommands;
+
+/**
+* @brief Provides the base for generic commands.
+*/
+class JUPITER_BOT_API GenericCommand : public Jupiter::Command
+{
+public:
+ /** Enumerated class to guide output in generic command interpreters */
+ enum class DisplayType
+ {
+ PublicSuccess,
+ PrivateSuccess,
+ PublicError,
+ PrivateError,
+ };
+
+ /** Data entry returned by trigger() */
+ struct JUPITER_BOT_API ResponseLine
+ {
+ Jupiter::StringS response;
+ GenericCommand::DisplayType type;
+ ResponseLine *next = nullptr;
+
+ /**
+ * @brief Sets the response and type of the ResponseLine.
+ *
+ * @param in_response Value to set response to.
+ * @param in_type Value to set type to.
+ * @return This.
+ */
+ ResponseLine *set(const Jupiter::ReadableString &response, GenericCommand::DisplayType type);
+ ResponseLine() = default;
+ ResponseLine(const Jupiter::ReadableString &response, GenericCommand::DisplayType type);
+ };
+
+ /**
+ * @brief Called when the command is to be executed.
+ *
+ * @param input Parameters passed to the command by the user.
+ */
+ virtual ResponseLine *trigger(const Jupiter::ReadableString &input) = 0;
+
+ /**
+ * @brief Default constructor for the generic command class.
+ */
+ GenericCommand();
+
+ /**
+ * @brief Destructor for the generic command class.
+ */
+ ~GenericCommand();
+};
+
+/**
+* @brief Fetches a generic command based on its trigger.
+*
+* @param trigger Trigger of the command to fetch.
+* @return A generic command if it exists, nullptr otherwise.
+*/
+JUPITER_BOT_API extern GenericCommand *getGenericCommand(const Jupiter::ReadableString &trigger);
+
+/** Generic Command Macros */
+
+/** Defines the core of a generic command's declaration. This should be included in every generic command. */
+#define BASE_GENERIC_COMMAND(CLASS) \
+ public: \
+ CLASS(); \
+ GenericCommand::ResponseLine *trigger(const Jupiter::ReadableString ¶meters); \
+ const Jupiter::ReadableString &getHelp(const Jupiter::ReadableString ¶meters);
+
+/** Expands to become the entire declaration for a generic command. In most cases, this will be sufficient. */
+#define GENERIC_GENERIC_COMMAND(CLASS) \
+class CLASS : public GenericCommand { \
+ BASE_GENERIC_COMMAND(CLASS) \
+};
+
+/** Instantiates a generic command. */
+#define GENERIC_COMMAND_INIT(CLASS) \
+ CLASS CLASS ## _instance;
+
+/** Re-enable warnings */
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // _GENERIC_COMMAND_H_HEADER
\ No newline at end of file
diff --git a/Bot/IRC_Command.h b/Bot/IRC_Command.h
index 209d1af..7540829 100644
--- a/Bot/IRC_Command.h
+++ b/Bot/IRC_Command.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2013-2014 Justin James.
+ * Copyright (C) 2013-2015 Justin James.
*
* This license must be preserved.
* Any applications, libraries, or code which make any use of any
@@ -27,20 +27,12 @@
#include "Jupiter/IRC_Client.h"
#include "Jupiter/ArrayList.h"
#include "Jupiter/String.h"
-#include "ServerManager.h"
#include "Jupiter_Bot.h"
+#include "ServerManager.h"
+#include "IRC_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)
@@ -52,7 +44,11 @@ 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.
+* 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.
*/
class JUPITER_BOT_API IRCCommand : public Jupiter::Command
{
@@ -189,6 +185,55 @@ class CLASS : public IRCCommand { \
CLASS CLASS ## _instance; \
CLASS *CLASS::copy() { return new CLASS(*this); }
+/** Generates a base IRC command implementation from a generic command. */
+#define GENERIC_COMMAND_AS_IRC_COMMAND_IMPL_BASE(CLASS) \
+ void CLASS ## _AS_IRC_COMMAND :: trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters) { \
+ GenericCommand::ResponseLine *del; \
+ GenericCommand::ResponseLine *ret = CLASS ## _instance.trigger(parameters); \
+ while (ret != nullptr) { \
+ switch(ret->type) { \
+ case GenericCommand::DisplayType::PublicSuccess: \
+ case GenericCommand::DisplayType::PublicError: \
+ source->sendMessage(channel, ret->response); \
+ break; \
+ case GenericCommand::DisplayType::PrivateSuccess: \
+ case GenericCommand::DisplayType::PrivateError: \
+ source->sendNotice(nick, ret->response); \
+ break; \
+ default: \
+ source->sendMessage(nick, ret->response); \
+ break; \
+ } \
+ del = ret; ret = ret->next; delete del; } } \
+ const Jupiter::ReadableString & CLASS ## _AS_IRC_COMMAND :: getHelp(const Jupiter::ReadableString ¶meters) { \
+ return CLASS ##_instance.getHelp(parameters); } \
+ IRC_COMMAND_INIT(CLASS ## _AS_IRC_COMMAND)
+
+/** Generates an IRC command implementation from a generic command. */
+#define GENERIC_COMMAND_AS_IRC_COMMAND_IMPL(CLASS) \
+ void CLASS ## _AS_IRC_COMMAND :: create() { \
+ size_t index = 0; \
+ while (index != CLASS ## _instance.getTriggerCount()) this->addTrigger(CLASS ## _instance.getTrigger(index++)); } \
+ GENERIC_COMMAND_AS_IRC_COMMAND_IMPL_BASE(CLASS)
+
+/** Generates an IRC command implementation from a generic command. */
+#define GENERIC_COMMAND_AS_IRC_COMMAND_IMPL_2(CLASS, ACCESS_LEVEL) \
+ void CLASS ## _AS_IRC_COMMAND :: create() { \
+ size_t index = 0; \
+ while (index != CLASS ## _instance.getTriggerCount()) this->addTrigger(CLASS ## _instance.getTrigger(index++)); \
+ this->setAccessLevel(ACCESS_LEVEL); } \
+ GENERIC_COMMAND_AS_IRC_COMMAND_IMPL_BASE(CLASS)
+
+/** Generates an IRC command from a generic command. */
+#define GENERIC_COMMAND_AS_IRC_COMMAND(CLASS) \
+ GENERIC_IRC_COMMAND(CLASS ## _AS_IRC_COMMAND) \
+ GENERIC_COMMAND_AS_IRC_COMMAND_IMPL(CLASS);
+
+/** Generates an IRC command from a generic command. */
+#define GENERIC_COMMAND_AS_IRC_COMMAND_2(CLASS, ACCESS_LEVEL) \
+ GENERIC_IRC_COMMAND(CLASS ## _AS_IRC_COMMAND) \
+ GENERIC_COMMAND_AS_IRC_COMMAND_IMPL_2(CLASS, ACCESS_LEVEL);
+
/** Re-enable warnings */
#if defined _MSC_VER
#pragma warning(pop)
diff --git a/Jupiter Bot.sln b/Jupiter Bot.sln
index 88da219..50e2b32 100644
--- a/Jupiter Bot.sln
+++ b/Jupiter Bot.sln
@@ -158,6 +158,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenX.Listen", "RenX.Listen\
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ChannelRelay", "ChannelRelay\ChannelRelay.vcxproj", "{ADAD973E-EAA8-446D-BCD3-83B53DBC3A3F}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C188871B-5F32-4946-B301-24CA2EBB275D} = {C188871B-5F32-4946-B301-24CA2EBB275D}
+ EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/Release/Bot.lib b/Release/Bot.lib
index bf5a487..9336cfe 100644
Binary files a/Release/Bot.lib and b/Release/Bot.lib differ
diff --git a/Release/Plugins/RenX.Core.lib b/Release/Plugins/RenX.Core.lib
index e2bf5ba..f04168f 100644
Binary files a/Release/Plugins/RenX.Core.lib and b/Release/Plugins/RenX.Core.lib differ