mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 10:03:45 +01:00
Initial sqlite3 maps.
* The map will reside in world/map.sqlite * It will load from the sectors folder but will not save there
This commit is contained in:
parent
e3c58eff1c
commit
d1a16f24cf
251
src/map.cpp
251
src/map.cpp
@ -29,12 +29,21 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "mapgen.h"
|
#include "mapgen.h"
|
||||||
#include "nodemetadata.h"
|
#include "nodemetadata.h"
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include "sqlite3.h"
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
SQLite format specification:
|
SQLite format specification:
|
||||||
- Initially only replaces sectors/ and sectors2/
|
- 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
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1408,6 +1417,8 @@ void Map::timerUpdate(float dtime, float unload_timeout,
|
|||||||
|
|
||||||
core::list<MapBlock*> blocks;
|
core::list<MapBlock*> blocks;
|
||||||
sector->getBlocks(blocks);
|
sector->getBlocks(blocks);
|
||||||
|
|
||||||
|
beginSave();
|
||||||
for(core::list<MapBlock*>::Iterator i = blocks.begin();
|
for(core::list<MapBlock*>::Iterator i = blocks.begin();
|
||||||
i != blocks.end(); i++)
|
i != blocks.end(); i++)
|
||||||
{
|
{
|
||||||
@ -1440,6 +1451,7 @@ void Map::timerUpdate(float dtime, float unload_timeout,
|
|||||||
all_blocks_deleted = false;
|
all_blocks_deleted = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
endSave();
|
||||||
|
|
||||||
if(all_blocks_deleted)
|
if(all_blocks_deleted)
|
||||||
{
|
{
|
||||||
@ -1873,7 +1885,10 @@ void Map::nodeMetadataStep(float dtime,
|
|||||||
ServerMap::ServerMap(std::string savedir):
|
ServerMap::ServerMap(std::string savedir):
|
||||||
Map(dout_server),
|
Map(dout_server),
|
||||||
m_seed(0),
|
m_seed(0),
|
||||||
m_map_metadata_changed(true)
|
m_map_metadata_changed(true),
|
||||||
|
m_database(NULL),
|
||||||
|
m_database_read(NULL),
|
||||||
|
m_database_write(NULL)
|
||||||
{
|
{
|
||||||
dstream<<__FUNCTION_NAME<<std::endl;
|
dstream<<__FUNCTION_NAME<<std::endl;
|
||||||
|
|
||||||
@ -1994,6 +2009,16 @@ ServerMap::~ServerMap()
|
|||||||
<<", exception: "<<e.what()<<std::endl;
|
<<", exception: "<<e.what()<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Close database if it was opened
|
||||||
|
*/
|
||||||
|
if(m_database_read)
|
||||||
|
sqlite3_finalize(m_database_read);
|
||||||
|
if(m_database_write)
|
||||||
|
sqlite3_finalize(m_database_write);
|
||||||
|
if(m_database)
|
||||||
|
sqlite3_close(m_database);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/*
|
/*
|
||||||
Free all MapChunks
|
Free all MapChunks
|
||||||
@ -2307,6 +2332,7 @@ ServerMapSector * ServerMap::createSector(v2s16 p2d)
|
|||||||
/*
|
/*
|
||||||
Try to load metadata from disk
|
Try to load metadata from disk
|
||||||
*/
|
*/
|
||||||
|
#if 0
|
||||||
if(loadSectorMeta(p2d) == true)
|
if(loadSectorMeta(p2d) == true)
|
||||||
{
|
{
|
||||||
ServerMapSector *sector = (ServerMapSector*)getSectorNoGenerateNoEx(p2d);
|
ServerMapSector *sector = (ServerMapSector*)getSectorNoGenerateNoEx(p2d);
|
||||||
@ -2317,7 +2343,7 @@ ServerMapSector * ServerMap::createSector(v2s16 p2d)
|
|||||||
}
|
}
|
||||||
return sector;
|
return sector;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
Do not create over-limit
|
Do not create over-limit
|
||||||
*/
|
*/
|
||||||
@ -2759,6 +2785,74 @@ plan_b:
|
|||||||
//return (s16)level;
|
//return (s16)level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServerMap::createDatabase() {
|
||||||
|
int e;
|
||||||
|
assert(m_database);
|
||||||
|
e = sqlite3_exec(m_database,
|
||||||
|
"CREATE TABLE IF NOT EXISTS `blocks` ("
|
||||||
|
"`pos` INT NOT NULL PRIMARY KEY,"
|
||||||
|
"`data` BLOB"
|
||||||
|
");"
|
||||||
|
, NULL, NULL, NULL);
|
||||||
|
if(e == SQLITE_ABORT)
|
||||||
|
throw FileNotGoodException("Could not create database structure");
|
||||||
|
else
|
||||||
|
dstream<<"Server: Database structure was created";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerMap::verifyDatabase() {
|
||||||
|
if(m_database)
|
||||||
|
return;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::string dbp = m_savedir + "/map.sqlite";
|
||||||
|
bool needs_create = false;
|
||||||
|
int d;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Open the database connection
|
||||||
|
*/
|
||||||
|
|
||||||
|
createDirs(m_savedir);
|
||||||
|
|
||||||
|
if(!fs::PathExists(dbp))
|
||||||
|
needs_create = true;
|
||||||
|
|
||||||
|
d = sqlite3_open_v2(dbp.c_str(), &m_database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
|
||||||
|
if(d != SQLITE_OK) {
|
||||||
|
dstream<<"WARNING: Database failed to open: "<<sqlite3_errmsg(m_database)<<std::endl;
|
||||||
|
throw FileNotGoodException("Cannot open database file");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(needs_create)
|
||||||
|
createDatabase();
|
||||||
|
|
||||||
|
d = sqlite3_prepare(m_database, "SELECT `data` FROM `blocks` WHERE `pos`=? LIMIT 1", -1, &m_database_read, NULL);
|
||||||
|
if(d != SQLITE_OK) {
|
||||||
|
dstream<<"WARNING: Database read statment failed to prepare: "<<sqlite3_errmsg(m_database)<<std::endl;
|
||||||
|
throw FileNotGoodException("Cannot prepare read statement");
|
||||||
|
}
|
||||||
|
|
||||||
|
d = sqlite3_prepare(m_database, "REPLACE INTO `blocks` VALUES(?, ?)", -1, &m_database_write, NULL);
|
||||||
|
if(d != SQLITE_OK) {
|
||||||
|
dstream<<"WARNING: Database write statment failed to prepare: "<<sqlite3_errmsg(m_database)<<std::endl;
|
||||||
|
throw FileNotGoodException("Cannot prepare write statement");
|
||||||
|
}
|
||||||
|
|
||||||
|
dstream<<"Server: Database opened"<<std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ServerMap::loadFromFolders() {
|
||||||
|
if(!m_database && !fs::PathExists(m_savedir + "/map.sqlite"))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerMap::getBlockAsInteger(const v3s16 pos) {
|
||||||
|
return (pos.Z+2048)*16777216 + (pos.Y+2048)*4096 + pos.X;
|
||||||
|
}
|
||||||
|
|
||||||
void ServerMap::createDirs(std::string path)
|
void ServerMap::createDirs(std::string path)
|
||||||
{
|
{
|
||||||
if(fs::CreateAllDirs(path) == false)
|
if(fs::CreateAllDirs(path) == false)
|
||||||
@ -2862,6 +2956,7 @@ void ServerMap::save(bool only_changed)
|
|||||||
u32 block_count = 0;
|
u32 block_count = 0;
|
||||||
u32 block_count_all = 0; // Number of blocks in memory
|
u32 block_count_all = 0; // Number of blocks in memory
|
||||||
|
|
||||||
|
beginSave();
|
||||||
core::map<v2s16, MapSector*>::Iterator i = m_sectors.getIterator();
|
core::map<v2s16, MapSector*>::Iterator i = m_sectors.getIterator();
|
||||||
for(; i.atEnd() == false; i++)
|
for(; i.atEnd() == false; i++)
|
||||||
{
|
{
|
||||||
@ -2876,6 +2971,8 @@ void ServerMap::save(bool only_changed)
|
|||||||
core::list<MapBlock*> blocks;
|
core::list<MapBlock*> blocks;
|
||||||
sector->getBlocks(blocks);
|
sector->getBlocks(blocks);
|
||||||
core::list<MapBlock*>::Iterator j;
|
core::list<MapBlock*>::Iterator j;
|
||||||
|
|
||||||
|
//sqlite3_exec(m_database, "BEGIN;", NULL, NULL, NULL);
|
||||||
for(j=blocks.begin(); j!=blocks.end(); j++)
|
for(j=blocks.begin(); j!=blocks.end(); j++)
|
||||||
{
|
{
|
||||||
MapBlock *block = *j;
|
MapBlock *block = *j;
|
||||||
@ -2894,8 +2991,10 @@ void ServerMap::save(bool only_changed)
|
|||||||
<<block->getPos().Z<<")"
|
<<block->getPos().Z<<")"
|
||||||
<<std::endl;*/
|
<<std::endl;*/
|
||||||
}
|
}
|
||||||
|
//sqlite3_exec(m_database, "COMMIT;", NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
endSave();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Only print if something happened or saved whole map
|
Only print if something happened or saved whole map
|
||||||
@ -3154,6 +3253,18 @@ bool ServerMap::loadSectorFull(v2s16 p2d)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void ServerMap::beginSave() {
|
||||||
|
verifyDatabase();
|
||||||
|
if(sqlite3_exec(m_database, "BEGIN;", NULL, NULL, NULL) != SQLITE_OK)
|
||||||
|
dstream<<"WARNING: beginSave() failed, saving might be slow.";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerMap::endSave() {
|
||||||
|
verifyDatabase();
|
||||||
|
if(sqlite3_exec(m_database, "COMMIT;", NULL, NULL, NULL) != SQLITE_OK)
|
||||||
|
dstream<<"WARNING: endSave() failed, map might not have saved.";
|
||||||
|
}
|
||||||
|
|
||||||
void ServerMap::saveBlock(MapBlock *block)
|
void ServerMap::saveBlock(MapBlock *block)
|
||||||
{
|
{
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
@ -3173,6 +3284,8 @@ void ServerMap::saveBlock(MapBlock *block)
|
|||||||
// Get destination
|
// Get destination
|
||||||
v3s16 p3d = block->getPos();
|
v3s16 p3d = block->getPos();
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
v2s16 p2d(p3d.X, p3d.Z);
|
v2s16 p2d(p3d.X, p3d.Z);
|
||||||
std::string sectordir = getSectorDir(p2d);
|
std::string sectordir = getSectorDir(p2d);
|
||||||
|
|
||||||
@ -3182,11 +3295,16 @@ void ServerMap::saveBlock(MapBlock *block)
|
|||||||
std::ofstream o(fullpath.c_str(), std::ios_base::binary);
|
std::ofstream o(fullpath.c_str(), std::ios_base::binary);
|
||||||
if(o.good() == false)
|
if(o.good() == false)
|
||||||
throw FileNotGoodException("Cannot open block data");
|
throw FileNotGoodException("Cannot open block data");
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
[0] u8 serialization version
|
[0] u8 serialization version
|
||||||
[1] data
|
[1] data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
verifyDatabase();
|
||||||
|
|
||||||
|
std::ostringstream o(std::ios_base::binary);
|
||||||
|
|
||||||
o.write((char*)&version, 1);
|
o.write((char*)&version, 1);
|
||||||
|
|
||||||
// Write basic data
|
// Write basic data
|
||||||
@ -3194,7 +3312,23 @@ void ServerMap::saveBlock(MapBlock *block)
|
|||||||
|
|
||||||
// Write extra data stored on disk
|
// Write extra data stored on disk
|
||||||
block->serializeDiskExtra(o, version);
|
block->serializeDiskExtra(o, version);
|
||||||
|
|
||||||
|
// Write block to database
|
||||||
|
|
||||||
|
std::string tmp = o.str();
|
||||||
|
const char *bytes = tmp.c_str();
|
||||||
|
|
||||||
|
if(sqlite3_bind_int(m_database_write, 1, getBlockAsInteger(p3d)) != SQLITE_OK)
|
||||||
|
dstream<<"WARNING: Block position failed to bind: "<<sqlite3_errmsg(m_database)<<std::endl;
|
||||||
|
if(sqlite3_bind_blob(m_database_write, 2, (void *)bytes, o.tellp(), NULL) != SQLITE_OK) // TODO this mught not be the right length
|
||||||
|
dstream<<"WARNING: Block data failed to bind: "<<sqlite3_errmsg(m_database)<<std::endl;
|
||||||
|
int written = sqlite3_step(m_database_write);
|
||||||
|
if(written != SQLITE_DONE)
|
||||||
|
dstream<<"WARNING: Block failed to save ("<<p3d.X<<", "<<p3d.Y<<", "<<p3d.Z<<") "
|
||||||
|
<<sqlite3_errmsg(m_database)<<std::endl;
|
||||||
|
// Make ready for later reuse
|
||||||
|
sqlite3_reset(m_database_write);
|
||||||
|
|
||||||
// We just wrote it to the disk so clear modified flag
|
// We just wrote it to the disk so clear modified flag
|
||||||
block->resetModified();
|
block->resetModified();
|
||||||
}
|
}
|
||||||
@ -3275,12 +3409,111 @@ void ServerMap::loadBlock(std::string sectordir, std::string blockfile, MapSecto
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServerMap::loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool save_after_load)
|
||||||
|
{
|
||||||
|
DSTACK(__FUNCTION_NAME);
|
||||||
|
|
||||||
|
try {
|
||||||
|
std::istringstream is(*blob, std::ios_base::binary);
|
||||||
|
|
||||||
|
u8 version = SER_FMT_VER_INVALID;
|
||||||
|
is.read((char*)&version, 1);
|
||||||
|
|
||||||
|
if(is.fail())
|
||||||
|
throw SerializationError("ServerMap::loadBlock(): Failed"
|
||||||
|
" to read MapBlock version");
|
||||||
|
|
||||||
|
/*u32 block_size = MapBlock::serializedLength(version);
|
||||||
|
SharedBuffer<u8> data(block_size);
|
||||||
|
is.read((char*)*data, block_size);*/
|
||||||
|
|
||||||
|
// This will always return a sector because we're the server
|
||||||
|
//MapSector *sector = emergeSector(p2d);
|
||||||
|
|
||||||
|
MapBlock *block = NULL;
|
||||||
|
bool created_new = false;
|
||||||
|
block = sector->getBlockNoCreateNoEx(p3d.Y);
|
||||||
|
if(block == NULL)
|
||||||
|
{
|
||||||
|
block = sector->createBlankBlockNoInsert(p3d.Y);
|
||||||
|
created_new = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read basic data
|
||||||
|
block->deSerialize(is, version);
|
||||||
|
|
||||||
|
// Read extra data stored on disk
|
||||||
|
block->deSerializeDiskExtra(is, version);
|
||||||
|
|
||||||
|
// If it's a new block, insert it to the map
|
||||||
|
if(created_new)
|
||||||
|
sector->insertBlock(block);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Save blocks loaded in old format in new format
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(version < SER_FMT_VER_HIGHEST || save_after_load)
|
||||||
|
{
|
||||||
|
saveBlock(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We just loaded it from, so it's up-to-date.
|
||||||
|
block->resetModified();
|
||||||
|
|
||||||
|
}
|
||||||
|
catch(SerializationError &e)
|
||||||
|
{
|
||||||
|
dstream<<"WARNING: Invalid block data in database "
|
||||||
|
<<" (SerializationError). "
|
||||||
|
<<"what()="<<e.what()
|
||||||
|
<<std::endl;
|
||||||
|
//" Ignoring. A new one will be generated.
|
||||||
|
assert(0);
|
||||||
|
|
||||||
|
// TODO: Copy to a backup database.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MapBlock* ServerMap::loadBlock(v3s16 blockpos)
|
MapBlock* ServerMap::loadBlock(v3s16 blockpos)
|
||||||
{
|
{
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
|
|
||||||
v2s16 p2d(blockpos.X, blockpos.Z);
|
v2s16 p2d(blockpos.X, blockpos.Z);
|
||||||
|
|
||||||
|
if(!loadFromFolders()) {
|
||||||
|
verifyDatabase();
|
||||||
|
|
||||||
|
if(sqlite3_bind_int(m_database_read, 1, getBlockAsInteger(blockpos)) != SQLITE_OK)
|
||||||
|
dstream<<"WARNING: Could not bind block position for load: "
|
||||||
|
<<sqlite3_errmsg(m_database)<<std::endl;
|
||||||
|
if(sqlite3_step(m_database_read) == SQLITE_ROW) {
|
||||||
|
/*
|
||||||
|
Make sure sector is loaded
|
||||||
|
*/
|
||||||
|
MapSector *sector = createSector(p2d);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Load block
|
||||||
|
*/
|
||||||
|
const char * data = (const char *)sqlite3_column_blob(m_database_read, 0);
|
||||||
|
size_t len = sqlite3_column_bytes(m_database_read, 0);
|
||||||
|
|
||||||
|
std::string datastr(data, len);
|
||||||
|
|
||||||
|
loadBlock(&datastr, blockpos, sector, false);
|
||||||
|
|
||||||
|
sqlite3_step(m_database_read);
|
||||||
|
// We should never get more than 1 row, so ok to reset
|
||||||
|
sqlite3_reset(m_database_read);
|
||||||
|
|
||||||
|
return getBlockNoCreateNoEx(blockpos);
|
||||||
|
}
|
||||||
|
sqlite3_reset(m_database_read);
|
||||||
|
|
||||||
|
// Not found in database, try the files
|
||||||
|
}
|
||||||
|
|
||||||
// The directory layout we're going to load from.
|
// The directory layout we're going to load from.
|
||||||
// 1 - original sectors/xxxxzzzz/
|
// 1 - original sectors/xxxxzzzz/
|
||||||
// 2 - new sectors2/xxx/zzz/
|
// 2 - new sectors2/xxx/zzz/
|
||||||
@ -3331,9 +3564,9 @@ MapBlock* ServerMap::loadBlock(v3s16 blockpos)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Load block
|
Load block and save it to the database
|
||||||
*/
|
*/
|
||||||
loadBlock(sectordir, blockfilename, sector, loadlayout != 2);
|
loadBlock(sectordir, blockfilename, sector, true);
|
||||||
return getBlockNoCreateNoEx(blockpos);
|
return getBlockNoCreateNoEx(blockpos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
35
src/map.h
35
src/map.h
@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include <jmutexautolock.h>
|
#include <jmutexautolock.h>
|
||||||
#include <jthread.h>
|
#include <jthread.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "common_irrlicht.h"
|
#include "common_irrlicht.h"
|
||||||
#include "mapnode.h"
|
#include "mapnode.h"
|
||||||
@ -31,6 +32,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "voxel.h"
|
#include "voxel.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "sqlite3.h"
|
||||||
|
}
|
||||||
|
|
||||||
class MapSector;
|
class MapSector;
|
||||||
class ServerMapSector;
|
class ServerMapSector;
|
||||||
class ClientMapSector;
|
class ClientMapSector;
|
||||||
@ -220,6 +225,10 @@ public:
|
|||||||
//core::aabbox3d<s16> getDisplayedBlockArea();
|
//core::aabbox3d<s16> getDisplayedBlockArea();
|
||||||
|
|
||||||
//bool updateChangedVisibleArea();
|
//bool updateChangedVisibleArea();
|
||||||
|
|
||||||
|
// Call these before and after saving of many blocks
|
||||||
|
virtual void beginSave() {return;};
|
||||||
|
virtual void endSave() {return;};
|
||||||
|
|
||||||
virtual void save(bool only_changed){assert(0);};
|
virtual void save(bool only_changed){assert(0);};
|
||||||
|
|
||||||
@ -361,6 +370,23 @@ public:
|
|||||||
v3s16 getBlockPos(std::string sectordir, std::string blockfile);
|
v3s16 getBlockPos(std::string sectordir, std::string blockfile);
|
||||||
static std::string getBlockFilename(v3s16 p);
|
static std::string getBlockFilename(v3s16 p);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Database functions
|
||||||
|
*/
|
||||||
|
// Create the database structure
|
||||||
|
void createDatabase();
|
||||||
|
// Verify we can read/write to the database
|
||||||
|
void verifyDatabase();
|
||||||
|
// Get an integer suitable for a block
|
||||||
|
static int getBlockAsInteger(const v3s16 pos);
|
||||||
|
|
||||||
|
// Returns true if the database file does not exist
|
||||||
|
bool loadFromFolders();
|
||||||
|
|
||||||
|
// Call these before and after saving of blocks
|
||||||
|
void beginSave();
|
||||||
|
void endSave();
|
||||||
|
|
||||||
void save(bool only_changed);
|
void save(bool only_changed);
|
||||||
//void loadAll();
|
//void loadAll();
|
||||||
|
|
||||||
@ -391,6 +417,8 @@ public:
|
|||||||
// This will generate a sector with getSector if not found.
|
// This will generate a sector with getSector if not found.
|
||||||
void loadBlock(std::string sectordir, std::string blockfile, MapSector *sector, bool save_after_load=false);
|
void loadBlock(std::string sectordir, std::string blockfile, MapSector *sector, bool save_after_load=false);
|
||||||
MapBlock* loadBlock(v3s16 p);
|
MapBlock* loadBlock(v3s16 p);
|
||||||
|
// Database version
|
||||||
|
void loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool save_after_load=false);
|
||||||
|
|
||||||
// For debug printing
|
// For debug printing
|
||||||
virtual void PrintInfo(std::ostream &out);
|
virtual void PrintInfo(std::ostream &out);
|
||||||
@ -419,6 +447,13 @@ private:
|
|||||||
This is reset to false when written on disk.
|
This is reset to false when written on disk.
|
||||||
*/
|
*/
|
||||||
bool m_map_metadata_changed;
|
bool m_map_metadata_changed;
|
||||||
|
|
||||||
|
/*
|
||||||
|
SQLite database and statements
|
||||||
|
*/
|
||||||
|
sqlite3 *m_database;
|
||||||
|
sqlite3_stmt *m_database_read;
|
||||||
|
sqlite3_stmt *m_database_write;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user