map.cpp 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329
  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(std::ostream &dout, IGameDef *gamedef):
  59. m_dout(dout),
  60. m_gamedef(gamedef),
  61. m_nodedef(gamedef->ndef())
  62. {
  63. }
  64. Map::~Map()
  65. {
  66. /*
  67. Free all MapSectors
  68. */
  69. for (auto &sector : m_sectors) {
  70. delete sector.second;
  71. }
  72. }
  73. void Map::addEventReceiver(MapEventReceiver *event_receiver)
  74. {
  75. m_event_receivers.insert(event_receiver);
  76. }
  77. void Map::removeEventReceiver(MapEventReceiver *event_receiver)
  78. {
  79. m_event_receivers.erase(event_receiver);
  80. }
  81. void Map::dispatchEvent(MapEditEvent *event)
  82. {
  83. for (MapEventReceiver *event_receiver : m_event_receivers) {
  84. event_receiver->onMapEditEvent(event);
  85. }
  86. }
  87. MapSector * Map::getSectorNoGenerateNoExNoLock(v2s16 p)
  88. {
  89. if(m_sector_cache != NULL && p == m_sector_cache_p){
  90. MapSector * sector = m_sector_cache;
  91. return sector;
  92. }
  93. std::map<v2s16, MapSector*>::iterator n = m_sectors.find(p);
  94. if (n == m_sectors.end())
  95. return NULL;
  96. MapSector *sector = n->second;
  97. // Cache the last result
  98. m_sector_cache_p = p;
  99. m_sector_cache = sector;
  100. return sector;
  101. }
  102. MapSector * Map::getSectorNoGenerateNoEx(v2s16 p)
  103. {
  104. return getSectorNoGenerateNoExNoLock(p);
  105. }
  106. MapSector * Map::getSectorNoGenerate(v2s16 p)
  107. {
  108. MapSector *sector = getSectorNoGenerateNoEx(p);
  109. if(sector == NULL)
  110. throw InvalidPositionException();
  111. return sector;
  112. }
  113. MapBlock * Map::getBlockNoCreateNoEx(v3s16 p3d)
  114. {
  115. v2s16 p2d(p3d.X, p3d.Z);
  116. MapSector * sector = getSectorNoGenerateNoEx(p2d);
  117. if(sector == NULL)
  118. return NULL;
  119. MapBlock *block = sector->getBlockNoCreateNoEx(p3d.Y);
  120. return block;
  121. }
  122. MapBlock * Map::getBlockNoCreate(v3s16 p3d)
  123. {
  124. MapBlock *block = getBlockNoCreateNoEx(p3d);
  125. if(block == NULL)
  126. throw InvalidPositionException();
  127. return block;
  128. }
  129. bool Map::isNodeUnderground(v3s16 p)
  130. {
  131. v3s16 blockpos = getNodeBlockPos(p);
  132. try{
  133. MapBlock * block = getBlockNoCreate(blockpos);
  134. return block->getIsUnderground();
  135. }
  136. catch(InvalidPositionException &e)
  137. {
  138. return false;
  139. }
  140. }
  141. bool Map::isValidPosition(v3s16 p)
  142. {
  143. v3s16 blockpos = getNodeBlockPos(p);
  144. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  145. return (block != NULL);
  146. }
  147. // Returns a CONTENT_IGNORE node if not found
  148. MapNode Map::getNodeNoEx(v3s16 p, bool *is_valid_position)
  149. {
  150. v3s16 blockpos = getNodeBlockPos(p);
  151. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  152. if (block == NULL) {
  153. if (is_valid_position != NULL)
  154. *is_valid_position = false;
  155. return {CONTENT_IGNORE};
  156. }
  157. v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
  158. bool is_valid_p;
  159. MapNode node = block->getNodeNoCheck(relpos, &is_valid_p);
  160. if (is_valid_position != NULL)
  161. *is_valid_position = is_valid_p;
  162. return node;
  163. }
  164. #if 0
  165. // Deprecated
  166. // throws InvalidPositionException if not found
  167. // TODO: Now this is deprecated, getNodeNoEx should be renamed
  168. MapNode Map::getNode(v3s16 p)
  169. {
  170. v3s16 blockpos = getNodeBlockPos(p);
  171. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  172. if (block == NULL)
  173. throw InvalidPositionException();
  174. v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
  175. bool is_valid_position;
  176. MapNode node = block->getNodeNoCheck(relpos, &is_valid_position);
  177. if (!is_valid_position)
  178. throw InvalidPositionException();
  179. return node;
  180. }
  181. #endif
  182. // throws InvalidPositionException if not found
  183. void Map::setNode(v3s16 p, MapNode & n)
  184. {
  185. v3s16 blockpos = getNodeBlockPos(p);
  186. MapBlock *block = getBlockNoCreate(blockpos);
  187. v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
  188. // Never allow placing CONTENT_IGNORE, it fucks up stuff
  189. if(n.getContent() == CONTENT_IGNORE){
  190. bool temp_bool;
  191. errorstream<<"Map::setNode(): Not allowing to place CONTENT_IGNORE"
  192. <<" while trying to replace \""
  193. <<m_nodedef->get(block->getNodeNoCheck(relpos, &temp_bool)).name
  194. <<"\" at "<<PP(p)<<" (block "<<PP(blockpos)<<")"<<std::endl;
  195. return;
  196. }
  197. block->setNodeNoCheck(relpos, n);
  198. }
  199. void Map::addNodeAndUpdate(v3s16 p, MapNode n,
  200. std::map<v3s16, MapBlock*> &modified_blocks,
  201. bool remove_metadata)
  202. {
  203. // Collect old node for rollback
  204. RollbackNode rollback_oldnode(this, p, m_gamedef);
  205. // This is needed for updating the lighting
  206. MapNode oldnode = getNodeNoEx(p);
  207. // Remove node metadata
  208. if (remove_metadata) {
  209. removeNodeMetadata(p);
  210. }
  211. // Set the node on the map
  212. // Ignore light (because calling voxalgo::update_lighting_nodes)
  213. n.setLight(LIGHTBANK_DAY, 0, m_nodedef);
  214. n.setLight(LIGHTBANK_NIGHT, 0, m_nodedef);
  215. setNode(p, n);
  216. // Update lighting
  217. std::vector<std::pair<v3s16, MapNode> > oldnodes;
  218. oldnodes.emplace_back(p, oldnode);
  219. voxalgo::update_lighting_nodes(this, oldnodes, modified_blocks);
  220. for (auto &modified_block : modified_blocks) {
  221. modified_block.second->expireDayNightDiff();
  222. }
  223. // Report for rollback
  224. if(m_gamedef->rollback())
  225. {
  226. RollbackNode rollback_newnode(this, p, m_gamedef);
  227. RollbackAction action;
  228. action.setSetNode(p, rollback_oldnode, rollback_newnode);
  229. m_gamedef->rollback()->reportAction(action);
  230. }
  231. /*
  232. Add neighboring liquid nodes and this node to transform queue.
  233. (it's vital for the node itself to get updated last, if it was removed.)
  234. */
  235. for (const v3s16 &dir : g_7dirs) {
  236. v3s16 p2 = p + dir;
  237. bool is_valid_position;
  238. MapNode n2 = getNodeNoEx(p2, &is_valid_position);
  239. if(is_valid_position &&
  240. (m_nodedef->get(n2).isLiquid() ||
  241. n2.getContent() == CONTENT_AIR))
  242. m_transforming_liquid.push_back(p2);
  243. }
  244. }
  245. void Map::removeNodeAndUpdate(v3s16 p,
  246. std::map<v3s16, MapBlock*> &modified_blocks)
  247. {
  248. addNodeAndUpdate(p, MapNode(CONTENT_AIR), modified_blocks, true);
  249. }
  250. bool Map::addNodeWithEvent(v3s16 p, MapNode n, bool remove_metadata)
  251. {
  252. MapEditEvent event;
  253. event.type = remove_metadata ? MEET_ADDNODE : MEET_SWAPNODE;
  254. event.p = p;
  255. event.n = n;
  256. bool succeeded = true;
  257. try{
  258. std::map<v3s16, MapBlock*> modified_blocks;
  259. addNodeAndUpdate(p, n, modified_blocks, remove_metadata);
  260. // Copy modified_blocks to event
  261. for (auto &modified_block : modified_blocks) {
  262. event.modified_blocks.insert(modified_block.first);
  263. }
  264. }
  265. catch(InvalidPositionException &e){
  266. succeeded = false;
  267. }
  268. dispatchEvent(&event);
  269. return succeeded;
  270. }
  271. bool Map::removeNodeWithEvent(v3s16 p)
  272. {
  273. MapEditEvent event;
  274. event.type = MEET_REMOVENODE;
  275. event.p = p;
  276. bool succeeded = true;
  277. try{
  278. std::map<v3s16, MapBlock*> modified_blocks;
  279. removeNodeAndUpdate(p, modified_blocks);
  280. // Copy modified_blocks to event
  281. for (auto &modified_block : modified_blocks) {
  282. event.modified_blocks.insert(modified_block.first);
  283. }
  284. }
  285. catch(InvalidPositionException &e){
  286. succeeded = false;
  287. }
  288. dispatchEvent(&event);
  289. return succeeded;
  290. }
  291. struct TimeOrderedMapBlock {
  292. MapSector *sect;
  293. MapBlock *block;
  294. TimeOrderedMapBlock(MapSector *sect, MapBlock *block) :
  295. sect(sect),
  296. block(block)
  297. {}
  298. bool operator<(const TimeOrderedMapBlock &b) const
  299. {
  300. return block->getUsageTimer() < b.block->getUsageTimer();
  301. };
  302. };
  303. /*
  304. Updates usage timers
  305. */
  306. void Map::timerUpdate(float dtime, float unload_timeout, u32 max_loaded_blocks,
  307. std::vector<v3s16> *unloaded_blocks)
  308. {
  309. bool save_before_unloading = (mapType() == MAPTYPE_SERVER);
  310. // Profile modified reasons
  311. Profiler modprofiler;
  312. std::vector<v2s16> sector_deletion_queue;
  313. u32 deleted_blocks_count = 0;
  314. u32 saved_blocks_count = 0;
  315. u32 block_count_all = 0;
  316. beginSave();
  317. // If there is no practical limit, we spare creation of mapblock_queue
  318. if (max_loaded_blocks == U32_MAX) {
  319. for (auto &sector_it : m_sectors) {
  320. MapSector *sector = sector_it.second;
  321. bool all_blocks_deleted = true;
  322. MapBlockVect blocks;
  323. sector->getBlocks(blocks);
  324. for (MapBlock *block : blocks) {
  325. block->incrementUsageTimer(dtime);
  326. if (block->refGet() == 0
  327. && block->getUsageTimer() > unload_timeout) {
  328. v3s16 p = block->getPos();
  329. // Save if modified
  330. if (block->getModified() != MOD_STATE_CLEAN
  331. && save_before_unloading) {
  332. modprofiler.add(block->getModifiedReasonString(), 1);
  333. if (!saveBlock(block))
  334. continue;
  335. saved_blocks_count++;
  336. }
  337. // Delete from memory
  338. sector->deleteBlock(block);
  339. if (unloaded_blocks)
  340. unloaded_blocks->push_back(p);
  341. deleted_blocks_count++;
  342. } else {
  343. all_blocks_deleted = false;
  344. block_count_all++;
  345. }
  346. }
  347. if (all_blocks_deleted) {
  348. sector_deletion_queue.push_back(sector_it.first);
  349. }
  350. }
  351. } else {
  352. std::priority_queue<TimeOrderedMapBlock> mapblock_queue;
  353. for (auto &sector_it : m_sectors) {
  354. MapSector *sector = sector_it.second;
  355. MapBlockVect blocks;
  356. sector->getBlocks(blocks);
  357. for (MapBlock *block : blocks) {
  358. block->incrementUsageTimer(dtime);
  359. mapblock_queue.push(TimeOrderedMapBlock(sector, block));
  360. }
  361. }
  362. block_count_all = mapblock_queue.size();
  363. // Delete old blocks, and blocks over the limit from the memory
  364. while (!mapblock_queue.empty() && (mapblock_queue.size() > max_loaded_blocks
  365. || mapblock_queue.top().block->getUsageTimer() > unload_timeout)) {
  366. TimeOrderedMapBlock b = mapblock_queue.top();
  367. mapblock_queue.pop();
  368. MapBlock *block = b.block;
  369. if (block->refGet() != 0)
  370. continue;
  371. v3s16 p = block->getPos();
  372. // Save if modified
  373. if (block->getModified() != MOD_STATE_CLEAN && save_before_unloading) {
  374. modprofiler.add(block->getModifiedReasonString(), 1);
  375. if (!saveBlock(block))
  376. continue;
  377. saved_blocks_count++;
  378. }
  379. // Delete from memory
  380. b.sect->deleteBlock(block);
  381. if (unloaded_blocks)
  382. unloaded_blocks->push_back(p);
  383. deleted_blocks_count++;
  384. block_count_all--;
  385. }
  386. // Delete empty sectors
  387. for (auto &sector_it : m_sectors) {
  388. if (sector_it.second->empty()) {
  389. sector_deletion_queue.push_back(sector_it.first);
  390. }
  391. }
  392. }
  393. endSave();
  394. // Finally delete the empty sectors
  395. deleteSectors(sector_deletion_queue);
  396. if(deleted_blocks_count != 0)
  397. {
  398. PrintInfo(infostream); // ServerMap/ClientMap:
  399. infostream<<"Unloaded "<<deleted_blocks_count
  400. <<" blocks from memory";
  401. if(save_before_unloading)
  402. infostream<<", of which "<<saved_blocks_count<<" were written";
  403. infostream<<", "<<block_count_all<<" blocks in memory";
  404. infostream<<"."<<std::endl;
  405. if(saved_blocks_count != 0){
  406. PrintInfo(infostream); // ServerMap/ClientMap:
  407. infostream<<"Blocks modified by: "<<std::endl;
  408. modprofiler.print(infostream);
  409. }
  410. }
  411. }
  412. void Map::unloadUnreferencedBlocks(std::vector<v3s16> *unloaded_blocks)
  413. {
  414. timerUpdate(0.0, -1.0, 0, unloaded_blocks);
  415. }
  416. void Map::deleteSectors(std::vector<v2s16> &sectorList)
  417. {
  418. for (v2s16 j : sectorList) {
  419. MapSector *sector = m_sectors[j];
  420. // If sector is in sector cache, remove it from there
  421. if(m_sector_cache == sector)
  422. m_sector_cache = NULL;
  423. // Remove from map and delete
  424. m_sectors.erase(j);
  425. delete sector;
  426. }
  427. }
  428. void Map::PrintInfo(std::ostream &out)
  429. {
  430. out<<"Map: ";
  431. }
  432. #define WATER_DROP_BOOST 4
  433. enum NeighborType : u8 {
  434. NEIGHBOR_UPPER,
  435. NEIGHBOR_SAME_LEVEL,
  436. NEIGHBOR_LOWER
  437. };
  438. struct NodeNeighbor {
  439. MapNode n;
  440. NeighborType t;
  441. v3s16 p;
  442. NodeNeighbor()
  443. : n(CONTENT_AIR), t(NEIGHBOR_SAME_LEVEL)
  444. { }
  445. NodeNeighbor(const MapNode &node, NeighborType n_type, const v3s16 &pos)
  446. : n(node),
  447. t(n_type),
  448. p(pos)
  449. { }
  450. };
  451. void Map::transforming_liquid_add(v3s16 p) {
  452. m_transforming_liquid.push_back(p);
  453. }
  454. void Map::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks,
  455. ServerEnvironment *env)
  456. {
  457. u32 loopcount = 0;
  458. u32 initial_size = m_transforming_liquid.size();
  459. /*if(initial_size != 0)
  460. infostream<<"transformLiquids(): initial_size="<<initial_size<<std::endl;*/
  461. // list of nodes that due to viscosity have not reached their max level height
  462. std::deque<v3s16> must_reflow;
  463. std::vector<std::pair<v3s16, MapNode> > changed_nodes;
  464. u32 liquid_loop_max = g_settings->getS32("liquid_loop_max");
  465. u32 loop_max = liquid_loop_max;
  466. #if 0
  467. /* If liquid_loop_max is not keeping up with the queue size increase
  468. * loop_max up to a maximum of liquid_loop_max * dedicated_server_step.
  469. */
  470. if (m_transforming_liquid.size() > loop_max * 2) {
  471. // "Burst" mode
  472. float server_step = g_settings->getFloat("dedicated_server_step");
  473. if (m_transforming_liquid_loop_count_multiplier - 1.0 < server_step)
  474. m_transforming_liquid_loop_count_multiplier *= 1.0 + server_step / 10;
  475. } else {
  476. m_transforming_liquid_loop_count_multiplier = 1.0;
  477. }
  478. loop_max *= m_transforming_liquid_loop_count_multiplier;
  479. #endif
  480. while (m_transforming_liquid.size() != 0)
  481. {
  482. // This should be done here so that it is done when continue is used
  483. if (loopcount >= initial_size || loopcount >= loop_max)
  484. break;
  485. loopcount++;
  486. /*
  487. Get a queued transforming liquid node
  488. */
  489. v3s16 p0 = m_transforming_liquid.front();
  490. m_transforming_liquid.pop_front();
  491. MapNode n0 = getNodeNoEx(p0);
  492. /*
  493. Collect information about current node
  494. */
  495. s8 liquid_level = -1;
  496. // The liquid node which will be placed there if
  497. // the liquid flows into this node.
  498. content_t liquid_kind = CONTENT_IGNORE;
  499. // The node which will be placed there if liquid
  500. // can't flow into this node.
  501. content_t floodable_node = CONTENT_AIR;
  502. const ContentFeatures &cf = m_nodedef->get(n0);
  503. LiquidType liquid_type = cf.liquid_type;
  504. switch (liquid_type) {
  505. case LIQUID_SOURCE:
  506. liquid_level = LIQUID_LEVEL_SOURCE;
  507. liquid_kind = m_nodedef->getId(cf.liquid_alternative_flowing);
  508. break;
  509. case LIQUID_FLOWING:
  510. liquid_level = (n0.param2 & LIQUID_LEVEL_MASK);
  511. liquid_kind = n0.getContent();
  512. break;
  513. case LIQUID_NONE:
  514. // if this node is 'floodable', it *could* be transformed
  515. // into a liquid, otherwise, continue with the next node.
  516. if (!cf.floodable)
  517. continue;
  518. floodable_node = n0.getContent();
  519. liquid_kind = CONTENT_AIR;
  520. break;
  521. }
  522. /*
  523. Collect information about the environment
  524. */
  525. const v3s16 *dirs = g_6dirs;
  526. NodeNeighbor sources[6]; // surrounding sources
  527. int num_sources = 0;
  528. NodeNeighbor flows[6]; // surrounding flowing liquid nodes
  529. int num_flows = 0;
  530. NodeNeighbor airs[6]; // surrounding air
  531. int num_airs = 0;
  532. NodeNeighbor neutrals[6]; // nodes that are solid or another kind of liquid
  533. int num_neutrals = 0;
  534. bool flowing_down = false;
  535. bool ignored_sources = false;
  536. for (u16 i = 0; i < 6; i++) {
  537. NeighborType nt = NEIGHBOR_SAME_LEVEL;
  538. switch (i) {
  539. case 1:
  540. nt = NEIGHBOR_UPPER;
  541. break;
  542. case 4:
  543. nt = NEIGHBOR_LOWER;
  544. break;
  545. default:
  546. break;
  547. }
  548. v3s16 npos = p0 + dirs[i];
  549. NodeNeighbor nb(getNodeNoEx(npos), nt, npos);
  550. const ContentFeatures &cfnb = m_nodedef->get(nb.n);
  551. switch (m_nodedef->get(nb.n.getContent()).liquid_type) {
  552. case LIQUID_NONE:
  553. if (cfnb.floodable) {
  554. airs[num_airs++] = nb;
  555. // if the current node is a water source the neighbor
  556. // should be enqueded for transformation regardless of whether the
  557. // current node changes or not.
  558. if (nb.t != NEIGHBOR_UPPER && liquid_type != LIQUID_NONE)
  559. m_transforming_liquid.push_back(npos);
  560. // if the current node happens to be a flowing node, it will start to flow down here.
  561. if (nb.t == NEIGHBOR_LOWER)
  562. flowing_down = true;
  563. } else {
  564. neutrals[num_neutrals++] = nb;
  565. if (nb.n.getContent() == CONTENT_IGNORE) {
  566. // If node below is ignore prevent water from
  567. // spreading outwards and otherwise prevent from
  568. // flowing away as ignore node might be the source
  569. if (nb.t == NEIGHBOR_LOWER)
  570. flowing_down = true;
  571. else
  572. ignored_sources = true;
  573. }
  574. }
  575. break;
  576. case LIQUID_SOURCE:
  577. // if this node is not (yet) of a liquid type, choose the first liquid type we encounter
  578. if (liquid_kind == CONTENT_AIR)
  579. liquid_kind = m_nodedef->getId(cfnb.liquid_alternative_flowing);
  580. if (m_nodedef->getId(cfnb.liquid_alternative_flowing) != liquid_kind) {
  581. neutrals[num_neutrals++] = nb;
  582. } else {
  583. // Do not count bottom source, it will screw things up
  584. if(dirs[i].Y != -1)
  585. sources[num_sources++] = nb;
  586. }
  587. break;
  588. case LIQUID_FLOWING:
  589. // if this node is not (yet) of a liquid type, choose the first liquid type we encounter
  590. if (liquid_kind == CONTENT_AIR)
  591. liquid_kind = m_nodedef->getId(cfnb.liquid_alternative_flowing);
  592. if (m_nodedef->getId(cfnb.liquid_alternative_flowing) != liquid_kind) {
  593. neutrals[num_neutrals++] = nb;
  594. } else {
  595. flows[num_flows++] = nb;
  596. if (nb.t == NEIGHBOR_LOWER)
  597. flowing_down = true;
  598. }
  599. break;
  600. }
  601. }
  602. /*
  603. decide on the type (and possibly level) of the current node
  604. */
  605. content_t new_node_content;
  606. s8 new_node_level = -1;
  607. s8 max_node_level = -1;
  608. u8 range = m_nodedef->get(liquid_kind).liquid_range;
  609. if (range > LIQUID_LEVEL_MAX + 1)
  610. range = LIQUID_LEVEL_MAX + 1;
  611. if ((num_sources >= 2 && m_nodedef->get(liquid_kind).liquid_renewable) || liquid_type == LIQUID_SOURCE) {
  612. // liquid_kind will be set to either the flowing alternative of the node (if it's a liquid)
  613. // or the flowing alternative of the first of the surrounding sources (if it's air), so
  614. // it's perfectly safe to use liquid_kind here to determine the new node content.
  615. new_node_content = m_nodedef->getId(m_nodedef->get(liquid_kind).liquid_alternative_source);
  616. } else if (num_sources >= 1 && sources[0].t != NEIGHBOR_LOWER) {
  617. // liquid_kind is set properly, see above
  618. max_node_level = new_node_level = LIQUID_LEVEL_MAX;
  619. if (new_node_level >= (LIQUID_LEVEL_MAX + 1 - range))
  620. new_node_content = liquid_kind;
  621. else
  622. new_node_content = floodable_node;
  623. } else if (ignored_sources && liquid_level >= 0) {
  624. // Maybe there are neighbouring sources that aren't loaded yet
  625. // so prevent flowing away.
  626. new_node_level = liquid_level;
  627. new_node_content = liquid_kind;
  628. } else {
  629. // no surrounding sources, so get the maximum level that can flow into this node
  630. for (u16 i = 0; i < num_flows; i++) {
  631. u8 nb_liquid_level = (flows[i].n.param2 & LIQUID_LEVEL_MASK);
  632. switch (flows[i].t) {
  633. case NEIGHBOR_UPPER:
  634. if (nb_liquid_level + WATER_DROP_BOOST > max_node_level) {
  635. max_node_level = LIQUID_LEVEL_MAX;
  636. if (nb_liquid_level + WATER_DROP_BOOST < LIQUID_LEVEL_MAX)
  637. max_node_level = nb_liquid_level + WATER_DROP_BOOST;
  638. } else if (nb_liquid_level > max_node_level) {
  639. max_node_level = nb_liquid_level;
  640. }
  641. break;
  642. case NEIGHBOR_LOWER:
  643. break;
  644. case NEIGHBOR_SAME_LEVEL:
  645. if ((flows[i].n.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK &&
  646. nb_liquid_level > 0 && nb_liquid_level - 1 > max_node_level)
  647. max_node_level = nb_liquid_level - 1;
  648. break;
  649. }
  650. }
  651. u8 viscosity = m_nodedef->get(liquid_kind).liquid_viscosity;
  652. if (viscosity > 1 && max_node_level != liquid_level) {
  653. // amount to gain, limited by viscosity
  654. // must be at least 1 in absolute value
  655. s8 level_inc = max_node_level - liquid_level;
  656. if (level_inc < -viscosity || level_inc > viscosity)
  657. new_node_level = liquid_level + level_inc/viscosity;
  658. else if (level_inc < 0)
  659. new_node_level = liquid_level - 1;
  660. else if (level_inc > 0)
  661. new_node_level = liquid_level + 1;
  662. if (new_node_level != max_node_level)
  663. must_reflow.push_back(p0);
  664. } else {
  665. new_node_level = max_node_level;
  666. }
  667. if (max_node_level >= (LIQUID_LEVEL_MAX + 1 - range))
  668. new_node_content = liquid_kind;
  669. else
  670. new_node_content = floodable_node;
  671. }
  672. /*
  673. check if anything has changed. if not, just continue with the next node.
  674. */
  675. if (new_node_content == n0.getContent() &&
  676. (m_nodedef->get(n0.getContent()).liquid_type != LIQUID_FLOWING ||
  677. ((n0.param2 & LIQUID_LEVEL_MASK) == (u8)new_node_level &&
  678. ((n0.param2 & LIQUID_FLOW_DOWN_MASK) == LIQUID_FLOW_DOWN_MASK)
  679. == flowing_down)))
  680. continue;
  681. /*
  682. update the current node
  683. */
  684. MapNode n00 = n0;
  685. //bool flow_down_enabled = (flowing_down && ((n0.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK));
  686. if (m_nodedef->get(new_node_content).liquid_type == LIQUID_FLOWING) {
  687. // set level to last 3 bits, flowing down bit to 4th bit
  688. n0.param2 = (flowing_down ? LIQUID_FLOW_DOWN_MASK : 0x00) | (new_node_level & LIQUID_LEVEL_MASK);
  689. } else {
  690. // set the liquid level and flow bit to 0
  691. n0.param2 = ~(LIQUID_LEVEL_MASK | LIQUID_FLOW_DOWN_MASK);
  692. }
  693. // change the node.
  694. n0.setContent(new_node_content);
  695. // on_flood() the node
  696. if (floodable_node != CONTENT_AIR) {
  697. if (env->getScriptIface()->node_on_flood(p0, n00, n0))
  698. continue;
  699. }
  700. // Ignore light (because calling voxalgo::update_lighting_nodes)
  701. n0.setLight(LIGHTBANK_DAY, 0, m_nodedef);
  702. n0.setLight(LIGHTBANK_NIGHT, 0, m_nodedef);
  703. // Find out whether there is a suspect for this action
  704. std::string suspect;
  705. if (m_gamedef->rollback())
  706. suspect = m_gamedef->rollback()->getSuspect(p0, 83, 1);
  707. if (m_gamedef->rollback() && !suspect.empty()) {
  708. // Blame suspect
  709. RollbackScopeActor rollback_scope(m_gamedef->rollback(), suspect, true);
  710. // Get old node for rollback
  711. RollbackNode rollback_oldnode(this, p0, m_gamedef);
  712. // Set node
  713. setNode(p0, n0);
  714. // Report
  715. RollbackNode rollback_newnode(this, p0, m_gamedef);
  716. RollbackAction action;
  717. action.setSetNode(p0, rollback_oldnode, rollback_newnode);
  718. m_gamedef->rollback()->reportAction(action);
  719. } else {
  720. // Set node
  721. setNode(p0, n0);
  722. }
  723. v3s16 blockpos = getNodeBlockPos(p0);
  724. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  725. if (block != NULL) {
  726. modified_blocks[blockpos] = block;
  727. changed_nodes.emplace_back(p0, n00);
  728. }
  729. /*
  730. enqueue neighbors for update if neccessary
  731. */
  732. switch (m_nodedef->get(n0.getContent()).liquid_type) {
  733. case LIQUID_SOURCE:
  734. case LIQUID_FLOWING:
  735. // make sure source flows into all neighboring nodes
  736. for (u16 i = 0; i < num_flows; i++)
  737. if (flows[i].t != NEIGHBOR_UPPER)
  738. m_transforming_liquid.push_back(flows[i].p);
  739. for (u16 i = 0; i < num_airs; i++)
  740. if (airs[i].t != NEIGHBOR_UPPER)
  741. m_transforming_liquid.push_back(airs[i].p);
  742. break;
  743. case LIQUID_NONE:
  744. // this flow has turned to air; neighboring flows might need to do the same
  745. for (u16 i = 0; i < num_flows; i++)
  746. m_transforming_liquid.push_back(flows[i].p);
  747. break;
  748. }
  749. }
  750. //infostream<<"Map::transformLiquids(): loopcount="<<loopcount<<std::endl;
  751. for (auto &iter : must_reflow)
  752. m_transforming_liquid.push_back(iter);
  753. voxalgo::update_lighting_nodes(this, changed_nodes, modified_blocks);
  754. /* ----------------------------------------------------------------------
  755. * Manage the queue so that it does not grow indefinately
  756. */
  757. u16 time_until_purge = g_settings->getU16("liquid_queue_purge_time");
  758. if (time_until_purge == 0)
  759. return; // Feature disabled
  760. time_until_purge *= 1000; // seconds -> milliseconds
  761. u64 curr_time = porting::getTimeMs();
  762. u32 prev_unprocessed = m_unprocessed_count;
  763. m_unprocessed_count = m_transforming_liquid.size();
  764. // if unprocessed block count is decreasing or stable
  765. if (m_unprocessed_count <= prev_unprocessed) {
  766. m_queue_size_timer_started = false;
  767. } else {
  768. if (!m_queue_size_timer_started)
  769. m_inc_trending_up_start_time = curr_time;
  770. m_queue_size_timer_started = true;
  771. }
  772. // Account for curr_time overflowing
  773. if (m_queue_size_timer_started && m_inc_trending_up_start_time > curr_time)
  774. m_queue_size_timer_started = false;
  775. /* If the queue has been growing for more than liquid_queue_purge_time seconds
  776. * and the number of unprocessed blocks is still > liquid_loop_max then we
  777. * cannot keep up; dump the oldest blocks from the queue so that the queue
  778. * has liquid_loop_max items in it
  779. */
  780. if (m_queue_size_timer_started
  781. && curr_time - m_inc_trending_up_start_time > time_until_purge
  782. && m_unprocessed_count > liquid_loop_max) {
  783. size_t dump_qty = m_unprocessed_count - liquid_loop_max;
  784. infostream << "transformLiquids(): DUMPING " << dump_qty
  785. << " blocks from the queue" << std::endl;
  786. while (dump_qty--)
  787. m_transforming_liquid.pop_front();
  788. m_queue_size_timer_started = false; // optimistically assume we can keep up now
  789. m_unprocessed_count = m_transforming_liquid.size();
  790. }
  791. }
  792. std::vector<v3s16> Map::findNodesWithMetadata(v3s16 p1, v3s16 p2)
  793. {
  794. std::vector<v3s16> positions_with_meta;
  795. sortBoxVerticies(p1, p2);
  796. v3s16 bpmin = getNodeBlockPos(p1);
  797. v3s16 bpmax = getNodeBlockPos(p2);
  798. VoxelArea area(p1, p2);
  799. for (s16 z = bpmin.Z; z <= bpmax.Z; z++)
  800. for (s16 y = bpmin.Y; y <= bpmax.Y; y++)
  801. for (s16 x = bpmin.X; x <= bpmax.X; x++) {
  802. v3s16 blockpos(x, y, z);
  803. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  804. if (!block) {
  805. verbosestream << "Map::getNodeMetadata(): Need to emerge "
  806. << PP(blockpos) << std::endl;
  807. block = emergeBlock(blockpos, false);
  808. }
  809. if (!block) {
  810. infostream << "WARNING: Map::getNodeMetadata(): Block not found"
  811. << std::endl;
  812. continue;
  813. }
  814. v3s16 p_base = blockpos * MAP_BLOCKSIZE;
  815. std::vector<v3s16> keys = block->m_node_metadata.getAllKeys();
  816. for (size_t i = 0; i != keys.size(); i++) {
  817. v3s16 p(keys[i] + p_base);
  818. if (!area.contains(p))
  819. continue;
  820. positions_with_meta.push_back(p);
  821. }
  822. }
  823. return positions_with_meta;
  824. }
  825. NodeMetadata *Map::getNodeMetadata(v3s16 p)
  826. {
  827. v3s16 blockpos = getNodeBlockPos(p);
  828. v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
  829. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  830. if(!block){
  831. infostream<<"Map::getNodeMetadata(): Need to emerge "
  832. <<PP(blockpos)<<std::endl;
  833. block = emergeBlock(blockpos, false);
  834. }
  835. if(!block){
  836. warningstream<<"Map::getNodeMetadata(): Block not found"
  837. <<std::endl;
  838. return NULL;
  839. }
  840. NodeMetadata *meta = block->m_node_metadata.get(p_rel);
  841. return meta;
  842. }
  843. bool Map::setNodeMetadata(v3s16 p, NodeMetadata *meta)
  844. {
  845. v3s16 blockpos = getNodeBlockPos(p);
  846. v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
  847. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  848. if(!block){
  849. infostream<<"Map::setNodeMetadata(): Need to emerge "
  850. <<PP(blockpos)<<std::endl;
  851. block = emergeBlock(blockpos, false);
  852. }
  853. if(!block){
  854. warningstream<<"Map::setNodeMetadata(): Block not found"
  855. <<std::endl;
  856. return false;
  857. }
  858. block->m_node_metadata.set(p_rel, meta);
  859. return true;
  860. }
  861. void Map::removeNodeMetadata(v3s16 p)
  862. {
  863. v3s16 blockpos = getNodeBlockPos(p);
  864. v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
  865. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  866. if(block == NULL)
  867. {
  868. warningstream<<"Map::removeNodeMetadata(): Block not found"
  869. <<std::endl;
  870. return;
  871. }
  872. block->m_node_metadata.remove(p_rel);
  873. }
  874. NodeTimer Map::getNodeTimer(v3s16 p)
  875. {
  876. v3s16 blockpos = getNodeBlockPos(p);
  877. v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
  878. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  879. if(!block){
  880. infostream<<"Map::getNodeTimer(): Need to emerge "
  881. <<PP(blockpos)<<std::endl;
  882. block = emergeBlock(blockpos, false);
  883. }
  884. if(!block){
  885. warningstream<<"Map::getNodeTimer(): Block not found"
  886. <<std::endl;
  887. return NodeTimer();
  888. }
  889. NodeTimer t = block->m_node_timers.get(p_rel);
  890. NodeTimer nt(t.timeout, t.elapsed, p);
  891. return nt;
  892. }
  893. void Map::setNodeTimer(const NodeTimer &t)
  894. {
  895. v3s16 p = t.position;
  896. v3s16 blockpos = getNodeBlockPos(p);
  897. v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
  898. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  899. if(!block){
  900. infostream<<"Map::setNodeTimer(): Need to emerge "
  901. <<PP(blockpos)<<std::endl;
  902. block = emergeBlock(blockpos, false);
  903. }
  904. if(!block){
  905. warningstream<<"Map::setNodeTimer(): Block not found"
  906. <<std::endl;
  907. return;
  908. }
  909. NodeTimer nt(t.timeout, t.elapsed, p_rel);
  910. block->m_node_timers.set(nt);
  911. }
  912. void Map::removeNodeTimer(v3s16 p)
  913. {
  914. v3s16 blockpos = getNodeBlockPos(p);
  915. v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
  916. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  917. if(block == NULL)
  918. {
  919. warningstream<<"Map::removeNodeTimer(): Block not found"
  920. <<std::endl;
  921. return;
  922. }
  923. block->m_node_timers.remove(p_rel);
  924. }
  925. bool Map::isOccluded(v3s16 p0, v3s16 p1, float step, float stepfac,
  926. float start_off, float end_off, u32 needed_count)
  927. {
  928. float d0 = (float)BS * p0.getDistanceFrom(p1);
  929. v3s16 u0 = p1 - p0;
  930. v3f uf = v3f(u0.X, u0.Y, u0.Z) * BS;
  931. uf.normalize();
  932. v3f p0f = v3f(p0.X, p0.Y, p0.Z) * BS;
  933. u32 count = 0;
  934. for(float s=start_off; s<d0+end_off; s+=step){
  935. v3f pf = p0f + uf * s;
  936. v3s16 p = floatToInt(pf, BS);
  937. MapNode n = getNodeNoEx(p);
  938. const ContentFeatures &f = m_nodedef->get(n);
  939. if(f.drawtype == NDT_NORMAL){
  940. // not transparent, see ContentFeature::updateTextures
  941. count++;
  942. if(count >= needed_count)
  943. return true;
  944. }
  945. step *= stepfac;
  946. }
  947. return false;
  948. }
  949. bool Map::isBlockOccluded(MapBlock *block, v3s16 cam_pos_nodes) {
  950. v3s16 cpn = block->getPos() * MAP_BLOCKSIZE;
  951. cpn += v3s16(MAP_BLOCKSIZE / 2, MAP_BLOCKSIZE / 2, MAP_BLOCKSIZE / 2);
  952. float step = BS * 1;
  953. float stepfac = 1.1;
  954. float startoff = BS * 1;
  955. // The occlusion search of 'isOccluded()' must stop short of the target
  956. // point by distance 'endoff' (end offset) to not enter the target mapblock.
  957. // For the 8 mapblock corners 'endoff' must therefore be the maximum diagonal
  958. // of a mapblock, because we must consider all view angles.
  959. // sqrt(1^2 + 1^2 + 1^2) = 1.732
  960. float endoff = -BS * MAP_BLOCKSIZE * 1.732050807569;
  961. s16 bs2 = MAP_BLOCKSIZE / 2 + 1;
  962. // to reduce the likelihood of falsely occluded blocks
  963. // require at least two solid blocks
  964. // this is a HACK, we should think of a more precise algorithm
  965. u32 needed_count = 2;
  966. return (
  967. // For the central point of the mapblock 'endoff' can be halved
  968. isOccluded(cam_pos_nodes, cpn,
  969. step, stepfac, startoff, endoff / 2.0f, needed_count) &&
  970. isOccluded(cam_pos_nodes, cpn + v3s16(bs2,bs2,bs2),
  971. step, stepfac, startoff, endoff, needed_count) &&
  972. isOccluded(cam_pos_nodes, cpn + v3s16(bs2,bs2,-bs2),
  973. step, stepfac, startoff, endoff, needed_count) &&
  974. isOccluded(cam_pos_nodes, cpn + v3s16(bs2,-bs2,bs2),
  975. step, stepfac, startoff, endoff, needed_count) &&
  976. isOccluded(cam_pos_nodes, cpn + v3s16(bs2,-bs2,-bs2),
  977. step, stepfac, startoff, endoff, needed_count) &&
  978. isOccluded(cam_pos_nodes, cpn + v3s16(-bs2,bs2,bs2),
  979. step, stepfac, startoff, endoff, needed_count) &&
  980. isOccluded(cam_pos_nodes, cpn + v3s16(-bs2,bs2,-bs2),
  981. step, stepfac, startoff, endoff, needed_count) &&
  982. isOccluded(cam_pos_nodes, cpn + v3s16(-bs2,-bs2,bs2),
  983. step, stepfac, startoff, endoff, needed_count) &&
  984. isOccluded(cam_pos_nodes, cpn + v3s16(-bs2,-bs2,-bs2),
  985. step, stepfac, startoff, endoff, needed_count));
  986. }
  987. /*
  988. ServerMap
  989. */
  990. ServerMap::ServerMap(const std::string &savedir, IGameDef *gamedef,
  991. EmergeManager *emerge):
  992. Map(dout_server, gamedef),
  993. settings_mgr(g_settings, savedir + DIR_DELIM + "map_meta.txt"),
  994. m_emerge(emerge)
  995. {
  996. verbosestream<<FUNCTION_NAME<<std::endl;
  997. // Tell the EmergeManager about our MapSettingsManager
  998. emerge->map_settings_mgr = &settings_mgr;
  999. /*
  1000. Try to load map; if not found, create a new one.
  1001. */
  1002. // Determine which database backend to use
  1003. std::string conf_path = savedir + DIR_DELIM + "world.mt";
  1004. Settings conf;
  1005. bool succeeded = conf.readConfigFile(conf_path.c_str());
  1006. if (!succeeded || !conf.exists("backend")) {
  1007. // fall back to sqlite3
  1008. conf.set("backend", "sqlite3");
  1009. }
  1010. std::string backend = conf.get("backend");
  1011. dbase = createDatabase(backend, savedir, conf);
  1012. if (conf.exists("readonly_backend")) {
  1013. std::string readonly_dir = savedir + DIR_DELIM + "readonly";
  1014. dbase_ro = createDatabase(conf.get("readonly_backend"), readonly_dir, conf);
  1015. }
  1016. if (!conf.updateConfigFile(conf_path.c_str()))
  1017. errorstream << "ServerMap::ServerMap(): Failed to update world.mt!" << std::endl;
  1018. m_savedir = savedir;
  1019. m_map_saving_enabled = false;
  1020. try {
  1021. // If directory exists, check contents and load if possible
  1022. if (fs::PathExists(m_savedir)) {
  1023. // If directory is empty, it is safe to save into it.
  1024. if (fs::GetDirListing(m_savedir).empty()) {
  1025. infostream<<"ServerMap: Empty save directory is valid."
  1026. <<std::endl;
  1027. m_map_saving_enabled = true;
  1028. }
  1029. else
  1030. {
  1031. if (settings_mgr.loadMapMeta()) {
  1032. infostream << "ServerMap: Metadata loaded from "
  1033. << savedir << std::endl;
  1034. } else {
  1035. infostream << "ServerMap: Metadata could not be loaded "
  1036. "from " << savedir << ", assuming valid save "
  1037. "directory." << std::endl;
  1038. }
  1039. m_map_saving_enabled = true;
  1040. // Map loaded, not creating new one
  1041. return;
  1042. }
  1043. }
  1044. // If directory doesn't exist, it is safe to save to it
  1045. else{
  1046. m_map_saving_enabled = true;
  1047. }
  1048. }
  1049. catch(std::exception &e)
  1050. {
  1051. warningstream<<"ServerMap: Failed to load map from "<<savedir
  1052. <<", exception: "<<e.what()<<std::endl;
  1053. infostream<<"Please remove the map or fix it."<<std::endl;
  1054. warningstream<<"Map saving will be disabled."<<std::endl;
  1055. }
  1056. }
  1057. ServerMap::~ServerMap()
  1058. {
  1059. verbosestream<<FUNCTION_NAME<<std::endl;
  1060. try
  1061. {
  1062. if (m_map_saving_enabled) {
  1063. // Save only changed parts
  1064. save(MOD_STATE_WRITE_AT_UNLOAD);
  1065. infostream << "ServerMap: Saved map to " << m_savedir << std::endl;
  1066. } else {
  1067. infostream << "ServerMap: Map not saved" << std::endl;
  1068. }
  1069. }
  1070. catch(std::exception &e)
  1071. {
  1072. infostream<<"ServerMap: Failed to save map to "<<m_savedir
  1073. <<", exception: "<<e.what()<<std::endl;
  1074. }
  1075. /*
  1076. Close database if it was opened
  1077. */
  1078. delete dbase;
  1079. if (dbase_ro)
  1080. delete dbase_ro;
  1081. #if 0
  1082. /*
  1083. Free all MapChunks
  1084. */
  1085. core::map<v2s16, MapChunk*>::Iterator i = m_chunks.getIterator();
  1086. for(; i.atEnd() == false; i++)
  1087. {
  1088. MapChunk *chunk = i.getNode()->getValue();
  1089. delete chunk;
  1090. }
  1091. #endif
  1092. }
  1093. MapgenParams *ServerMap::getMapgenParams()
  1094. {
  1095. // getMapgenParams() should only ever be called after Server is initialized
  1096. assert(settings_mgr.mapgen_params != NULL);
  1097. return settings_mgr.mapgen_params;
  1098. }
  1099. u64 ServerMap::getSeed()
  1100. {
  1101. return getMapgenParams()->seed;
  1102. }
  1103. s16 ServerMap::getWaterLevel()
  1104. {
  1105. return getMapgenParams()->water_level;
  1106. }
  1107. bool ServerMap::blockpos_over_mapgen_limit(v3s16 p)
  1108. {
  1109. const s16 mapgen_limit_bp = rangelim(
  1110. getMapgenParams()->mapgen_limit, 0, MAX_MAP_GENERATION_LIMIT) /
  1111. MAP_BLOCKSIZE;
  1112. return p.X < -mapgen_limit_bp ||
  1113. p.X > mapgen_limit_bp ||
  1114. p.Y < -mapgen_limit_bp ||
  1115. p.Y > mapgen_limit_bp ||
  1116. p.Z < -mapgen_limit_bp ||
  1117. p.Z > mapgen_limit_bp;
  1118. }
  1119. bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data)
  1120. {
  1121. s16 csize = getMapgenParams()->chunksize;
  1122. v3s16 bpmin = EmergeManager::getContainingChunk(blockpos, csize);
  1123. v3s16 bpmax = bpmin + v3s16(1, 1, 1) * (csize - 1);
  1124. bool enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info;
  1125. EMERGE_DBG_OUT("initBlockMake(): " PP(bpmin) " - " PP(bpmax));
  1126. v3s16 extra_borders(1, 1, 1);
  1127. v3s16 full_bpmin = bpmin - extra_borders;
  1128. v3s16 full_bpmax = bpmax + extra_borders;
  1129. // Do nothing if not inside mapgen limits (+-1 because of neighbors)
  1130. if (blockpos_over_mapgen_limit(full_bpmin) ||
  1131. blockpos_over_mapgen_limit(full_bpmax))
  1132. return false;
  1133. data->seed = getSeed();
  1134. data->blockpos_min = bpmin;
  1135. data->blockpos_max = bpmax;
  1136. data->blockpos_requested = blockpos;
  1137. data->nodedef = m_nodedef;
  1138. /*
  1139. Create the whole area of this and the neighboring blocks
  1140. */
  1141. for (s16 x = full_bpmin.X; x <= full_bpmax.X; x++)
  1142. for (s16 z = full_bpmin.Z; z <= full_bpmax.Z; z++) {
  1143. v2s16 sectorpos(x, z);
  1144. // Sector metadata is loaded from disk if not already loaded.
  1145. MapSector *sector = createSector(sectorpos);
  1146. FATAL_ERROR_IF(sector == NULL, "createSector() failed");
  1147. for (s16 y = full_bpmin.Y; y <= full_bpmax.Y; y++) {
  1148. v3s16 p(x, y, z);
  1149. MapBlock *block = emergeBlock(p, false);
  1150. if (block == NULL) {
  1151. block = createBlock(p);
  1152. // Block gets sunlight if this is true.
  1153. // Refer to the map generator heuristics.
  1154. bool ug = m_emerge->isBlockUnderground(p);
  1155. block->setIsUnderground(ug);
  1156. }
  1157. }
  1158. }
  1159. /*
  1160. Now we have a big empty area.
  1161. Make a ManualMapVoxelManipulator that contains this and the
  1162. neighboring blocks
  1163. */
  1164. data->vmanip = new MMVManip(this);
  1165. data->vmanip->initialEmerge(full_bpmin, full_bpmax);
  1166. // Note: we may need this again at some point.
  1167. #if 0
  1168. // Ensure none of the blocks to be generated were marked as
  1169. // containing CONTENT_IGNORE
  1170. for (s16 z = blockpos_min.Z; z <= blockpos_max.Z; z++) {
  1171. for (s16 y = blockpos_min.Y; y <= blockpos_max.Y; y++) {
  1172. for (s16 x = blockpos_min.X; x <= blockpos_max.X; x++) {
  1173. core::map<v3s16, u8>::Node *n;
  1174. n = data->vmanip->m_loaded_blocks.find(v3s16(x, y, z));
  1175. if (n == NULL)
  1176. continue;
  1177. u8 flags = n->getValue();
  1178. flags &= ~VMANIP_BLOCK_CONTAINS_CIGNORE;
  1179. n->setValue(flags);
  1180. }
  1181. }
  1182. }
  1183. #endif
  1184. // Data is ready now.
  1185. return true;
  1186. }
  1187. void ServerMap::finishBlockMake(BlockMakeData *data,
  1188. std::map<v3s16, MapBlock*> *changed_blocks)
  1189. {
  1190. v3s16 bpmin = data->blockpos_min;
  1191. v3s16 bpmax = data->blockpos_max;
  1192. v3s16 extra_borders(1, 1, 1);
  1193. bool enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info;
  1194. EMERGE_DBG_OUT("finishBlockMake(): " PP(bpmin) " - " PP(bpmax));
  1195. /*
  1196. Blit generated stuff to map
  1197. NOTE: blitBackAll adds nearly everything to changed_blocks
  1198. */
  1199. data->vmanip->blitBackAll(changed_blocks);
  1200. EMERGE_DBG_OUT("finishBlockMake: changed_blocks.size()="
  1201. << changed_blocks->size());
  1202. /*
  1203. Copy transforming liquid information
  1204. */
  1205. while (data->transforming_liquid.size()) {
  1206. m_transforming_liquid.push_back(data->transforming_liquid.front());
  1207. data->transforming_liquid.pop_front();
  1208. }
  1209. for (auto &changed_block : *changed_blocks) {
  1210. MapBlock *block = changed_block.second;
  1211. if (!block)
  1212. continue;
  1213. /*
  1214. Update day/night difference cache of the MapBlocks
  1215. */
  1216. block->expireDayNightDiff();
  1217. /*
  1218. Set block as modified
  1219. */
  1220. block->raiseModified(MOD_STATE_WRITE_NEEDED,
  1221. MOD_REASON_EXPIRE_DAYNIGHTDIFF);
  1222. }
  1223. /*
  1224. Set central blocks as generated
  1225. */
  1226. for (s16 x = bpmin.X; x <= bpmax.X; x++)
  1227. for (s16 z = bpmin.Z; z <= bpmax.Z; z++)
  1228. for (s16 y = bpmin.Y; y <= bpmax.Y; y++) {
  1229. MapBlock *block = getBlockNoCreateNoEx(v3s16(x, y, z));
  1230. if (!block)
  1231. continue;
  1232. block->setGenerated(true);
  1233. }
  1234. /*
  1235. Save changed parts of map
  1236. NOTE: Will be saved later.
  1237. */
  1238. //save(MOD_STATE_WRITE_AT_UNLOAD);
  1239. }
  1240. MapSector *ServerMap::createSector(v2s16 p2d)
  1241. {
  1242. /*
  1243. Check if it exists already in memory
  1244. */
  1245. MapSector *sector = getSectorNoGenerateNoEx(p2d);
  1246. if (sector)
  1247. return sector;
  1248. /*
  1249. Do not create over max mapgen limit
  1250. */
  1251. const s16 max_limit_bp = MAX_MAP_GENERATION_LIMIT / MAP_BLOCKSIZE;
  1252. if (p2d.X < -max_limit_bp ||
  1253. p2d.X > max_limit_bp ||
  1254. p2d.Y < -max_limit_bp ||
  1255. p2d.Y > max_limit_bp)
  1256. throw InvalidPositionException("createSector(): pos. over max mapgen limit");
  1257. /*
  1258. Generate blank sector
  1259. */
  1260. sector = new MapSector(this, p2d, m_gamedef);
  1261. // Sector position on map in nodes
  1262. //v2s16 nodepos2d = p2d * MAP_BLOCKSIZE;
  1263. /*
  1264. Insert to container
  1265. */
  1266. m_sectors[p2d] = sector;
  1267. return sector;
  1268. }
  1269. #if 0
  1270. /*
  1271. This is a quick-hand function for calling makeBlock().
  1272. */
  1273. MapBlock * ServerMap::generateBlock(
  1274. v3s16 p,
  1275. std::map<v3s16, MapBlock*> &modified_blocks
  1276. )
  1277. {
  1278. bool enable_mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info");
  1279. TimeTaker timer("generateBlock");
  1280. //MapBlock *block = original_dummy;
  1281. v2s16 p2d(p.X, p.Z);
  1282. v2s16 p2d_nodes = p2d * MAP_BLOCKSIZE;
  1283. /*
  1284. Do not generate over-limit
  1285. */
  1286. if(blockpos_over_limit(p))
  1287. {
  1288. infostream<<FUNCTION_NAME<<": Block position over limit"<<std::endl;
  1289. throw InvalidPositionException("generateBlock(): pos. over limit");
  1290. }
  1291. /*
  1292. Create block make data
  1293. */
  1294. BlockMakeData data;
  1295. initBlockMake(&data, p);
  1296. /*
  1297. Generate block
  1298. */
  1299. {
  1300. TimeTaker t("mapgen::make_block()");
  1301. mapgen->makeChunk(&data);
  1302. //mapgen::make_block(&data);
  1303. if(enable_mapgen_debug_info == false)
  1304. t.stop(true); // Hide output
  1305. }
  1306. /*
  1307. Blit data back on map, update lighting, add mobs and whatever this does
  1308. */
  1309. finishBlockMake(&data, modified_blocks);
  1310. /*
  1311. Get central block
  1312. */
  1313. MapBlock *block = getBlockNoCreateNoEx(p);
  1314. #if 0
  1315. /*
  1316. Check result
  1317. */
  1318. if(block)
  1319. {
  1320. bool erroneus_content = false;
  1321. for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
  1322. for(s16 y0=0; y0<MAP_BLOCKSIZE; y0++)
  1323. for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
  1324. {
  1325. v3s16 p(x0,y0,z0);
  1326. MapNode n = block->getNode(p);
  1327. if(n.getContent() == CONTENT_IGNORE)
  1328. {
  1329. infostream<<"CONTENT_IGNORE at "
  1330. <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
  1331. <<std::endl;
  1332. erroneus_content = true;
  1333. assert(0);
  1334. }
  1335. }
  1336. if(erroneus_content)
  1337. {
  1338. assert(0);
  1339. }
  1340. }
  1341. #endif
  1342. #if 0
  1343. /*
  1344. Generate a completely empty block
  1345. */
  1346. if(block)
  1347. {
  1348. for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
  1349. for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
  1350. {
  1351. for(s16 y0=0; y0<MAP_BLOCKSIZE; y0++)
  1352. {
  1353. MapNode n;
  1354. n.setContent(CONTENT_AIR);
  1355. block->setNode(v3s16(x0,y0,z0), n);
  1356. }
  1357. }
  1358. }
  1359. #endif
  1360. if(enable_mapgen_debug_info == false)
  1361. timer.stop(true); // Hide output
  1362. return block;
  1363. }
  1364. #endif
  1365. MapBlock * ServerMap::createBlock(v3s16 p)
  1366. {
  1367. /*
  1368. Do not create over max mapgen limit
  1369. */
  1370. if (blockpos_over_max_limit(p))
  1371. throw InvalidPositionException("createBlock(): pos. over max mapgen limit");
  1372. v2s16 p2d(p.X, p.Z);
  1373. s16 block_y = p.Y;
  1374. /*
  1375. This will create or load a sector if not found in memory.
  1376. If block exists on disk, it will be loaded.
  1377. NOTE: On old save formats, this will be slow, as it generates
  1378. lighting on blocks for them.
  1379. */
  1380. MapSector *sector;
  1381. try {
  1382. sector = createSector(p2d);
  1383. } catch (InvalidPositionException &e) {
  1384. infostream<<"createBlock: createSector() failed"<<std::endl;
  1385. throw e;
  1386. }
  1387. /*
  1388. Try to get a block from the sector
  1389. */
  1390. MapBlock *block = sector->getBlockNoCreateNoEx(block_y);
  1391. if (block) {
  1392. if(block->isDummy())
  1393. block->unDummify();
  1394. return block;
  1395. }
  1396. // Create blank
  1397. block = sector->createBlankBlock(block_y);
  1398. return block;
  1399. }
  1400. MapBlock * ServerMap::emergeBlock(v3s16 p, bool create_blank)
  1401. {
  1402. {
  1403. MapBlock *block = getBlockNoCreateNoEx(p);
  1404. if (block && !block->isDummy())
  1405. return block;
  1406. }
  1407. {
  1408. MapBlock *block = loadBlock(p);
  1409. if(block)
  1410. return block;
  1411. }
  1412. if (create_blank) {
  1413. MapSector *sector = createSector(v2s16(p.X, p.Z));
  1414. MapBlock *block = sector->createBlankBlock(p.Y);
  1415. return block;
  1416. }
  1417. return NULL;
  1418. }
  1419. MapBlock *ServerMap::getBlockOrEmerge(v3s16 p3d)
  1420. {
  1421. MapBlock *block = getBlockNoCreateNoEx(p3d);
  1422. if (block == NULL)
  1423. m_emerge->enqueueBlockEmerge(PEER_ID_INEXISTENT, p3d, false);
  1424. return block;
  1425. }
  1426. // N.B. This requires no synchronization, since data will not be modified unless
  1427. // the VoxelManipulator being updated belongs to the same thread.
  1428. void ServerMap::updateVManip(v3s16 pos)
  1429. {
  1430. Mapgen *mg = m_emerge->getCurrentMapgen();
  1431. if (!mg)
  1432. return;
  1433. MMVManip *vm = mg->vm;
  1434. if (!vm)
  1435. return;
  1436. if (!vm->m_area.contains(pos))
  1437. return;
  1438. s32 idx = vm->m_area.index(pos);
  1439. vm->m_data[idx] = getNodeNoEx(pos);
  1440. vm->m_flags[idx] &= ~VOXELFLAG_NO_DATA;
  1441. vm->m_is_dirty = true;
  1442. }
  1443. s16 ServerMap::findGroundLevel(v2s16 p2d)
  1444. {
  1445. #if 0
  1446. /*
  1447. Uh, just do something random...
  1448. */
  1449. // Find existing map from top to down
  1450. s16 max=63;
  1451. s16 min=-64;
  1452. v3s16 p(p2d.X, max, p2d.Y);
  1453. for(; p.Y>min; p.Y--)
  1454. {
  1455. MapNode n = getNodeNoEx(p);
  1456. if(n.getContent() != CONTENT_IGNORE)
  1457. break;
  1458. }
  1459. if(p.Y == min)
  1460. goto plan_b;
  1461. // If this node is not air, go to plan b
  1462. if(getNodeNoEx(p).getContent() != CONTENT_AIR)
  1463. goto plan_b;
  1464. // Search existing walkable and return it
  1465. for(; p.Y>min; p.Y--)
  1466. {
  1467. MapNode n = getNodeNoEx(p);
  1468. if(content_walkable(n.d) && n.getContent() != CONTENT_IGNORE)
  1469. return p.Y;
  1470. }
  1471. // Move to plan b
  1472. plan_b:
  1473. #endif
  1474. /*
  1475. Determine from map generator noise functions
  1476. */
  1477. s16 level = m_emerge->getGroundLevelAtPoint(p2d);
  1478. return level;
  1479. //double level = base_rock_level_2d(m_seed, p2d) + AVERAGE_MUD_AMOUNT;
  1480. //return (s16)level;
  1481. }
  1482. bool ServerMap::loadFromFolders() {
  1483. if (!dbase->initialized() &&
  1484. !fs::PathExists(m_savedir + DIR_DELIM + "map.sqlite"))
  1485. return true;
  1486. return false;
  1487. }
  1488. void ServerMap::createDirs(std::string path)
  1489. {
  1490. if (!fs::CreateAllDirs(path)) {
  1491. m_dout<<"ServerMap: Failed to create directory "
  1492. <<"\""<<path<<"\""<<std::endl;
  1493. throw BaseException("ServerMap failed to create directory");
  1494. }
  1495. }
  1496. std::string ServerMap::getSectorDir(v2s16 pos, int layout)
  1497. {
  1498. char cc[9];
  1499. switch(layout)
  1500. {
  1501. case 1:
  1502. porting::mt_snprintf(cc, sizeof(cc), "%.4x%.4x",
  1503. (unsigned int) pos.X & 0xffff,
  1504. (unsigned int) pos.Y & 0xffff);
  1505. return m_savedir + DIR_DELIM + "sectors" + DIR_DELIM + cc;
  1506. case 2:
  1507. porting::mt_snprintf(cc, sizeof(cc), (std::string("%.3x") + DIR_DELIM + "%.3x").c_str(),
  1508. (unsigned int) pos.X & 0xfff,
  1509. (unsigned int) pos.Y & 0xfff);
  1510. return m_savedir + DIR_DELIM + "sectors2" + DIR_DELIM + cc;
  1511. default:
  1512. assert(false);
  1513. return "";
  1514. }
  1515. }
  1516. v2s16 ServerMap::getSectorPos(const std::string &dirname)
  1517. {
  1518. unsigned int x = 0, y = 0;
  1519. int r;
  1520. std::string component;
  1521. fs::RemoveLastPathComponent(dirname, &component, 1);
  1522. if(component.size() == 8)
  1523. {
  1524. // Old layout
  1525. r = sscanf(component.c_str(), "%4x%4x", &x, &y);
  1526. }
  1527. else if(component.size() == 3)
  1528. {
  1529. // New layout
  1530. fs::RemoveLastPathComponent(dirname, &component, 2);
  1531. r = sscanf(component.c_str(), (std::string("%3x") + DIR_DELIM + "%3x").c_str(), &x, &y);
  1532. // Sign-extend the 12 bit values up to 16 bits...
  1533. if(x & 0x800) x |= 0xF000;
  1534. if(y & 0x800) y |= 0xF000;
  1535. }
  1536. else
  1537. {
  1538. r = -1;
  1539. }
  1540. FATAL_ERROR_IF(r != 2, "getSectorPos()");
  1541. v2s16 pos((s16)x, (s16)y);
  1542. return pos;
  1543. }
  1544. v3s16 ServerMap::getBlockPos(const std::string &sectordir, const std::string &blockfile)
  1545. {
  1546. v2s16 p2d = getSectorPos(sectordir);
  1547. if(blockfile.size() != 4){
  1548. throw InvalidFilenameException("Invalid block filename");
  1549. }
  1550. unsigned int y;
  1551. int r = sscanf(blockfile.c_str(), "%4x", &y);
  1552. if(r != 1)
  1553. throw InvalidFilenameException("Invalid block filename");
  1554. return v3s16(p2d.X, y, p2d.Y);
  1555. }
  1556. std::string ServerMap::getBlockFilename(v3s16 p)
  1557. {
  1558. char cc[5];
  1559. porting::mt_snprintf(cc, sizeof(cc), "%.4x", (unsigned int)p.Y&0xffff);
  1560. return cc;
  1561. }
  1562. void ServerMap::save(ModifiedState save_level)
  1563. {
  1564. if (!m_map_saving_enabled) {
  1565. warningstream<<"Not saving map, saving disabled."<<std::endl;
  1566. return;
  1567. }
  1568. if(save_level == MOD_STATE_CLEAN)
  1569. infostream<<"ServerMap: Saving whole map, this can take time."
  1570. <<std::endl;
  1571. if (m_map_metadata_changed || save_level == MOD_STATE_CLEAN) {
  1572. if (settings_mgr.saveMapMeta())
  1573. m_map_metadata_changed = false;
  1574. }
  1575. // Profile modified reasons
  1576. Profiler modprofiler;
  1577. u32 block_count = 0;
  1578. u32 block_count_all = 0; // Number of blocks in memory
  1579. // Don't do anything with sqlite unless something is really saved
  1580. bool save_started = false;
  1581. for (auto &sector_it : m_sectors) {
  1582. MapSector *sector = sector_it.second;
  1583. MapBlockVect blocks;
  1584. sector->getBlocks(blocks);
  1585. for (MapBlock *block : blocks) {
  1586. block_count_all++;
  1587. if(block->getModified() >= (u32)save_level) {
  1588. // Lazy beginSave()
  1589. if(!save_started) {
  1590. beginSave();
  1591. save_started = true;
  1592. }
  1593. modprofiler.add(block->getModifiedReasonString(), 1);
  1594. saveBlock(block);
  1595. block_count++;
  1596. }
  1597. }
  1598. }
  1599. if(save_started)
  1600. endSave();
  1601. /*
  1602. Only print if something happened or saved whole map
  1603. */
  1604. if(save_level == MOD_STATE_CLEAN
  1605. || block_count != 0) {
  1606. infostream<<"ServerMap: Written: "
  1607. <<block_count<<" block files"
  1608. <<", "<<block_count_all<<" blocks in memory."
  1609. <<std::endl;
  1610. PrintInfo(infostream); // ServerMap/ClientMap:
  1611. infostream<<"Blocks modified by: "<<std::endl;
  1612. modprofiler.print(infostream);
  1613. }
  1614. }
  1615. void ServerMap::listAllLoadableBlocks(std::vector<v3s16> &dst)
  1616. {
  1617. if (loadFromFolders()) {
  1618. errorstream << "Map::listAllLoadableBlocks(): Result will be missing "
  1619. << "all blocks that are stored in flat files." << std::endl;
  1620. }
  1621. dbase->listAllLoadableBlocks(dst);
  1622. if (dbase_ro)
  1623. dbase_ro->listAllLoadableBlocks(dst);
  1624. }
  1625. void ServerMap::listAllLoadedBlocks(std::vector<v3s16> &dst)
  1626. {
  1627. for (auto &sector_it : m_sectors) {
  1628. MapSector *sector = sector_it.second;
  1629. MapBlockVect blocks;
  1630. sector->getBlocks(blocks);
  1631. for (MapBlock *block : blocks) {
  1632. v3s16 p = block->getPos();
  1633. dst.push_back(p);
  1634. }
  1635. }
  1636. }
  1637. MapDatabase *ServerMap::createDatabase(
  1638. const std::string &name,
  1639. const std::string &savedir,
  1640. Settings &conf)
  1641. {
  1642. if (name == "sqlite3")
  1643. return new MapDatabaseSQLite3(savedir);
  1644. if (name == "dummy")
  1645. return new Database_Dummy();
  1646. #if USE_LEVELDB
  1647. if (name == "leveldb")
  1648. return new Database_LevelDB(savedir);
  1649. #endif
  1650. #if USE_REDIS
  1651. if (name == "redis")
  1652. return new Database_Redis(conf);
  1653. #endif
  1654. #if USE_POSTGRESQL
  1655. if (name == "postgresql") {
  1656. std::string connect_string;
  1657. conf.getNoEx("pgsql_connection", connect_string);
  1658. return new MapDatabasePostgreSQL(connect_string);
  1659. }
  1660. #endif
  1661. throw BaseException(std::string("Database backend ") + name + " not supported.");
  1662. }
  1663. void ServerMap::beginSave()
  1664. {
  1665. dbase->beginSave();
  1666. }
  1667. void ServerMap::endSave()
  1668. {
  1669. dbase->endSave();
  1670. }
  1671. bool ServerMap::saveBlock(MapBlock *block)
  1672. {
  1673. return saveBlock(block, dbase);
  1674. }
  1675. bool ServerMap::saveBlock(MapBlock *block, MapDatabase *db)
  1676. {
  1677. v3s16 p3d = block->getPos();
  1678. // Dummy blocks are not written
  1679. if (block->isDummy()) {
  1680. warningstream << "saveBlock: Not writing dummy block "
  1681. << PP(p3d) << std::endl;
  1682. return true;
  1683. }
  1684. // Format used for writing
  1685. u8 version = SER_FMT_VER_HIGHEST_WRITE;
  1686. /*
  1687. [0] u8 serialization version
  1688. [1] data
  1689. */
  1690. std::ostringstream o(std::ios_base::binary);
  1691. o.write((char*) &version, 1);
  1692. block->serialize(o, version, true);
  1693. bool ret = db->saveBlock(p3d, o.str());
  1694. if (ret) {
  1695. // We just wrote it to the disk so clear modified flag
  1696. block->resetModified();
  1697. }
  1698. return ret;
  1699. }
  1700. void ServerMap::loadBlock(const std::string &sectordir, const std::string &blockfile,
  1701. MapSector *sector, bool save_after_load)
  1702. {
  1703. std::string fullpath = sectordir + DIR_DELIM + blockfile;
  1704. try {
  1705. std::ifstream is(fullpath.c_str(), std::ios_base::binary);
  1706. if (!is.good())
  1707. throw FileNotGoodException("Cannot open block file");
  1708. v3s16 p3d = getBlockPos(sectordir, blockfile);
  1709. v2s16 p2d(p3d.X, p3d.Z);
  1710. assert(sector->getPos() == p2d);
  1711. u8 version = SER_FMT_VER_INVALID;
  1712. is.read((char*)&version, 1);
  1713. if(is.fail())
  1714. throw SerializationError("ServerMap::loadBlock(): Failed"
  1715. " to read MapBlock version");
  1716. /*u32 block_size = MapBlock::serializedLength(version);
  1717. SharedBuffer<u8> data(block_size);
  1718. is.read((char*)*data, block_size);*/
  1719. // This will always return a sector because we're the server
  1720. //MapSector *sector = emergeSector(p2d);
  1721. MapBlock *block = NULL;
  1722. bool created_new = false;
  1723. block = sector->getBlockNoCreateNoEx(p3d.Y);
  1724. if(block == NULL)
  1725. {
  1726. block = sector->createBlankBlockNoInsert(p3d.Y);
  1727. created_new = true;
  1728. }
  1729. // Read basic data
  1730. block->deSerialize(is, version, true);
  1731. // If it's a new block, insert it to the map
  1732. if (created_new) {
  1733. sector->insertBlock(block);
  1734. ReflowScan scanner(this, m_emerge->ndef);
  1735. scanner.scan(block, &m_transforming_liquid);
  1736. }
  1737. /*
  1738. Save blocks loaded in old format in new format
  1739. */
  1740. if(version < SER_FMT_VER_HIGHEST_WRITE || save_after_load)
  1741. {
  1742. saveBlock(block);
  1743. // Should be in database now, so delete the old file
  1744. fs::RecursiveDelete(fullpath);
  1745. }
  1746. // We just loaded it from the disk, so it's up-to-date.
  1747. block->resetModified();
  1748. }
  1749. catch(SerializationError &e)
  1750. {
  1751. warningstream<<"Invalid block data on disk "
  1752. <<"fullpath="<<fullpath
  1753. <<" (SerializationError). "
  1754. <<"what()="<<e.what()
  1755. <<std::endl;
  1756. // Ignoring. A new one will be generated.
  1757. abort();
  1758. // TODO: Backup file; name is in fullpath.
  1759. }
  1760. }
  1761. void ServerMap::loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool save_after_load)
  1762. {
  1763. try {
  1764. std::istringstream is(*blob, std::ios_base::binary);
  1765. u8 version = SER_FMT_VER_INVALID;
  1766. is.read((char*)&version, 1);
  1767. if(is.fail())
  1768. throw SerializationError("ServerMap::loadBlock(): Failed"
  1769. " to read MapBlock version");
  1770. MapBlock *block = NULL;
  1771. bool created_new = false;
  1772. block = sector->getBlockNoCreateNoEx(p3d.Y);
  1773. if(block == NULL)
  1774. {
  1775. block = sector->createBlankBlockNoInsert(p3d.Y);
  1776. created_new = true;
  1777. }
  1778. // Read basic data
  1779. block->deSerialize(is, version, true);
  1780. // If it's a new block, insert it to the map
  1781. if (created_new) {
  1782. sector->insertBlock(block);
  1783. ReflowScan scanner(this, m_emerge->ndef);
  1784. scanner.scan(block, &m_transforming_liquid);
  1785. }
  1786. /*
  1787. Save blocks loaded in old format in new format
  1788. */
  1789. //if(version < SER_FMT_VER_HIGHEST_READ || save_after_load)
  1790. // Only save if asked to; no need to update version
  1791. if(save_after_load)
  1792. saveBlock(block);
  1793. // We just loaded it from, so it's up-to-date.
  1794. block->resetModified();
  1795. }
  1796. catch(SerializationError &e)
  1797. {
  1798. errorstream<<"Invalid block data in database"
  1799. <<" ("<<p3d.X<<","<<p3d.Y<<","<<p3d.Z<<")"
  1800. <<" (SerializationError): "<<e.what()<<std::endl;
  1801. // TODO: Block should be marked as invalid in memory so that it is
  1802. // not touched but the game can run
  1803. if(g_settings->getBool("ignore_world_load_errors")){
  1804. errorstream<<"Ignoring block load error. Duck and cover! "
  1805. <<"(ignore_world_load_errors)"<<std::endl;
  1806. } else {
  1807. throw SerializationError("Invalid block data in database");
  1808. }
  1809. }
  1810. }
  1811. MapBlock* ServerMap::loadBlock(v3s16 blockpos)
  1812. {
  1813. bool created_new = (getBlockNoCreateNoEx(blockpos) == NULL);
  1814. v2s16 p2d(blockpos.X, blockpos.Z);
  1815. std::string ret;
  1816. dbase->loadBlock(blockpos, &ret);
  1817. if (!ret.empty()) {
  1818. loadBlock(&ret, blockpos, createSector(p2d), false);
  1819. } else if (dbase_ro) {
  1820. dbase_ro->loadBlock(blockpos, &ret);
  1821. if (!ret.empty()) {
  1822. loadBlock(&ret, blockpos, createSector(p2d), false);
  1823. }
  1824. } else {
  1825. // Not found in database, try the files
  1826. // The directory layout we're going to load from.
  1827. // 1 - original sectors/xxxxzzzz/
  1828. // 2 - new sectors2/xxx/zzz/
  1829. // If we load from anything but the latest structure, we will
  1830. // immediately save to the new one, and remove the old.
  1831. std::string sectordir1 = getSectorDir(p2d, 1);
  1832. std::string sectordir;
  1833. if (fs::PathExists(sectordir1)) {
  1834. sectordir = sectordir1;
  1835. } else {
  1836. sectordir = getSectorDir(p2d, 2);
  1837. }
  1838. /*
  1839. Make sure sector is loaded
  1840. */
  1841. MapSector *sector = getSectorNoGenerateNoEx(p2d);
  1842. /*
  1843. Make sure file exists
  1844. */
  1845. std::string blockfilename = getBlockFilename(blockpos);
  1846. if (!fs::PathExists(sectordir + DIR_DELIM + blockfilename))
  1847. return NULL;
  1848. /*
  1849. Load block and save it to the database
  1850. */
  1851. loadBlock(sectordir, blockfilename, sector, true);
  1852. }
  1853. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  1854. if (created_new && (block != NULL)) {
  1855. std::map<v3s16, MapBlock*> modified_blocks;
  1856. // Fix lighting if necessary
  1857. voxalgo::update_block_border_lighting(this, block, modified_blocks);
  1858. if (!modified_blocks.empty()) {
  1859. //Modified lighting, send event
  1860. MapEditEvent event;
  1861. event.type = MEET_OTHER;
  1862. std::map<v3s16, MapBlock *>::iterator it;
  1863. for (it = modified_blocks.begin();
  1864. it != modified_blocks.end(); ++it)
  1865. event.modified_blocks.insert(it->first);
  1866. dispatchEvent(&event);
  1867. }
  1868. }
  1869. return block;
  1870. }
  1871. bool ServerMap::deleteBlock(v3s16 blockpos)
  1872. {
  1873. if (!dbase->deleteBlock(blockpos))
  1874. return false;
  1875. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  1876. if (block) {
  1877. v2s16 p2d(blockpos.X, blockpos.Z);
  1878. MapSector *sector = getSectorNoGenerateNoEx(p2d);
  1879. if (!sector)
  1880. return false;
  1881. sector->deleteBlock(block);
  1882. }
  1883. return true;
  1884. }
  1885. void ServerMap::PrintInfo(std::ostream &out)
  1886. {
  1887. out<<"ServerMap: ";
  1888. }
  1889. bool ServerMap::repairBlockLight(v3s16 blockpos,
  1890. std::map<v3s16, MapBlock *> *modified_blocks)
  1891. {
  1892. MapBlock *block = emergeBlock(blockpos, false);
  1893. if (!block || !block->isGenerated())
  1894. return false;
  1895. voxalgo::repair_block_light(this, block, modified_blocks);
  1896. return true;
  1897. }
  1898. MMVManip::MMVManip(Map *map):
  1899. VoxelManipulator(),
  1900. m_map(map)
  1901. {
  1902. }
  1903. void MMVManip::initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max,
  1904. bool load_if_inexistent)
  1905. {
  1906. TimeTaker timer1("initialEmerge", &emerge_time);
  1907. // Units of these are MapBlocks
  1908. v3s16 p_min = blockpos_min;
  1909. v3s16 p_max = blockpos_max;
  1910. VoxelArea block_area_nodes
  1911. (p_min*MAP_BLOCKSIZE, (p_max+1)*MAP_BLOCKSIZE-v3s16(1,1,1));
  1912. u32 size_MB = block_area_nodes.getVolume()*4/1000000;
  1913. if(size_MB >= 1)
  1914. {
  1915. infostream<<"initialEmerge: area: ";
  1916. block_area_nodes.print(infostream);
  1917. infostream<<" ("<<size_MB<<"MB)";
  1918. infostream<<std::endl;
  1919. }
  1920. addArea(block_area_nodes);
  1921. for(s32 z=p_min.Z; z<=p_max.Z; z++)
  1922. for(s32 y=p_min.Y; y<=p_max.Y; y++)
  1923. for(s32 x=p_min.X; x<=p_max.X; x++)
  1924. {
  1925. u8 flags = 0;
  1926. MapBlock *block;
  1927. v3s16 p(x,y,z);
  1928. std::map<v3s16, u8>::iterator n;
  1929. n = m_loaded_blocks.find(p);
  1930. if(n != m_loaded_blocks.end())
  1931. continue;
  1932. bool block_data_inexistent = false;
  1933. try
  1934. {
  1935. TimeTaker timer2("emerge load", &emerge_load_time);
  1936. block = m_map->getBlockNoCreate(p);
  1937. if(block->isDummy())
  1938. block_data_inexistent = true;
  1939. else
  1940. block->copyTo(*this);
  1941. }
  1942. catch(InvalidPositionException &e)
  1943. {
  1944. block_data_inexistent = true;
  1945. }
  1946. if(block_data_inexistent)
  1947. {
  1948. if (load_if_inexistent && !blockpos_over_max_limit(p)) {
  1949. ServerMap *svrmap = (ServerMap *)m_map;
  1950. block = svrmap->emergeBlock(p, false);
  1951. if (block == NULL)
  1952. block = svrmap->createBlock(p);
  1953. block->copyTo(*this);
  1954. } else {
  1955. flags |= VMANIP_BLOCK_DATA_INEXIST;
  1956. /*
  1957. Mark area inexistent
  1958. */
  1959. VoxelArea a(p*MAP_BLOCKSIZE, (p+1)*MAP_BLOCKSIZE-v3s16(1,1,1));
  1960. // Fill with VOXELFLAG_NO_DATA
  1961. for(s32 z=a.MinEdge.Z; z<=a.MaxEdge.Z; z++)
  1962. for(s32 y=a.MinEdge.Y; y<=a.MaxEdge.Y; y++)
  1963. {
  1964. s32 i = m_area.index(a.MinEdge.X,y,z);
  1965. memset(&m_flags[i], VOXELFLAG_NO_DATA, MAP_BLOCKSIZE);
  1966. }
  1967. }
  1968. }
  1969. /*else if (block->getNode(0, 0, 0).getContent() == CONTENT_IGNORE)
  1970. {
  1971. // Mark that block was loaded as blank
  1972. flags |= VMANIP_BLOCK_CONTAINS_CIGNORE;
  1973. }*/
  1974. m_loaded_blocks[p] = flags;
  1975. }
  1976. m_is_dirty = false;
  1977. }
  1978. void MMVManip::blitBackAll(std::map<v3s16, MapBlock*> *modified_blocks,
  1979. bool overwrite_generated)
  1980. {
  1981. if(m_area.getExtent() == v3s16(0,0,0))
  1982. return;
  1983. /*
  1984. Copy data of all blocks
  1985. */
  1986. for (auto &loaded_block : m_loaded_blocks) {
  1987. v3s16 p = loaded_block.first;
  1988. MapBlock *block = m_map->getBlockNoCreateNoEx(p);
  1989. bool existed = !(loaded_block.second & VMANIP_BLOCK_DATA_INEXIST);
  1990. if (!existed || (block == NULL) ||
  1991. (!overwrite_generated && block->isGenerated()))
  1992. continue;
  1993. block->copyFrom(*this);
  1994. block->raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_VMANIP);
  1995. if(modified_blocks)
  1996. (*modified_blocks)[p] = block;
  1997. }
  1998. }
  1999. //END