diff options
Diffstat (limited to 'src/emerge.cpp')
-rw-r--r-- | src/emerge.cpp | 145 |
1 files changed, 91 insertions, 54 deletions
diff --git a/src/emerge.cpp b/src/emerge.cpp index e66e9520b..94b6464f6 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -56,10 +56,10 @@ public: Mapgen *mapgen; bool enable_mapgen_debug_info; int id; - + Event qevent; std::queue<v3s16> blockqueue; - + EmergeThread(Server *server, int ethreadid): SimpleThread(), m_server(server), @@ -100,14 +100,14 @@ EmergeManager::EmergeManager(IGameDef *gamedef) { this->ndef = gamedef->getNodeDefManager(); this->biomedef = new BiomeDefManager(); this->params = NULL; - + this->luaoverride_params = NULL; this->luaoverride_params_modified = 0; this->luaoverride_flagmask = 0; - + mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info"); - + int nthreads; if (g_settings->get("num_emerge_threads").empty()) { int nprocs = porting::getNumberOfProcessors(); @@ -118,7 +118,7 @@ EmergeManager::EmergeManager(IGameDef *gamedef) { } if (nthreads < 1) nthreads = 1; - + qlimit_total = g_settings->getU16("emergequeue_limit_total"); qlimit_diskonly = g_settings->get("emergequeue_limit_diskonly").empty() ? nthreads * 5 + 1 : @@ -126,10 +126,10 @@ EmergeManager::EmergeManager(IGameDef *gamedef) { qlimit_generate = g_settings->get("emergequeue_limit_generate").empty() ? nthreads + 1 : g_settings->getU16("emergequeue_limit_generate"); - + for (int i = 0; i != nthreads; i++) emergethread.push_back(new EmergeThread((Server *)gamedef, i)); - + infostream << "EmergeManager: using " << nthreads << " threads" << std::endl; } @@ -152,7 +152,7 @@ EmergeManager::~EmergeManager() { for (unsigned int i = 0; i < decorations.size(); i++) delete decorations[i]; decorations.clear(); - + for (std::map<std::string, MapgenFactory *>::iterator iter = mglist.begin(); iter != mglist.end(); iter ++) { delete iter->second; @@ -165,61 +165,97 @@ EmergeManager::~EmergeManager() { void EmergeManager::initMapgens(MapgenParams *mgparams) { Mapgen *mg; - + if (mapgen.size()) return; - + // Resolve names of nodes for things that were registered // (at this point, the registration period is over) biomedef->resolveNodeNames(ndef); - + for (size_t i = 0; i != ores.size(); i++) ores[i]->resolveNodeNames(ndef); - + for (size_t i = 0; i != decorations.size(); i++) decorations[i]->resolveNodeNames(ndef); - + // Apply mapgen parameter overrides from Lua if (luaoverride_params) { - if (luaoverride_params_modified & MGPARAMS_SET_MGNAME) - mgparams->mg_name = luaoverride_params->mg_name; - + if (luaoverride_params_modified & MGPARAMS_SET_MGNAME) { + MapgenParams *mgp = setMapgenType(mgparams, luaoverride_params->mg_name); + if (!mgp) { + errorstream << "EmergeManager: Failed to set new mapgen name" + << std::endl; + } else { + mgparams = mgp; + } + } + if (luaoverride_params_modified & MGPARAMS_SET_SEED) mgparams->seed = luaoverride_params->seed; - + if (luaoverride_params_modified & MGPARAMS_SET_WATER_LEVEL) mgparams->water_level = luaoverride_params->water_level; - + if (luaoverride_params_modified & MGPARAMS_SET_FLAGS) { mgparams->flags &= ~luaoverride_flagmask; mgparams->flags |= luaoverride_params->flags; } - + delete luaoverride_params; luaoverride_params = NULL; } - + // Create the mapgens this->params = mgparams; for (size_t i = 0; i != emergethread.size(); i++) { - mg = createMapgen(params->mg_name, 0, params); + mg = createMapgen(params->mg_name, i, params); if (!mg) { - infostream << "EmergeManager: falling back to mapgen v6" << std::endl; - delete params; - params = createMapgenParams("v6"); - mg = createMapgen("v6", 0, params); + infostream << "EmergeManager: Falling back to Mapgen V6" << std::endl; + + params = setMapgenType(params, "v6"); + mg = createMapgen(params->mg_name, i, params); + if (!mg) { + errorstream << "EmergeManager: CRITICAL ERROR: Failed to fall" + "back to Mapgen V6, not generating map" << std::endl; + } } mapgen.push_back(mg); } } +MapgenParams *EmergeManager::setMapgenType(MapgenParams *mgparams, + std::string newname) { + MapgenParams *newparams = createMapgenParams(newname); + if (!newparams) { + errorstream << "EmergeManager: Mapgen override failed" << std::endl; + return NULL; + } + + newparams->mg_name = newname; + newparams->seed = mgparams->seed; + newparams->water_level = mgparams->water_level; + newparams->chunksize = mgparams->chunksize; + newparams->flags = mgparams->flags; + + if (!newparams->readParams(g_settings)) { + errorstream << "EmergeManager: Mapgen override failed" << std::endl; + delete newparams; + return NULL; + } + + delete mgparams; + return newparams; +} + + Mapgen *EmergeManager::getCurrentMapgen() { for (unsigned int i = 0; i != emergethread.size(); i++) { if (emergethread[i]->IsSameThread()) return emergethread[i]->mapgen; } - + return NULL; } @@ -229,19 +265,20 @@ void EmergeManager::triggerAllThreads() { emergethread[i]->trigger(); } + bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate) { std::map<v3s16, BlockEmergeData *>::const_iterator iter; BlockEmergeData *bedata; u16 count; u8 flags = 0; int idx = 0; - + if (allow_generate) flags |= BLOCK_EMERGE_ALLOWGEN; { JMutexAutoLock queuelock(queuemutex); - + count = blocks_enqueued.size(); if (count >= qlimit_total) return false; @@ -250,7 +287,7 @@ bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate u16 qlimit_peer = allow_generate ? qlimit_generate : qlimit_diskonly; if (count >= qlimit_peer) return false; - + iter = blocks_enqueued.find(p); if (iter != blocks_enqueued.end()) { bedata = iter->second; @@ -262,9 +299,9 @@ bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate bedata->flags = flags; bedata->peer_requested = peer_id; blocks_enqueued.insert(std::make_pair(p, bedata)); - + peer_queue_count[peer_id] = count + 1; - + // insert into the EmergeThread queue with the least items int lowestitems = emergethread[0]->blockqueue.size(); for (unsigned int i = 1; i != emergethread.size(); i++) { @@ -274,11 +311,11 @@ bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate lowestitems = nitems; } } - + emergethread[idx]->blockqueue.push(p); } emergethread[idx]->qevent.signal(); - + return true; } @@ -286,10 +323,10 @@ bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate int EmergeManager::getGroundLevelAtPoint(v2s16 p) { if (mapgen.size() == 0 || !mapgen[0]) { errorstream << "EmergeManager: getGroundLevelAtPoint() called" - " before mapgen initialized" << std::endl; + " before mapgen initialized" << std::endl; return 0; } - + return mapgen[0]->getGroundLevelAtPoint(p); } @@ -325,7 +362,7 @@ Mapgen *EmergeManager::createMapgen(std::string mgname, int mgid, " not registered" << std::endl; return NULL; } - + MapgenFactory *mgfactory = iter->second; return mgfactory->createMapgen(mgid, mgparams, this); } @@ -339,7 +376,7 @@ MapgenParams *EmergeManager::createMapgenParams(std::string mgname) { " not registered" << std::endl; return NULL; } - + MapgenFactory *mgfactory = iter->second; return mgfactory->createMapgenParams(); } @@ -350,10 +387,10 @@ MapgenParams *EmergeManager::getParamsFromSettings(Settings *settings) { MapgenParams *mgparams = createMapgenParams(mg_name); if (!mgparams) return NULL; - + std::string seedstr = settings->get(settings == g_settings ? "fixed_map_seed" : "seed"); - + mgparams->mg_name = mg_name; mgparams->seed = read_seed(seedstr.c_str()); mgparams->water_level = settings->getS16("water_level"); @@ -395,21 +432,21 @@ bool EmergeThread::popBlockEmerge(v3s16 *pos, u8 *flags) { return false; v3s16 p = blockqueue.front(); blockqueue.pop(); - + *pos = p; - + iter = emerge->blocks_enqueued.find(p); if (iter == emerge->blocks_enqueued.end()) return false; //uh oh, queue and map out of sync!! BlockEmergeData *bedata = iter->second; *flags = bedata->flags; - + emerge->peer_queue_count[bedata->peer_requested]--; delete bedata; emerge->blocks_enqueued.erase(iter); - + return true; } @@ -419,7 +456,7 @@ bool EmergeThread::getBlockOrStartGen(v3s16 p, MapBlock **b, v2s16 p2d(p.X, p.Z); //envlock: usually takes <=1ms, sometimes 90ms or ~400ms to acquire JMutexAutoLock envlock(m_server->m_env_mutex); - + // Load sector if it isn't loaded if (map->getSectorNoGenerateNoEx(p2d) == NULL) map->loadSectorMeta(p2d); @@ -440,7 +477,7 @@ bool EmergeThread::getBlockOrStartGen(v3s16 p, MapBlock **b, *b = block; return map->initBlockMake(data, p); } - + *b = block; return false; } @@ -455,12 +492,12 @@ void *EmergeThread::Thread() { v3s16 last_tried_pos(-32768,-32768,-32768); // For error output v3s16 p; u8 flags; - + map = (ServerMap *)&(m_server->m_env->getMap()); emerge = m_server->m_emerge; mapgen = emerge->mapgen[id]; enable_mapgen_debug_info = emerge->mapgen_debug_info; - + while (getRun()) try { if (!popBlockEmerge(&p, &flags)) { @@ -474,7 +511,7 @@ void *EmergeThread::Thread() { bool allow_generate = flags & BLOCK_EMERGE_ALLOWGEN; EMERGE_DBG_OUT("p=" PP(p) " allow_generate=" << allow_generate); - + /* Try to fetch block from memory or disk. If not found and asked to generate, initialize generator. @@ -482,8 +519,8 @@ void *EmergeThread::Thread() { BlockMakeData data; MapBlock *block = NULL; std::map<v3s16, MapBlock *> modified_blocks; - - if (getBlockOrStartGen(p, &block, &data, allow_generate)) { + + if (getBlockOrStartGen(p, &block, &data, allow_generate) && mapgen) { { ScopeProfiler sp(g_profiler, "EmergeThread: Mapgen::makeChunk", SPT_AVG); TimeTaker t("mapgen::make_block()"); @@ -501,7 +538,7 @@ void *EmergeThread::Thread() { "Mapgen::makeChunk (envlock)", SPT_AVG); map->finishBlockMake(&data, modified_blocks); - + block = map->getBlockNoCreateNoEx(p); if (block) { /* @@ -522,7 +559,7 @@ void *EmergeThread::Thread() { } EMERGE_DBG_OUT("ended up with: " << analyze_block(block)); - + m_server->m_env->activateBlock(block, 0); } } @@ -568,7 +605,7 @@ void *EmergeThread::Thread() { err << "You can ignore this using [ignore_world_load_errors = true]."<<std::endl; m_server->setAsyncFatalError(err.str()); } - + END_DEBUG_EXCEPTION_HANDLER(errorstream) log_deregister_thread(); return NULL; |