@@ -56,10 +56,10 @@ class EmergeThread : public SimpleThread
56
56
Mapgen *mapgen;
57
57
bool enable_mapgen_debug_info;
58
58
int id;
59
-
59
+
60
60
Event qevent;
61
61
std::queue<v3s16> blockqueue;
62
-
62
+
63
63
EmergeThread (Server *server, int ethreadid):
64
64
SimpleThread (),
65
65
m_server (server),
@@ -100,14 +100,14 @@ EmergeManager::EmergeManager(IGameDef *gamedef) {
100
100
this ->ndef = gamedef->getNodeDefManager ();
101
101
this ->biomedef = new BiomeDefManager ();
102
102
this ->params = NULL ;
103
-
103
+
104
104
this ->luaoverride_params = NULL ;
105
105
this ->luaoverride_params_modified = 0 ;
106
106
this ->luaoverride_flagmask = 0 ;
107
-
107
+
108
108
mapgen_debug_info = g_settings->getBool (" enable_mapgen_debug_info" );
109
109
110
-
110
+
111
111
int nthreads;
112
112
if (g_settings->get (" num_emerge_threads" ).empty ()) {
113
113
int nprocs = porting::getNumberOfProcessors ();
@@ -118,18 +118,18 @@ EmergeManager::EmergeManager(IGameDef *gamedef) {
118
118
}
119
119
if (nthreads < 1 )
120
120
nthreads = 1 ;
121
-
121
+
122
122
qlimit_total = g_settings->getU16 (" emergequeue_limit_total" );
123
123
qlimit_diskonly = g_settings->get (" emergequeue_limit_diskonly" ).empty () ?
124
124
nthreads * 5 + 1 :
125
125
g_settings->getU16 (" emergequeue_limit_diskonly" );
126
126
qlimit_generate = g_settings->get (" emergequeue_limit_generate" ).empty () ?
127
127
nthreads + 1 :
128
128
g_settings->getU16 (" emergequeue_limit_generate" );
129
-
129
+
130
130
for (int i = 0 ; i != nthreads; i++)
131
131
emergethread.push_back (new EmergeThread ((Server *)gamedef, i));
132
-
132
+
133
133
infostream << " EmergeManager: using " << nthreads << " threads" << std::endl;
134
134
}
135
135
@@ -152,7 +152,7 @@ EmergeManager::~EmergeManager() {
152
152
for (unsigned int i = 0 ; i < decorations.size (); i++)
153
153
delete decorations[i];
154
154
decorations.clear ();
155
-
155
+
156
156
for (std::map<std::string, MapgenFactory *>::iterator iter = mglist.begin ();
157
157
iter != mglist.end (); iter ++) {
158
158
delete iter->second ;
@@ -165,61 +165,97 @@ EmergeManager::~EmergeManager() {
165
165
166
166
void EmergeManager::initMapgens (MapgenParams *mgparams) {
167
167
Mapgen *mg;
168
-
168
+
169
169
if (mapgen.size ())
170
170
return ;
171
-
171
+
172
172
// Resolve names of nodes for things that were registered
173
173
// (at this point, the registration period is over)
174
174
biomedef->resolveNodeNames (ndef);
175
-
175
+
176
176
for (size_t i = 0 ; i != ores.size (); i++)
177
177
ores[i]->resolveNodeNames (ndef);
178
-
178
+
179
179
for (size_t i = 0 ; i != decorations.size (); i++)
180
180
decorations[i]->resolveNodeNames (ndef);
181
-
181
+
182
182
// Apply mapgen parameter overrides from Lua
183
183
if (luaoverride_params) {
184
- if (luaoverride_params_modified & MGPARAMS_SET_MGNAME)
185
- mgparams->mg_name = luaoverride_params->mg_name ;
186
-
184
+ if (luaoverride_params_modified & MGPARAMS_SET_MGNAME) {
185
+ MapgenParams *mgp = setMapgenType (mgparams, luaoverride_params->mg_name );
186
+ if (!mgp) {
187
+ errorstream << " EmergeManager: Failed to set new mapgen name"
188
+ << std::endl;
189
+ } else {
190
+ mgparams = mgp;
191
+ }
192
+ }
193
+
187
194
if (luaoverride_params_modified & MGPARAMS_SET_SEED)
188
195
mgparams->seed = luaoverride_params->seed ;
189
-
196
+
190
197
if (luaoverride_params_modified & MGPARAMS_SET_WATER_LEVEL)
191
198
mgparams->water_level = luaoverride_params->water_level ;
192
-
199
+
193
200
if (luaoverride_params_modified & MGPARAMS_SET_FLAGS) {
194
201
mgparams->flags &= ~luaoverride_flagmask;
195
202
mgparams->flags |= luaoverride_params->flags ;
196
203
}
197
-
204
+
198
205
delete luaoverride_params;
199
206
luaoverride_params = NULL ;
200
207
}
201
-
208
+
202
209
// Create the mapgens
203
210
this ->params = mgparams;
204
211
for (size_t i = 0 ; i != emergethread.size (); i++) {
205
- mg = createMapgen (params->mg_name , 0 , params);
212
+ mg = createMapgen (params->mg_name , i , params);
206
213
if (!mg) {
207
- infostream << " EmergeManager: falling back to mapgen v6" << std::endl;
208
- delete params;
209
- params = createMapgenParams (" v6" );
210
- mg = createMapgen (" v6" , 0 , params);
214
+ infostream << " EmergeManager: Falling back to Mapgen V6" << std::endl;
215
+
216
+ params = setMapgenType (params, " v6" );
217
+ mg = createMapgen (params->mg_name , i, params);
218
+ if (!mg) {
219
+ errorstream << " EmergeManager: CRITICAL ERROR: Failed to fall"
220
+ " back to Mapgen V6, not generating map" << std::endl;
221
+ }
211
222
}
212
223
mapgen.push_back (mg);
213
224
}
214
225
}
215
226
216
227
228
+ MapgenParams *EmergeManager::setMapgenType (MapgenParams *mgparams,
229
+ std::string newname) {
230
+ MapgenParams *newparams = createMapgenParams (newname);
231
+ if (!newparams) {
232
+ errorstream << " EmergeManager: Mapgen override failed" << std::endl;
233
+ return NULL ;
234
+ }
235
+
236
+ newparams->mg_name = newname;
237
+ newparams->seed = mgparams->seed ;
238
+ newparams->water_level = mgparams->water_level ;
239
+ newparams->chunksize = mgparams->chunksize ;
240
+ newparams->flags = mgparams->flags ;
241
+
242
+ if (!newparams->readParams (g_settings)) {
243
+ errorstream << " EmergeManager: Mapgen override failed" << std::endl;
244
+ delete newparams;
245
+ return NULL ;
246
+ }
247
+
248
+ delete mgparams;
249
+ return newparams;
250
+ }
251
+
252
+
217
253
Mapgen *EmergeManager::getCurrentMapgen () {
218
254
for (unsigned int i = 0 ; i != emergethread.size (); i++) {
219
255
if (emergethread[i]->IsSameThread ())
220
256
return emergethread[i]->mapgen ;
221
257
}
222
-
258
+
223
259
return NULL ;
224
260
}
225
261
@@ -229,19 +265,20 @@ void EmergeManager::triggerAllThreads() {
229
265
emergethread[i]->trigger ();
230
266
}
231
267
268
+
232
269
bool EmergeManager::enqueueBlockEmerge (u16 peer_id, v3s16 p, bool allow_generate) {
233
270
std::map<v3s16, BlockEmergeData *>::const_iterator iter;
234
271
BlockEmergeData *bedata;
235
272
u16 count;
236
273
u8 flags = 0 ;
237
274
int idx = 0 ;
238
-
275
+
239
276
if (allow_generate)
240
277
flags |= BLOCK_EMERGE_ALLOWGEN;
241
278
242
279
{
243
280
JMutexAutoLock queuelock (queuemutex);
244
-
281
+
245
282
count = blocks_enqueued.size ();
246
283
if (count >= qlimit_total)
247
284
return false ;
@@ -250,7 +287,7 @@ bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate
250
287
u16 qlimit_peer = allow_generate ? qlimit_generate : qlimit_diskonly;
251
288
if (count >= qlimit_peer)
252
289
return false ;
253
-
290
+
254
291
iter = blocks_enqueued.find (p);
255
292
if (iter != blocks_enqueued.end ()) {
256
293
bedata = iter->second ;
@@ -262,9 +299,9 @@ bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate
262
299
bedata->flags = flags;
263
300
bedata->peer_requested = peer_id;
264
301
blocks_enqueued.insert (std::make_pair (p, bedata));
265
-
302
+
266
303
peer_queue_count[peer_id] = count + 1 ;
267
-
304
+
268
305
// insert into the EmergeThread queue with the least items
269
306
int lowestitems = emergethread[0 ]->blockqueue .size ();
270
307
for (unsigned int i = 1 ; i != emergethread.size (); i++) {
@@ -274,22 +311,22 @@ bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate
274
311
lowestitems = nitems;
275
312
}
276
313
}
277
-
314
+
278
315
emergethread[idx]->blockqueue .push (p);
279
316
}
280
317
emergethread[idx]->qevent .signal ();
281
-
318
+
282
319
return true ;
283
320
}
284
321
285
322
286
323
int EmergeManager::getGroundLevelAtPoint (v2s16 p) {
287
324
if (mapgen.size () == 0 || !mapgen[0 ]) {
288
325
errorstream << " EmergeManager: getGroundLevelAtPoint() called"
289
- " before mapgen initialized" << std::endl;
326
+ " before mapgen initialized" << std::endl;
290
327
return 0 ;
291
328
}
292
-
329
+
293
330
return mapgen[0 ]->getGroundLevelAtPoint (p);
294
331
}
295
332
@@ -325,7 +362,7 @@ Mapgen *EmergeManager::createMapgen(std::string mgname, int mgid,
325
362
" not registered" << std::endl;
326
363
return NULL ;
327
364
}
328
-
365
+
329
366
MapgenFactory *mgfactory = iter->second ;
330
367
return mgfactory->createMapgen (mgid, mgparams, this );
331
368
}
@@ -339,7 +376,7 @@ MapgenParams *EmergeManager::createMapgenParams(std::string mgname) {
339
376
" not registered" << std::endl;
340
377
return NULL ;
341
378
}
342
-
379
+
343
380
MapgenFactory *mgfactory = iter->second ;
344
381
return mgfactory->createMapgenParams ();
345
382
}
@@ -350,10 +387,10 @@ MapgenParams *EmergeManager::getParamsFromSettings(Settings *settings) {
350
387
MapgenParams *mgparams = createMapgenParams (mg_name);
351
388
if (!mgparams)
352
389
return NULL ;
353
-
390
+
354
391
std::string seedstr = settings->get (settings == g_settings ?
355
392
" fixed_map_seed" : " seed" );
356
-
393
+
357
394
mgparams->mg_name = mg_name;
358
395
mgparams->seed = read_seed (seedstr.c_str ());
359
396
mgparams->water_level = settings->getS16 (" water_level" );
@@ -395,21 +432,21 @@ bool EmergeThread::popBlockEmerge(v3s16 *pos, u8 *flags) {
395
432
return false ;
396
433
v3s16 p = blockqueue.front ();
397
434
blockqueue.pop ();
398
-
435
+
399
436
*pos = p;
400
-
437
+
401
438
iter = emerge->blocks_enqueued .find (p);
402
439
if (iter == emerge->blocks_enqueued .end ())
403
440
return false ; // uh oh, queue and map out of sync!!
404
441
405
442
BlockEmergeData *bedata = iter->second ;
406
443
*flags = bedata->flags ;
407
-
444
+
408
445
emerge->peer_queue_count [bedata->peer_requested ]--;
409
446
410
447
delete bedata;
411
448
emerge->blocks_enqueued .erase (iter);
412
-
449
+
413
450
return true ;
414
451
}
415
452
@@ -419,7 +456,7 @@ bool EmergeThread::getBlockOrStartGen(v3s16 p, MapBlock **b,
419
456
v2s16 p2d (p.X , p.Z );
420
457
// envlock: usually takes <=1ms, sometimes 90ms or ~400ms to acquire
421
458
JMutexAutoLock envlock (m_server->m_env_mutex );
422
-
459
+
423
460
// Load sector if it isn't loaded
424
461
if (map->getSectorNoGenerateNoEx (p2d) == NULL )
425
462
map->loadSectorMeta (p2d);
@@ -440,7 +477,7 @@ bool EmergeThread::getBlockOrStartGen(v3s16 p, MapBlock **b,
440
477
*b = block;
441
478
return map->initBlockMake (data, p);
442
479
}
443
-
480
+
444
481
*b = block;
445
482
return false ;
446
483
}
@@ -455,12 +492,12 @@ void *EmergeThread::Thread() {
455
492
v3s16 last_tried_pos (-32768 ,-32768 ,-32768 ); // For error output
456
493
v3s16 p;
457
494
u8 flags;
458
-
495
+
459
496
map = (ServerMap *)&(m_server->m_env ->getMap ());
460
497
emerge = m_server->m_emerge ;
461
498
mapgen = emerge->mapgen [id];
462
499
enable_mapgen_debug_info = emerge->mapgen_debug_info ;
463
-
500
+
464
501
while (getRun ())
465
502
try {
466
503
if (!popBlockEmerge (&p, &flags)) {
@@ -474,16 +511,16 @@ void *EmergeThread::Thread() {
474
511
475
512
bool allow_generate = flags & BLOCK_EMERGE_ALLOWGEN;
476
513
EMERGE_DBG_OUT (" p=" PP (p) " allow_generate=" << allow_generate);
477
-
514
+
478
515
/*
479
516
Try to fetch block from memory or disk.
480
517
If not found and asked to generate, initialize generator.
481
518
*/
482
519
BlockMakeData data;
483
520
MapBlock *block = NULL ;
484
521
std::map<v3s16, MapBlock *> modified_blocks;
485
-
486
- if (getBlockOrStartGen (p, &block, &data, allow_generate)) {
522
+
523
+ if (getBlockOrStartGen (p, &block, &data, allow_generate) && mapgen ) {
487
524
{
488
525
ScopeProfiler sp (g_profiler, " EmergeThread: Mapgen::makeChunk" , SPT_AVG);
489
526
TimeTaker t (" mapgen::make_block()" );
@@ -501,7 +538,7 @@ void *EmergeThread::Thread() {
501
538
" Mapgen::makeChunk (envlock)" , SPT_AVG);
502
539
503
540
map->finishBlockMake (&data, modified_blocks);
504
-
541
+
505
542
block = map->getBlockNoCreateNoEx (p);
506
543
if (block) {
507
544
/*
@@ -522,7 +559,7 @@ void *EmergeThread::Thread() {
522
559
}
523
560
524
561
EMERGE_DBG_OUT (" ended up with: " << analyze_block (block));
525
-
562
+
526
563
m_server->m_env ->activateBlock (block, 0 );
527
564
}
528
565
}
@@ -568,7 +605,7 @@ void *EmergeThread::Thread() {
568
605
err << " You can ignore this using [ignore_world_load_errors = true]." <<std::endl;
569
606
m_server->setAsyncFatalError (err.str ());
570
607
}
571
-
608
+
572
609
END_DEBUG_EXCEPTION_HANDLER (errorstream)
573
610
log_deregister_thread ();
574
611
return NULL ;
0 commit comments