aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--minetest.conf.example5
-rw-r--r--src/defaultsettings.cpp1
-rw-r--r--src/map.cpp20
-rw-r--r--src/mapblock.cpp25
-rw-r--r--src/server.cpp23
5 files changed, 62 insertions, 12 deletions
diff --git a/minetest.conf.example b/minetest.conf.example
index 14e3f776c..7a8a2719c 100644
--- a/minetest.conf.example
+++ b/minetest.conf.example
@@ -178,4 +178,7 @@
# To reduce lag, block transfers are slowed down when a player is building something.
# This determines how long they are slowed down after placing or removing a node.
#full_block_send_enable_min_time_from_building = 2.0
-
+# Length of a server tick in dedicated server
+#dedicated_server_step = 0.05
+# Can be set to true to disable shutting down on invalid world data
+#ignore_world_load_errors = false
diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp
index ab6866cec..d0ed22c2d 100644
--- a/src/defaultsettings.cpp
+++ b/src/defaultsettings.cpp
@@ -137,5 +137,6 @@ void set_default_settings(Settings *settings)
settings->setDefault("server_map_save_interval", "5.3");
settings->setDefault("full_block_send_enable_min_time_from_building", "2.0");
settings->setDefault("dedicated_server_step", "0.05");
+ settings->setDefault("ignore_world_load_errors", "false");
}
diff --git a/src/map.cpp b/src/map.cpp
index 10dba3de9..647b9fe15 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -3378,14 +3378,20 @@ void ServerMap::loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool
}
catch(SerializationError &e)
{
- infostream<<"WARNING: Invalid block data in database "
- <<" (SerializationError). "
- <<"what()="<<e.what()
- <<std::endl;
- //" Ignoring. A new one will be generated.
- assert(0);
+ errorstream<<"Invalid block data in database"
+ <<" ("<<p3d.X<<","<<p3d.Y<<","<<p3d.Z<<")"
+ <<" (SerializationError): "<<e.what()<<std::endl;
+
+ // TODO: Block should be marked as invalid in memory so that it is
+ // not touched but the game can run
- // TODO: Copy to a backup database.
+ if(g_settings->getBool("ignore_world_load_errors")){
+ errorstream<<"Ignoring block load error. Duck and cover! "
+ <<"(ignore_world_load_errors)"<<std::endl;
+ } else {
+ throw SerializationError("Invalid block data in database");
+ //assert(0);
+ }
}
}
diff --git a/src/mapblock.cpp b/src/mapblock.cpp
index ed49f7b82..907be05eb 100644
--- a/src/mapblock.cpp
+++ b/src/mapblock.cpp
@@ -35,6 +35,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapblock_mesh.h"
#endif
+#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
+
/*
MapBlock
*/
@@ -634,6 +636,8 @@ void MapBlock::deSerialize(std::istream &is, u8 version, bool disk)
{
if(!ser_ver_supported(version))
throw VersionMismatchException("ERROR: MapBlock format not supported");
+
+ TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos())<<std::endl);
m_day_night_differs_expired = false;
@@ -652,6 +656,8 @@ void MapBlock::deSerialize(std::istream &is, u8 version, bool disk)
/*
Bulk node data
*/
+ TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos())
+ <<": Bulk node data"<<std::endl);
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
u8 content_width = readU8(is);
u8 params_width = readU8(is);
@@ -665,6 +671,8 @@ void MapBlock::deSerialize(std::istream &is, u8 version, bool disk)
/*
NodeMetadata
*/
+ TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos())
+ <<": Node metadata"<<std::endl);
// Ignore errors
try{
std::ostringstream oss(std::ios_base::binary);
@@ -680,7 +688,8 @@ void MapBlock::deSerialize(std::istream &is, u8 version, bool disk)
catch(SerializationError &e)
{
errorstream<<"WARNING: MapBlock::deSerialize(): Ignoring an error"
- <<" while deserializing node metadata: "<<e.what()<<std::endl;
+ <<" while deserializing node metadata at ("
+ <<PP(getPos())<<": "<<e.what()<<std::endl;
}
/*
@@ -689,21 +698,33 @@ void MapBlock::deSerialize(std::istream &is, u8 version, bool disk)
if(disk)
{
// Node timers
- if(version >= 23)
+ if(version >= 23){
+ TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos())
+ <<": Node timers"<<std::endl);
m_node_timers.deSerialize(is);
+ }
// Static objects
+ TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos())
+ <<": Static objects"<<std::endl);
m_static_objects.deSerialize(is);
// Timestamp
+ TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos())
+ <<": Timestamp"<<std::endl);
setTimestamp(readU32(is));
m_disk_timestamp = m_timestamp;
// Dynamically re-set ids based on node names
+ TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos())
+ <<": NameIdMapping"<<std::endl);
NameIdMapping nimap;
nimap.deSerialize(is);
correctBlockNodeIds(&nimap, data, m_gamedef);
}
+
+ TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos())
+ <<": Done."<<std::endl);
}
/*
diff --git a/src/server.cpp b/src/server.cpp
index fbeff83bf..f336fadc8 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -164,6 +164,8 @@ void * EmergeThread::Thread()
BEGIN_DEBUG_EXCEPTION_HANDLER
bool enable_mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info");
+
+ v3s16 last_tried_pos(-32768,-32768,-32768); // For error output
/*
Get block info from queue, emerge them and send them
@@ -181,6 +183,8 @@ void * EmergeThread::Thread()
v3s16 &p = q->pos;
v2s16 p2d(p.X,p.Z);
+
+ last_tried_pos = p;
/*
Do not generate over-limit
@@ -377,8 +381,23 @@ void * EmergeThread::Thread()
}
catch(VersionMismatchException &e)
{
- m_server->setAsyncFatalError(std::string(
- "World data version mismatch (server-side) (world probably saved by a newer version of Minetest): ")+e.what());
+ std::ostringstream err;
+ err<<"World data version mismatch in MapBlock "<<PP(last_tried_pos)<<std::endl;
+ err<<"----"<<std::endl;
+ err<<"\""<<e.what()<<"\""<<std::endl;
+ err<<"See debug.txt."<<std::endl;
+ err<<"World probably saved by a newer version of Minetest."<<std::endl;
+ m_server->setAsyncFatalError(err.str());
+ }
+ catch(SerializationError &e)
+ {
+ std::ostringstream err;
+ err<<"Invalid data in MapBlock "<<PP(last_tried_pos)<<std::endl;
+ err<<"----"<<std::endl;
+ err<<"\""<<e.what()<<"\""<<std::endl;
+ err<<"See debug.txt."<<std::endl;
+ err<<"You can ignore this using [ignore_world_load_errors = true]."<<std::endl;
+ m_server->setAsyncFatalError(err.str());
}
END_DEBUG_EXCEPTION_HANDLER(errorstream)