1
0
Fork 0

OnExecuteCommand hook can override the command result (crXXX).

This commit is contained in:
Mattes D 2015-05-10 23:11:30 +02:00
parent 693ffb689c
commit dd10ffb63a
8 changed files with 40 additions and 20 deletions

View File

@ -28,9 +28,11 @@ return
{ Name = "EntireCommand", Type = "string", Notes = "The entire command as a single string" },
},
Returns = [[
If the plugin returns true, the command will be blocked and none of the remaining hook handlers will
be called. If the plugin returns false, MCServer calls all the remaining hook handlers and finally
the command will be executed.
If the plugin returns false, MCServer calls all the remaining hook handlers and finally the command
will be executed. If the plugin returns true, the none of the remaining hook handlers will be called.
In this case the plugin can return a second value, specifying whether what the command result should
be set to, one of the {{cPluginManager#CommandResult|CommandResult}} constants. If not
provided, the value defaults to crBlocked.
]],
}, -- HOOK_EXECUTE_COMMAND
}

View File

@ -958,6 +958,18 @@ void cLuaState::GetStackValue(int a_StackPos, bool & a_ReturnedVal)
void cLuaState::GetStackValue(int a_StackPos, cPluginManager::CommandResult & a_Result)
{
if (lua_isnumber(m_LuaState, a_StackPos))
{
a_Result = static_cast<cPluginManager::CommandResult>(static_cast<int>((tolua_tonumber(m_LuaState, a_StackPos, a_Result))));
}
}
void cLuaState::GetStackValue(int a_StackPos, cRef & a_Ref)
{
a_Ref.RefStack(*this, a_StackPos);

View File

@ -32,6 +32,7 @@ extern "C"
#include "../Vector3.h"
#include "../Defines.h"
#include "PluginManager.h"
@ -57,7 +58,6 @@ class cPickup;
class cPlayer;
class cPlugin;
class cPluginLua;
class cPluginManager;
class cProjectileEntity;
class cRoot;
class cScoreboard;
@ -249,6 +249,7 @@ public:
void GetStackValue(int a_StackPos, AString & a_Value);
void GetStackValue(int a_StackPos, BLOCKTYPE & a_Value);
void GetStackValue(int a_StackPos, bool & a_Value);
void GetStackValue(int a_StackPos, cPluginManager::CommandResult & a_Result);
void GetStackValue(int a_StackPos, cRef & a_Ref);
void GetStackValue(int a_StackPos, double & a_Value);
void GetStackValue(int a_StackPos, float & a_ReturnedVal);

View File

@ -56,7 +56,7 @@ public:
virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) = 0;
virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) = 0;
virtual bool OnEntityTeleport (cEntity & a_Entity, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition) = 0;
virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand) = 0;
virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, cPluginManager::CommandResult & a_Result) = 0;
virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0;
virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0;
virtual bool OnHandshake (cClientHandle & a_Client, const AString & a_Username) = 0;

View File

@ -534,7 +534,7 @@ bool cPluginLua::OnEntityAddEffect(cEntity & a_Entity, int a_EffectType, int a_E
bool cPluginLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand)
bool cPluginLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, cPluginManager::CommandResult & a_Result)
{
cCSLock Lock(m_CriticalSection);
if (!m_LuaState.IsValid())
@ -545,7 +545,7 @@ bool cPluginLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & a_Sp
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_EXECUTE_COMMAND];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{
m_LuaState.Call((int)(**itr), a_Player, a_Split, a_EntireCommand, cLuaState::Return, res);
m_LuaState.Call((int)(**itr), a_Player, a_Split, a_EntireCommand, cLuaState::Return, res, a_Result);
if (res)
{
return true;

View File

@ -115,7 +115,7 @@ public:
virtual bool OnCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) override;
virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) override;
virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) override;
virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand) override;
virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, cPluginManager::CommandResult & a_Result) override;
virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override;
virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override;
virtual bool OnHandshake (cClientHandle & a_Client, const AString & a_Username) override;

View File

@ -525,14 +525,14 @@ bool cPluginManager::CallHookEntityTeleport(cEntity & a_Entity, const Vector3d &
bool cPluginManager::CallHookExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand)
bool cPluginManager::CallHookExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, CommandResult & a_Result)
{
FIND_HOOK(HOOK_EXECUTE_COMMAND);
VERIFY_HOOK;
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnExecuteCommand(a_Player, a_Split, a_EntireCommand))
if ((*itr)->OnExecuteCommand(a_Player, a_Split, a_EntireCommand, a_Result))
{
return true;
}
@ -1449,10 +1449,14 @@ cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer & a_Player,
}
// Ask plugins first if a command is okay to execute the command:
if (CallHookExecuteCommand(&a_Player, Split, a_Command))
CommandResult Result = crBlocked;
if (CallHookExecuteCommand(&a_Player, Split, a_Command, Result))
{
LOGINFO("Player %s tried executing command \"%s\" that was stopped by the HOOK_EXECUTE_COMMAND hook", a_Player.GetName().c_str(), Split[0].c_str());
return crBlocked;
if (Result == crBlocked)
{
LOGINFO("Player %s tried executing command \"%s\" that was stopped by the HOOK_EXECUTE_COMMAND hook", a_Player.GetName().c_str(), Split[0].c_str());
}
return Result;
}
if (
@ -1750,9 +1754,10 @@ bool cPluginManager::ExecuteConsoleCommand(const AStringVector & a_Split, cComma
if (cmd == m_ConsoleCommands.end())
{
// Command not found
// Still notify the plugins (so that plugins such as Aliases can intercept unknown commands):
CallHookExecuteCommand(nullptr, a_Split, a_Command);
return false;
// Still notify the plugins (so that plugins such as Aliases can intercept unknown commands).
CommandResult res = crBlocked;
CallHookExecuteCommand(nullptr, a_Split, a_Command, res);
return (res == crExecuted);
}
if (cmd->second.m_Plugin == nullptr)
@ -1762,10 +1767,10 @@ bool cPluginManager::ExecuteConsoleCommand(const AStringVector & a_Split, cComma
}
// Ask plugins first if a command is okay to execute the console command:
if (CallHookExecuteCommand(nullptr, a_Split, a_Command))
CommandResult res = crBlocked;
if (CallHookExecuteCommand(nullptr, a_Split, a_Command, res))
{
a_Output.Out("Command \"%s\" was stopped by the HOOK_EXECUTE_COMMAND hook", a_Split[0].c_str());
return false;
return (res == crExecuted);
}
return cmd->second.m_Plugin->HandleConsoleCommand(a_Split, a_Output, a_Command);

View File

@ -200,7 +200,7 @@ public:
bool CallHookDisconnect (cClientHandle & a_Client, const AString & a_Reason);
bool CallHookEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier);
bool CallHookEntityTeleport (cEntity & a_Entity, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition);
bool CallHookExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand); // If a_Player == nullptr, it is a console cmd
bool CallHookExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, CommandResult & a_Result); // If a_Player == nullptr, it is a console cmd
bool CallHookExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData);
bool CallHookExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData);
bool CallHookHandshake (cClientHandle & a_ClientHandle, const AString & a_Username);