Browse Source

Added GenericCommand class.

Added macros for generating ConsoleCommands and IRCCommands from GenericCommands.
pull/3/head
JustinAJ 9 years ago
parent
commit
af6d3758eb
  1. 2
      Bot/Bot.vcxproj
  2. 6
      Bot/Bot.vcxproj.filters
  3. 41
      Bot/Console_Command.h
  4. 62
      Bot/Generic_Command.cpp
  5. 125
      Bot/Generic_Command.h
  6. 69
      Bot/IRC_Command.h
  7. 3
      Jupiter Bot.sln
  8. BIN
      Release/Bot.lib
  9. BIN
      Release/Plugins/RenX.Core.lib

2
Bot/Bot.vcxproj

@ -88,6 +88,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Console_Command.cpp" />
<ClCompile Include="Generic_Command.cpp" />
<ClCompile Include="IRC_Command.cpp" />
<ClCompile Include="Main.cpp" />
<ClCompile Include="IRC_Bot.cpp" />
@ -95,6 +96,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="Console_Command.h" />
<ClInclude Include="Generic_Command.h" />
<ClInclude Include="IRC_Bot.h" />
<ClInclude Include="IRC_Command.h" />
<ClInclude Include="Jupiter_Bot.h" />

6
Bot/Bot.vcxproj.filters

@ -30,6 +30,9 @@
<ClCompile Include="Console_Command.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Generic_Command.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="IRC_Bot.h">
@ -47,6 +50,9 @@
<ClInclude Include="Console_Command.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Generic_Command.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Library Include="..\Jupiter\Release\Jupiter.lib">

41
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<ConsoleCommand> *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 &parameters) { \
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 &parameters) { \
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)

62
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 <justin.aj@hotmail.com>
*/
#include "Generic_Command.h"
Jupiter::ArrayList<GenericCommand> _genericCommands;
Jupiter::ArrayList<GenericCommand> *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;
}

125
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 <justin.aj@hotmail.com>
*/
#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<GenericCommand> *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 &parameters); \
const Jupiter::ReadableString &getHelp(const Jupiter::ReadableString &parameters);
/** 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

69
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<IRCCommand> *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 &parameters) { \
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 &parameters) { \
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)

3
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

BIN
Release/Bot.lib

Binary file not shown.

BIN
Release/Plugins/RenX.Core.lib

Binary file not shown.
Loading…
Cancel
Save