From 36a97d441bbb164c59d095aef1ef73f41fa38247 Mon Sep 17 00:00:00 2001 From: Kiryu144 <123davidLP@gmail.com> Date: Fri, 23 Jul 2021 11:14:01 +0200 Subject: Added y bounds checking for cPlayer::PlaceBlock (#5194) --- Server/Plugins/APIDump/APIDesc.lua | 14 ++------ src/Bindings/ManualBindings.cpp | 68 +++++++++++++++++++++++++++++--------- src/Entities/Player.cpp | 18 +++++----- src/Entities/Player.h | 15 +++------ 4 files changed, 69 insertions(+), 46 deletions(-) diff --git a/Server/Plugins/APIDump/APIDesc.lua b/Server/Plugins/APIDump/APIDesc.lua index 6055ff8f1..2f1d66648 100644 --- a/Server/Plugins/APIDump/APIDesc.lua +++ b/Server/Plugins/APIDump/APIDesc.lua @@ -10879,16 +10879,8 @@ a_Player:OpenWindow(Window); Params = { { - Name = "BlockX", - Type = "number", - }, - { - Name = "BlockY", - Type = "number", - }, - { - Name = "BlockZ", - Type = "number", + Name = "BlockPos", + Type = "Vector3i", }, { Name = "BlockType", @@ -10905,7 +10897,7 @@ a_Player:OpenWindow(Window); Type = "boolean", }, }, - Notes = "Places a block while impersonating the player. The {{OnPlayerPlacingBlock|HOOK_PLAYER_PLACING_BLOCK}} hook is called before the placement, and if it succeeds, the block is placed and the {{OnPlayerPlacedBlock|HOOK_PLAYER_PLACED_BLOCK}} hook is called. Returns true iff the block is successfully placed. Assumes that the block is in a currently loaded chunk.", + Notes = "Places a block while impersonating the player. The {{OnPlayerPlacingBlock|HOOK_PLAYER_PLACING_BLOCK}} hook is called before the placement, and if it succeeds, the block is placed and the {{OnPlayerPlacedBlock|HOOK_PLAYER_PLACED_BLOCK}} hook is called. Returns true iff the block is successfully placed.", }, ReplaceOneEquippedItemTossRest = { diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 37fc20d39..08f324aec 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -1595,27 +1595,56 @@ static int tolua_cPlayer_GetRestrictions(lua_State * tolua_S) -static int tolua_cPlayer_PermissionMatches(lua_State * tolua_S) +static int tolua_cPlayer_GetUUID(lua_State * tolua_S) { - // Function signature: cPlayer:PermissionMatches(PermissionStr, TemplateStr) -> bool + // Check the params: + cLuaState L(tolua_S); + if (!L.CheckParamSelf("cPlayer")) + { + return 0; + } + // Get the params: + cPlayer * Self = nullptr; + L.GetStackValue(1, Self); + + // Return the UUID as a string + L.Push(Self->GetUUID().ToShortString()); + return 1; +} + + + + + +static int tolua_cPlayer_PlaceBlock(lua_State * tolua_S) +{ // Check the params: cLuaState L(tolua_S); if ( - !L.CheckParamUserTable(1, "cPlayer") || - !L.CheckParamString (2, 3) || - !L.CheckParamEnd (4) + !L.CheckParamSelf("cPlayer") || + !L.CheckParamUserType(2, "Vector3") || + !L.CheckParamNumber(3, 4) || + !L.CheckParamEnd(5) ) { return 0; } // Get the params: - AString Permission, Template; - L.GetStackValues(2, Permission, Template); + cPlayer * Self; + Vector3i Position; + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + L.GetStackValues(1, Self, Position, BlockType, BlockMeta); - // Push the result of the match: - L.Push(cPlayer::PermissionMatches(StringSplit(Permission, "."), StringSplit(Template, "."))); + if (!cChunkDef::IsValidHeight(Position.y)) + { + return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'position'"); + } + + // Return the result of placement: + L.Push(Self->PlaceBlock(Position, BlockType, BlockMeta)); return 1; } @@ -1623,21 +1652,27 @@ static int tolua_cPlayer_PermissionMatches(lua_State * tolua_S) -static int tolua_cPlayer_GetUUID(lua_State * tolua_S) +static int tolua_cPlayer_PermissionMatches(lua_State * tolua_S) { + // Function signature: cPlayer:PermissionMatches(PermissionStr, TemplateStr) -> bool + // Check the params: cLuaState L(tolua_S); - if (!L.CheckParamSelf("cPlayer")) + if ( + !L.CheckParamUserTable(1, "cPlayer") || + !L.CheckParamString (2, 3) || + !L.CheckParamEnd (4) + ) { return 0; } // Get the params: - cPlayer * Self = nullptr; - L.GetStackValue(1, Self); + AString Permission, Template; + L.GetStackValues(2, Permission, Template); - // Return the UUID as a string - L.Push(Self->GetUUID().ToShortString()); + // Push the result of the match: + L.Push(cPlayer::PermissionMatches(StringSplit(Permission, "."), StringSplit(Template, "."))); return 1; } @@ -4601,8 +4636,9 @@ void cManualBindings::Bind(lua_State * tolua_S) tolua_beginmodule(tolua_S, "cPlayer"); tolua_function(tolua_S, "GetPermissions", tolua_cPlayer_GetPermissions); tolua_function(tolua_S, "GetRestrictions", tolua_cPlayer_GetRestrictions); - tolua_function(tolua_S, "PermissionMatches", tolua_cPlayer_PermissionMatches); tolua_function(tolua_S, "GetUUID", tolua_cPlayer_GetUUID); + tolua_function(tolua_S, "PermissionMatches", tolua_cPlayer_PermissionMatches); + tolua_function(tolua_S, "PlaceBlock", tolua_cPlayer_PlaceBlock); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cPlugin"); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index db64d2e1d..ad8d79fbb 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -2333,15 +2333,6 @@ void cPlayer::LoadRank(void) -bool cPlayer::PlaceBlock(const Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) -{ - return PlaceBlocks({ { a_Position, a_BlockType, a_BlockMeta } }); -} - - - - - void cPlayer::SendBlocksAround(int a_BlockX, int a_BlockY, int a_BlockZ, int a_Range) { // Collect the coords of all the blocks to send: @@ -2457,6 +2448,15 @@ const cUUID & cPlayer::GetUUID(void) const +bool cPlayer::PlaceBlock(const Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + return PlaceBlocks({ { a_Position, a_BlockType, a_BlockMeta } }); +} + + + + + bool cPlayer::PlaceBlocks(const std::initializer_list a_Blocks) { if (DoesPlacingBlocksIntersectEntity(a_Blocks)) diff --git a/src/Entities/Player.h b/src/Entities/Player.h index dc30fca30..d2d2fa60c 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -548,12 +548,6 @@ public: Loads the m_Rank, m_Permissions, m_MsgPrefix, m_MsgSuffix and m_MsgNameColorCode members. */ void LoadRank(void); - /** Calls the block-placement hook and places the block in the world, unless refused by the hook. - If the hook prevents the placement, sends the current block at the specified coords back to the client. - Assumes that the block is in a currently loaded chunk. - Returns true if the block is successfully placed. */ - bool PlaceBlock(Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); - /** Sends the block in the specified range around the specified coord to the client as a block change packet. The blocks in range (a_BlockX - a_Range, a_BlockX + a_Range) are sent (NY-metric). */ @@ -565,12 +559,13 @@ public: // tolua_end + /** Attempts to place the block in the world with a call to PlaceBlocks. */ + bool PlaceBlock(Vector3i a_Position, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); + /** Calls the block placement hooks and places the blocks in the world. - First the "placing" hooks for all the blocks are called, then the blocks are placed, and finally - the "placed" hooks are called. + First the "placing" hooks for all the blocks are called, then the blocks are placed, and finally the "placed" hooks are called. If the any of the "placing" hooks aborts, none of the blocks are placed and the function returns false. - Returns true if all the blocks are placed. - Assumes that all the blocks are in currently loaded chunks. */ + Returns true if all the blocks are placed. */ bool PlaceBlocks(std::initializer_list a_Blocks); /** Notify nearby wolves that the player or one of the player's wolves took damage or did damage to an entity -- cgit v1.2.3