9ca0e732809d6766bedcb604720142e62811ee9c
[oweals/minetest.git] / src / database-dummy.cpp
1 /*
2 Dummy "database" class
3 */
4
5
6 #include "map.h"
7 #include "mapsector.h"
8 #include "mapblock.h"
9 #include "main.h"
10 #include "filesys.h"
11 #include "voxel.h"
12 #include "porting.h"
13 #include "mapgen.h"
14 #include "nodemetadata.h"
15 #include "settings.h"
16 #include "log.h"
17 #include "profiler.h"
18 #include "nodedef.h"
19 #include "gamedef.h"
20 #include "util/directiontables.h"
21 #include "rollback_interface.h"
22
23 #include "database-dummy.h"
24
25 Database_Dummy::Database_Dummy(ServerMap *map)
26 {
27         srvmap = map;
28 }
29
30 int Database_Dummy::Initialized(void)
31 {
32         return 1;
33 }
34
35 void Database_Dummy::beginSave() {}
36 void Database_Dummy::endSave() {}
37
38 void Database_Dummy::saveBlock(MapBlock *block)
39 {
40         DSTACK(__FUNCTION_NAME);
41         /*
42                 Dummy blocks are not written
43         */
44         if(block->isDummy())
45         {
46                 return;
47         }
48
49         // Format used for writing
50         u8 version = SER_FMT_VER_HIGHEST_WRITE;
51         // Get destination
52         v3s16 p3d = block->getPos();
53
54         /*
55                 [0] u8 serialization version
56                 [1] data
57         */
58
59         std::ostringstream o(std::ios_base::binary);
60         o.write((char*)&version, 1);
61         // Write basic data
62         block->serialize(o, version, true);
63         // Write block to database
64         std::string tmp = o.str();
65
66         m_database[getBlockAsInteger(p3d)] = tmp;
67         // We just wrote it to the disk so clear modified flag
68         block->resetModified();
69 }
70
71 MapBlock* Database_Dummy::loadBlock(v3s16 blockpos)
72 {
73         v2s16 p2d(blockpos.X, blockpos.Z);
74
75         if(m_database.count(getBlockAsInteger(blockpos))) {
76                 /*
77                         Make sure sector is loaded
78                 */
79                 MapSector *sector = srvmap->createSector(p2d);
80                 /*
81                         Load block
82                 */
83                 std::string datastr = m_database[getBlockAsInteger(blockpos)];
84 //                srvmap->loadBlock(&datastr, blockpos, sector, false);
85
86                 try {
87                         std::istringstream is(datastr, std::ios_base::binary);
88                         u8 version = SER_FMT_VER_INVALID;
89                         is.read((char*)&version, 1);
90
91                         if(is.fail())
92                                 throw SerializationError("ServerMap::loadBlock(): Failed"
93                                                      " to read MapBlock version");
94
95                         MapBlock *block = NULL;
96                         bool created_new = false;
97                         block = sector->getBlockNoCreateNoEx(blockpos.Y);
98                         if(block == NULL)
99                         {
100                                 block = sector->createBlankBlockNoInsert(blockpos.Y);
101                                 created_new = true;
102                         }
103                         // Read basic data
104                         block->deSerialize(is, version, true);
105                         // If it's a new block, insert it to the map
106                         if(created_new)
107                                 sector->insertBlock(block);
108                         /*
109                                 Save blocks loaded in old format in new format
110                         */
111
112                         //if(version < SER_FMT_VER_HIGHEST || save_after_load)
113                         // Only save if asked to; no need to update version
114                         //if(save_after_load)
115                         //      saveBlock(block);
116                         // We just loaded it from, so it's up-to-date.
117                         block->resetModified();
118
119                 }
120                 catch(SerializationError &e)
121                 {
122                         errorstream<<"Invalid block data in database"
123                                      <<" ("<<blockpos.X<<","<<blockpos.Y<<","<<blockpos.Z<<")"
124                                      <<" (SerializationError): "<<e.what()<<std::endl;
125                      // TODO: Block should be marked as invalid in memory so that it is
126                      // not touched but the game can run
127
128                         if(g_settings->getBool("ignore_world_load_errors")){
129                              errorstream<<"Ignoring block load error. Duck and cover! "
130                                              <<"(ignore_world_load_errors)"<<std::endl;
131                         } else {
132                              throw SerializationError("Invalid block data in database");
133                              //assert(0);
134                         }
135                 }
136
137                 return srvmap->getBlockNoCreateNoEx(blockpos);  // should not be using this here
138         }
139         return(NULL);
140 }
141
142 void Database_Dummy::listAllLoadableBlocks(std::list<v3s16> &dst)
143 {
144         for(std::map<unsigned long long, std::string>::iterator x = m_database.begin(); x != m_database.end(); ++x)
145         {
146                 v3s16 p = getIntegerAsBlock(x->first);
147                 //dstream<<"block_i="<<block_i<<" p="<<PP(p)<<std::endl;
148                 dst.push_back(p);
149         }
150 }
151
152 Database_Dummy::~Database_Dummy()
153 {
154         m_database.clear();
155 }