diff options
Diffstat (limited to 'src/Bindings')
-rw-r--r-- | src/Bindings/LuaState.cpp | 12 | ||||
-rw-r--r-- | src/Bindings/LuaState.h | 5 | ||||
-rw-r--r-- | src/Bindings/Plugin.h | 1 | ||||
-rw-r--r-- | src/Bindings/PluginLua.cpp | 25 | ||||
-rw-r--r-- | src/Bindings/PluginLua.h | 1 | ||||
-rw-r--r-- | src/Bindings/PluginManager.cpp | 86 | ||||
-rw-r--r-- | src/Bindings/PluginManager.h | 30 |
7 files changed, 125 insertions, 35 deletions
diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 7a5ed1425..32638df96 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -811,6 +811,18 @@ void cLuaState::GetStackValue(int a_StackPos, double & a_ReturnedVal) +void cLuaState::GetStackValue(int a_StackPos, eWeather & a_ReturnedVal) +{ + if (lua_isnumber(m_LuaState, a_StackPos)) + { + a_ReturnedVal = (eWeather)Clamp((int)tolua_tonumber(m_LuaState, a_StackPos, a_ReturnedVal), (int)wSunny, (int)wThunderstorm); + } +} + + + + + bool cLuaState::CallFunction(int a_NumResults) { ASSERT (m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 8aefa7c6b..b1ac3578a 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -31,6 +31,7 @@ extern "C" } #include "../Vector3.h" +#include "../Defines.h" @@ -223,6 +224,10 @@ public: /** Retrieve value at a_StackPos, if it is a valid number. If not, a_Value is unchanged */ void GetStackValue(int a_StackPos, double & a_Value); + /** Retrieve value at a_StackPos, if it is a valid number, converting and clamping it to eWeather. + If not, a_Value is unchanged. */ + void GetStackValue(int a_StackPos, eWeather & a_Value); + // Include the cLuaState::Call() overload implementation that is generated by the gen_LuaState_Call.lua script: #include "LuaState_Call.inc" diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index c6461c861..8ba20c026 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -72,6 +72,7 @@ public: virtual bool OnPlayerEating (cPlayer & a_Player) = 0; virtual bool OnPlayerFished (cPlayer & a_Player, const cItems & a_Reward) = 0; virtual bool OnPlayerFishing (cPlayer & a_Player, cItems & a_Reward) = 0; + virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) = 0; virtual bool OnPlayerJoined (cPlayer & a_Player) = 0; virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) = 0; virtual bool OnPlayerMoved (cPlayer & a_Player) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 97366cc4c..104380ea4 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -715,6 +715,26 @@ bool cPluginLua::OnPlayerEating(cPlayer & a_Player) +bool cPluginLua::OnPlayerFoodLevelChange(cPlayer & a_Player, int a_NewFoodLevel) +{ + cCSLock Lock(m_CriticalSection); + bool res = false; + cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_FOOD_LEVEL_CHANGE]; + for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) + { + m_LuaState.Call((int)(**itr), &a_Player, a_NewFoodLevel, cLuaState::Return, res); + if (res) + { + return true; + } + } + return false; +} + + + + + bool cPluginLua::OnPlayerFished(cPlayer & a_Player, const cItems & a_Reward) { cCSLock Lock(m_CriticalSection); @@ -1327,18 +1347,15 @@ bool cPluginLua::OnWeatherChanging(cWorld & a_World, eWeather & a_NewWeather) { cCSLock Lock(m_CriticalSection); bool res = false; - int NewWeather = a_NewWeather; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_WEATHER_CHANGING]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), &a_World, NewWeather, cLuaState::Return, res, NewWeather); + m_LuaState.Call((int)(**itr), &a_World, a_NewWeather, cLuaState::Return, res, a_NewWeather); if (res) { - a_NewWeather = (eWeather)NewWeather; return true; } } - a_NewWeather = (eWeather)NewWeather; return false; } diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 598e031c0..9c9de95c6 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -95,6 +95,7 @@ public: virtual bool OnPlayerEating (cPlayer & a_Player) override; virtual bool OnPlayerFished (cPlayer & a_Player, const cItems & a_Reward) override; virtual bool OnPlayerFishing (cPlayer & a_Player, cItems & a_Reward) override; + virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) override; virtual bool OnPlayerJoined (cPlayer & a_Player) override; virtual bool OnPlayerMoved (cPlayer & a_Player) override; virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index c50100d6f..7e6502515 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -257,18 +257,44 @@ bool cPluginManager::CallHookBlockToPickups( bool cPluginManager::CallHookChat(cPlayer * a_Player, AString & a_Message) { - bool WasCommandForbidden = false; - if (HandleCommand(a_Player, a_Message, true, WasCommandForbidden)) // We use HandleCommand as opposed to ExecuteCommand to accomodate the need to the WasCommandForbidden bool + // Check if the message contains a command, execute it: + switch (HandleCommand(a_Player, a_Message, true)) { - return true; // Chat message was handled as command - } - else if (WasCommandForbidden) // Couldn't be handled as command, was it because of insufficient permissions? - { - return true; // Yes - message was sent in HandleCommand, abort + case crExecuted: + { + // The command has executed successfully + return true; + } + + case crBlocked: + { + // The command was blocked by a plugin using HOOK_EXECUTE_COMMAND + // The plugin has most likely sent a message to the player already + return true; + } + + case crError: + { + // An error in the plugin has prevented the command from executing. Report the error to the player: + a_Player->SendMessageFailure(Printf("Something went wrong while executing command \"%s\"", a_Message.c_str())); + return true; + } + + case crNoPermission: + { + // The player is not allowed to execute this command + a_Player->SendMessageFailure(Printf("Forbidden command; insufficient privileges: \"%s\"", a_Message.c_str())); + return true; + } + + case crUnknownCommand: + { + // This was not a known command, keep processing as a message + break; + } } - // Check if it was a standard command (starts with a slash) - // If it was, we know that it was completely unrecognised (WasCommandForbidden == false) + // Check if the message is a command (starts with a slash). If it is, we know that it wasn't recognised: if (!a_Message.empty() && (a_Message[0] == '/')) { AStringVector Split(StringSplit(a_Message, " ")); @@ -695,6 +721,25 @@ bool cPluginManager::CallHookPlayerEating(cPlayer & a_Player) +bool cPluginManager::CallHookPlayerFoodLevelChange(cPlayer & a_Player, int a_NewFoodLevel) +{ + FIND_HOOK(HOOK_PLAYER_FOOD_LEVEL_CHANGE); + VERIFY_HOOK; + + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnPlayerFoodLevelChange(a_Player, a_NewFoodLevel)) + { + return true; + } + } + return false; +} + + + + + bool cPluginManager::CallHookPlayerFished(cPlayer & a_Player, const cItems a_Reward) { FIND_HOOK(HOOK_PLAYER_FISHED); @@ -1318,28 +1363,28 @@ bool cPluginManager::CallHookWorldTick(cWorld & a_World, float a_Dt, int a_LastT -bool cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions, bool & a_WasCommandForbidden) +cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions) { ASSERT(a_Player != NULL); AStringVector Split(StringSplit(a_Command, " ")); if (Split.empty()) { - return false; + return crUnknownCommand; } CommandMap::iterator cmd = m_Commands.find(Split[0]); if (cmd == m_Commands.end()) { // Command not found - return false; + return crUnknownCommand; } // Ask plugins first if a command is okay to execute the command: if (CallHookExecuteCommand(a_Player, Split)) { 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 false; + return crBlocked; } if ( @@ -1348,15 +1393,18 @@ bool cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command !a_Player->HasPermission(cmd->second.m_Permission) ) { - a_Player->SendMessageFailure(Printf("Forbidden command; insufficient privileges: \"%s\"", Split[0].c_str())); LOGINFO("Player %s tried to execute forbidden command: \"%s\"", a_Player->GetName().c_str(), Split[0].c_str()); - a_WasCommandForbidden = true; - return false; + return crNoPermission; } ASSERT(cmd->second.m_Plugin != NULL); - return cmd->second.m_Plugin->HandleCommand(Split, a_Player); + if (!cmd->second.m_Plugin->HandleCommand(Split, a_Player)) + { + return crError; + } + + return crExecuted; } @@ -1554,7 +1602,7 @@ AString cPluginManager::GetCommandPermission(const AString & a_Command) -bool cPluginManager::ExecuteCommand(cPlayer * a_Player, const AString & a_Command) +cPluginManager::CommandResult cPluginManager::ExecuteCommand(cPlayer * a_Player, const AString & a_Command) { return HandleCommand(a_Player, a_Command, true); } @@ -1563,7 +1611,7 @@ bool cPluginManager::ExecuteCommand(cPlayer * a_Player, const AString & a_Comman -bool cPluginManager::ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command) +cPluginManager::CommandResult cPluginManager::ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command) { return HandleCommand(a_Player, a_Command, false); } diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index be40bd2f7..d435024bb 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -57,8 +57,17 @@ public: // tolua_export // Called each tick virtual void Tick(float a_Dt); - + // tolua_begin + enum CommandResult + { + crExecuted, + crUnknownCommand, + crError, + crBlocked, + crNoPermission, + } ; + enum PluginHook { HOOK_BLOCK_SPREAD, @@ -87,6 +96,7 @@ public: // tolua_export HOOK_PLAYER_EATING, HOOK_PLAYER_FISHED, HOOK_PLAYER_FISHING, + HOOK_PLAYER_FOOD_LEVEL_CHANGE, HOOK_PLAYER_JOINED, HOOK_PLAYER_LEFT_CLICK, HOOK_PLAYER_MOVING, @@ -188,6 +198,7 @@ public: // tolua_export bool CallHookPlayerEating (cPlayer & a_Player); bool CallHookPlayerFished (cPlayer & a_Player, const cItems a_Reward); bool CallHookPlayerFishing (cPlayer & a_Player, cItems a_Reward); + bool CallHookPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel); bool CallHookPlayerJoined (cPlayer & a_Player); bool CallHookPlayerMoving (cPlayer & a_Player); bool CallHookPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status); @@ -244,11 +255,11 @@ public: // tolua_export /** Returns the permission needed for the specified command; empty string if command not found */ AString GetCommandPermission(const AString & a_Command); // tolua_export - /** Executes the command, as if it was requested by a_Player. Checks permissions first. Returns true if executed. */ - bool ExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export + /** Executes the command, as if it was requested by a_Player. Checks permissions first. Returns crExecuted if executed. */ + CommandResult ExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export - /** Executes the command, as if it was requested by a_Player. Permisssions are not checked. Returns true if executed (false if not found) */ - bool ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export + /** Executes the command, as if it was requested by a_Player. Permisssions are not checked. Returns crExecuted if executed. */ + CommandResult ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export /** Removes all console command bindings that the specified plugin has made */ void RemovePluginConsoleCommands(cPlugin * a_Plugin); @@ -321,13 +332,8 @@ private: /** Adds the plugin into the internal list of plugins and initializes it. If initialization fails, the plugin is removed again. */ bool AddPlugin(cPlugin * a_Plugin); - /** Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns true if the command is handled. */ - bool HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions, bool & a_WasCommandForbidden); - bool HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions) - { - bool DummyBoolean = false; - return HandleCommand(a_Player, a_Command, a_ShouldCheckPermissions, DummyBoolean); - } + /** Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns crExecuted if the command is executed. */ + cPluginManager::CommandResult HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions); } ; // tolua_export |