map.cpp 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065
  1. /*
  2. Minetest
  3. Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #include "map.h"
  17. #include "mapsector.h"
  18. #include "mapblock.h"
  19. #include "filesys.h"
  20. #include "voxel.h"
  21. #include "voxelalgorithms.h"
  22. #include "porting.h"
  23. #include "serialization.h"
  24. #include "nodemetadata.h"
  25. #include "settings.h"
  26. #include "log.h"
  27. #include "profiler.h"
  28. #include "nodedef.h"
  29. #include "gamedef.h"
  30. #include "util/directiontables.h"
  31. #include "util/basic_macros.h"
  32. #include "rollback_interface.h"
  33. #include "environment.h"
  34. #include "reflowscan.h"
  35. #include "emerge.h"
  36. #include "mapgen/mapgen_v6.h"
  37. #include "mapgen/mg_biome.h"
  38. #include "config.h"
  39. #include "server.h"
  40. #include "database/database.h"
  41. #include "database/database-dummy.h"
  42. #include "database/database-sqlite3.h"
  43. #include "script/scripting_server.h"
  44. #include <deque>
  45. #include <queue>
  46. #if USE_LEVELDB
  47. #include "database/database-leveldb.h"
  48. #endif
  49. #if USE_REDIS
  50. #include "database/database-redis.h"
  51. #endif
  52. #if USE_POSTGRESQL
  53. #include "database/database-postgresql.h"
  54. #endif
  55. /*
  56. Map
  57. */
  58. Map::Map(IGameDef *gamedef):
  59. m_gamedef(gamedef),
  60. m_nodedef(gamedef->ndef())
  61. {
  62. }
  63. Map::~Map()
  64. {
  65. /*
  66. Free all MapSectors
  67. */
  68. for (auto &sector : m_sectors) {
  69. delete sector.second;
  70. }
  71. }
  72. void Map::addEventReceiver(MapEventReceiver *event_receiver)
  73. {
  74. m_event_receivers.insert(event_receiver);
  75. }
  76. void Map::removeEventReceiver(MapEventReceiver *event_receiver)
  77. {
  78. m_event_receivers.erase(event_receiver);
  79. }
  80. void Map::dispatchEvent(const MapEditEvent &event)
  81. {
  82. for (MapEventReceiver *event_receiver : m_event_receivers) {
  83. event_receiver->onMapEditEvent(event);
  84. }
  85. }
  86. MapSector * Map::getSectorNoGenerateNoLock(v2s16 p)
  87. {
  88. if(m_sector_cache != NULL && p == m_sector_cache_p){
  89. MapSector * sector = m_sector_cache;
  90. return sector;
  91. }
  92. auto n = m_sectors.find(p);
  93. if (n == m_sectors.end())
  94. return NULL;
  95. MapSector *sector = n->second;
  96. // Cache the last result
  97. m_sector_cache_p = p;
  98. m_sector_cache = sector;
  99. return sector;
  100. }
  101. MapSector * Map::getSectorNoGenerate(v2s16 p)
  102. {
  103. return getSectorNoGenerateNoLock(p);
  104. }
  105. MapBlock * Map::getBlockNoCreateNoEx(v3s16 p3d)
  106. {
  107. v2s16 p2d(p3d.X, p3d.Z);
  108. MapSector * sector = getSectorNoGenerate(p2d);
  109. if(sector == NULL)
  110. return NULL;
  111. MapBlock *block = sector->getBlockNoCreateNoEx(p3d.Y);
  112. return block;
  113. }
  114. MapBlock * Map::getBlockNoCreate(v3s16 p3d)
  115. {
  116. MapBlock *block = getBlockNoCreateNoEx(p3d);
  117. if(block == NULL)
  118. throw InvalidPositionException();
  119. return block;
  120. }
  121. bool Map::isValidPosition(v3s16 p)
  122. {
  123. v3s16 blockpos = getNodeBlockPos(p);
  124. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  125. return (block != NULL);
  126. }
  127. // Returns a CONTENT_IGNORE node if not found
  128. MapNode Map::getNode(v3s16 p, bool *is_valid_position)
  129. {
  130. v3s16 blockpos = getNodeBlockPos(p);
  131. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  132. if (block == NULL) {
  133. if (is_valid_position != NULL)
  134. *is_valid_position = false;
  135. return {CONTENT_IGNORE};
  136. }
  137. v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
  138. MapNode node = block->getNodeNoCheck(relpos);
  139. if (is_valid_position != NULL)
  140. *is_valid_position = true;
  141. return node;
  142. }
  143. static void set_node_in_block(MapBlock *block, v3s16 relpos, MapNode n)
  144. {
  145. // Never allow placing CONTENT_IGNORE, it causes problems
  146. if(n.getContent() == CONTENT_IGNORE){
  147. const NodeDefManager *nodedef = block->getParent()->getNodeDefManager();
  148. v3s16 blockpos = block->getPos();
  149. v3s16 p = blockpos * MAP_BLOCKSIZE + relpos;
  150. errorstream<<"Not allowing to place CONTENT_IGNORE"
  151. <<" while trying to replace \""
  152. <<nodedef->get(block->getNodeNoCheck(relpos)).name
  153. <<"\" at "<<PP(p)<<" (block "<<PP(blockpos)<<")"<<std::endl;
  154. return;
  155. }
  156. block->setNodeNoCheck(relpos, n);
  157. }
  158. // throws InvalidPositionException if not found
  159. void Map::setNode(v3s16 p, MapNode n)
  160. {
  161. v3s16 blockpos = getNodeBlockPos(p);
  162. MapBlock *block = getBlockNoCreate(blockpos);
  163. v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
  164. set_node_in_block(block, relpos, n);
  165. }
  166. void Map::addNodeAndUpdate(v3s16 p, MapNode n,
  167. std::map<v3s16, MapBlock*> &modified_blocks,
  168. bool remove_metadata)
  169. {
  170. // Collect old node for rollback
  171. RollbackNode rollback_oldnode(this, p, m_gamedef);
  172. v3s16 blockpos = getNodeBlockPos(p);
  173. MapBlock *block = getBlockNoCreate(blockpos);
  174. v3s16 relpos = p - blockpos * MAP_BLOCKSIZE;
  175. // This is needed for updating the lighting
  176. MapNode oldnode = block->getNodeNoCheck(relpos);
  177. // Remove node metadata
  178. if (remove_metadata) {
  179. removeNodeMetadata(p);
  180. }
  181. // Set the node on the map
  182. ContentLightingFlags f = m_nodedef->getLightingFlags(n);
  183. ContentLightingFlags oldf = m_nodedef->getLightingFlags(oldnode);
  184. if (f == oldf) {
  185. // No light update needed, just copy over the old light.
  186. n.setLight(LIGHTBANK_DAY, oldnode.getLightRaw(LIGHTBANK_DAY, oldf), f);
  187. n.setLight(LIGHTBANK_NIGHT, oldnode.getLightRaw(LIGHTBANK_NIGHT, oldf), f);
  188. set_node_in_block(block, relpos, n);
  189. modified_blocks[blockpos] = block;
  190. } else {
  191. // Ignore light (because calling voxalgo::update_lighting_nodes)
  192. n.setLight(LIGHTBANK_DAY, 0, f);
  193. n.setLight(LIGHTBANK_NIGHT, 0, f);
  194. set_node_in_block(block, relpos, n);
  195. // Update lighting
  196. std::vector<std::pair<v3s16, MapNode> > oldnodes;
  197. oldnodes.emplace_back(p, oldnode);
  198. voxalgo::update_lighting_nodes(this, oldnodes, modified_blocks);
  199. for (auto &modified_block : modified_blocks) {
  200. modified_block.second->expireDayNightDiff();
  201. }
  202. }
  203. // Report for rollback
  204. if(m_gamedef->rollback())
  205. {
  206. RollbackNode rollback_newnode(this, p, m_gamedef);
  207. RollbackAction action;
  208. action.setSetNode(p, rollback_oldnode, rollback_newnode);
  209. m_gamedef->rollback()->reportAction(action);
  210. }
  211. }
  212. void Map::removeNodeAndUpdate(v3s16 p,
  213. std::map<v3s16, MapBlock*> &modified_blocks)
  214. {
  215. addNodeAndUpdate(p, MapNode(CONTENT_AIR), modified_blocks, true);
  216. }
  217. bool Map::addNodeWithEvent(v3s16 p, MapNode n, bool remove_metadata)
  218. {
  219. MapEditEvent event;
  220. event.type = remove_metadata ? MEET_ADDNODE : MEET_SWAPNODE;
  221. event.p = p;
  222. event.n = n;
  223. bool succeeded = true;
  224. try{
  225. std::map<v3s16, MapBlock*> modified_blocks;
  226. addNodeAndUpdate(p, n, modified_blocks, remove_metadata);
  227. // Copy modified_blocks to event
  228. for (auto &modified_block : modified_blocks) {
  229. event.modified_blocks.insert(modified_block.first);
  230. }
  231. }
  232. catch(InvalidPositionException &e){
  233. succeeded = false;
  234. }
  235. dispatchEvent(event);
  236. return succeeded;
  237. }
  238. bool Map::removeNodeWithEvent(v3s16 p)
  239. {
  240. MapEditEvent event;
  241. event.type = MEET_REMOVENODE;
  242. event.p = p;
  243. bool succeeded = true;
  244. try{
  245. std::map<v3s16, MapBlock*> modified_blocks;
  246. removeNodeAndUpdate(p, modified_blocks);
  247. // Copy modified_blocks to event
  248. for (auto &modified_block : modified_blocks) {
  249. event.modified_blocks.insert(modified_block.first);
  250. }
  251. }
  252. catch(InvalidPositionException &e){
  253. succeeded = false;
  254. }
  255. dispatchEvent(event);
  256. return succeeded;
  257. }
  258. struct TimeOrderedMapBlock {
  259. MapSector *sect;
  260. MapBlock *block;
  261. TimeOrderedMapBlock(MapSector *sect, MapBlock *block) :
  262. sect(sect),
  263. block(block)
  264. {}
  265. bool operator<(const TimeOrderedMapBlock &b) const
  266. {
  267. return block->getUsageTimer() < b.block->getUsageTimer();
  268. };
  269. };
  270. /*
  271. Updates usage timers
  272. */
  273. void Map::timerUpdate(float dtime, float unload_timeout, s32 max_loaded_blocks,
  274. std::vector<v3s16> *unloaded_blocks)
  275. {
  276. bool save_before_unloading = maySaveBlocks();
  277. // Profile modified reasons
  278. Profiler modprofiler;
  279. std::vector<v2s16> sector_deletion_queue;
  280. u32 deleted_blocks_count = 0;
  281. u32 saved_blocks_count = 0;
  282. u32 block_count_all = 0;
  283. const auto start_time = porting::getTimeUs();
  284. beginSave();
  285. // If there is no practical limit, we spare creation of mapblock_queue
  286. if (max_loaded_blocks < 0) {
  287. for (auto &sector_it : m_sectors) {
  288. MapSector *sector = sector_it.second;
  289. bool all_blocks_deleted = true;
  290. MapBlockVect blocks;
  291. sector->getBlocks(blocks);
  292. for (MapBlock *block : blocks) {
  293. block->incrementUsageTimer(dtime);
  294. if (block->refGet() == 0
  295. && block->getUsageTimer() > unload_timeout) {
  296. v3s16 p = block->getPos();
  297. // Save if modified
  298. if (block->getModified() != MOD_STATE_CLEAN
  299. && save_before_unloading) {
  300. modprofiler.add(block->getModifiedReasonString(), 1);
  301. if (!saveBlock(block))
  302. continue;
  303. saved_blocks_count++;
  304. }
  305. // Delete from memory
  306. sector->deleteBlock(block);
  307. if (unloaded_blocks)
  308. unloaded_blocks->push_back(p);
  309. deleted_blocks_count++;
  310. } else {
  311. all_blocks_deleted = false;
  312. block_count_all++;
  313. }
  314. }
  315. // Delete sector if we emptied it
  316. if (all_blocks_deleted) {
  317. sector_deletion_queue.push_back(sector_it.first);
  318. }
  319. }
  320. } else {
  321. std::priority_queue<TimeOrderedMapBlock> mapblock_queue;
  322. for (auto &sector_it : m_sectors) {
  323. MapSector *sector = sector_it.second;
  324. MapBlockVect blocks;
  325. sector->getBlocks(blocks);
  326. for (MapBlock *block : blocks) {
  327. block->incrementUsageTimer(dtime);
  328. mapblock_queue.push(TimeOrderedMapBlock(sector, block));
  329. }
  330. }
  331. block_count_all = mapblock_queue.size();
  332. // Delete old blocks, and blocks over the limit from the memory
  333. while (!mapblock_queue.empty() && ((s32)mapblock_queue.size() > max_loaded_blocks
  334. || mapblock_queue.top().block->getUsageTimer() > unload_timeout)) {
  335. TimeOrderedMapBlock b = mapblock_queue.top();
  336. mapblock_queue.pop();
  337. MapBlock *block = b.block;
  338. if (block->refGet() != 0)
  339. continue;
  340. v3s16 p = block->getPos();
  341. // Save if modified
  342. if (block->getModified() != MOD_STATE_CLEAN && save_before_unloading) {
  343. modprofiler.add(block->getModifiedReasonString(), 1);
  344. if (!saveBlock(block))
  345. continue;
  346. saved_blocks_count++;
  347. }
  348. // Delete from memory
  349. b.sect->deleteBlock(block);
  350. if (unloaded_blocks)
  351. unloaded_blocks->push_back(p);
  352. deleted_blocks_count++;
  353. block_count_all--;
  354. }
  355. // Delete empty sectors
  356. for (auto &sector_it : m_sectors) {
  357. if (sector_it.second->empty()) {
  358. sector_deletion_queue.push_back(sector_it.first);
  359. }
  360. }
  361. }
  362. endSave();
  363. const auto end_time = porting::getTimeUs();
  364. reportMetrics(end_time - start_time, saved_blocks_count, block_count_all);
  365. // Finally delete the empty sectors
  366. deleteSectors(sector_deletion_queue);
  367. if(deleted_blocks_count != 0)
  368. {
  369. PrintInfo(infostream); // ServerMap/ClientMap:
  370. infostream<<"Unloaded "<<deleted_blocks_count
  371. <<" blocks from memory";
  372. if(save_before_unloading)
  373. infostream<<", of which "<<saved_blocks_count<<" were written";
  374. infostream<<", "<<block_count_all<<" blocks in memory";
  375. infostream<<"."<<std::endl;
  376. if(saved_blocks_count != 0){
  377. PrintInfo(infostream); // ServerMap/ClientMap:
  378. infostream<<"Blocks modified by: "<<std::endl;
  379. modprofiler.print(infostream);
  380. }
  381. }
  382. }
  383. void Map::unloadUnreferencedBlocks(std::vector<v3s16> *unloaded_blocks)
  384. {
  385. timerUpdate(0.0, -1.0, 0, unloaded_blocks);
  386. }
  387. void Map::deleteSectors(std::vector<v2s16> &sectorList)
  388. {
  389. for (v2s16 j : sectorList) {
  390. MapSector *sector = m_sectors[j];
  391. // If sector is in sector cache, remove it from there
  392. if(m_sector_cache == sector)
  393. m_sector_cache = NULL;
  394. // Remove from map and delete
  395. m_sectors.erase(j);
  396. delete sector;
  397. }
  398. }
  399. void Map::PrintInfo(std::ostream &out)
  400. {
  401. out<<"Map: ";
  402. }
  403. #define WATER_DROP_BOOST 4
  404. const static v3s16 liquid_6dirs[6] = {
  405. // order: upper before same level before lower
  406. v3s16( 0, 1, 0),
  407. v3s16( 0, 0, 1),
  408. v3s16( 1, 0, 0),
  409. v3s16( 0, 0,-1),
  410. v3s16(-1, 0, 0),
  411. v3s16( 0,-1, 0)
  412. };
  413. enum NeighborType : u8 {
  414. NEIGHBOR_UPPER,
  415. NEIGHBOR_SAME_LEVEL,
  416. NEIGHBOR_LOWER
  417. };
  418. struct NodeNeighbor {
  419. MapNode n;
  420. NeighborType t;
  421. v3s16 p;
  422. NodeNeighbor()
  423. : n(CONTENT_AIR), t(NEIGHBOR_SAME_LEVEL)
  424. { }
  425. NodeNeighbor(const MapNode &node, NeighborType n_type, const v3s16 &pos)
  426. : n(node),
  427. t(n_type),
  428. p(pos)
  429. { }
  430. };
  431. void ServerMap::transforming_liquid_add(v3s16 p) {
  432. m_transforming_liquid.push_back(p);
  433. }
  434. void ServerMap::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks,
  435. ServerEnvironment *env)
  436. {
  437. u32 loopcount = 0;
  438. u32 initial_size = m_transforming_liquid.size();
  439. /*if(initial_size != 0)
  440. infostream<<"transformLiquids(): initial_size="<<initial_size<<std::endl;*/
  441. // list of nodes that due to viscosity have not reached their max level height
  442. std::vector<v3s16> must_reflow;
  443. std::vector<std::pair<v3s16, MapNode> > changed_nodes;
  444. std::vector<v3s16> check_for_falling;
  445. u32 liquid_loop_max = g_settings->getS32("liquid_loop_max");
  446. u32 loop_max = liquid_loop_max;
  447. while (m_transforming_liquid.size() != 0)
  448. {
  449. // This should be done here so that it is done when continue is used
  450. if (loopcount >= initial_size || loopcount >= loop_max)
  451. break;
  452. loopcount++;
  453. /*
  454. Get a queued transforming liquid node
  455. */
  456. v3s16 p0 = m_transforming_liquid.front();
  457. m_transforming_liquid.pop_front();
  458. MapNode n0 = getNode(p0);
  459. /*
  460. Collect information about current node
  461. */
  462. s8 liquid_level = -1;
  463. // The liquid node which will be placed there if
  464. // the liquid flows into this node.
  465. content_t liquid_kind = CONTENT_IGNORE;
  466. // The node which will be placed there if liquid
  467. // can't flow into this node.
  468. content_t floodable_node = CONTENT_AIR;
  469. const ContentFeatures &cf = m_nodedef->get(n0);
  470. LiquidType liquid_type = cf.liquid_type;
  471. switch (liquid_type) {
  472. case LIQUID_SOURCE:
  473. liquid_level = LIQUID_LEVEL_SOURCE;
  474. liquid_kind = cf.liquid_alternative_flowing_id;
  475. break;
  476. case LIQUID_FLOWING:
  477. liquid_level = (n0.param2 & LIQUID_LEVEL_MASK);
  478. liquid_kind = n0.getContent();
  479. break;
  480. case LIQUID_NONE:
  481. // if this node is 'floodable', it *could* be transformed
  482. // into a liquid, otherwise, continue with the next node.
  483. if (!cf.floodable)
  484. continue;
  485. floodable_node = n0.getContent();
  486. liquid_kind = CONTENT_AIR;
  487. break;
  488. }
  489. /*
  490. Collect information about the environment
  491. */
  492. NodeNeighbor sources[6]; // surrounding sources
  493. int num_sources = 0;
  494. NodeNeighbor flows[6]; // surrounding flowing liquid nodes
  495. int num_flows = 0;
  496. NodeNeighbor airs[6]; // surrounding air
  497. int num_airs = 0;
  498. NodeNeighbor neutrals[6]; // nodes that are solid or another kind of liquid
  499. int num_neutrals = 0;
  500. bool flowing_down = false;
  501. bool ignored_sources = false;
  502. bool floating_node_above = false;
  503. for (u16 i = 0; i < 6; i++) {
  504. NeighborType nt = NEIGHBOR_SAME_LEVEL;
  505. switch (i) {
  506. case 0:
  507. nt = NEIGHBOR_UPPER;
  508. break;
  509. case 5:
  510. nt = NEIGHBOR_LOWER;
  511. break;
  512. default:
  513. break;
  514. }
  515. v3s16 npos = p0 + liquid_6dirs[i];
  516. NodeNeighbor nb(getNode(npos), nt, npos);
  517. const ContentFeatures &cfnb = m_nodedef->get(nb.n);
  518. if (nt == NEIGHBOR_UPPER && cfnb.floats)
  519. floating_node_above = true;
  520. switch (cfnb.liquid_type) {
  521. case LIQUID_NONE:
  522. if (cfnb.floodable) {
  523. airs[num_airs++] = nb;
  524. // if the current node is a water source the neighbor
  525. // should be enqueded for transformation regardless of whether the
  526. // current node changes or not.
  527. if (nb.t != NEIGHBOR_UPPER && liquid_type != LIQUID_NONE)
  528. m_transforming_liquid.push_back(npos);
  529. // if the current node happens to be a flowing node, it will start to flow down here.
  530. if (nb.t == NEIGHBOR_LOWER)
  531. flowing_down = true;
  532. } else {
  533. neutrals[num_neutrals++] = nb;
  534. if (nb.n.getContent() == CONTENT_IGNORE) {
  535. // If node below is ignore prevent water from
  536. // spreading outwards and otherwise prevent from
  537. // flowing away as ignore node might be the source
  538. if (nb.t == NEIGHBOR_LOWER)
  539. flowing_down = true;
  540. else
  541. ignored_sources = true;
  542. }
  543. }
  544. break;
  545. case LIQUID_SOURCE:
  546. // if this node is not (yet) of a liquid type, choose the first liquid type we encounter
  547. if (liquid_kind == CONTENT_AIR)
  548. liquid_kind = cfnb.liquid_alternative_flowing_id;
  549. if (cfnb.liquid_alternative_flowing_id != liquid_kind) {
  550. neutrals[num_neutrals++] = nb;
  551. } else {
  552. // Do not count bottom source, it will screw things up
  553. if(nt != NEIGHBOR_LOWER)
  554. sources[num_sources++] = nb;
  555. }
  556. break;
  557. case LIQUID_FLOWING:
  558. if (nb.t != NEIGHBOR_SAME_LEVEL ||
  559. (nb.n.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK) {
  560. // if this node is not (yet) of a liquid type, choose the first liquid type we encounter
  561. // but exclude falling liquids on the same level, they cannot flow here anyway
  562. if (liquid_kind == CONTENT_AIR)
  563. liquid_kind = cfnb.liquid_alternative_flowing_id;
  564. }
  565. if (cfnb.liquid_alternative_flowing_id != liquid_kind) {
  566. neutrals[num_neutrals++] = nb;
  567. } else {
  568. flows[num_flows++] = nb;
  569. if (nb.t == NEIGHBOR_LOWER)
  570. flowing_down = true;
  571. }
  572. break;
  573. }
  574. }
  575. /*
  576. decide on the type (and possibly level) of the current node
  577. */
  578. content_t new_node_content;
  579. s8 new_node_level = -1;
  580. s8 max_node_level = -1;
  581. u8 range = m_nodedef->get(liquid_kind).liquid_range;
  582. if (range > LIQUID_LEVEL_MAX + 1)
  583. range = LIQUID_LEVEL_MAX + 1;
  584. if ((num_sources >= 2 && m_nodedef->get(liquid_kind).liquid_renewable) || liquid_type == LIQUID_SOURCE) {
  585. // liquid_kind will be set to either the flowing alternative of the node (if it's a liquid)
  586. // or the flowing alternative of the first of the surrounding sources (if it's air), so
  587. // it's perfectly safe to use liquid_kind here to determine the new node content.
  588. new_node_content = m_nodedef->get(liquid_kind).liquid_alternative_source_id;
  589. } else if (num_sources >= 1 && sources[0].t != NEIGHBOR_LOWER) {
  590. // liquid_kind is set properly, see above
  591. max_node_level = new_node_level = LIQUID_LEVEL_MAX;
  592. if (new_node_level >= (LIQUID_LEVEL_MAX + 1 - range))
  593. new_node_content = liquid_kind;
  594. else
  595. new_node_content = floodable_node;
  596. } else if (ignored_sources && liquid_level >= 0) {
  597. // Maybe there are neighboring sources that aren't loaded yet
  598. // so prevent flowing away.
  599. new_node_level = liquid_level;
  600. new_node_content = liquid_kind;
  601. } else {
  602. // no surrounding sources, so get the maximum level that can flow into this node
  603. for (u16 i = 0; i < num_flows; i++) {
  604. u8 nb_liquid_level = (flows[i].n.param2 & LIQUID_LEVEL_MASK);
  605. switch (flows[i].t) {
  606. case NEIGHBOR_UPPER:
  607. if (nb_liquid_level + WATER_DROP_BOOST > max_node_level) {
  608. max_node_level = LIQUID_LEVEL_MAX;
  609. if (nb_liquid_level + WATER_DROP_BOOST < LIQUID_LEVEL_MAX)
  610. max_node_level = nb_liquid_level + WATER_DROP_BOOST;
  611. } else if (nb_liquid_level > max_node_level) {
  612. max_node_level = nb_liquid_level;
  613. }
  614. break;
  615. case NEIGHBOR_LOWER:
  616. break;
  617. case NEIGHBOR_SAME_LEVEL:
  618. if ((flows[i].n.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK &&
  619. nb_liquid_level > 0 && nb_liquid_level - 1 > max_node_level)
  620. max_node_level = nb_liquid_level - 1;
  621. break;
  622. }
  623. }
  624. u8 viscosity = m_nodedef->get(liquid_kind).liquid_viscosity;
  625. if (viscosity > 1 && max_node_level != liquid_level) {
  626. // amount to gain, limited by viscosity
  627. // must be at least 1 in absolute value
  628. s8 level_inc = max_node_level - liquid_level;
  629. if (level_inc < -viscosity || level_inc > viscosity)
  630. new_node_level = liquid_level + level_inc/viscosity;
  631. else if (level_inc < 0)
  632. new_node_level = liquid_level - 1;
  633. else if (level_inc > 0)
  634. new_node_level = liquid_level + 1;
  635. if (new_node_level != max_node_level)
  636. must_reflow.push_back(p0);
  637. } else {
  638. new_node_level = max_node_level;
  639. }
  640. if (max_node_level >= (LIQUID_LEVEL_MAX + 1 - range))
  641. new_node_content = liquid_kind;
  642. else
  643. new_node_content = floodable_node;
  644. }
  645. /*
  646. check if anything has changed. if not, just continue with the next node.
  647. */
  648. if (new_node_content == n0.getContent() &&
  649. (m_nodedef->get(n0.getContent()).liquid_type != LIQUID_FLOWING ||
  650. ((n0.param2 & LIQUID_LEVEL_MASK) == (u8)new_node_level &&
  651. ((n0.param2 & LIQUID_FLOW_DOWN_MASK) == LIQUID_FLOW_DOWN_MASK)
  652. == flowing_down)))
  653. continue;
  654. /*
  655. check if there is a floating node above that needs to be updated.
  656. */
  657. if (floating_node_above && new_node_content == CONTENT_AIR)
  658. check_for_falling.push_back(p0);
  659. /*
  660. update the current node
  661. */
  662. MapNode n00 = n0;
  663. //bool flow_down_enabled = (flowing_down && ((n0.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK));
  664. if (m_nodedef->get(new_node_content).liquid_type == LIQUID_FLOWING) {
  665. // set level to last 3 bits, flowing down bit to 4th bit
  666. n0.param2 = (flowing_down ? LIQUID_FLOW_DOWN_MASK : 0x00) | (new_node_level & LIQUID_LEVEL_MASK);
  667. } else {
  668. // set the liquid level and flow bits to 0
  669. n0.param2 &= ~(LIQUID_LEVEL_MASK | LIQUID_FLOW_DOWN_MASK);
  670. }
  671. // change the node.
  672. n0.setContent(new_node_content);
  673. // on_flood() the node
  674. if (floodable_node != CONTENT_AIR) {
  675. if (env->getScriptIface()->node_on_flood(p0, n00, n0))
  676. continue;
  677. }
  678. // Ignore light (because calling voxalgo::update_lighting_nodes)
  679. ContentLightingFlags f0 = m_nodedef->getLightingFlags(n0);
  680. n0.setLight(LIGHTBANK_DAY, 0, f0);
  681. n0.setLight(LIGHTBANK_NIGHT, 0, f0);
  682. // Find out whether there is a suspect for this action
  683. std::string suspect;
  684. if (m_gamedef->rollback())
  685. suspect = m_gamedef->rollback()->getSuspect(p0, 83, 1);
  686. if (m_gamedef->rollback() && !suspect.empty()) {
  687. // Blame suspect
  688. RollbackScopeActor rollback_scope(m_gamedef->rollback(), suspect, true);
  689. // Get old node for rollback
  690. RollbackNode rollback_oldnode(this, p0, m_gamedef);
  691. // Set node
  692. setNode(p0, n0);
  693. // Report
  694. RollbackNode rollback_newnode(this, p0, m_gamedef);
  695. RollbackAction action;
  696. action.setSetNode(p0, rollback_oldnode, rollback_newnode);
  697. m_gamedef->rollback()->reportAction(action);
  698. } else {
  699. // Set node
  700. setNode(p0, n0);
  701. }
  702. v3s16 blockpos = getNodeBlockPos(p0);
  703. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  704. if (block != NULL) {
  705. modified_blocks[blockpos] = block;
  706. changed_nodes.emplace_back(p0, n00);
  707. }
  708. /*
  709. enqueue neighbors for update if necessary
  710. */
  711. switch (m_nodedef->get(n0.getContent()).liquid_type) {
  712. case LIQUID_SOURCE:
  713. case LIQUID_FLOWING:
  714. // make sure source flows into all neighboring nodes
  715. for (u16 i = 0; i < num_flows; i++)
  716. if (flows[i].t != NEIGHBOR_UPPER)
  717. m_transforming_liquid.push_back(flows[i].p);
  718. for (u16 i = 0; i < num_airs; i++)
  719. if (airs[i].t != NEIGHBOR_UPPER)
  720. m_transforming_liquid.push_back(airs[i].p);
  721. break;
  722. case LIQUID_NONE:
  723. // this flow has turned to air; neighboring flows might need to do the same
  724. for (u16 i = 0; i < num_flows; i++)
  725. m_transforming_liquid.push_back(flows[i].p);
  726. break;
  727. }
  728. }
  729. //infostream<<"Map::transformLiquids(): loopcount="<<loopcount<<std::endl;
  730. for (const auto &iter : must_reflow)
  731. m_transforming_liquid.push_back(iter);
  732. voxalgo::update_lighting_nodes(this, changed_nodes, modified_blocks);
  733. for (const v3s16 &p : check_for_falling) {
  734. env->getScriptIface()->check_for_falling(p);
  735. }
  736. env->getScriptIface()->on_liquid_transformed(changed_nodes);
  737. /* ----------------------------------------------------------------------
  738. * Manage the queue so that it does not grow indefinitely
  739. */
  740. u16 time_until_purge = g_settings->getU16("liquid_queue_purge_time");
  741. if (time_until_purge == 0)
  742. return; // Feature disabled
  743. time_until_purge *= 1000; // seconds -> milliseconds
  744. u64 curr_time = porting::getTimeMs();
  745. u32 prev_unprocessed = m_unprocessed_count;
  746. m_unprocessed_count = m_transforming_liquid.size();
  747. // if unprocessed block count is decreasing or stable
  748. if (m_unprocessed_count <= prev_unprocessed) {
  749. m_queue_size_timer_started = false;
  750. } else {
  751. if (!m_queue_size_timer_started)
  752. m_inc_trending_up_start_time = curr_time;
  753. m_queue_size_timer_started = true;
  754. }
  755. // Account for curr_time overflowing
  756. if (m_queue_size_timer_started && m_inc_trending_up_start_time > curr_time)
  757. m_queue_size_timer_started = false;
  758. /* If the queue has been growing for more than liquid_queue_purge_time seconds
  759. * and the number of unprocessed blocks is still > liquid_loop_max then we
  760. * cannot keep up; dump the oldest blocks from the queue so that the queue
  761. * has liquid_loop_max items in it
  762. */
  763. if (m_queue_size_timer_started
  764. && curr_time - m_inc_trending_up_start_time > time_until_purge
  765. && m_unprocessed_count > liquid_loop_max) {
  766. size_t dump_qty = m_unprocessed_count - liquid_loop_max;
  767. infostream << "transformLiquids(): DUMPING " << dump_qty
  768. << " blocks from the queue" << std::endl;
  769. while (dump_qty--)
  770. m_transforming_liquid.pop_front();
  771. m_queue_size_timer_started = false; // optimistically assume we can keep up now
  772. m_unprocessed_count = m_transforming_liquid.size();
  773. }
  774. }
  775. std::vector<v3s16> Map::findNodesWithMetadata(v3s16 p1, v3s16 p2)
  776. {
  777. std::vector<v3s16> positions_with_meta;
  778. sortBoxVerticies(p1, p2);
  779. v3s16 bpmin = getNodeBlockPos(p1);
  780. v3s16 bpmax = getNodeBlockPos(p2);
  781. VoxelArea area(p1, p2);
  782. for (s16 z = bpmin.Z; z <= bpmax.Z; z++)
  783. for (s16 y = bpmin.Y; y <= bpmax.Y; y++)
  784. for (s16 x = bpmin.X; x <= bpmax.X; x++) {
  785. v3s16 blockpos(x, y, z);
  786. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  787. if (!block) {
  788. verbosestream << "Map::getNodeMetadata(): Need to emerge "
  789. << PP(blockpos) << std::endl;
  790. block = emergeBlock(blockpos, false);
  791. }
  792. if (!block) {
  793. infostream << "WARNING: Map::getNodeMetadata(): Block not found"
  794. << std::endl;
  795. continue;
  796. }
  797. v3s16 p_base = blockpos * MAP_BLOCKSIZE;
  798. std::vector<v3s16> keys = block->m_node_metadata.getAllKeys();
  799. for (size_t i = 0; i != keys.size(); i++) {
  800. v3s16 p(keys[i] + p_base);
  801. if (!area.contains(p))
  802. continue;
  803. positions_with_meta.push_back(p);
  804. }
  805. }
  806. return positions_with_meta;
  807. }
  808. NodeMetadata *Map::getNodeMetadata(v3s16 p)
  809. {
  810. v3s16 blockpos = getNodeBlockPos(p);
  811. v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
  812. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  813. if(!block){
  814. infostream<<"Map::getNodeMetadata(): Need to emerge "
  815. <<PP(blockpos)<<std::endl;
  816. block = emergeBlock(blockpos, false);
  817. }
  818. if(!block){
  819. warningstream<<"Map::getNodeMetadata(): Block not found"
  820. <<std::endl;
  821. return NULL;
  822. }
  823. NodeMetadata *meta = block->m_node_metadata.get(p_rel);
  824. return meta;
  825. }
  826. bool Map::setNodeMetadata(v3s16 p, NodeMetadata *meta)
  827. {
  828. v3s16 blockpos = getNodeBlockPos(p);
  829. v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
  830. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  831. if(!block){
  832. infostream<<"Map::setNodeMetadata(): Need to emerge "
  833. <<PP(blockpos)<<std::endl;
  834. block = emergeBlock(blockpos, false);
  835. }
  836. if(!block){
  837. warningstream<<"Map::setNodeMetadata(): Block not found"
  838. <<std::endl;
  839. return false;
  840. }
  841. block->m_node_metadata.set(p_rel, meta);
  842. return true;
  843. }
  844. void Map::removeNodeMetadata(v3s16 p)
  845. {
  846. v3s16 blockpos = getNodeBlockPos(p);
  847. v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
  848. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  849. if(block == NULL)
  850. {
  851. warningstream<<"Map::removeNodeMetadata(): Block not found"
  852. <<std::endl;
  853. return;
  854. }
  855. block->m_node_metadata.remove(p_rel);
  856. }
  857. NodeTimer Map::getNodeTimer(v3s16 p)
  858. {
  859. v3s16 blockpos = getNodeBlockPos(p);
  860. v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
  861. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  862. if(!block){
  863. infostream<<"Map::getNodeTimer(): Need to emerge "
  864. <<PP(blockpos)<<std::endl;
  865. block = emergeBlock(blockpos, false);
  866. }
  867. if(!block){
  868. warningstream<<"Map::getNodeTimer(): Block not found"
  869. <<std::endl;
  870. return NodeTimer();
  871. }
  872. NodeTimer t = block->getNodeTimer(p_rel);
  873. NodeTimer nt(t.timeout, t.elapsed, p);
  874. return nt;
  875. }
  876. void Map::setNodeTimer(const NodeTimer &t)
  877. {
  878. v3s16 p = t.position;
  879. v3s16 blockpos = getNodeBlockPos(p);
  880. v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
  881. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  882. if(!block){
  883. infostream<<"Map::setNodeTimer(): Need to emerge "
  884. <<PP(blockpos)<<std::endl;
  885. block = emergeBlock(blockpos, false);
  886. }
  887. if(!block){
  888. warningstream<<"Map::setNodeTimer(): Block not found"
  889. <<std::endl;
  890. return;
  891. }
  892. NodeTimer nt(t.timeout, t.elapsed, p_rel);
  893. block->setNodeTimer(nt);
  894. }
  895. void Map::removeNodeTimer(v3s16 p)
  896. {
  897. v3s16 blockpos = getNodeBlockPos(p);
  898. v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
  899. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  900. if(block == NULL)
  901. {
  902. warningstream<<"Map::removeNodeTimer(): Block not found"
  903. <<std::endl;
  904. return;
  905. }
  906. block->removeNodeTimer(p_rel);
  907. }
  908. bool Map::determineAdditionalOcclusionCheck(const v3s16 &pos_camera,
  909. const core::aabbox3d<s16> &block_bounds, v3s16 &check)
  910. {
  911. /*
  912. This functions determines the node inside the target block that is
  913. closest to the camera position. This increases the occlusion culling
  914. accuracy in straight and diagonal corridors.
  915. The returned position will be occlusion checked first in addition to the
  916. others (8 corners + center).
  917. No position is returned if
  918. - the closest node is a corner, corners are checked anyway.
  919. - the camera is inside the target block, it will never be occluded.
  920. */
  921. #define CLOSEST_EDGE(pos, bounds, axis) \
  922. ((pos).axis <= (bounds).MinEdge.axis) ? (bounds).MinEdge.axis : \
  923. (bounds).MaxEdge.axis
  924. bool x_inside = (block_bounds.MinEdge.X <= pos_camera.X) &&
  925. (pos_camera.X <= block_bounds.MaxEdge.X);
  926. bool y_inside = (block_bounds.MinEdge.Y <= pos_camera.Y) &&
  927. (pos_camera.Y <= block_bounds.MaxEdge.Y);
  928. bool z_inside = (block_bounds.MinEdge.Z <= pos_camera.Z) &&
  929. (pos_camera.Z <= block_bounds.MaxEdge.Z);
  930. if (x_inside && y_inside && z_inside)
  931. return false; // Camera inside target mapblock
  932. // straight
  933. if (x_inside && y_inside) {
  934. check = v3s16(pos_camera.X, pos_camera.Y, 0);
  935. check.Z = CLOSEST_EDGE(pos_camera, block_bounds, Z);
  936. return true;
  937. } else if (y_inside && z_inside) {
  938. check = v3s16(0, pos_camera.Y, pos_camera.Z);
  939. check.X = CLOSEST_EDGE(pos_camera, block_bounds, X);
  940. return true;
  941. } else if (x_inside && z_inside) {
  942. check = v3s16(pos_camera.X, 0, pos_camera.Z);
  943. check.Y = CLOSEST_EDGE(pos_camera, block_bounds, Y);
  944. return true;
  945. }
  946. // diagonal
  947. if (x_inside) {
  948. check = v3s16(pos_camera.X, 0, 0);
  949. check.Y = CLOSEST_EDGE(pos_camera, block_bounds, Y);
  950. check.Z = CLOSEST_EDGE(pos_camera, block_bounds, Z);
  951. return true;
  952. } else if (y_inside) {
  953. check = v3s16(0, pos_camera.Y, 0);
  954. check.X = CLOSEST_EDGE(pos_camera, block_bounds, X);
  955. check.Z = CLOSEST_EDGE(pos_camera, block_bounds, Z);
  956. return true;
  957. } else if (z_inside) {
  958. check = v3s16(0, 0, pos_camera.Z);
  959. check.X = CLOSEST_EDGE(pos_camera, block_bounds, X);
  960. check.Y = CLOSEST_EDGE(pos_camera, block_bounds, Y);
  961. return true;
  962. }
  963. // Closest node would be a corner, none returned
  964. return false;
  965. }
  966. bool Map::isOccluded(const v3s16 &pos_camera, const v3s16 &pos_target,
  967. float step, float stepfac, float offset, float end_offset, u32 needed_count)
  968. {
  969. v3f direction = intToFloat(pos_target - pos_camera, BS);
  970. float distance = direction.getLength();
  971. // Normalize direction vector
  972. if (distance > 0.0f)
  973. direction /= distance;
  974. v3f pos_origin_f = intToFloat(pos_camera, BS);
  975. u32 count = 0;
  976. bool is_valid_position;
  977. for (; offset < distance + end_offset; offset += step) {
  978. v3f pos_node_f = pos_origin_f + direction * offset;
  979. v3s16 pos_node = floatToInt(pos_node_f, BS);
  980. MapNode node = getNode(pos_node, &is_valid_position);
  981. if (is_valid_position &&
  982. !m_nodedef->getLightingFlags(node).light_propagates) {
  983. // Cannot see through light-blocking nodes --> occluded
  984. count++;
  985. if (count >= needed_count)
  986. return true;
  987. }
  988. step *= stepfac;
  989. }
  990. return false;
  991. }
  992. bool Map::isBlockOccluded(MapBlock *block, v3s16 cam_pos_nodes)
  993. {
  994. // Check occlusion for center and all 8 corners of the mapblock
  995. // Overshoot a little for less flickering
  996. static const s16 bs2 = MAP_BLOCKSIZE / 2 + 1;
  997. static const v3s16 dir9[9] = {
  998. v3s16( 0, 0, 0),
  999. v3s16( 1, 1, 1) * bs2,
  1000. v3s16( 1, 1, -1) * bs2,
  1001. v3s16( 1, -1, 1) * bs2,
  1002. v3s16( 1, -1, -1) * bs2,
  1003. v3s16(-1, 1, 1) * bs2,
  1004. v3s16(-1, 1, -1) * bs2,
  1005. v3s16(-1, -1, 1) * bs2,
  1006. v3s16(-1, -1, -1) * bs2,
  1007. };
  1008. v3s16 pos_blockcenter = block->getPosRelative() + (MAP_BLOCKSIZE / 2);
  1009. // Starting step size, value between 1m and sqrt(3)m
  1010. float step = BS * 1.2f;
  1011. // Multiply step by each iteraction by 'stepfac' to reduce checks in distance
  1012. float stepfac = 1.05f;
  1013. float start_offset = BS * 1.0f;
  1014. // The occlusion search of 'isOccluded()' must stop short of the target
  1015. // point by distance 'end_offset' to not enter the target mapblock.
  1016. // For the 8 mapblock corners 'end_offset' must therefore be the maximum
  1017. // diagonal of a mapblock, because we must consider all view angles.
  1018. // sqrt(1^2 + 1^2 + 1^2) = 1.732
  1019. float end_offset = -BS * MAP_BLOCKSIZE * 1.732f;
  1020. // to reduce the likelihood of falsely occluded blocks
  1021. // require at least two solid blocks
  1022. // this is a HACK, we should think of a more precise algorithm
  1023. u32 needed_count = 2;
  1024. // Additional occlusion check, see comments in that function
  1025. v3s16 check;
  1026. if (determineAdditionalOcclusionCheck(cam_pos_nodes, block->getBox(), check)) {
  1027. // node is always on a side facing the camera, end_offset can be lower
  1028. if (!isOccluded(cam_pos_nodes, check, step, stepfac, start_offset,
  1029. -1.0f, needed_count))
  1030. return false;
  1031. }
  1032. for (const v3s16 &dir : dir9) {
  1033. if (!isOccluded(cam_pos_nodes, pos_blockcenter + dir, step, stepfac,
  1034. start_offset, end_offset, needed_count))
  1035. return false;
  1036. }
  1037. return true;
  1038. }
  1039. /*
  1040. ServerMap
  1041. */
  1042. ServerMap::ServerMap(const std::string &savedir, IGameDef *gamedef,
  1043. EmergeManager *emerge, MetricsBackend *mb):
  1044. Map(gamedef),
  1045. settings_mgr(savedir + DIR_DELIM + "map_meta.txt"),
  1046. m_emerge(emerge)
  1047. {
  1048. verbosestream<<FUNCTION_NAME<<std::endl;
  1049. // Tell the EmergeManager about our MapSettingsManager
  1050. emerge->map_settings_mgr = &settings_mgr;
  1051. /*
  1052. Try to load map; if not found, create a new one.
  1053. */
  1054. // Determine which database backend to use
  1055. std::string conf_path = savedir + DIR_DELIM + "world.mt";
  1056. Settings conf;
  1057. bool succeeded = conf.readConfigFile(conf_path.c_str());
  1058. if (!succeeded || !conf.exists("backend")) {
  1059. // fall back to sqlite3
  1060. conf.set("backend", "sqlite3");
  1061. }
  1062. std::string backend = conf.get("backend");
  1063. dbase = createDatabase(backend, savedir, conf);
  1064. if (conf.exists("readonly_backend")) {
  1065. std::string readonly_dir = savedir + DIR_DELIM + "readonly";
  1066. dbase_ro = createDatabase(conf.get("readonly_backend"), readonly_dir, conf);
  1067. }
  1068. if (!conf.updateConfigFile(conf_path.c_str()))
  1069. errorstream << "ServerMap::ServerMap(): Failed to update world.mt!" << std::endl;
  1070. m_savedir = savedir;
  1071. m_map_saving_enabled = false;
  1072. m_save_time_counter = mb->addCounter(
  1073. "minetest_map_save_time", "Time spent saving blocks (in microseconds)");
  1074. m_save_count_counter = mb->addCounter(
  1075. "minetest_map_saved_blocks", "Number of blocks saved");
  1076. m_loaded_blocks_gauge = mb->addGauge(
  1077. "minetest_map_loaded_blocks", "Number of loaded blocks");
  1078. m_map_compression_level = rangelim(g_settings->getS16("map_compression_level_disk"), -1, 9);
  1079. try {
  1080. // If directory exists, check contents and load if possible
  1081. if (fs::PathExists(m_savedir)) {
  1082. // If directory is empty, it is safe to save into it.
  1083. if (fs::GetDirListing(m_savedir).empty()) {
  1084. infostream<<"ServerMap: Empty save directory is valid."
  1085. <<std::endl;
  1086. m_map_saving_enabled = true;
  1087. }
  1088. else
  1089. {
  1090. if (settings_mgr.loadMapMeta()) {
  1091. infostream << "ServerMap: Metadata loaded from "
  1092. << savedir << std::endl;
  1093. } else {
  1094. infostream << "ServerMap: Metadata could not be loaded "
  1095. "from " << savedir << ", assuming valid save "
  1096. "directory." << std::endl;
  1097. }
  1098. m_map_saving_enabled = true;
  1099. // Map loaded, not creating new one
  1100. return;
  1101. }
  1102. }
  1103. // If directory doesn't exist, it is safe to save to it
  1104. else{
  1105. m_map_saving_enabled = true;
  1106. }
  1107. }
  1108. catch(std::exception &e)
  1109. {
  1110. warningstream<<"ServerMap: Failed to load map from "<<savedir
  1111. <<", exception: "<<e.what()<<std::endl;
  1112. infostream<<"Please remove the map or fix it."<<std::endl;
  1113. warningstream<<"Map saving will be disabled."<<std::endl;
  1114. }
  1115. }
  1116. ServerMap::~ServerMap()
  1117. {
  1118. verbosestream<<FUNCTION_NAME<<std::endl;
  1119. try
  1120. {
  1121. if (m_map_saving_enabled) {
  1122. // Save only changed parts
  1123. save(MOD_STATE_WRITE_AT_UNLOAD);
  1124. infostream << "ServerMap: Saved map to " << m_savedir << std::endl;
  1125. } else {
  1126. infostream << "ServerMap: Map not saved" << std::endl;
  1127. }
  1128. }
  1129. catch(std::exception &e)
  1130. {
  1131. infostream<<"ServerMap: Failed to save map to "<<m_savedir
  1132. <<", exception: "<<e.what()<<std::endl;
  1133. }
  1134. /*
  1135. Close database if it was opened
  1136. */
  1137. delete dbase;
  1138. delete dbase_ro;
  1139. }
  1140. MapgenParams *ServerMap::getMapgenParams()
  1141. {
  1142. // getMapgenParams() should only ever be called after Server is initialized
  1143. assert(settings_mgr.mapgen_params != NULL);
  1144. return settings_mgr.mapgen_params;
  1145. }
  1146. u64 ServerMap::getSeed()
  1147. {
  1148. return getMapgenParams()->seed;
  1149. }
  1150. bool ServerMap::blockpos_over_mapgen_limit(v3s16 p)
  1151. {
  1152. const s16 mapgen_limit_bp = rangelim(
  1153. getMapgenParams()->mapgen_limit, 0, MAX_MAP_GENERATION_LIMIT) /
  1154. MAP_BLOCKSIZE;
  1155. return p.X < -mapgen_limit_bp ||
  1156. p.X > mapgen_limit_bp ||
  1157. p.Y < -mapgen_limit_bp ||
  1158. p.Y > mapgen_limit_bp ||
  1159. p.Z < -mapgen_limit_bp ||
  1160. p.Z > mapgen_limit_bp;
  1161. }
  1162. bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data)
  1163. {
  1164. s16 csize = getMapgenParams()->chunksize;
  1165. v3s16 bpmin = EmergeManager::getContainingChunk(blockpos, csize);
  1166. v3s16 bpmax = bpmin + v3s16(1, 1, 1) * (csize - 1);
  1167. if (!m_chunks_in_progress.insert(bpmin).second)
  1168. return false;
  1169. bool enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info;
  1170. EMERGE_DBG_OUT("initBlockMake(): " PP(bpmin) " - " PP(bpmax));
  1171. v3s16 extra_borders(1, 1, 1);
  1172. v3s16 full_bpmin = bpmin - extra_borders;
  1173. v3s16 full_bpmax = bpmax + extra_borders;
  1174. // Do nothing if not inside mapgen limits (+-1 because of neighbors)
  1175. if (blockpos_over_mapgen_limit(full_bpmin) ||
  1176. blockpos_over_mapgen_limit(full_bpmax))
  1177. return false;
  1178. data->seed = getSeed();
  1179. data->blockpos_min = bpmin;
  1180. data->blockpos_max = bpmax;
  1181. data->nodedef = m_nodedef;
  1182. /*
  1183. Create the whole area of this and the neighboring blocks
  1184. */
  1185. for (s16 x = full_bpmin.X; x <= full_bpmax.X; x++)
  1186. for (s16 z = full_bpmin.Z; z <= full_bpmax.Z; z++) {
  1187. v2s16 sectorpos(x, z);
  1188. // Sector metadata is loaded from disk if not already loaded.
  1189. MapSector *sector = createSector(sectorpos);
  1190. FATAL_ERROR_IF(sector == NULL, "createSector() failed");
  1191. for (s16 y = full_bpmin.Y; y <= full_bpmax.Y; y++) {
  1192. v3s16 p(x, y, z);
  1193. MapBlock *block = emergeBlock(p, false);
  1194. if (block == NULL) {
  1195. block = createBlock(p);
  1196. // Block gets sunlight if this is true.
  1197. // Refer to the map generator heuristics.
  1198. bool ug = m_emerge->isBlockUnderground(p);
  1199. block->setIsUnderground(ug);
  1200. }
  1201. }
  1202. }
  1203. /*
  1204. Now we have a big empty area.
  1205. Make a ManualMapVoxelManipulator that contains this and the
  1206. neighboring blocks
  1207. */
  1208. data->vmanip = new MMVManip(this);
  1209. data->vmanip->initialEmerge(full_bpmin, full_bpmax);
  1210. // Data is ready now.
  1211. return true;
  1212. }
  1213. void ServerMap::finishBlockMake(BlockMakeData *data,
  1214. std::map<v3s16, MapBlock*> *changed_blocks)
  1215. {
  1216. v3s16 bpmin = data->blockpos_min;
  1217. v3s16 bpmax = data->blockpos_max;
  1218. bool enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info;
  1219. EMERGE_DBG_OUT("finishBlockMake(): " PP(bpmin) " - " PP(bpmax));
  1220. /*
  1221. Blit generated stuff to map
  1222. NOTE: blitBackAll adds nearly everything to changed_blocks
  1223. */
  1224. data->vmanip->blitBackAll(changed_blocks);
  1225. EMERGE_DBG_OUT("finishBlockMake: changed_blocks.size()="
  1226. << changed_blocks->size());
  1227. /*
  1228. Copy transforming liquid information
  1229. */
  1230. while (data->transforming_liquid.size()) {
  1231. m_transforming_liquid.push_back(data->transforming_liquid.front());
  1232. data->transforming_liquid.pop_front();
  1233. }
  1234. for (auto &changed_block : *changed_blocks) {
  1235. MapBlock *block = changed_block.second;
  1236. if (!block)
  1237. continue;
  1238. /*
  1239. Update day/night difference cache of the MapBlocks
  1240. */
  1241. block->expireDayNightDiff();
  1242. /*
  1243. Set block as modified
  1244. */
  1245. block->raiseModified(MOD_STATE_WRITE_NEEDED,
  1246. MOD_REASON_EXPIRE_DAYNIGHTDIFF);
  1247. }
  1248. /*
  1249. Set central blocks as generated
  1250. */
  1251. for (s16 x = bpmin.X; x <= bpmax.X; x++)
  1252. for (s16 z = bpmin.Z; z <= bpmax.Z; z++)
  1253. for (s16 y = bpmin.Y; y <= bpmax.Y; y++) {
  1254. MapBlock *block = getBlockNoCreateNoEx(v3s16(x, y, z));
  1255. if (!block)
  1256. continue;
  1257. block->setGenerated(true);
  1258. }
  1259. /*
  1260. Save changed parts of map
  1261. NOTE: Will be saved later.
  1262. */
  1263. //save(MOD_STATE_WRITE_AT_UNLOAD);
  1264. m_chunks_in_progress.erase(bpmin);
  1265. }
  1266. MapSector *ServerMap::createSector(v2s16 p2d)
  1267. {
  1268. /*
  1269. Check if it exists already in memory
  1270. */
  1271. MapSector *sector = getSectorNoGenerate(p2d);
  1272. if (sector)
  1273. return sector;
  1274. /*
  1275. Do not create over max mapgen limit
  1276. */
  1277. if (blockpos_over_max_limit(v3s16(p2d.X, 0, p2d.Y)))
  1278. throw InvalidPositionException("createSector(): pos. over max mapgen limit");
  1279. /*
  1280. Generate blank sector
  1281. */
  1282. sector = new MapSector(this, p2d, m_gamedef);
  1283. /*
  1284. Insert to container
  1285. */
  1286. m_sectors[p2d] = sector;
  1287. return sector;
  1288. }
  1289. MapBlock * ServerMap::createBlock(v3s16 p)
  1290. {
  1291. /*
  1292. Do not create over max mapgen limit
  1293. */
  1294. if (blockpos_over_max_limit(p))
  1295. throw InvalidPositionException("createBlock(): pos. over max mapgen limit");
  1296. v2s16 p2d(p.X, p.Z);
  1297. s16 block_y = p.Y;
  1298. /*
  1299. This will create or load a sector if not found in memory.
  1300. If block exists on disk, it will be loaded.
  1301. NOTE: On old save formats, this will be slow, as it generates
  1302. lighting on blocks for them.
  1303. */
  1304. MapSector *sector;
  1305. try {
  1306. sector = createSector(p2d);
  1307. } catch (InvalidPositionException &e) {
  1308. infostream<<"createBlock: createSector() failed"<<std::endl;
  1309. throw e;
  1310. }
  1311. /*
  1312. Try to get a block from the sector
  1313. */
  1314. MapBlock *block = sector->getBlockNoCreateNoEx(block_y);
  1315. if (block) {
  1316. return block;
  1317. }
  1318. // Create blank
  1319. block = sector->createBlankBlock(block_y);
  1320. return block;
  1321. }
  1322. MapBlock * ServerMap::emergeBlock(v3s16 p, bool create_blank)
  1323. {
  1324. {
  1325. MapBlock *block = getBlockNoCreateNoEx(p);
  1326. if (block)
  1327. return block;
  1328. }
  1329. {
  1330. MapBlock *block = loadBlock(p);
  1331. if(block)
  1332. return block;
  1333. }
  1334. if (create_blank) {
  1335. MapSector *sector = createSector(v2s16(p.X, p.Z));
  1336. MapBlock *block = sector->createBlankBlock(p.Y);
  1337. return block;
  1338. }
  1339. return NULL;
  1340. }
  1341. MapBlock *ServerMap::getBlockOrEmerge(v3s16 p3d)
  1342. {
  1343. MapBlock *block = getBlockNoCreateNoEx(p3d);
  1344. if (block == NULL)
  1345. m_emerge->enqueueBlockEmerge(PEER_ID_INEXISTENT, p3d, false);
  1346. return block;
  1347. }
  1348. bool ServerMap::isBlockInQueue(v3s16 pos)
  1349. {
  1350. return m_emerge && m_emerge->isBlockInQueue(pos);
  1351. }
  1352. void ServerMap::addNodeAndUpdate(v3s16 p, MapNode n,
  1353. std::map<v3s16, MapBlock*> &modified_blocks,
  1354. bool remove_metadata)
  1355. {
  1356. Map::addNodeAndUpdate(p, n, modified_blocks, remove_metadata);
  1357. /*
  1358. Add neighboring liquid nodes and this node to transform queue.
  1359. (it's vital for the node itself to get updated last, if it was removed.)
  1360. */
  1361. for (const v3s16 &dir : g_7dirs) {
  1362. v3s16 p2 = p + dir;
  1363. bool is_valid_position;
  1364. MapNode n2 = getNode(p2, &is_valid_position);
  1365. if(is_valid_position &&
  1366. (m_nodedef->get(n2).isLiquid() ||
  1367. n2.getContent() == CONTENT_AIR))
  1368. m_transforming_liquid.push_back(p2);
  1369. }
  1370. }
  1371. // N.B. This requires no synchronization, since data will not be modified unless
  1372. // the VoxelManipulator being updated belongs to the same thread.
  1373. void ServerMap::updateVManip(v3s16 pos)
  1374. {
  1375. Mapgen *mg = m_emerge->getCurrentMapgen();
  1376. if (!mg)
  1377. return;
  1378. MMVManip *vm = mg->vm;
  1379. if (!vm)
  1380. return;
  1381. if (!vm->m_area.contains(pos))
  1382. return;
  1383. s32 idx = vm->m_area.index(pos);
  1384. vm->m_data[idx] = getNode(pos);
  1385. vm->m_flags[idx] &= ~VOXELFLAG_NO_DATA;
  1386. vm->m_is_dirty = true;
  1387. }
  1388. void ServerMap::reportMetrics(u64 save_time_us, u32 saved_blocks, u32 all_blocks)
  1389. {
  1390. m_loaded_blocks_gauge->set(all_blocks);
  1391. m_save_time_counter->increment(save_time_us);
  1392. m_save_count_counter->increment(saved_blocks);
  1393. }
  1394. void ServerMap::save(ModifiedState save_level)
  1395. {
  1396. if (!m_map_saving_enabled) {
  1397. warningstream<<"Not saving map, saving disabled."<<std::endl;
  1398. return;
  1399. }
  1400. const auto start_time = porting::getTimeUs();
  1401. if(save_level == MOD_STATE_CLEAN)
  1402. infostream<<"ServerMap: Saving whole map, this can take time."
  1403. <<std::endl;
  1404. if (m_map_metadata_changed || save_level == MOD_STATE_CLEAN) {
  1405. if (settings_mgr.saveMapMeta())
  1406. m_map_metadata_changed = false;
  1407. }
  1408. // Profile modified reasons
  1409. Profiler modprofiler;
  1410. u32 block_count = 0;
  1411. u32 block_count_all = 0; // Number of blocks in memory
  1412. // Don't do anything with sqlite unless something is really saved
  1413. bool save_started = false;
  1414. for (auto &sector_it : m_sectors) {
  1415. MapSector *sector = sector_it.second;
  1416. MapBlockVect blocks;
  1417. sector->getBlocks(blocks);
  1418. for (MapBlock *block : blocks) {
  1419. block_count_all++;
  1420. if(block->getModified() >= (u32)save_level) {
  1421. // Lazy beginSave()
  1422. if(!save_started) {
  1423. beginSave();
  1424. save_started = true;
  1425. }
  1426. modprofiler.add(block->getModifiedReasonString(), 1);
  1427. saveBlock(block);
  1428. block_count++;
  1429. }
  1430. }
  1431. }
  1432. if(save_started)
  1433. endSave();
  1434. /*
  1435. Only print if something happened or saved whole map
  1436. */
  1437. if(save_level == MOD_STATE_CLEAN
  1438. || block_count != 0) {
  1439. infostream << "ServerMap: Written: "
  1440. << block_count << " blocks"
  1441. << ", " << block_count_all << " blocks in memory."
  1442. << std::endl;
  1443. PrintInfo(infostream); // ServerMap/ClientMap:
  1444. infostream<<"Blocks modified by: "<<std::endl;
  1445. modprofiler.print(infostream);
  1446. }
  1447. const auto end_time = porting::getTimeUs();
  1448. reportMetrics(end_time - start_time, block_count, block_count_all);
  1449. }
  1450. void ServerMap::listAllLoadableBlocks(std::vector<v3s16> &dst)
  1451. {
  1452. dbase->listAllLoadableBlocks(dst);
  1453. if (dbase_ro)
  1454. dbase_ro->listAllLoadableBlocks(dst);
  1455. }
  1456. void ServerMap::listAllLoadedBlocks(std::vector<v3s16> &dst)
  1457. {
  1458. for (auto &sector_it : m_sectors) {
  1459. MapSector *sector = sector_it.second;
  1460. MapBlockVect blocks;
  1461. sector->getBlocks(blocks);
  1462. for (MapBlock *block : blocks) {
  1463. v3s16 p = block->getPos();
  1464. dst.push_back(p);
  1465. }
  1466. }
  1467. }
  1468. MapDatabase *ServerMap::createDatabase(
  1469. const std::string &name,
  1470. const std::string &savedir,
  1471. Settings &conf)
  1472. {
  1473. if (name == "sqlite3")
  1474. return new MapDatabaseSQLite3(savedir);
  1475. if (name == "dummy")
  1476. return new Database_Dummy();
  1477. #if USE_LEVELDB
  1478. if (name == "leveldb")
  1479. return new Database_LevelDB(savedir);
  1480. #endif
  1481. #if USE_REDIS
  1482. if (name == "redis")
  1483. return new Database_Redis(conf);
  1484. #endif
  1485. #if USE_POSTGRESQL
  1486. if (name == "postgresql") {
  1487. std::string connect_string;
  1488. conf.getNoEx("pgsql_connection", connect_string);
  1489. return new MapDatabasePostgreSQL(connect_string);
  1490. }
  1491. #endif
  1492. throw BaseException(std::string("Database backend ") + name + " not supported.");
  1493. }
  1494. void ServerMap::beginSave()
  1495. {
  1496. dbase->beginSave();
  1497. }
  1498. void ServerMap::endSave()
  1499. {
  1500. dbase->endSave();
  1501. }
  1502. bool ServerMap::saveBlock(MapBlock *block)
  1503. {
  1504. return saveBlock(block, dbase, m_map_compression_level);
  1505. }
  1506. bool ServerMap::saveBlock(MapBlock *block, MapDatabase *db, int compression_level)
  1507. {
  1508. v3s16 p3d = block->getPos();
  1509. // Format used for writing
  1510. u8 version = SER_FMT_VER_HIGHEST_WRITE;
  1511. /*
  1512. [0] u8 serialization version
  1513. [1] data
  1514. */
  1515. std::ostringstream o(std::ios_base::binary);
  1516. o.write((char*) &version, 1);
  1517. block->serialize(o, version, true, compression_level);
  1518. bool ret = db->saveBlock(p3d, o.str());
  1519. if (ret) {
  1520. // We just wrote it to the disk so clear modified flag
  1521. block->resetModified();
  1522. }
  1523. return ret;
  1524. }
  1525. void ServerMap::loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool save_after_load)
  1526. {
  1527. try {
  1528. std::istringstream is(*blob, std::ios_base::binary);
  1529. u8 version = SER_FMT_VER_INVALID;
  1530. is.read((char*)&version, 1);
  1531. if(is.fail())
  1532. throw SerializationError("ServerMap::loadBlock(): Failed"
  1533. " to read MapBlock version");
  1534. MapBlock *block = NULL;
  1535. bool created_new = false;
  1536. block = sector->getBlockNoCreateNoEx(p3d.Y);
  1537. if(block == NULL)
  1538. {
  1539. block = sector->createBlankBlockNoInsert(p3d.Y);
  1540. created_new = true;
  1541. }
  1542. // Read basic data
  1543. block->deSerialize(is, version, true);
  1544. // If it's a new block, insert it to the map
  1545. if (created_new) {
  1546. sector->insertBlock(block);
  1547. ReflowScan scanner(this, m_emerge->ndef);
  1548. scanner.scan(block, &m_transforming_liquid);
  1549. }
  1550. /*
  1551. Save blocks loaded in old format in new format
  1552. */
  1553. //if(version < SER_FMT_VER_HIGHEST_READ || save_after_load)
  1554. // Only save if asked to; no need to update version
  1555. if(save_after_load)
  1556. saveBlock(block);
  1557. // We just loaded it from, so it's up-to-date.
  1558. block->resetModified();
  1559. }
  1560. catch(SerializationError &e)
  1561. {
  1562. errorstream<<"Invalid block data in database"
  1563. <<" ("<<p3d.X<<","<<p3d.Y<<","<<p3d.Z<<")"
  1564. <<" (SerializationError): "<<e.what()<<std::endl;
  1565. // TODO: Block should be marked as invalid in memory so that it is
  1566. // not touched but the game can run
  1567. if(g_settings->getBool("ignore_world_load_errors")){
  1568. errorstream<<"Ignoring block load error. Duck and cover! "
  1569. <<"(ignore_world_load_errors)"<<std::endl;
  1570. } else {
  1571. throw SerializationError("Invalid block data in database");
  1572. }
  1573. }
  1574. }
  1575. MapBlock* ServerMap::loadBlock(v3s16 blockpos)
  1576. {
  1577. bool created_new = (getBlockNoCreateNoEx(blockpos) == NULL);
  1578. v2s16 p2d(blockpos.X, blockpos.Z);
  1579. std::string ret;
  1580. dbase->loadBlock(blockpos, &ret);
  1581. if (!ret.empty()) {
  1582. loadBlock(&ret, blockpos, createSector(p2d), false);
  1583. } else if (dbase_ro) {
  1584. dbase_ro->loadBlock(blockpos, &ret);
  1585. if (!ret.empty()) {
  1586. loadBlock(&ret, blockpos, createSector(p2d), false);
  1587. }
  1588. } else {
  1589. return NULL;
  1590. }
  1591. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  1592. if (created_new && (block != NULL)) {
  1593. std::map<v3s16, MapBlock*> modified_blocks;
  1594. // Fix lighting if necessary
  1595. voxalgo::update_block_border_lighting(this, block, modified_blocks);
  1596. if (!modified_blocks.empty()) {
  1597. //Modified lighting, send event
  1598. MapEditEvent event;
  1599. event.type = MEET_OTHER;
  1600. std::map<v3s16, MapBlock *>::iterator it;
  1601. for (it = modified_blocks.begin();
  1602. it != modified_blocks.end(); ++it)
  1603. event.modified_blocks.insert(it->first);
  1604. dispatchEvent(event);
  1605. }
  1606. }
  1607. return block;
  1608. }
  1609. bool ServerMap::deleteBlock(v3s16 blockpos)
  1610. {
  1611. if (!dbase->deleteBlock(blockpos))
  1612. return false;
  1613. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  1614. if (block) {
  1615. v2s16 p2d(blockpos.X, blockpos.Z);
  1616. MapSector *sector = getSectorNoGenerate(p2d);
  1617. if (!sector)
  1618. return false;
  1619. sector->deleteBlock(block);
  1620. }
  1621. return true;
  1622. }
  1623. void ServerMap::PrintInfo(std::ostream &out)
  1624. {
  1625. out<<"ServerMap: ";
  1626. }
  1627. bool ServerMap::repairBlockLight(v3s16 blockpos,
  1628. std::map<v3s16, MapBlock *> *modified_blocks)
  1629. {
  1630. MapBlock *block = emergeBlock(blockpos, false);
  1631. if (!block || !block->isGenerated())
  1632. return false;
  1633. voxalgo::repair_block_light(this, block, modified_blocks);
  1634. return true;
  1635. }
  1636. MMVManip::MMVManip(Map *map):
  1637. VoxelManipulator(),
  1638. m_map(map)
  1639. {
  1640. assert(map);
  1641. }
  1642. void MMVManip::initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max,
  1643. bool load_if_inexistent)
  1644. {
  1645. TimeTaker timer1("initialEmerge", &emerge_time);
  1646. assert(m_map);
  1647. // Units of these are MapBlocks
  1648. v3s16 p_min = blockpos_min;
  1649. v3s16 p_max = blockpos_max;
  1650. VoxelArea block_area_nodes
  1651. (p_min*MAP_BLOCKSIZE, (p_max+1)*MAP_BLOCKSIZE-v3s16(1,1,1));
  1652. u32 size_MB = block_area_nodes.getVolume()*4/1000000;
  1653. if(size_MB >= 1)
  1654. {
  1655. infostream<<"initialEmerge: area: ";
  1656. block_area_nodes.print(infostream);
  1657. infostream<<" ("<<size_MB<<"MB)";
  1658. infostream<<std::endl;
  1659. }
  1660. addArea(block_area_nodes);
  1661. for(s32 z=p_min.Z; z<=p_max.Z; z++)
  1662. for(s32 y=p_min.Y; y<=p_max.Y; y++)
  1663. for(s32 x=p_min.X; x<=p_max.X; x++)
  1664. {
  1665. u8 flags = 0;
  1666. MapBlock *block;
  1667. v3s16 p(x,y,z);
  1668. std::map<v3s16, u8>::iterator n;
  1669. n = m_loaded_blocks.find(p);
  1670. if(n != m_loaded_blocks.end())
  1671. continue;
  1672. bool block_data_inexistent = false;
  1673. {
  1674. TimeTaker timer2("emerge load", &emerge_load_time);
  1675. block = m_map->getBlockNoCreateNoEx(p);
  1676. if (!block)
  1677. block_data_inexistent = true;
  1678. else
  1679. block->copyTo(*this);
  1680. }
  1681. if(block_data_inexistent)
  1682. {
  1683. if (load_if_inexistent && !blockpos_over_max_limit(p)) {
  1684. ServerMap *svrmap = (ServerMap *)m_map;
  1685. block = svrmap->emergeBlock(p, false);
  1686. if (block == NULL)
  1687. block = svrmap->createBlock(p);
  1688. block->copyTo(*this);
  1689. } else {
  1690. flags |= VMANIP_BLOCK_DATA_INEXIST;
  1691. /*
  1692. Mark area inexistent
  1693. */
  1694. VoxelArea a(p*MAP_BLOCKSIZE, (p+1)*MAP_BLOCKSIZE-v3s16(1,1,1));
  1695. // Fill with VOXELFLAG_NO_DATA
  1696. for(s32 z=a.MinEdge.Z; z<=a.MaxEdge.Z; z++)
  1697. for(s32 y=a.MinEdge.Y; y<=a.MaxEdge.Y; y++)
  1698. {
  1699. s32 i = m_area.index(a.MinEdge.X,y,z);
  1700. memset(&m_flags[i], VOXELFLAG_NO_DATA, MAP_BLOCKSIZE);
  1701. }
  1702. }
  1703. }
  1704. /*else if (block->getNode(0, 0, 0).getContent() == CONTENT_IGNORE)
  1705. {
  1706. // Mark that block was loaded as blank
  1707. flags |= VMANIP_BLOCK_CONTAINS_CIGNORE;
  1708. }*/
  1709. m_loaded_blocks[p] = flags;
  1710. }
  1711. m_is_dirty = false;
  1712. }
  1713. void MMVManip::blitBackAll(std::map<v3s16, MapBlock*> *modified_blocks,
  1714. bool overwrite_generated)
  1715. {
  1716. if(m_area.getExtent() == v3s16(0,0,0))
  1717. return;
  1718. assert(m_map);
  1719. /*
  1720. Copy data of all blocks
  1721. */
  1722. for (auto &loaded_block : m_loaded_blocks) {
  1723. v3s16 p = loaded_block.first;
  1724. MapBlock *block = m_map->getBlockNoCreateNoEx(p);
  1725. bool existed = !(loaded_block.second & VMANIP_BLOCK_DATA_INEXIST);
  1726. if (!existed || (block == NULL) ||
  1727. (!overwrite_generated && block->isGenerated()))
  1728. continue;
  1729. block->copyFrom(*this);
  1730. block->raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_VMANIP);
  1731. if(modified_blocks)
  1732. (*modified_blocks)[p] = block;
  1733. }
  1734. }
  1735. MMVManip *MMVManip::clone() const
  1736. {
  1737. MMVManip *ret = new MMVManip();
  1738. const s32 size = m_area.getVolume();
  1739. ret->m_area = m_area;
  1740. if (m_data) {
  1741. ret->m_data = new MapNode[size];
  1742. memcpy(ret->m_data, m_data, size * sizeof(MapNode));
  1743. }
  1744. if (m_flags) {
  1745. ret->m_flags = new u8[size];
  1746. memcpy(ret->m_flags, m_flags, size * sizeof(u8));
  1747. }
  1748. ret->m_is_dirty = m_is_dirty;
  1749. // Even if the copy is disconnected from a map object keep the information
  1750. // needed to write it back to one
  1751. ret->m_loaded_blocks = m_loaded_blocks;
  1752. return ret;
  1753. }
  1754. void MMVManip::reparent(Map *map)
  1755. {
  1756. assert(map && !m_map);
  1757. m_map = map;
  1758. }
  1759. //END