X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fmap.cpp;h=9974ff363a7aa5f520e9df961a45ffecd58a0e0e;hb=ba15c98e4d5d7f4bc515e351d6af1a084d46092e;hp=191b05ed5601afe332977109e63e8140d44d48c4;hpb=3c91ad8fc2b7a7888503e85d31bfe286afa6560d;p=oweals%2Fminetest.git diff --git a/src/map.cpp b/src/map.cpp index 191b05ed5..9974ff363 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -20,7 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "map.h" #include "mapsector.h" #include "mapblock.h" -#include "main.h" #include "filesys.h" #include "voxel.h" #include "porting.h" @@ -53,22 +52,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" -/* - SQLite format specification: - - Initially only replaces sectors/ and sectors2/ - - If map.sqlite does not exist in the save dir - or the block was not found in the database - the map will try to load from sectors folder. - In either case, map.sqlite will be created - and all future saves will save there. - - Structure of map.sqlite: - Tables: - blocks - (PK) INT pos - BLOB data -*/ /* Map @@ -783,8 +766,7 @@ void Map::updateLighting(enum LightBank bank, } else { - // Invalid lighting bank - assert(0); + assert("Invalid lighting bank" == NULL); } /*infostream<<"Bottom for sunlight-propagated block (" @@ -799,7 +781,7 @@ void Map::updateLighting(enum LightBank bank, } catch(InvalidPositionException &e) { - assert(0); + FATAL_ERROR("Invalid position"); } } @@ -1236,7 +1218,7 @@ void Map::removeNodeAndUpdate(v3s16 p, n.setLight(LIGHTBANK_DAY, 0, ndef); setNode(p, n); } else { - assert(0); + FATAL_ERROR("Invalid position"); } } @@ -1428,7 +1410,7 @@ void Map::timerUpdate(float dtime, float unload_timeout, // Profile modified reasons Profiler modprofiler; - std::list sector_deletion_queue; + std::vector sector_deletion_queue; u32 deleted_blocks_count = 0; u32 saved_blocks_count = 0; u32 block_count_all = 0; @@ -1440,24 +1422,21 @@ void Map::timerUpdate(float dtime, float unload_timeout, bool all_blocks_deleted = true; - std::list blocks; + MapBlockVect blocks; sector->getBlocks(blocks); - for(std::list::iterator i = blocks.begin(); - i != blocks.end(); ++i) - { + for(MapBlockVect::iterator i = blocks.begin(); + i != blocks.end(); ++i) { MapBlock *block = (*i); block->incrementUsageTimer(dtime); - if(block->refGet() == 0 && block->getUsageTimer() > unload_timeout) - { + if(block->refGet() == 0 && block->getUsageTimer() > unload_timeout) { v3s16 p = block->getPos(); // Save if modified - if (block->getModified() != MOD_STATE_CLEAN && save_before_unloading) - { - modprofiler.add(block->getModifiedReason(), 1); + if (block->getModified() != MOD_STATE_CLEAN && save_before_unloading) { + modprofiler.add(block->getModifiedReasonString(), 1); if (!saveBlock(block)) continue; saved_blocks_count++; @@ -1471,15 +1450,13 @@ void Map::timerUpdate(float dtime, float unload_timeout, deleted_blocks_count++; } - else - { + else { all_blocks_deleted = false; block_count_all++; } } - if(all_blocks_deleted) - { + if(all_blocks_deleted) { sector_deletion_queue.push_back(si->first); } } @@ -1510,11 +1487,10 @@ void Map::unloadUnreferencedBlocks(std::vector *unloaded_blocks) timerUpdate(0.0, -1.0, unloaded_blocks); } -void Map::deleteSectors(std::list &list) +void Map::deleteSectors(std::vector §orList) { - for(std::list::iterator j = list.begin(); - j != list.end(); ++j) - { + for(std::vector::iterator j = sectorList.begin(); + j != sectorList.end(); ++j) { MapSector *sector = m_sectors[*j]; // If sector is in sector cache, remove it from there if(m_sector_cache == sector) @@ -1525,63 +1501,6 @@ void Map::deleteSectors(std::list &list) } } -#if 0 -void Map::unloadUnusedData(float timeout, - core::list *deleted_blocks) -{ - core::list sector_deletion_queue; - u32 deleted_blocks_count = 0; - u32 saved_blocks_count = 0; - - core::map::Iterator si = m_sectors.getIterator(); - for(; si.atEnd() == false; si++) - { - MapSector *sector = si.getNode()->getValue(); - - bool all_blocks_deleted = true; - - core::list blocks; - sector->getBlocks(blocks); - for(core::list::Iterator i = blocks.begin(); - i != blocks.end(); i++) - { - MapBlock *block = (*i); - - if(block->getUsageTimer() > timeout) - { - // Save if modified - if(block->getModified() != MOD_STATE_CLEAN) - { - saveBlock(block); - saved_blocks_count++; - } - // Delete from memory - sector->deleteBlock(block); - deleted_blocks_count++; - } - else - { - all_blocks_deleted = false; - } - } - - if(all_blocks_deleted) - { - sector_deletion_queue.push_back(si.getNode()->getKey()); - } - } - - deleteSectors(sector_deletion_queue); - - infostream<<"Map: Unloaded "< & modified_blocks) // Find out whether there is a suspect for this action std::string suspect; - if(m_gamedef->rollback()){ + if(m_gamedef->rollback()) { suspect = m_gamedef->rollback()->getSuspect(p0, 83, 1); } - if(!suspect.empty()){ + if(m_gamedef->rollback() && !suspect.empty()){ // Blame suspect RollbackScopeActor rollback_scope(m_gamedef->rollback(), suspect, true); // Get old node for rollback @@ -1971,6 +1890,47 @@ void Map::transformLiquids(std::map & modified_blocks) } } +std::vector Map::findNodesWithMetadata(v3s16 p1, v3s16 p2) +{ + std::vector positions_with_meta; + + sortBoxVerticies(p1, p2); + v3s16 bpmin = getNodeBlockPos(p1); + v3s16 bpmax = getNodeBlockPos(p2); + + VoxelArea area(p1, p2); + + for (s16 z = bpmin.Z; z <= bpmax.Z; z++) + for (s16 y = bpmin.Y; y <= bpmax.Y; y++) + for (s16 x = bpmin.X; x <= bpmax.X; x++) { + v3s16 blockpos(x, y, z); + + MapBlock *block = getBlockNoCreateNoEx(blockpos); + if (!block) { + verbosestream << "Map::getNodeMetadata(): Need to emerge " + << PP(blockpos) << std::endl; + block = emergeBlock(blockpos, false); + } + if (!block) { + infostream << "WARNING: Map::getNodeMetadata(): Block not found" + << std::endl; + continue; + } + + v3s16 p_base = blockpos * MAP_BLOCKSIZE; + std::vector keys = block->m_node_metadata.getAllKeys(); + for (size_t i = 0; i != keys.size(); i++) { + v3s16 p(keys[i] + p_base); + if (!area.contains(p)) + continue; + + positions_with_meta.push_back(p); + } + } + + return positions_with_meta; +} + NodeMetadata *Map::getNodeMetadata(v3s16 p) { v3s16 blockpos = getNodeBlockPos(p); @@ -2094,25 +2054,13 @@ ServerMap::ServerMap(std::string savedir, IGameDef *gamedef, EmergeManager *emer bool succeeded = conf.readConfigFile(conf_path.c_str()); if (!succeeded || !conf.exists("backend")) { // fall back to sqlite3 - dbase = new Database_SQLite3(this, savedir); conf.set("backend", "sqlite3"); - } else { - std::string backend = conf.get("backend"); - if (backend == "dummy") - dbase = new Database_Dummy(this); - else if (backend == "sqlite3") - dbase = new Database_SQLite3(this, savedir); - #if USE_LEVELDB - else if (backend == "leveldb") - dbase = new Database_LevelDB(this, savedir); - #endif - #if USE_REDIS - else if (backend == "redis") - dbase = new Database_Redis(this, savedir); - #endif - else - throw BaseException("Unknown map backend"); } + std::string backend = conf.get("backend"); + dbase = createDatabase(backend, savedir, conf); + + if (!conf.updateConfigFile(conf_path.c_str())) + errorstream << "ServerMap::ServerMap(): Failed to update world.mt!" << std::endl; m_savedir = savedir; m_map_saving_enabled = false; @@ -2271,7 +2219,7 @@ bool ServerMap::initBlockMake(BlockMakeData *data, v3s16 blockpos) v2s16 sectorpos(x, z); // Sector metadata is loaded from disk if not already loaded. ServerMapSector *sector = createSector(sectorpos); - assert(sector); + FATAL_ERROR_IF(sector == NULL, "createSector() failed"); (void) sector; for(s16 y=blockpos_min.Y-extra_borders.Y; @@ -2464,7 +2412,7 @@ void ServerMap::finishBlockMake(BlockMakeData *data, Set block as modified */ block->raiseModified(MOD_STATE_WRITE_NEEDED, - "finishBlockMake expireDayNightDiff"); + MOD_REASON_EXPIRE_DAYNIGHTDIFF); } /* @@ -2719,7 +2667,7 @@ MapBlock * ServerMap::createBlock(v3s16 p) lighting on blocks for them. */ ServerMapSector *sector; - try{ + try { sector = (ServerMapSector*)createSector(p2d); assert(sector->getId() == MAPSECTOR_SERVER); } @@ -2891,7 +2839,8 @@ plan_b: } bool ServerMap::loadFromFolders() { - if(!dbase->Initialized() && !fs::PathExists(m_savedir + DIR_DELIM + "map.sqlite")) // ? + if (!dbase->initialized() && + !fs::PathExists(m_savedir + DIR_DELIM + "map.sqlite")) return true; return false; } @@ -2913,14 +2862,14 @@ std::string ServerMap::getSectorDir(v2s16 pos, int layout) { case 1: snprintf(cc, 9, "%.4x%.4x", - (unsigned int)pos.X&0xffff, - (unsigned int)pos.Y&0xffff); + (unsigned int) pos.X & 0xffff, + (unsigned int) pos.Y & 0xffff); return m_savedir + DIR_DELIM + "sectors" + DIR_DELIM + cc; case 2: - snprintf(cc, 9, "%.3x" DIR_DELIM "%.3x", - (unsigned int)pos.X&0xfff, - (unsigned int)pos.Y&0xfff); + snprintf(cc, 9, (std::string("%.3x") + DIR_DELIM + "%.3x").c_str(), + (unsigned int) pos.X & 0xfff, + (unsigned int) pos.Y & 0xfff); return m_savedir + DIR_DELIM + "sectors2" + DIR_DELIM + cc; default: @@ -2944,16 +2893,17 @@ v2s16 ServerMap::getSectorPos(std::string dirname) { // New layout fs::RemoveLastPathComponent(dirname, &component, 2); - r = sscanf(component.c_str(), "%3x" DIR_DELIM "%3x", &x, &y); + r = sscanf(component.c_str(), (std::string("%3x") + DIR_DELIM + "%3x").c_str(), &x, &y); // Sign-extend the 12 bit values up to 16 bits... - if(x&0x800) x|=0xF000; - if(y&0x800) y|=0xF000; + if(x & 0x800) x |= 0xF000; + if(y & 0x800) y |= 0xF000; } else { - assert(false); + r = -1; } - assert(r == 2); + + FATAL_ERROR_IF(r != 2, "getSectorPos()"); v2s16 pos((s16)x, (s16)y); return pos; } @@ -2982,8 +2932,7 @@ std::string ServerMap::getBlockFilename(v3s16 p) void ServerMap::save(ModifiedState save_level) { DSTACK(__FUNCTION_NAME); - if(m_map_saving_enabled == false) - { + if(m_map_saving_enabled == false) { infostream<<"WARNING: Not saving map, saving disabled."<::iterator i = m_sectors.begin(); - i != m_sectors.end(); ++i) - { + i != m_sectors.end(); ++i) { ServerMapSector *sector = (ServerMapSector*)i->second; assert(sector->getId() == MAPSECTOR_SERVER); - if(sector->differs_from_disk || save_level == MOD_STATE_CLEAN) - { + if(sector->differs_from_disk || save_level == MOD_STATE_CLEAN) { saveSectorMeta(sector); sector_meta_count++; } - std::list blocks; + + MapBlockVect blocks; sector->getBlocks(blocks); - for(std::list::iterator j = blocks.begin(); - j != blocks.end(); ++j) - { + for(MapBlockVect::iterator j = blocks.begin(); + j != blocks.end(); ++j) { MapBlock *block = *j; block_count_all++; - if(block->getModified() >= (u32)save_level) - { + if(block->getModified() >= (u32)save_level) { // Lazy beginSave() - if(!save_started){ + if(!save_started) { beginSave(); save_started = true; } - modprofiler.add(block->getModifiedReason(), 1); + modprofiler.add(block->getModifiedReasonString(), 1); saveBlock(block); block_count++; @@ -3049,6 +2994,7 @@ void ServerMap::save(ModifiedState save_level) } } } + if(save_started) endSave(); @@ -3056,8 +3002,7 @@ void ServerMap::save(ModifiedState save_level) Only print if something happened or saved whole map */ if(save_level == MOD_STATE_CLEAN || sector_meta_count != 0 - || block_count != 0) - { + || block_count != 0) { infostream<<"ServerMap: Written: " < &dst) { - if(loadFromFolders()){ - errorstream<<"Map::listAllLoadableBlocks(): Result will be missing " - <<"all blocks that are stored in flat files"<listAllLoadableBlocks(dst); } @@ -3085,14 +3030,12 @@ void ServerMap::listAllLoadedBlocks(std::vector &dst) { MapSector *sector = si->second; - std::list blocks; + MapBlockVect blocks; sector->getBlocks(blocks); - for(std::list::iterator i = blocks.begin(); - i != blocks.end(); ++i) - { - MapBlock *block = (*i); - v3s16 p = block->getPos(); + for(MapBlockVect::iterator i = blocks.begin(); + i != blocks.end(); ++i) { + v3s16 p = (*i)->getPos(); dst.push_back(p); } } @@ -3102,26 +3045,20 @@ void ServerMap::saveMapMeta() { DSTACK(__FUNCTION_NAME); - /*infostream<<"ServerMap::saveMapMeta(): " - <<"seed="<saveParamsToSettings(¶ms); - params.writeLines(ss); + m_emerge->params.save(conf); + conf.writeLines(oss); - ss<<"[end_of_params]\n"; + oss << "[end_of_params]\n"; - if(!fs::safeWriteToFile(fullpath, ss.str())) - { - infostream<<"ERROR: ServerMap::saveMapMeta(): " - <<"could not write "<loadParamsFromSettings(¶ms); + m_emerge->params.load(conf); verbosestream << "ServerMap::loadMapMeta(): seed=" << m_emerge->params.seed << std::endl; @@ -3330,6 +3265,24 @@ bool ServerMap::loadSectorFull(v2s16 p2d) } #endif +Database *ServerMap::createDatabase(const std::string &name, const std::string &savedir, Settings &conf) +{ + if (name == "sqlite3") + return new Database_SQLite3(savedir); + if (name == "dummy") + return new Database_Dummy(); + #if USE_LEVELDB + else if (name == "leveldb") + return new Database_LevelDB(savedir); + #endif + #if USE_REDIS + else if (name == "redis") + return new Database_Redis(conf); + #endif + else + throw BaseException(std::string("Database backend ") + name + " not supported."); +} + void ServerMap::beginSave() { dbase->beginSave(); @@ -3369,7 +3322,7 @@ bool ServerMap::saveBlock(MapBlock *block, Database *db) std::string data = o.str(); bool ret = db->saveBlock(p3d, data); - if(ret) { + if (ret) { // We just wrote it to the disk so clear modified flag block->resetModified(); } @@ -3381,7 +3334,7 @@ void ServerMap::loadBlock(std::string sectordir, std::string blockfile, { DSTACK(__FUNCTION_NAME); - std::string fullpath = sectordir+DIR_DELIM+blockfile; + std::string fullpath = sectordir + DIR_DELIM + blockfile; try { std::ifstream is(fullpath.c_str(), std::ios_base::binary); @@ -3447,7 +3400,7 @@ void ServerMap::loadBlock(std::string sectordir, std::string blockfile, <<"what()="<