From b1428ab4bb1e2cf73bc8ac951d41d22203ea68a0 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Mon, 8 Feb 2016 22:20:04 +0100 Subject: Add '/clearobjects quick' --- src/environment.cpp | 115 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 44 deletions(-) (limited to 'src/environment.cpp') diff --git a/src/environment.cpp b/src/environment.cpp index 38316cb31..3bf5e1f0a 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -354,6 +354,7 @@ ServerEnvironment::ServerEnvironment(ServerMap *map, m_active_block_interval_overload_skip(0), m_game_time(0), m_game_time_fraction_counter(0), + m_last_clear_objects_time(0), m_recommended_send_interval(0.1), m_max_lag_estimate(0.1) { @@ -503,6 +504,7 @@ void ServerEnvironment::saveMeta() Settings args; args.setU64("game_time", m_game_time); args.setU64("time_of_day", getTimeOfDay()); + args.setU64("last_clear_objects_time", m_last_clear_objects_time); args.writeLines(ss); ss<<"EnvArgsEnd\n"; @@ -546,6 +548,13 @@ void ServerEnvironment::loadMeta() // This is not as important setTimeOfDay(9000); } + + try { + m_last_clear_objects_time = args.getU64("last_clear_objects_time"); + } catch (SettingNotFoundException &e) { + // If missing, do as if clearObjects was never called + m_last_clear_objects_time = 0; + } } struct ActiveABM @@ -739,13 +748,19 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime) // Get time difference u32 dtime_s = 0; u32 stamp = block->getTimestamp(); - if(m_game_time > stamp && stamp != BLOCK_TIMESTAMP_UNDEFINED) - dtime_s = m_game_time - block->getTimestamp(); + if (m_game_time > stamp && stamp != BLOCK_TIMESTAMP_UNDEFINED) + dtime_s = m_game_time - stamp; dtime_s += additional_dtime; /*infostream<<"ServerEnvironment::activateBlock(): block timestamp: " <m_static_objects.m_stored.clear(); + // do not set changed flag to avoid unnecessary mapblock writes + } + // Set current time as timestamp block->setTimestampNoChangedFlag(m_game_time); @@ -858,22 +873,22 @@ void ServerEnvironment::getObjectsInsideRadius(std::vector &objects, v3f po } } -void ServerEnvironment::clearAllObjects() +void ServerEnvironment::clearObjects(ClearObjectsMode mode) { - infostream<<"ServerEnvironment::clearAllObjects(): " - <<"Removing all active objects"< objects_to_remove; - for(std::map::iterator + for (std::map::iterator i = m_active_objects.begin(); i != m_active_objects.end(); ++i) { ServerActiveObject* obj = i->second; - if(obj->getType() == ACTIVEOBJECT_TYPE_PLAYER) + if (obj->getType() == ACTIVEOBJECT_TYPE_PLAYER) continue; u16 id = i->first; // Delete static object if block is loaded - if(obj->m_static_exists){ + if (obj->m_static_exists) { MapBlock *block = m_map->getBlockNoCreateNoEx(obj->m_static_block); - if(block){ + if (block) { block->m_static_objects.remove(id); block->raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_CLEAR_ALL_OBJECTS); @@ -881,7 +896,7 @@ void ServerEnvironment::clearAllObjects() } } // If known by some client, don't delete immediately - if(obj->m_known_by_count > 0){ + if (obj->m_known_by_count > 0) { obj->m_pending_deactivation = true; obj->m_removed = true; continue; @@ -893,39 +908,46 @@ void ServerEnvironment::clearAllObjects() m_script->removeObjectReference(obj); // Delete active object - if(obj->environmentDeletes()) + if (obj->environmentDeletes()) delete obj; // Id to be removed from m_active_objects objects_to_remove.push_back(id); } // Remove references from m_active_objects - for(std::vector::iterator i = objects_to_remove.begin(); + for (std::vector::iterator i = objects_to_remove.begin(); i != objects_to_remove.end(); ++i) { m_active_objects.erase(*i); } // Get list of loaded blocks std::vector loaded_blocks; - infostream<<"ServerEnvironment::clearAllObjects(): " - <<"Listing all loaded blocks"<listAllLoadedBlocks(loaded_blocks); - infostream<<"ServerEnvironment::clearAllObjects(): " - <<"Done listing all loaded blocks: " - < loadable_blocks; - infostream<<"ServerEnvironment::clearAllObjects(): " - <<"Listing all loadable blocks"<listAllLoadableBlocks(loadable_blocks); - infostream<<"ServerEnvironment::clearAllObjects(): " - <<"Done listing all loadable blocks: " - <listAllLoadableBlocks(loadable_blocks); + infostream << "ServerEnvironment::clearObjects(): " + << "Done listing all loadable blocks: " + << loadable_blocks.size() << std::endl; + } else { + loadable_blocks = loaded_blocks; + } + + infostream << "ServerEnvironment::clearObjects(): " + << "Now clearing objects in " << loadable_blocks.size() + << " blocks" << std::endl; // Grab a reference on each loaded block to avoid unloading it - for(std::vector::iterator i = loaded_blocks.begin(); + for (std::vector::iterator i = loaded_blocks.begin(); i != loaded_blocks.end(); ++i) { v3s16 p = *i; MapBlock *block = m_map->getBlockNoCreateNoEx(p); @@ -934,24 +956,27 @@ void ServerEnvironment::clearAllObjects() } // Remove objects in all loadable blocks - u32 unload_interval = g_settings->getS32("max_clearobjects_extra_loaded_blocks"); - unload_interval = MYMAX(unload_interval, 1); + u32 unload_interval = U32_MAX; + if (mode == CLEAR_OBJECTS_MODE_FULL) { + unload_interval = g_settings->getS32("max_clearobjects_extra_loaded_blocks"); + unload_interval = MYMAX(unload_interval, 1); + } u32 report_interval = loadable_blocks.size() / 10; u32 num_blocks_checked = 0; u32 num_blocks_cleared = 0; u32 num_objs_cleared = 0; - for(std::vector::iterator i = loadable_blocks.begin(); + for (std::vector::iterator i = loadable_blocks.begin(); i != loadable_blocks.end(); ++i) { v3s16 p = *i; MapBlock *block = m_map->emergeBlock(p, false); - if(!block){ - errorstream<<"ServerEnvironment::clearAllObjects(): " - <<"Failed to emerge block "<m_static_objects.m_stored.size(); u32 num_active = block->m_static_objects.m_active.size(); - if(num_stored != 0 || num_active != 0){ + if (num_stored != 0 || num_active != 0) { block->m_static_objects.m_stored.clear(); block->m_static_objects.m_active.clear(); block->raiseModified(MOD_STATE_WRITE_NEEDED, @@ -961,23 +986,23 @@ void ServerEnvironment::clearAllObjects() } num_blocks_checked++; - if(report_interval != 0 && - num_blocks_checked % report_interval == 0){ + if (report_interval != 0 && + num_blocks_checked % report_interval == 0) { float percent = 100.0 * (float)num_blocks_checked / - loadable_blocks.size(); - infostream<<"ServerEnvironment::clearAllObjects(): " - <<"Cleared "<unloadUnreferencedBlocks(); } } m_map->unloadUnreferencedBlocks(); // Drop references that were added above - for(std::vector::iterator i = loaded_blocks.begin(); + for (std::vector::iterator i = loaded_blocks.begin(); i != loaded_blocks.end(); ++i) { v3s16 p = *i; MapBlock *block = m_map->getBlockNoCreateNoEx(p); @@ -985,9 +1010,11 @@ void ServerEnvironment::clearAllObjects() block->refDrop(); } - infostream<<"ServerEnvironment::clearAllObjects(): " - <<"Finished: Cleared "<