From 78f4142f4ff033351030a2008f76c6bf8768780c Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Tue, 18 Oct 2011 00:01:50 +0300 Subject: Add /clearobjects --- src/environment.cpp | 86 ++++++++++++++++++++++ src/environment.h | 5 ++ src/map.cpp | 198 +++++++++++++------------------------------------- src/map.h | 4 + src/server.cpp | 5 ++ src/server.h | 1 + src/servercommand.cpp | 52 ++++++++----- 7 files changed, 185 insertions(+), 166 deletions(-) diff --git a/src/environment.cpp b/src/environment.cpp index 174ee1e1d..142271849 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -647,6 +647,92 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime) } } +void ServerEnvironment::clearAllObjects() +{ + infostream<<"ServerEnvironment::clearAllObjects(): " + <<"Removing all active objects"< objects_to_remove; + for(core::map::Iterator + i = m_active_objects.getIterator(); + i.atEnd()==false; i++) + { + ServerActiveObject* obj = i.getNode()->getValue(); + u16 id = i.getNode()->getKey(); + v3f objectpos = obj->getBasePosition(); + // Delete static object if block is loaded + if(obj->m_static_exists){ + MapBlock *block = m_map->getBlockNoCreateNoEx(obj->m_static_block); + if(block){ + block->m_static_objects.remove(id); + block->raiseModified(MOD_STATE_WRITE_NEEDED); + obj->m_static_exists = false; + } + } + // If known by some client, don't delete immediately + if(obj->m_known_by_count > 0){ + obj->m_pending_deactivation = true; + obj->m_removed = true; + continue; + } + // Delete active object + delete obj; + // Id to be removed from m_active_objects + objects_to_remove.push_back(id); + } + // Remove references from m_active_objects + for(core::list::Iterator i = objects_to_remove.begin(); + i != objects_to_remove.end(); i++) + { + m_active_objects.remove(*i); + } + + core::list loadable_blocks; + infostream<<"ServerEnvironment::clearAllObjects(): " + <<"Listing all loadable blocks"<listAllLoadableBlocks(loadable_blocks); + infostream<<"ServerEnvironment::clearAllObjects(): " + <<"Done listing all loadable blocks: " + <::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){ + block->m_static_objects.m_stored.clear(); + block->m_static_objects.m_active.clear(); + block->raiseModified(MOD_STATE_WRITE_NEEDED); + num_objs_cleared += num_stored + num_active; + num_blocks_cleared++; + } + num_blocks_checked++; + + if(num_blocks_checked % report_interval == 0){ + float percent = 100.0 * (float)num_blocks_checked / + loadable_blocks.size(); + infostream<<"ServerEnvironment::clearAllObjects(): " + <<"Cleared "< MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Y < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Y > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Z < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE - || p.Z > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE) - throw InvalidPositionException("emergeBlock(): pos. over limit"); - - v2s16 p2d(p.X, p.Z); - s16 block_y = p.Y; - /* - This will create or load a sector if not found in memory. - If block exists on disk, it will be loaded. - */ - ServerMapSector *sector; - try{ - sector = createSector(p2d); - //sector = emergeSector(p2d, changed_blocks); - } - catch(InvalidPositionException &e) - { - infostream<<"emergeBlock: createSector() failed: " - <getBlockNoCreateNoEx(block_y); - - // If not found, try loading from disk - if(block == NULL) - { - block = loadBlock(p); - } - - // Handle result - if(block == NULL) - { - does_not_exist = true; - } - else if(block->isDummy() == true) - { - does_not_exist = true; - } - else if(block->getLightingExpired()) - { - lighting_expired = true; - } - else - { - // Valid block - //infostream<<"emergeBlock(): Returning already valid block"<insertBlock(block); - } - // Done. - return block; - } - - //infostream<<"Not found on disk, generating."< making one"< light_sources; - bool black_air_left = false; - bool bottom_invalid = - block->propagateSunlight(light_sources, true, - &black_air_left); - - // If sunlight didn't reach everywhere and part of block is - // above ground, lighting has to be properly updated - //if(black_air_left && some_part_underground) - if(black_air_left) - { - lighting_invalidated_blocks[block->getPos()] = block; - } - - if(bottom_invalid) - { - lighting_invalidated_blocks[block->getPos()] = block; - } - } -#endif - - return block; -} -#endif - s16 ServerMap::findGroundLevel(v2s16 p2d) { #if 0 @@ -2867,6 +2721,12 @@ void ServerMap::verifyDatabase() { throw FileNotGoodException("Cannot prepare write statement"); } + d = sqlite3_prepare(m_database, "SELECT `pos` FROM `blocks`", -1, &m_database_list, NULL); + if(d != SQLITE_OK) { + infostream<<"WARNING: Database list statment failed to prepare: "<= 0) + return i % mod; + return mod - ((-i) % mod); +} + +v3s16 ServerMap::getIntegerAsBlock(sqlite3_int64 i) +{ + s32 x = unsignedToSigned(pythonmodulo(i, 4096), 2048); + i = (i - x) / 4096; + s32 y = unsignedToSigned(pythonmodulo(i, 4096), 2048); + i = (i - y) / 4096; + s32 z = unsignedToSigned(pythonmodulo(i, 4096), 2048); + return v3s16(x,y,z); +} + +void ServerMap::listAllLoadableBlocks(core::list &dst) +{ + if(loadFromFolders()){ + errorstream<<"Map::listAllLoadableBlocks(): Result will be missing " + <<"all blocks that are stored in flat files"<privs & PRIV_SERVER) ==0) + { + os<player->getName() + <<" clears all objects"<player->getName()); + msg += L")"; + ctx->server->notifyPlayers(msg); + } + + ctx->env->clearAllObjects(); + + actionstream<<"object clearing done"<flags |= SEND_TO_OTHERS; +} + std::wstring processServerCommand(ServerCommandContext *ctx) { @@ -302,45 +331,28 @@ std::wstring processServerCommand(ServerCommandContext *ctx) os<parms[0] == L"status") - { cmd_status(os, ctx); - } else if(ctx->parms[0] == L"privs") - { cmd_privs(os, ctx); - } else if(ctx->parms[0] == L"grant" || ctx->parms[0] == L"revoke") - { cmd_grantrevoke(os, ctx); - } else if(ctx->parms[0] == L"time") - { cmd_time(os, ctx); - } else if(ctx->parms[0] == L"shutdown") - { cmd_shutdown(os, ctx); - } else if(ctx->parms[0] == L"setting") - { cmd_setting(os, ctx); - } else if(ctx->parms[0] == L"teleport") - { cmd_teleport(os, ctx); - } else if(ctx->parms[0] == L"ban" || ctx->parms[0] == L"unban") - { cmd_banunban(os, ctx); - } else if(ctx->parms[0] == L"me") - { cmd_me(os, ctx); - } + else if(ctx->parms[0] == L"clearobjects") + cmd_clearobjects(os, ctx); else - { os<parms[0]; - } + return os.str(); } -- cgit v1.2.3