diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Bindings/LuaState.cpp | 12 | ||||
-rw-r--r-- | src/Bindings/LuaState.h | 5 | ||||
-rw-r--r-- | src/Bindings/PluginLua.cpp | 5 | ||||
-rw-r--r-- | src/Bindings/PluginManager.cpp | 67 | ||||
-rw-r--r-- | src/Bindings/PluginManager.h | 28 | ||||
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/Simulator/IncrementalRedstoneSimulator.cpp | 4 | ||||
-rw-r--r-- | src/World.cpp | 2 | ||||
-rw-r--r-- | src/WorldStorage/WorldStorage.cpp | 35 | ||||
-rw-r--r-- | src/WorldStorage/WorldStorage.h | 3 |
10 files changed, 90 insertions, 73 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 066390e39..723193ae7 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -30,6 +30,7 @@ extern "C" } #include "../Vector3.h" +#include "../Defines.h" @@ -222,6 +223,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); + /** Call any 0-param 0-return Lua function in a single line: */ template <typename FnT> diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 344031995..104380ea4 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -1347,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/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 3cb8c99a1..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, " ")); @@ -1337,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 ( @@ -1367,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; } @@ -1573,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); } @@ -1582,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 72cedfae1..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, @@ -246,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); @@ -323,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 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c905ebebe..55f3028ef 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -88,7 +88,7 @@ if (WIN32) OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.h # Copy the Lua DLL into the Bindings folder, so that tolua can run from there: - COMMAND ${CMAKE_COMMAND} -E copy_if_different ..\\..\\MCServer\\lua51.dll .\\lua51.dll + COMMAND ${CMAKE_COMMAND} -E copy_if_different ../../MCServer/lua51.dll ./lua51.dll # Regenerate bindings: COMMAND tolua -L virtual_method_hooks.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 866a5b65a..5af9a295d 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -1700,7 +1700,7 @@ bool cIncrementalRedstoneSimulator::IsWirePowered(int a_RelBlockX, int a_RelBloc { continue; } - a_PowerLevel = itr->a_PowerLevel; + a_PowerLevel = std::max(itr->a_PowerLevel , a_PowerLevel); // Get the highest power level (a_PowerLevel is initialised already and there CAN be multiple levels for one block) } for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks->begin(); itr != m_LinkedPoweredBlocks->end(); ++itr) // Check linked powered list @@ -1709,7 +1709,7 @@ bool cIncrementalRedstoneSimulator::IsWirePowered(int a_RelBlockX, int a_RelBloc { continue; } - a_PowerLevel = itr->a_PowerLevel; + a_PowerLevel = std::max(itr->a_PowerLevel, a_PowerLevel); } return (a_PowerLevel != 0); // Answer the inital question: is the wire powered? diff --git a/src/World.cpp b/src/World.cpp index bd7694e96..48c3448a3 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2776,10 +2776,8 @@ bool cWorld::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunk void cWorld::SaveAllChunks(void) { - LOGINFO("Saving all chunks..."); m_LastSave = m_WorldAge; m_ChunkMap->SaveAllChunks(); - m_Storage.QueueSavedMessage(); } diff --git a/src/WorldStorage/WorldStorage.cpp b/src/WorldStorage/WorldStorage.cpp index 6867ad5bc..d3f35384b 100644 --- a/src/WorldStorage/WorldStorage.cpp +++ b/src/WorldStorage/WorldStorage.cpp @@ -17,13 +17,6 @@ -/// If a chunk with this Y coord is de-queued, it is a signal to emit the saved-all message (cWorldStorage::QueueSavedMessage()) -#define CHUNK_Y_MESSAGE 2 - - - - - /// Example storage schema - forgets all chunks ;) class cWSSForgetful : public cWSSchema @@ -168,17 +161,6 @@ void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -void cWorldStorage::QueueSavedMessage(void) -{ - // Pushes a special coord pair into the queue, signalizing a message instead - m_SaveQueue.EnqueueItem(cChunkCoords(0, CHUNK_Y_MESSAGE, 0)); - m_Event.Set(); -} - - - - - void cWorldStorage::UnqueueLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ) { m_LoadQueue.Remove(sChunkLoad(a_ChunkX, a_ChunkY, a_ChunkZ,true)); @@ -286,19 +268,12 @@ bool cWorldStorage::SaveOneChunk(void) { cChunkCoords ToSave(0, 0, 0); bool ShouldSave = m_SaveQueue.TryDequeueItem(ToSave); - if(ShouldSave) { - if (ToSave.m_ChunkY == CHUNK_Y_MESSAGE) - { - LOGINFO("Saved all chunks in world %s", m_World->GetName().c_str()); - return ShouldSave; - } - if (ShouldSave && m_World->IsChunkValid(ToSave.m_ChunkX, ToSave.m_ChunkZ)) + if (ShouldSave && m_World->IsChunkValid(ToSave.m_ChunkX, ToSave.m_ChunkZ)) + { + m_World->MarkChunkSaving(ToSave.m_ChunkX, ToSave.m_ChunkZ); + if (m_SaveSchema->SaveChunk(ToSave)) { - m_World->MarkChunkSaving(ToSave.m_ChunkX, ToSave.m_ChunkZ); - if (m_SaveSchema->SaveChunk(ToSave)) - { - m_World->MarkChunkSaved(ToSave.m_ChunkX, ToSave.m_ChunkZ); - } + m_World->MarkChunkSaved(ToSave.m_ChunkX, ToSave.m_ChunkZ); } } return ShouldSave; diff --git a/src/WorldStorage/WorldStorage.h b/src/WorldStorage/WorldStorage.h index bb189b6c9..1204b4310 100644 --- a/src/WorldStorage/WorldStorage.h +++ b/src/WorldStorage/WorldStorage.h @@ -67,9 +67,6 @@ public: void QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate); // Queues the chunk for loading; if not loaded, the chunk will be generated if a_Generate is true void QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); - /// Signals that a message should be output to the console when all the chunks have been saved - void QueueSavedMessage(void); - /// Loads the chunk specified; returns true on success, false on failure bool LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); |