From 58b1b3160dd0622a3609a3c8c8d93f6482fb94af Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Tue, 4 Sep 2012 15:07:08 +0000 Subject: Fixed FS #243, server crash after restart. The blockhandler table and the itemhandler table weren't properly re-initialized. git-svn-id: http://mc-server.googlecode.com/svn/trunk@830 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/blocks/Block.cpp | 340 ++++++++++++++++++++++++++++++++---------------- source/cChunk.cpp | 13 +- source/items/Item.cpp | 1 + 3 files changed, 239 insertions(+), 115 deletions(-) (limited to 'source') diff --git a/source/blocks/Block.cpp b/source/blocks/Block.cpp index 3d2fe23e6..7764e2881 100644 --- a/source/blocks/Block.cpp +++ b/source/blocks/Block.cpp @@ -40,159 +40,198 @@ #include "BlockOre.h" #include "BlockNote.h" + + + + bool cBlockHandler::m_HandlerInitialized = false; cBlockHandler *cBlockHandler::m_BlockHandler[256]; + + + + cBlockHandler *cBlockHandler::GetBlockHandler(BLOCKTYPE a_BlockID) { - if(!m_HandlerInitialized) - { //We have to initialize + if (!m_HandlerInitialized) + { + //We have to initialize memset(m_BlockHandler, 0, sizeof(m_BlockHandler)); m_HandlerInitialized = true; } - if(m_BlockHandler[a_BlockID]) + if (m_BlockHandler[a_BlockID] != NULL) + { return m_BlockHandler[a_BlockID]; + } return m_BlockHandler[a_BlockID] = CreateBlockHandler(a_BlockID); } + + + + cBlockHandler *cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockID) { switch(a_BlockID) { - case E_BLOCK_WOODEN_DOOR: - case E_BLOCK_IRON_DOOR: - return new cBlockDoorHandler(a_BlockID); - case E_BLOCK_FIRE: - return new cBlockFireHandler(a_BlockID); - case E_BLOCK_REDSTONE_TORCH_ON: - case E_BLOCK_REDSTONE_TORCH_OFF: - return new cBlockRedstoneTorchHandler(a_BlockID); - case E_BLOCK_REDSTONE_WIRE: - return new cBlockRedstoneHandler(a_BlockID); - case E_BLOCK_PISTON: - case E_BLOCK_STICKY_PISTON: - return new cBlockPistonHandler(a_BlockID); - case E_BLOCK_REDSTONE_REPEATER_ON: - case E_BLOCK_REDSTONE_REPEATER_OFF: - return new cBlockRedstoneRepeaterHandler(a_BlockID); - case E_BLOCK_WORKBENCH: - return new cBlockWorkbenchHandler(a_BlockID); - case E_BLOCK_SNOW: - return new cBlockSnowHandler(a_BlockID); - case E_BLOCK_TALL_GRASS: - return new cBlockTallGrassHandler(a_BlockID); - case E_BLOCK_VINES: - return new cBlockVineHandler(a_BlockID); - case ::E_BLOCK_WOOL: - return new cBlockClothHandler(a_BlockID); - case E_BLOCK_WOODEN_SLAB: - case E_BLOCK_STONE_SLAB: - case E_BLOCK_DOUBLE_WOODEN_SLAB: - case E_BLOCK_DOUBLE_STONE_SLAB: - return new cBlockSlabHandler(a_BlockID); - case E_BLOCK_LOG: - case E_BLOCK_PLANKS: - return new cBlockWoodHandler(a_BlockID); - case E_BLOCK_TORCH: - return new cBlockTorchHandler(a_BlockID); - case E_BLOCK_DIRT: - case E_BLOCK_GRASS: - return new cBlockDirtHandler(a_BlockID); - case E_BLOCK_LEAVES: - return new cBlockLeavesHandler(a_BlockID); - case E_BLOCK_SAPLING: - return new cBlockSaplingHandler(a_BlockID); - case E_BLOCK_WATER: - case E_BLOCK_STATIONARY_WATER: - case E_BLOCK_STATIONARY_LAVA: - case E_BLOCK_LAVA: - return new cBlockFluidHandler(a_BlockID); - case E_BLOCK_DISPENSER: - return new cBlockDispenserHandler(a_BlockID); - case E_BLOCK_FURNACE: - case E_BLOCK_LIT_FURNACE: - return new cBlockFurnaceHandler(a_BlockID); - case E_BLOCK_CHEST: - return new cBlockChestHandler(a_BlockID); - case E_BLOCK_ICE: - return new cBlockIceHandler(a_BlockID); - case E_BLOCK_LADDER: - return new cBlockLadderHandler(a_BlockID); - case E_BLOCK_COBBLESTONE_STAIRS: - case E_BLOCK_BRICK_STAIRS: - case E_BLOCK_STONE_BRICK_STAIRS: - case E_BLOCK_NETHER_BRICK_STAIRS: - case E_BLOCK_WOODEN_STAIRS: - return new cBlockStairsHandler(a_BlockID); - case E_BLOCK_SIGN_POST: - case E_BLOCK_WALLSIGN: - return new cBlockSignHandler(a_BlockID); - case E_BLOCK_CROPS: - return new cBlockCropsHandler(a_BlockID); - case E_BLOCK_SUGARCANE: - return new cBlockSugarcaneHandler(a_BlockID); - case E_BLOCK_YELLOW_FLOWER: - case E_BLOCK_RED_ROSE: - return new cBlockFlowerHandler(a_BlockID); - case E_BLOCK_BROWN_MUSHROOM: - case E_BLOCK_RED_MUSHROOM: - return new cBlockMushroomHandler(a_BlockID); - case E_BLOCK_CACTUS: - return new cBlockCactusHandler(a_BlockID); - case E_BLOCK_MELON_STEM: - case E_BLOCK_PUMPKIN_STEM: - return new cBlockStemsHandler(a_BlockID); - case E_BLOCK_GLOWSTONE: - return new cBlockGlowstoneHandler(a_BlockID); - case E_BLOCK_DIAMOND_ORE: - case E_BLOCK_GOLD_ORE: - case E_BLOCK_REDSTONE_ORE: - case E_BLOCK_REDSTONE_ORE_GLOWING: - case E_BLOCK_EMERALD_ORE: - case E_BLOCK_IRON_ORE: - case E_BLOCK_LAPIS_ORE: - case E_BLOCK_COAL_ORE: - return new cBlockOreHandler(a_BlockID); - case E_BLOCK_STONE: - case E_BLOCK_COBBLESTONE: - return new cBlockStoneHandler(a_BlockID); - case E_BLOCK_MELON: - return new cBlockMelonHandler(a_BlockID); - case E_BLOCK_NOTE_BLOCK: - return new cBlockNoteHandler(a_BlockID); - default: - return new cBlockHandler(a_BlockID); - break; + case E_BLOCK_WOODEN_DOOR: + case E_BLOCK_IRON_DOOR: + return new cBlockDoorHandler(a_BlockID); + case E_BLOCK_FIRE: + return new cBlockFireHandler(a_BlockID); + case E_BLOCK_REDSTONE_TORCH_ON: + case E_BLOCK_REDSTONE_TORCH_OFF: + return new cBlockRedstoneTorchHandler(a_BlockID); + case E_BLOCK_REDSTONE_WIRE: + return new cBlockRedstoneHandler(a_BlockID); + case E_BLOCK_PISTON: + case E_BLOCK_STICKY_PISTON: + return new cBlockPistonHandler(a_BlockID); + case E_BLOCK_REDSTONE_REPEATER_ON: + case E_BLOCK_REDSTONE_REPEATER_OFF: + return new cBlockRedstoneRepeaterHandler(a_BlockID); + case E_BLOCK_WORKBENCH: + return new cBlockWorkbenchHandler(a_BlockID); + case E_BLOCK_SNOW: + return new cBlockSnowHandler(a_BlockID); + case E_BLOCK_TALL_GRASS: + return new cBlockTallGrassHandler(a_BlockID); + case E_BLOCK_VINES: + return new cBlockVineHandler(a_BlockID); + case ::E_BLOCK_WOOL: + return new cBlockClothHandler(a_BlockID); + case E_BLOCK_WOODEN_SLAB: + case E_BLOCK_STONE_SLAB: + case E_BLOCK_DOUBLE_WOODEN_SLAB: + case E_BLOCK_DOUBLE_STONE_SLAB: + return new cBlockSlabHandler(a_BlockID); + case E_BLOCK_LOG: + case E_BLOCK_PLANKS: + return new cBlockWoodHandler(a_BlockID); + case E_BLOCK_TORCH: + return new cBlockTorchHandler(a_BlockID); + case E_BLOCK_DIRT: + case E_BLOCK_GRASS: + return new cBlockDirtHandler(a_BlockID); + case E_BLOCK_LEAVES: + return new cBlockLeavesHandler(a_BlockID); + case E_BLOCK_SAPLING: + return new cBlockSaplingHandler(a_BlockID); + case E_BLOCK_WATER: + case E_BLOCK_STATIONARY_WATER: + case E_BLOCK_STATIONARY_LAVA: + case E_BLOCK_LAVA: + return new cBlockFluidHandler(a_BlockID); + case E_BLOCK_DISPENSER: + return new cBlockDispenserHandler(a_BlockID); + case E_BLOCK_FURNACE: + case E_BLOCK_LIT_FURNACE: + return new cBlockFurnaceHandler(a_BlockID); + case E_BLOCK_CHEST: + return new cBlockChestHandler(a_BlockID); + case E_BLOCK_ICE: + return new cBlockIceHandler(a_BlockID); + case E_BLOCK_LADDER: + return new cBlockLadderHandler(a_BlockID); + case E_BLOCK_COBBLESTONE_STAIRS: + case E_BLOCK_BRICK_STAIRS: + case E_BLOCK_STONE_BRICK_STAIRS: + case E_BLOCK_NETHER_BRICK_STAIRS: + case E_BLOCK_WOODEN_STAIRS: + return new cBlockStairsHandler(a_BlockID); + case E_BLOCK_SIGN_POST: + case E_BLOCK_WALLSIGN: + return new cBlockSignHandler(a_BlockID); + case E_BLOCK_CROPS: + return new cBlockCropsHandler(a_BlockID); + case E_BLOCK_SUGARCANE: + return new cBlockSugarcaneHandler(a_BlockID); + case E_BLOCK_YELLOW_FLOWER: + case E_BLOCK_RED_ROSE: + return new cBlockFlowerHandler(a_BlockID); + case E_BLOCK_BROWN_MUSHROOM: + case E_BLOCK_RED_MUSHROOM: + return new cBlockMushroomHandler(a_BlockID); + case E_BLOCK_CACTUS: + return new cBlockCactusHandler(a_BlockID); + case E_BLOCK_MELON_STEM: + case E_BLOCK_PUMPKIN_STEM: + return new cBlockStemsHandler(a_BlockID); + case E_BLOCK_GLOWSTONE: + return new cBlockGlowstoneHandler(a_BlockID); + case E_BLOCK_DIAMOND_ORE: + case E_BLOCK_GOLD_ORE: + case E_BLOCK_REDSTONE_ORE: + case E_BLOCK_REDSTONE_ORE_GLOWING: + case E_BLOCK_EMERALD_ORE: + case E_BLOCK_IRON_ORE: + case E_BLOCK_LAPIS_ORE: + case E_BLOCK_COAL_ORE: + return new cBlockOreHandler(a_BlockID); + case E_BLOCK_STONE: + case E_BLOCK_COBBLESTONE: + return new cBlockStoneHandler(a_BlockID); + case E_BLOCK_MELON: + return new cBlockMelonHandler(a_BlockID); + case E_BLOCK_NOTE_BLOCK: + return new cBlockNoteHandler(a_BlockID); + default: + return new cBlockHandler(a_BlockID); + break; } } + + + + void cBlockHandler::Deinit() { for(int i = 0; i < 256; i++) { delete m_BlockHandler[i]; } + m_HandlerInitialized = false; } + + + + cBlockHandler::cBlockHandler(BLOCKTYPE a_BlockID) { m_BlockID = a_BlockID; } + + + + void cBlockHandler::OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z) { - } + + + + void cBlockHandler::OnPlacedByPlayer(cWorld *a_World, cPlayer * a_Player, int a_X, int a_Y, int a_Z, int a_Dir) { } + + + + void cBlockHandler::OnDestroyedByPlayer(cWorld *a_World, cPlayer * a_Player, int a_X, int a_Y, int a_Z) { } + + + + void cBlockHandler::OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir) { //Notify the neighbors @@ -204,6 +243,10 @@ void cBlockHandler::OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_D NeighborChanged(a_World, a_X, a_Y, a_Z + 1); } + + + + void cBlockHandler::OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) { //Notify the neighbors @@ -215,47 +258,80 @@ void cBlockHandler::OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z) NeighborChanged(a_World, a_X, a_Y, a_Z + 1); } + + + + void cBlockHandler::NeighborChanged(cWorld *a_World, int a_X, int a_Y, int a_Z) { GetBlockHandler(a_World->GetBlock(a_X, a_Y, a_Z))->OnNeighborChanged(a_World, a_X, a_Y, a_Z); } + + + + void cBlockHandler::OnNeighborChanged(cWorld *a_World, int a_X, int a_Y, int a_Z) { - } + + + + void cBlockHandler::OnDigging(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z) { - } + + + + void cBlockHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z) { - } + + + + void cBlockHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, NIBBLETYPE a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir) { a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, a_BlockMeta); OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir); } + + + + char cBlockHandler::GetDropCount() { return 1; } + + + + int cBlockHandler::GetDropID() { return m_BlockID; } + + + + NIBBLETYPE cBlockHandler::GetDropMeta(NIBBLETYPE a_BlockMeta) { return a_BlockMeta; //This keeps most textures. The few other blocks have to override this } + + + + void cBlockHandler::DropBlock(cWorld *a_World, int a_X, int a_Y, int a_Z) { cItems Drops; @@ -269,47 +345,87 @@ void cBlockHandler::DropBlock(cWorld *a_World, int a_X, int a_Y, int a_Z) } } + + + + bool cBlockHandler::CanBePlacedAt(cWorld *a_World, int a_X, int a_Y, int a_Z, char a_Dir) { return CanBeAt(a_World, a_X, a_Y, a_Z); } + + + + bool cBlockHandler::CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z) { return true; } + + + + bool cBlockHandler::IsUseable() { return false; } + + + + bool cBlockHandler::IsClickedThrough() { return false; } + + + + bool cBlockHandler::IgnoreBuildCollision() { return m_BlockID == E_BLOCK_AIR; } + + + + bool cBlockHandler::NeedsRandomTicks() { return false; } + + + + bool cBlockHandler::AllowBlockOnTop() { return true; } + + + + bool cBlockHandler::CanBePlacedOnSide() { return true; } + + + + bool cBlockHandler::DropOnUnsuitable() { return true; -} \ No newline at end of file +} + + + + diff --git a/source/cChunk.cpp b/source/cChunk.cpp index 4e32b4dad..6295d4bba 100644 --- a/source/cChunk.cpp +++ b/source/cChunk.cpp @@ -580,15 +580,22 @@ void cChunk::TickBlocks(MTRand & a_TickRandom) default: { - cBlockHandler *Handler = BlockHandler(ID); - if(Handler->NeedsRandomTicks()) - Handler->OnUpdate(m_World, m_BlockTickX + m_PosX*Width, m_BlockTickY, m_BlockTickZ + m_PosZ*Width); + cBlockHandler * Handler = BlockHandler(ID); + ASSERT(Handler != NULL); // Happenned on server restart, FS #243 + if (Handler->NeedsRandomTicks()) + { + Handler->OnUpdate(m_World, m_BlockTickX + m_PosX * Width, m_BlockTickY, m_BlockTickZ + m_PosZ * Width); + } break; } } } } + + + + void cChunk::TickMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, int a_BlockIdx, BLOCKTYPE a_BlockType, MTRand & a_TickRandom) { NIBBLETYPE Meta = GetMeta(a_BlockIdx); diff --git a/source/items/Item.cpp b/source/items/Item.cpp index 17f4ead71..f1b376493 100644 --- a/source/items/Item.cpp +++ b/source/items/Item.cpp @@ -179,6 +179,7 @@ void cItemHandler::Deinit() { delete m_ItemHandler[i]; } + m_HandlerInitialized = false; } -- cgit v1.2.3