mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 08:47:17 +01:00
623 lines
24 KiB
C++
623 lines
24 KiB
C++
#ifndef _COMMAND_HPP_
|
|
#define _COMMAND_HPP_
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
#include "Common.hpp"
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
#include <unordered_map>
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
namespace SqMod {
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* Flags of the types of values supported by the command arguments.
|
|
*/
|
|
enum CmdArgType
|
|
{
|
|
CMDARG_ANY = 0,
|
|
CMDARG_INTEGER = (1 << 1),
|
|
CMDARG_FLOAT = (1 << 2),
|
|
CMDARG_BOOLEAN = (1 << 3),
|
|
CMDARG_STRING = (1 << 4),
|
|
};
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* Convert a command type specifier to a name string.
|
|
*/
|
|
const SQChar * CmdArgSpecToStr(Uint8 spec);
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* The type of error that's being reported by the command manager.
|
|
*/
|
|
enum CmdError
|
|
{
|
|
CMDERR_UNKNOWN = 0,
|
|
CMDERR_SYNTAX_ERROR,
|
|
CMDERR_UNKNOWN_COMMAND,
|
|
CMDERR_MISSING_EXECUTER,
|
|
CMDERR_INSUFFICIENT_AUTH,
|
|
CMDERR_INCOMPLETE_ARGS,
|
|
CMDERR_EXTRANEOUS_ARGS,
|
|
CMDERR_UNSUPPORTED_ARG,
|
|
CMDERR_EXECUTION_FAILED,
|
|
};
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
class CmdListener;
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
#define MAX_CMD_ARGS 12
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* Helper class used to simplify the code for creating and managing commands.
|
|
*/
|
|
class CmdManager
|
|
{
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Allow only the smart pointer to delete this class instance as soon as it's not needed.
|
|
*/
|
|
friend class std::unique_ptr< CmdManager, void(*)(CmdManager *) >;
|
|
|
|
protected:
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* The type of container for storing command listeners.
|
|
*/
|
|
typedef std::unordered_map< String, CmdListener * > CmdPool;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* The type of container for storing command arguments.
|
|
*/
|
|
typedef std::array< std::pair< Uint8, SqObj >, MAX_CMD_ARGS > CmdArgs;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Default constructor.
|
|
*/
|
|
CmdManager();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Copy constructor (disabled).
|
|
*/
|
|
CmdManager(const CmdManager &) = delete;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Move constructor (disabled).
|
|
*/
|
|
CmdManager(CmdManager &&) = delete;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Destructor.
|
|
*/
|
|
~CmdManager();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Copy assignment operator (disabled).
|
|
*/
|
|
CmdManager & operator = (const CmdManager &) = delete;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Move assignment operator (disabled).
|
|
*/
|
|
CmdManager & operator = (CmdManager &&) = delete;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Called by the smart pointer to delete the instance of this class.
|
|
*/
|
|
static void _Finalizer(CmdManager * ptr);
|
|
|
|
public:
|
|
|
|
// --------------------------------------------------------------------------------------------
|
|
typedef std::unique_ptr< CmdManager, void(*)(CmdManager *) > Pointer;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Creates an instance of this type if one doesn't already exist and returns it.
|
|
*/
|
|
static Pointer Inst();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* ...
|
|
*/
|
|
bool Init();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* ...
|
|
*/
|
|
bool Load();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* ...
|
|
*/
|
|
void Deinit();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* ...
|
|
*/
|
|
void Unload();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* ...
|
|
*/
|
|
void Terminate();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Called by the core class before the VM is closed to release all resources.
|
|
*/
|
|
void VMClose();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Bind a command listener to a certain command name.
|
|
*/
|
|
void Bind(const String & name, CmdListener * cmd);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Unbind a command listener from a certain command name.
|
|
*/
|
|
void Unbind(const String & name);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the currently used error handler.
|
|
*/
|
|
Function & GetOnError();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Change the error handler.
|
|
*/
|
|
void SetOnError(Function & func);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the default authority inspector.
|
|
*/
|
|
Function & GetOnAuth();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Change the default authority inspector.
|
|
*/
|
|
void SetOnAuth(Function & func);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the default authority inspector.
|
|
*/
|
|
SQInt32 GetInvokerID();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the name of the currently executed command.
|
|
*/
|
|
const SQChar * GetName();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the argument text of the currently executed command.
|
|
*/
|
|
const SQChar * GetText();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Execute the specified command for the specified player.
|
|
*/
|
|
void Execute(SQInt32 invoker, const String & str);
|
|
|
|
protected:
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Execute the specified command.
|
|
*/
|
|
void Exec(CmdListener & cmd);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Forward the error message to the error handler.
|
|
*/
|
|
template < typename... Args> void Error(SQInt32 type, const SQChar * msg, Args&&... args)
|
|
{
|
|
// Skip if there's no error handler
|
|
if (!m_OnError.IsNull())
|
|
{
|
|
m_OnError.Execute< SQInt32, const SQChar * >(type, ToStringF(msg, std::forward< Args >(args)...));
|
|
}
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Parse the specified argument text and extract the arguments from it.
|
|
*/
|
|
bool Parse(SQUint32 max);
|
|
|
|
private:
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* List of command listeners and their associated names.
|
|
*/
|
|
CmdPool m_Commands;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Currently and last command invoker.
|
|
*/
|
|
SQInt32 m_Invoker;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Currently and last used command name.
|
|
*/
|
|
String m_Name;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Currently and last used command argument text.
|
|
*/
|
|
String m_Text;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Extracted values from the argument text.
|
|
*/
|
|
CmdArgs m_Argv;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Number of values extracted from the argument text.
|
|
*/
|
|
SQUint32 m_Argc;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Custom error handler.
|
|
*/
|
|
Function m_OnError;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Default authority inspector for newly created commands.
|
|
*/
|
|
Function m_OnAuth;
|
|
};
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
extern const CmdManager::Pointer _Cmd;
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* Class used to bind to certain commands.
|
|
*/
|
|
class CmdListener
|
|
{
|
|
public:
|
|
|
|
// --------------------------------------------------------------------------------------------
|
|
friend class CmdManager;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Default constructor.
|
|
*/
|
|
CmdListener();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Construct and instance and attach it to the specified name.
|
|
*/
|
|
CmdListener(const SQChar * name);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Construct and instance and attach it to the specified name.
|
|
*/
|
|
CmdListener(const SQChar * name, const SQChar * spec);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Construct and instance and attach it to the specified name.
|
|
*/
|
|
CmdListener(const SQChar * name, const SQChar * spec, Array & tags);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Construct and instance and attach it to the specified name.
|
|
*/
|
|
CmdListener(const SQChar * name, const SQChar * spec, SQUint32 min, SQUint32 max);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Construct and instance and attach it to the specified name.
|
|
*/
|
|
CmdListener(const SQChar * name, const SQChar * spec, Array & tags, SQUint32 min, SQUint32 max);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Copy constructor (disabled).
|
|
*/
|
|
CmdListener(const CmdListener & o) = delete;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Move constructor (disabled).
|
|
*/
|
|
CmdListener(CmdListener && o) = delete;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Destructor.
|
|
*/
|
|
~CmdListener();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Copy assignment operator (disabled).
|
|
*/
|
|
CmdListener & operator = (const CmdListener & o) = delete;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Move assignment operator (disabled).
|
|
*/
|
|
CmdListener & operator = (CmdListener && o) = delete;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Used to released stored resources before the VM is closed.
|
|
*/
|
|
void VMClose();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Compare two instances of this type.
|
|
*/
|
|
SQInt32 Cmp(const CmdListener & o) const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Attempt to convert this instance to a string.
|
|
*/
|
|
const SQChar * ToString() const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the local tag.
|
|
*/
|
|
const SQChar * GetTag() const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Change the local tag.
|
|
*/
|
|
void SetTag(const SQChar * tag);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the local data.
|
|
*/
|
|
SqObj & GetData();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Change the local data.
|
|
*/
|
|
void SetData(SqObj & data);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the name of the command.
|
|
*/
|
|
const SQChar * GetName() const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Change the name of the command.
|
|
*/
|
|
void SetName(const SQChar * name);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the argument type specifiers for this command as a string.
|
|
*/
|
|
const SQChar * GetSpec() const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Change the argument type specifiers for this command by extracting them from a string.
|
|
*/
|
|
void SetSpec(const SQChar * spec);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the tag/name of a command argument.
|
|
*/
|
|
const SQChar * GetArgTag(SQUint32 arg) const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Change the tag/name of a command argument.
|
|
*/
|
|
void SetArgTag(SQUint32 arg, const SQChar * name);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the tag/name of multiple command arguments.
|
|
*/
|
|
Array GetArgTags() const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Change the tag/name of multiple command arguments.
|
|
*/
|
|
void SetArgTags(Array & tags);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the help text associated with this command.
|
|
*/
|
|
const SQChar * GetHelp() const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Change the help text associated with this command.
|
|
*/
|
|
void SetHelp(const SQChar * help);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the informational text associated with this command.
|
|
*/
|
|
const SQChar * GetInfo() const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Change the informational text associated with this command.
|
|
*/
|
|
void SetInfo(const SQChar * info);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the function responsible for processing the command.
|
|
*/
|
|
Function & GetOnExec();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Change the function responsible for processing the command.
|
|
*/
|
|
void SetOnExec(Function & func);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Change the function responsible for processing the command.
|
|
*/
|
|
void SetOnExec_Env(SqObj & env, Function & func);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the function responsible for testing the invoker authority.
|
|
*/
|
|
Function & GetOnAuth();
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Change the function responsible for testing the invoker authority.
|
|
*/
|
|
void SetOnAuth(Function & func);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Change the function responsible for testing the invoker authority.
|
|
*/
|
|
void SetOnAuth_Env(SqObj & env, Function & func);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the internal level required to execute this command.
|
|
*/
|
|
SQInt32 GetLevel() const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Change the internal level required to execute this command.
|
|
*/
|
|
void SetLevel(SQInt32 level);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* See whether this command needs explicit authority clearance to execute.
|
|
*/
|
|
bool GetAuthority() const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Set whether this command needs explicit authority clearance to execute.
|
|
*/
|
|
void SetAuthority(bool toggle);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* See whether this command listener is allowed to execute or not.
|
|
*/
|
|
bool GetSuspended() const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Set whether this command listener is allowed to execute or not.
|
|
*/
|
|
void SetSuspended(bool toggle);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the minimum arguments allowed required to execute this command.
|
|
*/
|
|
SQUint32 GetMinArgC() const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Change the minimum arguments allowed required to execute this command.
|
|
*/
|
|
void SetMinArgC(SQUint32 val);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Retrieve the maximum arguments allowed required to execute this command.
|
|
*/
|
|
SQUint32 GetMaxArgC() const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Change the maximum arguments allowed required to execute this command.
|
|
*/
|
|
void SetMaxArgC(SQUint32 val);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Check whether the specified argument is compatible with the specified type.
|
|
*/
|
|
bool ArgCheck(SQUint32 arg, Uint8 mask) const;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Check whether the specified player is allowed to execute this command.
|
|
*/
|
|
bool AuthCheckID(SQInt32 id);
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Attempt to execute this command.
|
|
*/
|
|
bool Execute(SQInt32 invoker, Array & args);
|
|
|
|
protected:
|
|
|
|
// --------------------------------------------------------------------------------------------
|
|
typedef std::array< Uint8 , MAX_CMD_ARGS > Args;
|
|
|
|
// --------------------------------------------------------------------------------------------
|
|
typedef std::array< String , MAX_CMD_ARGS > Argt;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Process the specifiers string.
|
|
*/
|
|
bool ProcSpec(const SQChar * spec);
|
|
|
|
private:
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Array of type specifiers for each of the command arguments.
|
|
*/
|
|
Args m_Args;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Array of strings to be used as the tag/name for each argument.
|
|
*/
|
|
Argt m_Argt;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Minimum arguments allowed to execute this command.
|
|
*/
|
|
SQUint32 m_MinArgc;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Maximum arguments allowed to execute this command.
|
|
*/
|
|
SQUint32 m_MaxArgc;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* The name of the command.
|
|
*/
|
|
String m_Name;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* The specifiers for each of the command arguments represented as a string.
|
|
*/
|
|
String m_Spec;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Help about the purpose and requirements of the command.
|
|
*/
|
|
String m_Help;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Information for when the command execution failed.
|
|
*/
|
|
String m_Info;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Function responsible for processing the received command arguments.
|
|
*/
|
|
Function m_OnExec;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Function responsible for deciding whether the invoker is allowed to execute.
|
|
*/
|
|
Function m_OnAuth;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Arbitrary tag associated with this instance.
|
|
*/
|
|
String m_Tag;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Arbitrary data associated with this instance.
|
|
*/
|
|
SqObj m_Data;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* The level required to execute this command.
|
|
*/
|
|
SQInt32 m_Level;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Whether this command needs an explicit authority verification in order to execute.
|
|
*/
|
|
bool m_Authority;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Whether the command is allowed to execute or not.
|
|
*/
|
|
bool m_Suspended;
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Whether the command is allowed to change name.
|
|
*/
|
|
bool m_Lock;
|
|
};
|
|
|
|
} // Namespace:: SqMod
|
|
|
|
#endif // _COMMAND_HPP_
|