From ba048e2101d42af53f2ac7a9a3ed04c194918136 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Fri, 3 Apr 2020 20:24:49 +0000 Subject: New hotfix to prevent calling OnBroken (#4600) * Fix stack overflow in breaking ice. Stupid fix, but it does work and is used in other places too... * Replace hotfix for pistons with better one * Fix comments in BlockBed handler --- src/Blocks/BlockBed.cpp | 16 ++++++++-------- src/Blocks/BlockIce.h | 2 ++ src/Blocks/BlockPiston.cpp | 7 ++++--- src/ChunkMap.cpp | 7 +------ 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/Blocks/BlockBed.cpp b/src/Blocks/BlockBed.cpp index e6193682a..8b349ef5e 100644 --- a/src/Blocks/BlockBed.cpp +++ b/src/Blocks/BlockBed.cpp @@ -21,27 +21,27 @@ void cBlockBedHandler::OnBroken(cChunkInterface & a_ChunkInterface, cWorldInterf if ((a_OldBlockMeta & 0x08) != 0) { // Was pillow - if (a_ChunkInterface.GetBlock(a_BlockPos - Direction) == E_BLOCK_BED) + Vector3i FootPos(a_BlockPos - Direction); + if (a_ChunkInterface.GetBlock(FootPos) == E_BLOCK_BED) { // First replace the bed with air - a_ChunkInterface.FastSetBlock(a_BlockPos - Direction, E_BLOCK_AIR, 0); + a_ChunkInterface.FastSetBlock(FootPos, E_BLOCK_AIR, 0); // Then destroy the bed entity - Vector3i PillowPos(a_BlockPos - Direction); - a_ChunkInterface.SetBlock(PillowPos, E_BLOCK_AIR, 0); + a_ChunkInterface.SetBlock(FootPos, E_BLOCK_AIR, 0); } } else { // Was foot end - if (a_ChunkInterface.GetBlock(a_BlockPos + Direction) == E_BLOCK_BED) + Vector3i PillowPos(a_BlockPos + Direction); + if (a_ChunkInterface.GetBlock(PillowPos) == E_BLOCK_BED) { // First replace the bed with air - a_ChunkInterface.FastSetBlock(a_BlockPos + Direction, E_BLOCK_AIR, 0); + a_ChunkInterface.FastSetBlock(PillowPos, E_BLOCK_AIR, 0); // Then destroy the bed entity - Vector3i FootPos(a_BlockPos + Direction); - a_ChunkInterface.SetBlock(FootPos, E_BLOCK_AIR, 0); + a_ChunkInterface.SetBlock(PillowPos, E_BLOCK_AIR, 0); } } } diff --git a/src/Blocks/BlockIce.h b/src/Blocks/BlockIce.h index 672288ca3..a39162d79 100644 --- a/src/Blocks/BlockIce.h +++ b/src/Blocks/BlockIce.h @@ -54,6 +54,8 @@ public: auto blockTypeBelow = a_ChunkInterface.GetBlock(a_BlockPos.addedY(-1)); if (cBlockInfo::FullyOccupiesVoxel(blockTypeBelow) || IsBlockLiquid(blockTypeBelow)) { + // Setting air with FastSetBlock prevents SetBlock recursively calling OnBroken. + a_ChunkInterface.FastSetBlock(a_BlockPos, E_BLOCK_AIR, 0); a_ChunkInterface.SetBlock(a_BlockPos, E_BLOCK_WATER, 0); } } diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index 5a18cffac..8c6940454 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -297,9 +297,10 @@ void cBlockPistonHandler::RetractPiston(Vector3i a_BlockPos, cWorld & a_World) return; } - // Remove extension, update base state - World.SetBlock(extensionPos.x, extensionPos.y, extensionPos.z, E_BLOCK_AIR, 0); - World.SetBlock(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, pistonBlock, pistonMeta & ~(8)); + // Remove extension, update base state. Calling FastSetBlock inhibits OnBroken being called by SetBlock. + World.FastSetBlock(extensionPos, E_BLOCK_AIR, 0); + World.SetBlock(extensionPos, E_BLOCK_AIR, 0); + World.SetBlock(a_BlockPos, pistonBlock, pistonMeta & ~(8)); // (Retraction is always successful, but play in the task for consistency) World.BroadcastSoundEffect("block.piston.contract", a_BlockPos, 0.5f, 0.7f); diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index cb6ba07ca..fd4987bb4 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -641,12 +641,7 @@ void cChunkMap::SetBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE GetBlockTypeMeta(a_BlockPos, blockType, blockMeta); cChunkInterface ChunkInterface(this); - // Hotfix for https://github.com/cuberite/cuberite/issues/4468 - // Should be removed when a proper fix is found. - if ((blockType != E_BLOCK_PISTON) && (blockType != E_BLOCK_STICKY_PISTON) && (blockType != E_BLOCK_PISTON_EXTENSION)) - { - BlockHandler(blockType)->OnBroken(ChunkInterface, *m_World, a_BlockPos, blockType, blockMeta); - } + BlockHandler(blockType)->OnBroken(ChunkInterface, *m_World, a_BlockPos, blockType, blockMeta); chunk->SetBlock(relPos, a_BlockType, a_BlockMeta); m_World->GetSimulatorManager()->WakeUp(a_BlockPos, chunk); -- cgit v1.2.3