10 #include "mapsector.h"
17 #include "nodemetadata.h"
23 #include "util/directiontables.h"
24 #include "rollback_interface.h"
26 #include "database-leveldb.h"
27 #include "leveldb/db.h"
29 Database_LevelDB::Database_LevelDB(ServerMap *map, std::string savedir)
31 leveldb::Options options;
32 options.create_if_missing = true;
33 leveldb::Status status = leveldb::DB::Open(options, savedir + DIR_DELIM + "map.db", &m_database);
38 int Database_LevelDB::Initialized(void)
43 void Database_LevelDB::beginSave() {}
44 void Database_LevelDB::endSave() {}
46 void Database_LevelDB::saveBlock(MapBlock *block)
48 DSTACK(__FUNCTION_NAME);
50 Dummy blocks are not written
57 // Format used for writing
58 u8 version = SER_FMT_VER_HIGHEST;
60 v3s16 p3d = block->getPos();
63 [0] u8 serialization version
67 std::ostringstream o(std::ios_base::binary);
68 o.write((char*)&version, 1);
70 block->serialize(o, version, true);
71 // Write block to database
72 std::string tmp = o.str();
74 m_database->Put(leveldb::WriteOptions(), i64tos(getBlockAsInteger(p3d)), tmp);
76 // We just wrote it to the disk so clear modified flag
77 block->resetModified();
80 MapBlock* Database_LevelDB::loadBlock(v3s16 blockpos)
82 v2s16 p2d(blockpos.X, blockpos.Z);
85 leveldb::Status s = m_database->Get(leveldb::ReadOptions(), i64tos(getBlockAsInteger(blockpos)), &datastr);
89 Make sure sector is loaded
91 MapSector *sector = srvmap->createSector(p2d);
94 std::istringstream is(datastr, std::ios_base::binary);
95 u8 version = SER_FMT_VER_INVALID;
96 is.read((char*)&version, 1);
99 throw SerializationError("ServerMap::loadBlock(): Failed"
100 " to read MapBlock version");
102 MapBlock *block = NULL;
103 bool created_new = false;
104 block = sector->getBlockNoCreateNoEx(blockpos.Y);
107 block = sector->createBlankBlockNoInsert(blockpos.Y);
111 block->deSerialize(is, version, true);
112 // If it's a new block, insert it to the map
114 sector->insertBlock(block);
116 Save blocks loaded in old format in new format
119 //if(version < SER_FMT_VER_HIGHEST || save_after_load)
120 // Only save if asked to; no need to update version
121 //if(save_after_load)
123 // We just loaded it from, so it's up-to-date.
124 block->resetModified();
127 catch(SerializationError &e)
129 errorstream<<"Invalid block data in database"
130 <<" ("<<blockpos.X<<","<<blockpos.Y<<","<<blockpos.Z<<")"
131 <<" (SerializationError): "<<e.what()<<std::endl;
132 // TODO: Block should be marked as invalid in memory so that it is
133 // not touched but the game can run
135 if(g_settings->getBool("ignore_world_load_errors")){
136 errorstream<<"Ignoring block load error. Duck and cover! "
137 <<"(ignore_world_load_errors)"<<std::endl;
139 throw SerializationError("Invalid block data in database");
144 return srvmap->getBlockNoCreateNoEx(blockpos); // should not be using this here
149 void Database_LevelDB::listAllLoadableBlocks(core::list<v3s16> &dst)
151 leveldb::Iterator* it = m_database->NewIterator(leveldb::ReadOptions());
152 for (it->SeekToFirst(); it->Valid(); it->Next()) {
153 dst.push_back(getIntegerAsBlock(stoi64(it->key().ToString())));
155 assert(it->status().ok()); // Check for any errors found during the scan
159 Database_LevelDB::~Database_LevelDB()