map.cpp 78 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234
  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_v6.h"
  37. #include "mg_biome.h"
  38. #include "config.h"
  39. #include "server.h"
  40. #include "database.h"
  41. #include "database-dummy.h"
  42. #include "database-sqlite3.h"
  43. #include <deque>
  44. #include <queue>
  45. #if USE_LEVELDB
  46. #include "database-leveldb.h"
  47. #endif
  48. #if USE_REDIS
  49. #include "database-redis.h"
  50. #endif
  51. #if USE_POSTGRESQL
  52. #include "database-postgresql.h"
  53. #endif
  54. /*
  55. Map
  56. */
  57. Map::Map(std::ostream &dout, IGameDef *gamedef):
  58. m_dout(dout),
  59. m_gamedef(gamedef),
  60. m_sector_cache(NULL),
  61. m_nodedef(gamedef->ndef()),
  62. m_transforming_liquid_loop_count_multiplier(1.0f),
  63. m_unprocessed_count(0),
  64. m_inc_trending_up_start_time(0),
  65. m_queue_size_timer_started(false)
  66. {
  67. }
  68. Map::~Map()
  69. {
  70. /*
  71. Free all MapSectors
  72. */
  73. for(std::map<v2s16, MapSector*>::iterator i = m_sectors.begin();
  74. i != m_sectors.end(); ++i)
  75. {
  76. delete i->second;
  77. }
  78. }
  79. void Map::addEventReceiver(MapEventReceiver *event_receiver)
  80. {
  81. m_event_receivers.insert(event_receiver);
  82. }
  83. void Map::removeEventReceiver(MapEventReceiver *event_receiver)
  84. {
  85. m_event_receivers.erase(event_receiver);
  86. }
  87. void Map::dispatchEvent(MapEditEvent *event)
  88. {
  89. for(std::set<MapEventReceiver*>::iterator
  90. i = m_event_receivers.begin();
  91. i != m_event_receivers.end(); ++i)
  92. {
  93. (*i)->onMapEditEvent(event);
  94. }
  95. }
  96. MapSector * Map::getSectorNoGenerateNoExNoLock(v2s16 p)
  97. {
  98. if(m_sector_cache != NULL && p == m_sector_cache_p){
  99. MapSector * sector = m_sector_cache;
  100. return sector;
  101. }
  102. std::map<v2s16, MapSector*>::iterator n = m_sectors.find(p);
  103. if(n == m_sectors.end())
  104. return NULL;
  105. MapSector *sector = n->second;
  106. // Cache the last result
  107. m_sector_cache_p = p;
  108. m_sector_cache = sector;
  109. return sector;
  110. }
  111. MapSector * Map::getSectorNoGenerateNoEx(v2s16 p)
  112. {
  113. return getSectorNoGenerateNoExNoLock(p);
  114. }
  115. MapSector * Map::getSectorNoGenerate(v2s16 p)
  116. {
  117. MapSector *sector = getSectorNoGenerateNoEx(p);
  118. if(sector == NULL)
  119. throw InvalidPositionException();
  120. return sector;
  121. }
  122. MapBlock * Map::getBlockNoCreateNoEx(v3s16 p3d)
  123. {
  124. v2s16 p2d(p3d.X, p3d.Z);
  125. MapSector * sector = getSectorNoGenerateNoEx(p2d);
  126. if(sector == NULL)
  127. return NULL;
  128. MapBlock *block = sector->getBlockNoCreateNoEx(p3d.Y);
  129. return block;
  130. }
  131. MapBlock * Map::getBlockNoCreate(v3s16 p3d)
  132. {
  133. MapBlock *block = getBlockNoCreateNoEx(p3d);
  134. if(block == NULL)
  135. throw InvalidPositionException();
  136. return block;
  137. }
  138. bool Map::isNodeUnderground(v3s16 p)
  139. {
  140. v3s16 blockpos = getNodeBlockPos(p);
  141. try{
  142. MapBlock * block = getBlockNoCreate(blockpos);
  143. return block->getIsUnderground();
  144. }
  145. catch(InvalidPositionException &e)
  146. {
  147. return false;
  148. }
  149. }
  150. bool Map::isValidPosition(v3s16 p)
  151. {
  152. v3s16 blockpos = getNodeBlockPos(p);
  153. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  154. return (block != NULL);
  155. }
  156. // Returns a CONTENT_IGNORE node if not found
  157. MapNode Map::getNodeNoEx(v3s16 p, bool *is_valid_position)
  158. {
  159. v3s16 blockpos = getNodeBlockPos(p);
  160. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  161. if (block == NULL) {
  162. if (is_valid_position != NULL)
  163. *is_valid_position = false;
  164. return MapNode(CONTENT_IGNORE);
  165. }
  166. v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
  167. bool is_valid_p;
  168. MapNode node = block->getNodeNoCheck(relpos, &is_valid_p);
  169. if (is_valid_position != NULL)
  170. *is_valid_position = is_valid_p;
  171. return node;
  172. }
  173. #if 0
  174. // Deprecated
  175. // throws InvalidPositionException if not found
  176. // TODO: Now this is deprecated, getNodeNoEx should be renamed
  177. MapNode Map::getNode(v3s16 p)
  178. {
  179. v3s16 blockpos = getNodeBlockPos(p);
  180. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  181. if (block == NULL)
  182. throw InvalidPositionException();
  183. v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
  184. bool is_valid_position;
  185. MapNode node = block->getNodeNoCheck(relpos, &is_valid_position);
  186. if (!is_valid_position)
  187. throw InvalidPositionException();
  188. return node;
  189. }
  190. #endif
  191. // throws InvalidPositionException if not found
  192. void Map::setNode(v3s16 p, MapNode & n)
  193. {
  194. v3s16 blockpos = getNodeBlockPos(p);
  195. MapBlock *block = getBlockNoCreate(blockpos);
  196. v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
  197. // Never allow placing CONTENT_IGNORE, it fucks up stuff
  198. if(n.getContent() == CONTENT_IGNORE){
  199. bool temp_bool;
  200. errorstream<<"Map::setNode(): Not allowing to place CONTENT_IGNORE"
  201. <<" while trying to replace \""
  202. <<m_nodedef->get(block->getNodeNoCheck(relpos, &temp_bool)).name
  203. <<"\" at "<<PP(p)<<" (block "<<PP(blockpos)<<")"<<std::endl;
  204. debug_stacks_print_to(infostream);
  205. return;
  206. }
  207. block->setNodeNoCheck(relpos, n);
  208. }
  209. /*
  210. Goes recursively through the neighbours of the node.
  211. Alters only transparent nodes.
  212. If the lighting of the neighbour is lower than the lighting of
  213. the node was (before changing it to 0 at the step before), the
  214. lighting of the neighbour is set to 0 and then the same stuff
  215. repeats for the neighbour.
  216. The ending nodes of the routine are stored in light_sources.
  217. This is useful when a light is removed. In such case, this
  218. routine can be called for the light node and then again for
  219. light_sources to re-light the area without the removed light.
  220. values of from_nodes are lighting values.
  221. */
  222. void Map::unspreadLight(enum LightBank bank,
  223. std::map<v3s16, u8> & from_nodes,
  224. std::set<v3s16> & light_sources,
  225. std::map<v3s16, MapBlock*> & modified_blocks)
  226. {
  227. v3s16 dirs[6] = {
  228. v3s16(0,0,1), // back
  229. v3s16(0,1,0), // top
  230. v3s16(1,0,0), // right
  231. v3s16(0,0,-1), // front
  232. v3s16(0,-1,0), // bottom
  233. v3s16(-1,0,0), // left
  234. };
  235. if(from_nodes.empty())
  236. return;
  237. u32 blockchangecount = 0;
  238. std::map<v3s16, u8> unlighted_nodes;
  239. /*
  240. Initialize block cache
  241. */
  242. v3s16 blockpos_last;
  243. MapBlock *block = NULL;
  244. // Cache this a bit, too
  245. bool block_checked_in_modified = false;
  246. for(std::map<v3s16, u8>::iterator j = from_nodes.begin();
  247. j != from_nodes.end(); ++j)
  248. {
  249. v3s16 pos = j->first;
  250. v3s16 blockpos = getNodeBlockPos(pos);
  251. // Only fetch a new block if the block position has changed
  252. try{
  253. if(block == NULL || blockpos != blockpos_last){
  254. block = getBlockNoCreate(blockpos);
  255. blockpos_last = blockpos;
  256. block_checked_in_modified = false;
  257. blockchangecount++;
  258. }
  259. }
  260. catch(InvalidPositionException &e)
  261. {
  262. continue;
  263. }
  264. if(block->isDummy())
  265. continue;
  266. // Calculate relative position in block
  267. //v3s16 relpos = pos - blockpos_last * MAP_BLOCKSIZE;
  268. // Get node straight from the block
  269. //MapNode n = block->getNode(relpos);
  270. u8 oldlight = j->second;
  271. // Loop through 6 neighbors
  272. for(u16 i=0; i<6; i++)
  273. {
  274. // Get the position of the neighbor node
  275. v3s16 n2pos = pos + dirs[i];
  276. // Get the block where the node is located
  277. v3s16 blockpos, relpos;
  278. getNodeBlockPosWithOffset(n2pos, blockpos, relpos);
  279. // Only fetch a new block if the block position has changed
  280. try {
  281. if(block == NULL || blockpos != blockpos_last){
  282. block = getBlockNoCreate(blockpos);
  283. blockpos_last = blockpos;
  284. block_checked_in_modified = false;
  285. blockchangecount++;
  286. }
  287. }
  288. catch(InvalidPositionException &e) {
  289. continue;
  290. }
  291. // Get node straight from the block
  292. bool is_valid_position;
  293. MapNode n2 = block->getNode(relpos, &is_valid_position);
  294. if (!is_valid_position)
  295. continue;
  296. bool changed = false;
  297. //TODO: Optimize output by optimizing light_sources?
  298. /*
  299. If the neighbor is dimmer than what was specified
  300. as oldlight (the light of the previous node)
  301. */
  302. if(n2.getLight(bank, m_nodedef) < oldlight)
  303. {
  304. /*
  305. And the neighbor is transparent and it has some light
  306. */
  307. if(m_nodedef->get(n2).light_propagates
  308. && n2.getLight(bank, m_nodedef) != 0)
  309. {
  310. /*
  311. Set light to 0 and add to queue
  312. */
  313. u8 current_light = n2.getLight(bank, m_nodedef);
  314. n2.setLight(bank, 0, m_nodedef);
  315. block->setNode(relpos, n2);
  316. unlighted_nodes[n2pos] = current_light;
  317. changed = true;
  318. /*
  319. Remove from light_sources if it is there
  320. NOTE: This doesn't happen nearly at all
  321. */
  322. /*if(light_sources.find(n2pos))
  323. {
  324. infostream<<"Removed from light_sources"<<std::endl;
  325. light_sources.remove(n2pos);
  326. }*/
  327. }
  328. /*// DEBUG
  329. if(light_sources.find(n2pos) != NULL)
  330. light_sources.remove(n2pos);*/
  331. }
  332. else{
  333. light_sources.insert(n2pos);
  334. }
  335. // Add to modified_blocks
  336. if(changed == true && block_checked_in_modified == false)
  337. {
  338. // If the block is not found in modified_blocks, add.
  339. if(modified_blocks.find(blockpos) == modified_blocks.end())
  340. {
  341. modified_blocks[blockpos] = block;
  342. }
  343. block_checked_in_modified = true;
  344. }
  345. }
  346. }
  347. /*infostream<<"unspreadLight(): Changed block "
  348. <<blockchangecount<<" times"
  349. <<" for "<<from_nodes.size()<<" nodes"
  350. <<std::endl;*/
  351. if(!unlighted_nodes.empty())
  352. unspreadLight(bank, unlighted_nodes, light_sources, modified_blocks);
  353. }
  354. /*
  355. Lights neighbors of from_nodes, collects all them and then
  356. goes on recursively.
  357. */
  358. void Map::spreadLight(enum LightBank bank,
  359. std::set<v3s16> & from_nodes,
  360. std::map<v3s16, MapBlock*> & modified_blocks)
  361. {
  362. const v3s16 dirs[6] = {
  363. v3s16(0,0,1), // back
  364. v3s16(0,1,0), // top
  365. v3s16(1,0,0), // right
  366. v3s16(0,0,-1), // front
  367. v3s16(0,-1,0), // bottom
  368. v3s16(-1,0,0), // left
  369. };
  370. if(from_nodes.empty())
  371. return;
  372. u32 blockchangecount = 0;
  373. std::set<v3s16> lighted_nodes;
  374. /*
  375. Initialize block cache
  376. */
  377. v3s16 blockpos_last;
  378. MapBlock *block = NULL;
  379. // Cache this a bit, too
  380. bool block_checked_in_modified = false;
  381. for(std::set<v3s16>::iterator j = from_nodes.begin();
  382. j != from_nodes.end(); ++j)
  383. {
  384. v3s16 pos = *j;
  385. v3s16 blockpos, relpos;
  386. getNodeBlockPosWithOffset(pos, blockpos, relpos);
  387. // Only fetch a new block if the block position has changed
  388. try {
  389. if(block == NULL || blockpos != blockpos_last){
  390. block = getBlockNoCreate(blockpos);
  391. blockpos_last = blockpos;
  392. block_checked_in_modified = false;
  393. blockchangecount++;
  394. }
  395. }
  396. catch(InvalidPositionException &e) {
  397. continue;
  398. }
  399. if(block->isDummy())
  400. continue;
  401. // Get node straight from the block
  402. bool is_valid_position;
  403. MapNode n = block->getNode(relpos, &is_valid_position);
  404. u8 oldlight = is_valid_position ? n.getLight(bank, m_nodedef) : 0;
  405. u8 newlight = diminish_light(oldlight);
  406. // Loop through 6 neighbors
  407. for(u16 i=0; i<6; i++){
  408. // Get the position of the neighbor node
  409. v3s16 n2pos = pos + dirs[i];
  410. // Get the block where the node is located
  411. v3s16 blockpos, relpos;
  412. getNodeBlockPosWithOffset(n2pos, blockpos, relpos);
  413. // Only fetch a new block if the block position has changed
  414. try {
  415. if(block == NULL || blockpos != blockpos_last){
  416. block = getBlockNoCreate(blockpos);
  417. blockpos_last = blockpos;
  418. block_checked_in_modified = false;
  419. blockchangecount++;
  420. }
  421. }
  422. catch(InvalidPositionException &e) {
  423. continue;
  424. }
  425. // Get node straight from the block
  426. MapNode n2 = block->getNode(relpos, &is_valid_position);
  427. if (!is_valid_position)
  428. continue;
  429. bool changed = false;
  430. /*
  431. If the neighbor is brighter than the current node,
  432. add to list (it will light up this node on its turn)
  433. */
  434. if(n2.getLight(bank, m_nodedef) > undiminish_light(oldlight))
  435. {
  436. lighted_nodes.insert(n2pos);
  437. changed = true;
  438. }
  439. /*
  440. If the neighbor is dimmer than how much light this node
  441. would spread on it, add to list
  442. */
  443. if(n2.getLight(bank, m_nodedef) < newlight)
  444. {
  445. if(m_nodedef->get(n2).light_propagates)
  446. {
  447. n2.setLight(bank, newlight, m_nodedef);
  448. block->setNode(relpos, n2);
  449. lighted_nodes.insert(n2pos);
  450. changed = true;
  451. }
  452. }
  453. // Add to modified_blocks
  454. if(changed == true && block_checked_in_modified == false)
  455. {
  456. // If the block is not found in modified_blocks, add.
  457. if(modified_blocks.find(blockpos) == modified_blocks.end())
  458. {
  459. modified_blocks[blockpos] = block;
  460. }
  461. block_checked_in_modified = true;
  462. }
  463. }
  464. }
  465. /*infostream<<"spreadLight(): Changed block "
  466. <<blockchangecount<<" times"
  467. <<" for "<<from_nodes.size()<<" nodes"
  468. <<std::endl;*/
  469. if(!lighted_nodes.empty())
  470. spreadLight(bank, lighted_nodes, modified_blocks);
  471. }
  472. void Map::updateLighting(enum LightBank bank,
  473. std::map<v3s16, MapBlock*> & a_blocks,
  474. std::map<v3s16, MapBlock*> & modified_blocks)
  475. {
  476. /*m_dout<<"Map::updateLighting(): "
  477. <<a_blocks.size()<<" blocks."<<std::endl;*/
  478. //TimeTaker timer("updateLighting");
  479. // For debugging
  480. //bool debug=true;
  481. //u32 count_was = modified_blocks.size();
  482. //std::map<v3s16, MapBlock*> blocks_to_update;
  483. std::set<v3s16> light_sources;
  484. std::map<v3s16, u8> unlight_from;
  485. int num_bottom_invalid = 0;
  486. {
  487. //TimeTaker t("first stuff");
  488. for(std::map<v3s16, MapBlock*>::iterator i = a_blocks.begin();
  489. i != a_blocks.end(); ++i)
  490. {
  491. MapBlock *block = i->second;
  492. for(;;)
  493. {
  494. // Don't bother with dummy blocks.
  495. if(block->isDummy())
  496. break;
  497. v3s16 pos = block->getPos();
  498. v3s16 posnodes = block->getPosRelative();
  499. modified_blocks[pos] = block;
  500. //blocks_to_update[pos] = block;
  501. /*
  502. Clear all light from block
  503. */
  504. for(s16 z=0; z<MAP_BLOCKSIZE; z++)
  505. for(s16 x=0; x<MAP_BLOCKSIZE; x++)
  506. for(s16 y=0; y<MAP_BLOCKSIZE; y++)
  507. {
  508. v3s16 p(x,y,z);
  509. bool is_valid_position;
  510. MapNode n = block->getNode(p, &is_valid_position);
  511. if (!is_valid_position) {
  512. /* This would happen when dealing with a
  513. dummy block.
  514. */
  515. infostream<<"updateLighting(): InvalidPositionException"
  516. <<std::endl;
  517. continue;
  518. }
  519. u8 oldlight = n.getLight(bank, m_nodedef);
  520. n.setLight(bank, 0, m_nodedef);
  521. block->setNode(p, n);
  522. // If node sources light, add to list
  523. u8 source = m_nodedef->get(n).light_source;
  524. if(source != 0)
  525. light_sources.insert(p + posnodes);
  526. // Collect borders for unlighting
  527. if((x==0 || x == MAP_BLOCKSIZE-1
  528. || y==0 || y == MAP_BLOCKSIZE-1
  529. || z==0 || z == MAP_BLOCKSIZE-1)
  530. && oldlight != 0)
  531. {
  532. v3s16 p_map = p + posnodes;
  533. unlight_from[p_map] = oldlight;
  534. }
  535. }
  536. if(bank == LIGHTBANK_DAY)
  537. {
  538. bool bottom_valid = block->propagateSunlight(light_sources);
  539. if(!bottom_valid)
  540. num_bottom_invalid++;
  541. // If bottom is valid, we're done.
  542. if(bottom_valid)
  543. break;
  544. }
  545. else if(bank == LIGHTBANK_NIGHT)
  546. {
  547. // For night lighting, sunlight is not propagated
  548. break;
  549. }
  550. else
  551. {
  552. assert("Invalid lighting bank" == NULL);
  553. }
  554. /*infostream<<"Bottom for sunlight-propagated block ("
  555. <<pos.X<<","<<pos.Y<<","<<pos.Z<<") not valid"
  556. <<std::endl;*/
  557. // Bottom sunlight is not valid; get the block and loop to it
  558. pos.Y--;
  559. try{
  560. block = getBlockNoCreate(pos);
  561. }
  562. catch(InvalidPositionException &e)
  563. {
  564. FATAL_ERROR("Invalid position");
  565. }
  566. }
  567. }
  568. }
  569. /*
  570. Enable this to disable proper lighting for speeding up map
  571. generation for testing or whatever
  572. */
  573. #if 0
  574. //if(g_settings->get(""))
  575. {
  576. core::map<v3s16, MapBlock*>::Iterator i;
  577. i = blocks_to_update.getIterator();
  578. for(; i.atEnd() == false; i++)
  579. {
  580. MapBlock *block = i.getNode()->getValue();
  581. v3s16 p = block->getPos();
  582. block->setLightingExpired(false);
  583. }
  584. return;
  585. }
  586. #endif
  587. #if 1
  588. {
  589. //TimeTaker timer("unspreadLight");
  590. unspreadLight(bank, unlight_from, light_sources, modified_blocks);
  591. }
  592. /*if(debug)
  593. {
  594. u32 diff = modified_blocks.size() - count_was;
  595. count_was = modified_blocks.size();
  596. infostream<<"unspreadLight modified "<<diff<<std::endl;
  597. }*/
  598. {
  599. //TimeTaker timer("spreadLight");
  600. spreadLight(bank, light_sources, modified_blocks);
  601. }
  602. /*if(debug)
  603. {
  604. u32 diff = modified_blocks.size() - count_was;
  605. count_was = modified_blocks.size();
  606. infostream<<"spreadLight modified "<<diff<<std::endl;
  607. }*/
  608. #endif
  609. #if 0
  610. {
  611. //MapVoxelManipulator vmanip(this);
  612. // Make a manual voxel manipulator and load all the blocks
  613. // that touch the requested blocks
  614. ManualMapVoxelManipulator vmanip(this);
  615. {
  616. //TimeTaker timer("initialEmerge");
  617. core::map<v3s16, MapBlock*>::Iterator i;
  618. i = blocks_to_update.getIterator();
  619. for(; i.atEnd() == false; i++)
  620. {
  621. MapBlock *block = i.getNode()->getValue();
  622. v3s16 p = block->getPos();
  623. // Add all surrounding blocks
  624. vmanip.initialEmerge(p - v3s16(1,1,1), p + v3s16(1,1,1));
  625. /*
  626. Add all surrounding blocks that have up-to-date lighting
  627. NOTE: This doesn't quite do the job (not everything
  628. appropriate is lighted)
  629. */
  630. /*for(s16 z=-1; z<=1; z++)
  631. for(s16 y=-1; y<=1; y++)
  632. for(s16 x=-1; x<=1; x++)
  633. {
  634. v3s16 p2 = p + v3s16(x,y,z);
  635. MapBlock *block = getBlockNoCreateNoEx(p2);
  636. if(block == NULL)
  637. continue;
  638. if(block->isDummy())
  639. continue;
  640. if(block->getLightingExpired())
  641. continue;
  642. vmanip.initialEmerge(p2, p2);
  643. }*/
  644. // Lighting of block will be updated completely
  645. block->setLightingExpired(false);
  646. }
  647. }
  648. {
  649. //TimeTaker timer("unSpreadLight");
  650. vmanip.unspreadLight(bank, unlight_from, light_sources, nodemgr);
  651. }
  652. {
  653. //TimeTaker timer("spreadLight");
  654. vmanip.spreadLight(bank, light_sources, nodemgr);
  655. }
  656. {
  657. //TimeTaker timer("blitBack");
  658. vmanip.blitBack(modified_blocks);
  659. }
  660. /*infostream<<"emerge_time="<<emerge_time<<std::endl;
  661. emerge_time = 0;*/
  662. }
  663. #endif
  664. //m_dout<<"Done ("<<getTimestamp()<<")"<<std::endl;
  665. }
  666. void Map::updateLighting(std::map<v3s16, MapBlock*> & a_blocks,
  667. std::map<v3s16, MapBlock*> & modified_blocks)
  668. {
  669. updateLighting(LIGHTBANK_DAY, a_blocks, modified_blocks);
  670. updateLighting(LIGHTBANK_NIGHT, a_blocks, modified_blocks);
  671. /*
  672. Update information about whether day and night light differ
  673. */
  674. for(std::map<v3s16, MapBlock*>::iterator
  675. i = modified_blocks.begin();
  676. i != modified_blocks.end(); ++i)
  677. {
  678. MapBlock *block = i->second;
  679. block->expireDayNightDiff();
  680. }
  681. }
  682. void Map::addNodeAndUpdate(v3s16 p, MapNode n,
  683. std::map<v3s16, MapBlock*> &modified_blocks,
  684. bool remove_metadata)
  685. {
  686. // Collect old node for rollback
  687. RollbackNode rollback_oldnode(this, p, m_gamedef);
  688. // This is needed for updating the lighting
  689. MapNode oldnode = getNodeNoEx(p);
  690. // Remove node metadata
  691. if (remove_metadata) {
  692. removeNodeMetadata(p);
  693. }
  694. // Set the node on the map
  695. // Ignore light (because calling voxalgo::update_lighting_nodes)
  696. n.setLight(LIGHTBANK_DAY, 0, m_nodedef);
  697. n.setLight(LIGHTBANK_NIGHT, 0, m_nodedef);
  698. setNode(p, n);
  699. // Update lighting
  700. std::vector<std::pair<v3s16, MapNode> > oldnodes;
  701. oldnodes.push_back(std::pair<v3s16, MapNode>(p, oldnode));
  702. voxalgo::update_lighting_nodes(this, m_nodedef, oldnodes, modified_blocks);
  703. for(std::map<v3s16, MapBlock*>::iterator
  704. i = modified_blocks.begin();
  705. i != modified_blocks.end(); ++i)
  706. {
  707. i->second->expireDayNightDiff();
  708. }
  709. // Report for rollback
  710. if(m_gamedef->rollback())
  711. {
  712. RollbackNode rollback_newnode(this, p, m_gamedef);
  713. RollbackAction action;
  714. action.setSetNode(p, rollback_oldnode, rollback_newnode);
  715. m_gamedef->rollback()->reportAction(action);
  716. }
  717. /*
  718. Add neighboring liquid nodes and this node to transform queue.
  719. (it's vital for the node itself to get updated last, if it was removed.)
  720. */
  721. v3s16 dirs[7] = {
  722. v3s16(0,0,1), // back
  723. v3s16(0,1,0), // top
  724. v3s16(1,0,0), // right
  725. v3s16(0,0,-1), // front
  726. v3s16(0,-1,0), // bottom
  727. v3s16(-1,0,0), // left
  728. v3s16(0,0,0), // self
  729. };
  730. for(u16 i=0; i<7; i++)
  731. {
  732. v3s16 p2 = p + dirs[i];
  733. bool is_valid_position;
  734. MapNode n2 = getNodeNoEx(p2, &is_valid_position);
  735. if(is_valid_position &&
  736. (m_nodedef->get(n2).isLiquid() ||
  737. n2.getContent() == CONTENT_AIR))
  738. m_transforming_liquid.push_back(p2);
  739. }
  740. }
  741. void Map::removeNodeAndUpdate(v3s16 p,
  742. std::map<v3s16, MapBlock*> &modified_blocks)
  743. {
  744. addNodeAndUpdate(p, MapNode(CONTENT_AIR), modified_blocks, true);
  745. }
  746. bool Map::addNodeWithEvent(v3s16 p, MapNode n, bool remove_metadata)
  747. {
  748. MapEditEvent event;
  749. event.type = remove_metadata ? MEET_ADDNODE : MEET_SWAPNODE;
  750. event.p = p;
  751. event.n = n;
  752. bool succeeded = true;
  753. try{
  754. std::map<v3s16, MapBlock*> modified_blocks;
  755. addNodeAndUpdate(p, n, modified_blocks, remove_metadata);
  756. // Copy modified_blocks to event
  757. for(std::map<v3s16, MapBlock*>::iterator
  758. i = modified_blocks.begin();
  759. i != modified_blocks.end(); ++i)
  760. {
  761. event.modified_blocks.insert(i->first);
  762. }
  763. }
  764. catch(InvalidPositionException &e){
  765. succeeded = false;
  766. }
  767. dispatchEvent(&event);
  768. return succeeded;
  769. }
  770. bool Map::removeNodeWithEvent(v3s16 p)
  771. {
  772. MapEditEvent event;
  773. event.type = MEET_REMOVENODE;
  774. event.p = p;
  775. bool succeeded = true;
  776. try{
  777. std::map<v3s16, MapBlock*> modified_blocks;
  778. removeNodeAndUpdate(p, modified_blocks);
  779. // Copy modified_blocks to event
  780. for(std::map<v3s16, MapBlock*>::iterator
  781. i = modified_blocks.begin();
  782. i != modified_blocks.end(); ++i)
  783. {
  784. event.modified_blocks.insert(i->first);
  785. }
  786. }
  787. catch(InvalidPositionException &e){
  788. succeeded = false;
  789. }
  790. dispatchEvent(&event);
  791. return succeeded;
  792. }
  793. bool Map::getDayNightDiff(v3s16 blockpos)
  794. {
  795. try{
  796. v3s16 p = blockpos + v3s16(0,0,0);
  797. MapBlock *b = getBlockNoCreate(p);
  798. if(b->getDayNightDiff())
  799. return true;
  800. }
  801. catch(InvalidPositionException &e){}
  802. // Leading edges
  803. try{
  804. v3s16 p = blockpos + v3s16(-1,0,0);
  805. MapBlock *b = getBlockNoCreate(p);
  806. if(b->getDayNightDiff())
  807. return true;
  808. }
  809. catch(InvalidPositionException &e){}
  810. try{
  811. v3s16 p = blockpos + v3s16(0,-1,0);
  812. MapBlock *b = getBlockNoCreate(p);
  813. if(b->getDayNightDiff())
  814. return true;
  815. }
  816. catch(InvalidPositionException &e){}
  817. try{
  818. v3s16 p = blockpos + v3s16(0,0,-1);
  819. MapBlock *b = getBlockNoCreate(p);
  820. if(b->getDayNightDiff())
  821. return true;
  822. }
  823. catch(InvalidPositionException &e){}
  824. // Trailing edges
  825. try{
  826. v3s16 p = blockpos + v3s16(1,0,0);
  827. MapBlock *b = getBlockNoCreate(p);
  828. if(b->getDayNightDiff())
  829. return true;
  830. }
  831. catch(InvalidPositionException &e){}
  832. try{
  833. v3s16 p = blockpos + v3s16(0,1,0);
  834. MapBlock *b = getBlockNoCreate(p);
  835. if(b->getDayNightDiff())
  836. return true;
  837. }
  838. catch(InvalidPositionException &e){}
  839. try{
  840. v3s16 p = blockpos + v3s16(0,0,1);
  841. MapBlock *b = getBlockNoCreate(p);
  842. if(b->getDayNightDiff())
  843. return true;
  844. }
  845. catch(InvalidPositionException &e){}
  846. return false;
  847. }
  848. struct TimeOrderedMapBlock {
  849. MapSector *sect;
  850. MapBlock *block;
  851. TimeOrderedMapBlock(MapSector *sect, MapBlock *block) :
  852. sect(sect),
  853. block(block)
  854. {}
  855. bool operator<(const TimeOrderedMapBlock &b) const
  856. {
  857. return block->getUsageTimer() < b.block->getUsageTimer();
  858. };
  859. };
  860. /*
  861. Updates usage timers
  862. */
  863. void Map::timerUpdate(float dtime, float unload_timeout, u32 max_loaded_blocks,
  864. std::vector<v3s16> *unloaded_blocks)
  865. {
  866. bool save_before_unloading = (mapType() == MAPTYPE_SERVER);
  867. // Profile modified reasons
  868. Profiler modprofiler;
  869. std::vector<v2s16> sector_deletion_queue;
  870. u32 deleted_blocks_count = 0;
  871. u32 saved_blocks_count = 0;
  872. u32 block_count_all = 0;
  873. beginSave();
  874. // If there is no practical limit, we spare creation of mapblock_queue
  875. if (max_loaded_blocks == U32_MAX) {
  876. for (std::map<v2s16, MapSector*>::iterator si = m_sectors.begin();
  877. si != m_sectors.end(); ++si) {
  878. MapSector *sector = si->second;
  879. bool all_blocks_deleted = true;
  880. MapBlockVect blocks;
  881. sector->getBlocks(blocks);
  882. for (MapBlockVect::iterator i = blocks.begin();
  883. i != blocks.end(); ++i) {
  884. MapBlock *block = (*i);
  885. block->incrementUsageTimer(dtime);
  886. if (block->refGet() == 0
  887. && block->getUsageTimer() > unload_timeout) {
  888. v3s16 p = block->getPos();
  889. // Save if modified
  890. if (block->getModified() != MOD_STATE_CLEAN
  891. && save_before_unloading) {
  892. modprofiler.add(block->getModifiedReasonString(), 1);
  893. if (!saveBlock(block))
  894. continue;
  895. saved_blocks_count++;
  896. }
  897. // Delete from memory
  898. sector->deleteBlock(block);
  899. if (unloaded_blocks)
  900. unloaded_blocks->push_back(p);
  901. deleted_blocks_count++;
  902. } else {
  903. all_blocks_deleted = false;
  904. block_count_all++;
  905. }
  906. }
  907. if (all_blocks_deleted) {
  908. sector_deletion_queue.push_back(si->first);
  909. }
  910. }
  911. } else {
  912. std::priority_queue<TimeOrderedMapBlock> mapblock_queue;
  913. for (std::map<v2s16, MapSector*>::iterator si = m_sectors.begin();
  914. si != m_sectors.end(); ++si) {
  915. MapSector *sector = si->second;
  916. MapBlockVect blocks;
  917. sector->getBlocks(blocks);
  918. for(MapBlockVect::iterator i = blocks.begin();
  919. i != blocks.end(); ++i) {
  920. MapBlock *block = (*i);
  921. block->incrementUsageTimer(dtime);
  922. mapblock_queue.push(TimeOrderedMapBlock(sector, block));
  923. }
  924. }
  925. block_count_all = mapblock_queue.size();
  926. // Delete old blocks, and blocks over the limit from the memory
  927. while (!mapblock_queue.empty() && (mapblock_queue.size() > max_loaded_blocks
  928. || mapblock_queue.top().block->getUsageTimer() > unload_timeout)) {
  929. TimeOrderedMapBlock b = mapblock_queue.top();
  930. mapblock_queue.pop();
  931. MapBlock *block = b.block;
  932. if (block->refGet() != 0)
  933. continue;
  934. v3s16 p = block->getPos();
  935. // Save if modified
  936. if (block->getModified() != MOD_STATE_CLEAN && save_before_unloading) {
  937. modprofiler.add(block->getModifiedReasonString(), 1);
  938. if (!saveBlock(block))
  939. continue;
  940. saved_blocks_count++;
  941. }
  942. // Delete from memory
  943. b.sect->deleteBlock(block);
  944. if (unloaded_blocks)
  945. unloaded_blocks->push_back(p);
  946. deleted_blocks_count++;
  947. block_count_all--;
  948. }
  949. // Delete empty sectors
  950. for (std::map<v2s16, MapSector*>::iterator si = m_sectors.begin();
  951. si != m_sectors.end(); ++si) {
  952. if (si->second->empty()) {
  953. sector_deletion_queue.push_back(si->first);
  954. }
  955. }
  956. }
  957. endSave();
  958. // Finally delete the empty sectors
  959. deleteSectors(sector_deletion_queue);
  960. if(deleted_blocks_count != 0)
  961. {
  962. PrintInfo(infostream); // ServerMap/ClientMap:
  963. infostream<<"Unloaded "<<deleted_blocks_count
  964. <<" blocks from memory";
  965. if(save_before_unloading)
  966. infostream<<", of which "<<saved_blocks_count<<" were written";
  967. infostream<<", "<<block_count_all<<" blocks in memory";
  968. infostream<<"."<<std::endl;
  969. if(saved_blocks_count != 0){
  970. PrintInfo(infostream); // ServerMap/ClientMap:
  971. infostream<<"Blocks modified by: "<<std::endl;
  972. modprofiler.print(infostream);
  973. }
  974. }
  975. }
  976. void Map::unloadUnreferencedBlocks(std::vector<v3s16> *unloaded_blocks)
  977. {
  978. timerUpdate(0.0, -1.0, 0, unloaded_blocks);
  979. }
  980. void Map::deleteSectors(std::vector<v2s16> &sectorList)
  981. {
  982. for(std::vector<v2s16>::iterator j = sectorList.begin();
  983. j != sectorList.end(); ++j) {
  984. MapSector *sector = m_sectors[*j];
  985. // If sector is in sector cache, remove it from there
  986. if(m_sector_cache == sector)
  987. m_sector_cache = NULL;
  988. // Remove from map and delete
  989. m_sectors.erase(*j);
  990. delete sector;
  991. }
  992. }
  993. void Map::PrintInfo(std::ostream &out)
  994. {
  995. out<<"Map: ";
  996. }
  997. #define WATER_DROP_BOOST 4
  998. enum NeighborType {
  999. NEIGHBOR_UPPER,
  1000. NEIGHBOR_SAME_LEVEL,
  1001. NEIGHBOR_LOWER
  1002. };
  1003. struct NodeNeighbor {
  1004. MapNode n;
  1005. NeighborType t;
  1006. v3s16 p;
  1007. bool l; //can liquid
  1008. NodeNeighbor()
  1009. : n(CONTENT_AIR)
  1010. { }
  1011. NodeNeighbor(const MapNode &node, NeighborType n_type, v3s16 pos)
  1012. : n(node),
  1013. t(n_type),
  1014. p(pos)
  1015. { }
  1016. };
  1017. void Map::transforming_liquid_add(v3s16 p) {
  1018. m_transforming_liquid.push_back(p);
  1019. }
  1020. s32 Map::transforming_liquid_size() {
  1021. return m_transforming_liquid.size();
  1022. }
  1023. void Map::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks)
  1024. {
  1025. DSTACK(FUNCTION_NAME);
  1026. //TimeTaker timer("transformLiquids()");
  1027. u32 loopcount = 0;
  1028. u32 initial_size = m_transforming_liquid.size();
  1029. /*if(initial_size != 0)
  1030. infostream<<"transformLiquids(): initial_size="<<initial_size<<std::endl;*/
  1031. // list of nodes that due to viscosity have not reached their max level height
  1032. std::deque<v3s16> must_reflow;
  1033. std::vector<std::pair<v3s16, MapNode> > changed_nodes;
  1034. u32 liquid_loop_max = g_settings->getS32("liquid_loop_max");
  1035. u32 loop_max = liquid_loop_max;
  1036. #if 0
  1037. /* If liquid_loop_max is not keeping up with the queue size increase
  1038. * loop_max up to a maximum of liquid_loop_max * dedicated_server_step.
  1039. */
  1040. if (m_transforming_liquid.size() > loop_max * 2) {
  1041. // "Burst" mode
  1042. float server_step = g_settings->getFloat("dedicated_server_step");
  1043. if (m_transforming_liquid_loop_count_multiplier - 1.0 < server_step)
  1044. m_transforming_liquid_loop_count_multiplier *= 1.0 + server_step / 10;
  1045. } else {
  1046. m_transforming_liquid_loop_count_multiplier = 1.0;
  1047. }
  1048. loop_max *= m_transforming_liquid_loop_count_multiplier;
  1049. #endif
  1050. while (m_transforming_liquid.size() != 0)
  1051. {
  1052. // This should be done here so that it is done when continue is used
  1053. if (loopcount >= initial_size || loopcount >= loop_max)
  1054. break;
  1055. loopcount++;
  1056. /*
  1057. Get a queued transforming liquid node
  1058. */
  1059. v3s16 p0 = m_transforming_liquid.front();
  1060. m_transforming_liquid.pop_front();
  1061. MapNode n0 = getNodeNoEx(p0);
  1062. /*
  1063. Collect information about current node
  1064. */
  1065. s8 liquid_level = -1;
  1066. // The liquid node which will be placed there if
  1067. // the liquid flows into this node.
  1068. content_t liquid_kind = CONTENT_IGNORE;
  1069. // The node which will be placed there if liquid
  1070. // can't flow into this node.
  1071. content_t floodable_node = CONTENT_AIR;
  1072. const ContentFeatures &cf = m_nodedef->get(n0);
  1073. LiquidType liquid_type = cf.liquid_type;
  1074. switch (liquid_type) {
  1075. case LIQUID_SOURCE:
  1076. liquid_level = LIQUID_LEVEL_SOURCE;
  1077. liquid_kind = m_nodedef->getId(cf.liquid_alternative_flowing);
  1078. break;
  1079. case LIQUID_FLOWING:
  1080. liquid_level = (n0.param2 & LIQUID_LEVEL_MASK);
  1081. liquid_kind = n0.getContent();
  1082. break;
  1083. case LIQUID_NONE:
  1084. // if this node is 'floodable', it *could* be transformed
  1085. // into a liquid, otherwise, continue with the next node.
  1086. if (!cf.floodable)
  1087. continue;
  1088. floodable_node = n0.getContent();
  1089. liquid_kind = CONTENT_AIR;
  1090. break;
  1091. }
  1092. /*
  1093. Collect information about the environment
  1094. */
  1095. const v3s16 *dirs = g_6dirs;
  1096. NodeNeighbor sources[6]; // surrounding sources
  1097. int num_sources = 0;
  1098. NodeNeighbor flows[6]; // surrounding flowing liquid nodes
  1099. int num_flows = 0;
  1100. NodeNeighbor airs[6]; // surrounding air
  1101. int num_airs = 0;
  1102. NodeNeighbor neutrals[6]; // nodes that are solid or another kind of liquid
  1103. int num_neutrals = 0;
  1104. bool flowing_down = false;
  1105. bool ignored_sources = false;
  1106. for (u16 i = 0; i < 6; i++) {
  1107. NeighborType nt = NEIGHBOR_SAME_LEVEL;
  1108. switch (i) {
  1109. case 1:
  1110. nt = NEIGHBOR_UPPER;
  1111. break;
  1112. case 4:
  1113. nt = NEIGHBOR_LOWER;
  1114. break;
  1115. }
  1116. v3s16 npos = p0 + dirs[i];
  1117. NodeNeighbor nb(getNodeNoEx(npos), nt, npos);
  1118. const ContentFeatures &cfnb = m_nodedef->get(nb.n);
  1119. switch (m_nodedef->get(nb.n.getContent()).liquid_type) {
  1120. case LIQUID_NONE:
  1121. if (cfnb.floodable) {
  1122. airs[num_airs++] = nb;
  1123. // if the current node is a water source the neighbor
  1124. // should be enqueded for transformation regardless of whether the
  1125. // current node changes or not.
  1126. if (nb.t != NEIGHBOR_UPPER && liquid_type != LIQUID_NONE)
  1127. m_transforming_liquid.push_back(npos);
  1128. // if the current node happens to be a flowing node, it will start to flow down here.
  1129. if (nb.t == NEIGHBOR_LOWER)
  1130. flowing_down = true;
  1131. } else {
  1132. neutrals[num_neutrals++] = nb;
  1133. if (nb.n.getContent() == CONTENT_IGNORE) {
  1134. // If node below is ignore prevent water from
  1135. // spreading outwards and otherwise prevent from
  1136. // flowing away as ignore node might be the source
  1137. if (nb.t == NEIGHBOR_LOWER)
  1138. flowing_down = true;
  1139. else
  1140. ignored_sources = true;
  1141. }
  1142. }
  1143. break;
  1144. case LIQUID_SOURCE:
  1145. // if this node is not (yet) of a liquid type, choose the first liquid type we encounter
  1146. if (liquid_kind == CONTENT_AIR)
  1147. liquid_kind = m_nodedef->getId(cfnb.liquid_alternative_flowing);
  1148. if (m_nodedef->getId(cfnb.liquid_alternative_flowing) != liquid_kind) {
  1149. neutrals[num_neutrals++] = nb;
  1150. } else {
  1151. // Do not count bottom source, it will screw things up
  1152. if(dirs[i].Y != -1)
  1153. sources[num_sources++] = nb;
  1154. }
  1155. break;
  1156. case LIQUID_FLOWING:
  1157. // if this node is not (yet) of a liquid type, choose the first liquid type we encounter
  1158. if (liquid_kind == CONTENT_AIR)
  1159. liquid_kind = m_nodedef->getId(cfnb.liquid_alternative_flowing);
  1160. if (m_nodedef->getId(cfnb.liquid_alternative_flowing) != liquid_kind) {
  1161. neutrals[num_neutrals++] = nb;
  1162. } else {
  1163. flows[num_flows++] = nb;
  1164. if (nb.t == NEIGHBOR_LOWER)
  1165. flowing_down = true;
  1166. }
  1167. break;
  1168. }
  1169. }
  1170. /*
  1171. decide on the type (and possibly level) of the current node
  1172. */
  1173. content_t new_node_content;
  1174. s8 new_node_level = -1;
  1175. s8 max_node_level = -1;
  1176. u8 range = m_nodedef->get(liquid_kind).liquid_range;
  1177. if (range > LIQUID_LEVEL_MAX + 1)
  1178. range = LIQUID_LEVEL_MAX + 1;
  1179. if ((num_sources >= 2 && m_nodedef->get(liquid_kind).liquid_renewable) || liquid_type == LIQUID_SOURCE) {
  1180. // liquid_kind will be set to either the flowing alternative of the node (if it's a liquid)
  1181. // or the flowing alternative of the first of the surrounding sources (if it's air), so
  1182. // it's perfectly safe to use liquid_kind here to determine the new node content.
  1183. new_node_content = m_nodedef->getId(m_nodedef->get(liquid_kind).liquid_alternative_source);
  1184. } else if (num_sources >= 1 && sources[0].t != NEIGHBOR_LOWER) {
  1185. // liquid_kind is set properly, see above
  1186. max_node_level = new_node_level = LIQUID_LEVEL_MAX;
  1187. if (new_node_level >= (LIQUID_LEVEL_MAX + 1 - range))
  1188. new_node_content = liquid_kind;
  1189. else
  1190. new_node_content = floodable_node;
  1191. } else if (ignored_sources && liquid_level >= 0) {
  1192. // Maybe there are neighbouring sources that aren't loaded yet
  1193. // so prevent flowing away.
  1194. new_node_level = liquid_level;
  1195. new_node_content = liquid_kind;
  1196. } else {
  1197. // no surrounding sources, so get the maximum level that can flow into this node
  1198. for (u16 i = 0; i < num_flows; i++) {
  1199. u8 nb_liquid_level = (flows[i].n.param2 & LIQUID_LEVEL_MASK);
  1200. switch (flows[i].t) {
  1201. case NEIGHBOR_UPPER:
  1202. if (nb_liquid_level + WATER_DROP_BOOST > max_node_level) {
  1203. max_node_level = LIQUID_LEVEL_MAX;
  1204. if (nb_liquid_level + WATER_DROP_BOOST < LIQUID_LEVEL_MAX)
  1205. max_node_level = nb_liquid_level + WATER_DROP_BOOST;
  1206. } else if (nb_liquid_level > max_node_level) {
  1207. max_node_level = nb_liquid_level;
  1208. }
  1209. break;
  1210. case NEIGHBOR_LOWER:
  1211. break;
  1212. case NEIGHBOR_SAME_LEVEL:
  1213. if ((flows[i].n.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK &&
  1214. nb_liquid_level > 0 && nb_liquid_level - 1 > max_node_level)
  1215. max_node_level = nb_liquid_level - 1;
  1216. break;
  1217. }
  1218. }
  1219. u8 viscosity = m_nodedef->get(liquid_kind).liquid_viscosity;
  1220. if (viscosity > 1 && max_node_level != liquid_level) {
  1221. // amount to gain, limited by viscosity
  1222. // must be at least 1 in absolute value
  1223. s8 level_inc = max_node_level - liquid_level;
  1224. if (level_inc < -viscosity || level_inc > viscosity)
  1225. new_node_level = liquid_level + level_inc/viscosity;
  1226. else if (level_inc < 0)
  1227. new_node_level = liquid_level - 1;
  1228. else if (level_inc > 0)
  1229. new_node_level = liquid_level + 1;
  1230. if (new_node_level != max_node_level)
  1231. must_reflow.push_back(p0);
  1232. } else {
  1233. new_node_level = max_node_level;
  1234. }
  1235. if (max_node_level >= (LIQUID_LEVEL_MAX + 1 - range))
  1236. new_node_content = liquid_kind;
  1237. else
  1238. new_node_content = floodable_node;
  1239. }
  1240. /*
  1241. check if anything has changed. if not, just continue with the next node.
  1242. */
  1243. if (new_node_content == n0.getContent() &&
  1244. (m_nodedef->get(n0.getContent()).liquid_type != LIQUID_FLOWING ||
  1245. ((n0.param2 & LIQUID_LEVEL_MASK) == (u8)new_node_level &&
  1246. ((n0.param2 & LIQUID_FLOW_DOWN_MASK) == LIQUID_FLOW_DOWN_MASK)
  1247. == flowing_down)))
  1248. continue;
  1249. /*
  1250. update the current node
  1251. */
  1252. MapNode n00 = n0;
  1253. //bool flow_down_enabled = (flowing_down && ((n0.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK));
  1254. if (m_nodedef->get(new_node_content).liquid_type == LIQUID_FLOWING) {
  1255. // set level to last 3 bits, flowing down bit to 4th bit
  1256. n0.param2 = (flowing_down ? LIQUID_FLOW_DOWN_MASK : 0x00) | (new_node_level & LIQUID_LEVEL_MASK);
  1257. } else {
  1258. // set the liquid level and flow bit to 0
  1259. n0.param2 = ~(LIQUID_LEVEL_MASK | LIQUID_FLOW_DOWN_MASK);
  1260. }
  1261. n0.setContent(new_node_content);
  1262. // Ignore light (because calling voxalgo::update_lighting_nodes)
  1263. n0.setLight(LIGHTBANK_DAY, 0, m_nodedef);
  1264. n0.setLight(LIGHTBANK_NIGHT, 0, m_nodedef);
  1265. // Find out whether there is a suspect for this action
  1266. std::string suspect;
  1267. if (m_gamedef->rollback())
  1268. suspect = m_gamedef->rollback()->getSuspect(p0, 83, 1);
  1269. if (m_gamedef->rollback() && !suspect.empty()) {
  1270. // Blame suspect
  1271. RollbackScopeActor rollback_scope(m_gamedef->rollback(), suspect, true);
  1272. // Get old node for rollback
  1273. RollbackNode rollback_oldnode(this, p0, m_gamedef);
  1274. // Set node
  1275. setNode(p0, n0);
  1276. // Report
  1277. RollbackNode rollback_newnode(this, p0, m_gamedef);
  1278. RollbackAction action;
  1279. action.setSetNode(p0, rollback_oldnode, rollback_newnode);
  1280. m_gamedef->rollback()->reportAction(action);
  1281. } else {
  1282. // Set node
  1283. setNode(p0, n0);
  1284. }
  1285. v3s16 blockpos = getNodeBlockPos(p0);
  1286. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  1287. if (block != NULL) {
  1288. modified_blocks[blockpos] = block;
  1289. changed_nodes.push_back(std::pair<v3s16, MapNode>(p0, n00));
  1290. }
  1291. /*
  1292. enqueue neighbors for update if neccessary
  1293. */
  1294. switch (m_nodedef->get(n0.getContent()).liquid_type) {
  1295. case LIQUID_SOURCE:
  1296. case LIQUID_FLOWING:
  1297. // make sure source flows into all neighboring nodes
  1298. for (u16 i = 0; i < num_flows; i++)
  1299. if (flows[i].t != NEIGHBOR_UPPER)
  1300. m_transforming_liquid.push_back(flows[i].p);
  1301. for (u16 i = 0; i < num_airs; i++)
  1302. if (airs[i].t != NEIGHBOR_UPPER)
  1303. m_transforming_liquid.push_back(airs[i].p);
  1304. break;
  1305. case LIQUID_NONE:
  1306. // this flow has turned to air; neighboring flows might need to do the same
  1307. for (u16 i = 0; i < num_flows; i++)
  1308. m_transforming_liquid.push_back(flows[i].p);
  1309. break;
  1310. }
  1311. }
  1312. //infostream<<"Map::transformLiquids(): loopcount="<<loopcount<<std::endl;
  1313. for (std::deque<v3s16>::iterator iter = must_reflow.begin(); iter != must_reflow.end(); ++iter)
  1314. m_transforming_liquid.push_back(*iter);
  1315. voxalgo::update_lighting_nodes(this, m_nodedef, changed_nodes, modified_blocks);
  1316. /* ----------------------------------------------------------------------
  1317. * Manage the queue so that it does not grow indefinately
  1318. */
  1319. u16 time_until_purge = g_settings->getU16("liquid_queue_purge_time");
  1320. if (time_until_purge == 0)
  1321. return; // Feature disabled
  1322. time_until_purge *= 1000; // seconds -> milliseconds
  1323. u32 curr_time = getTime(PRECISION_MILLI);
  1324. u32 prev_unprocessed = m_unprocessed_count;
  1325. m_unprocessed_count = m_transforming_liquid.size();
  1326. // if unprocessed block count is decreasing or stable
  1327. if (m_unprocessed_count <= prev_unprocessed) {
  1328. m_queue_size_timer_started = false;
  1329. } else {
  1330. if (!m_queue_size_timer_started)
  1331. m_inc_trending_up_start_time = curr_time;
  1332. m_queue_size_timer_started = true;
  1333. }
  1334. // Account for curr_time overflowing
  1335. if (m_queue_size_timer_started && m_inc_trending_up_start_time > curr_time)
  1336. m_queue_size_timer_started = false;
  1337. /* If the queue has been growing for more than liquid_queue_purge_time seconds
  1338. * and the number of unprocessed blocks is still > liquid_loop_max then we
  1339. * cannot keep up; dump the oldest blocks from the queue so that the queue
  1340. * has liquid_loop_max items in it
  1341. */
  1342. if (m_queue_size_timer_started
  1343. && curr_time - m_inc_trending_up_start_time > time_until_purge
  1344. && m_unprocessed_count > liquid_loop_max) {
  1345. size_t dump_qty = m_unprocessed_count - liquid_loop_max;
  1346. infostream << "transformLiquids(): DUMPING " << dump_qty
  1347. << " blocks from the queue" << std::endl;
  1348. while (dump_qty--)
  1349. m_transforming_liquid.pop_front();
  1350. m_queue_size_timer_started = false; // optimistically assume we can keep up now
  1351. m_unprocessed_count = m_transforming_liquid.size();
  1352. }
  1353. }
  1354. std::vector<v3s16> Map::findNodesWithMetadata(v3s16 p1, v3s16 p2)
  1355. {
  1356. std::vector<v3s16> positions_with_meta;
  1357. sortBoxVerticies(p1, p2);
  1358. v3s16 bpmin = getNodeBlockPos(p1);
  1359. v3s16 bpmax = getNodeBlockPos(p2);
  1360. VoxelArea area(p1, p2);
  1361. for (s16 z = bpmin.Z; z <= bpmax.Z; z++)
  1362. for (s16 y = bpmin.Y; y <= bpmax.Y; y++)
  1363. for (s16 x = bpmin.X; x <= bpmax.X; x++) {
  1364. v3s16 blockpos(x, y, z);
  1365. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  1366. if (!block) {
  1367. verbosestream << "Map::getNodeMetadata(): Need to emerge "
  1368. << PP(blockpos) << std::endl;
  1369. block = emergeBlock(blockpos, false);
  1370. }
  1371. if (!block) {
  1372. infostream << "WARNING: Map::getNodeMetadata(): Block not found"
  1373. << std::endl;
  1374. continue;
  1375. }
  1376. v3s16 p_base = blockpos * MAP_BLOCKSIZE;
  1377. std::vector<v3s16> keys = block->m_node_metadata.getAllKeys();
  1378. for (size_t i = 0; i != keys.size(); i++) {
  1379. v3s16 p(keys[i] + p_base);
  1380. if (!area.contains(p))
  1381. continue;
  1382. positions_with_meta.push_back(p);
  1383. }
  1384. }
  1385. return positions_with_meta;
  1386. }
  1387. NodeMetadata *Map::getNodeMetadata(v3s16 p)
  1388. {
  1389. v3s16 blockpos = getNodeBlockPos(p);
  1390. v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
  1391. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  1392. if(!block){
  1393. infostream<<"Map::getNodeMetadata(): Need to emerge "
  1394. <<PP(blockpos)<<std::endl;
  1395. block = emergeBlock(blockpos, false);
  1396. }
  1397. if(!block){
  1398. warningstream<<"Map::getNodeMetadata(): Block not found"
  1399. <<std::endl;
  1400. return NULL;
  1401. }
  1402. NodeMetadata *meta = block->m_node_metadata.get(p_rel);
  1403. return meta;
  1404. }
  1405. bool Map::setNodeMetadata(v3s16 p, NodeMetadata *meta)
  1406. {
  1407. v3s16 blockpos = getNodeBlockPos(p);
  1408. v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
  1409. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  1410. if(!block){
  1411. infostream<<"Map::setNodeMetadata(): Need to emerge "
  1412. <<PP(blockpos)<<std::endl;
  1413. block = emergeBlock(blockpos, false);
  1414. }
  1415. if(!block){
  1416. warningstream<<"Map::setNodeMetadata(): Block not found"
  1417. <<std::endl;
  1418. return false;
  1419. }
  1420. block->m_node_metadata.set(p_rel, meta);
  1421. return true;
  1422. }
  1423. void Map::removeNodeMetadata(v3s16 p)
  1424. {
  1425. v3s16 blockpos = getNodeBlockPos(p);
  1426. v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
  1427. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  1428. if(block == NULL)
  1429. {
  1430. warningstream<<"Map::removeNodeMetadata(): Block not found"
  1431. <<std::endl;
  1432. return;
  1433. }
  1434. block->m_node_metadata.remove(p_rel);
  1435. }
  1436. NodeTimer Map::getNodeTimer(v3s16 p)
  1437. {
  1438. v3s16 blockpos = getNodeBlockPos(p);
  1439. v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
  1440. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  1441. if(!block){
  1442. infostream<<"Map::getNodeTimer(): Need to emerge "
  1443. <<PP(blockpos)<<std::endl;
  1444. block = emergeBlock(blockpos, false);
  1445. }
  1446. if(!block){
  1447. warningstream<<"Map::getNodeTimer(): Block not found"
  1448. <<std::endl;
  1449. return NodeTimer();
  1450. }
  1451. NodeTimer t = block->m_node_timers.get(p_rel);
  1452. NodeTimer nt(t.timeout, t.elapsed, p);
  1453. return nt;
  1454. }
  1455. void Map::setNodeTimer(const NodeTimer &t)
  1456. {
  1457. v3s16 p = t.position;
  1458. v3s16 blockpos = getNodeBlockPos(p);
  1459. v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
  1460. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  1461. if(!block){
  1462. infostream<<"Map::setNodeTimer(): Need to emerge "
  1463. <<PP(blockpos)<<std::endl;
  1464. block = emergeBlock(blockpos, false);
  1465. }
  1466. if(!block){
  1467. warningstream<<"Map::setNodeTimer(): Block not found"
  1468. <<std::endl;
  1469. return;
  1470. }
  1471. NodeTimer nt(t.timeout, t.elapsed, p_rel);
  1472. block->m_node_timers.set(nt);
  1473. }
  1474. void Map::removeNodeTimer(v3s16 p)
  1475. {
  1476. v3s16 blockpos = getNodeBlockPos(p);
  1477. v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
  1478. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  1479. if(block == NULL)
  1480. {
  1481. warningstream<<"Map::removeNodeTimer(): Block not found"
  1482. <<std::endl;
  1483. return;
  1484. }
  1485. block->m_node_timers.remove(p_rel);
  1486. }
  1487. /*
  1488. ServerMap
  1489. */
  1490. ServerMap::ServerMap(std::string savedir, IGameDef *gamedef, EmergeManager *emerge):
  1491. Map(dout_server, gamedef),
  1492. settings_mgr(g_settings, savedir + DIR_DELIM + "map_meta.txt"),
  1493. m_emerge(emerge),
  1494. m_map_metadata_changed(true)
  1495. {
  1496. verbosestream<<FUNCTION_NAME<<std::endl;
  1497. // Tell the EmergeManager about our MapSettingsManager
  1498. emerge->map_settings_mgr = &settings_mgr;
  1499. /*
  1500. Try to load map; if not found, create a new one.
  1501. */
  1502. // Determine which database backend to use
  1503. std::string conf_path = savedir + DIR_DELIM + "world.mt";
  1504. Settings conf;
  1505. bool succeeded = conf.readConfigFile(conf_path.c_str());
  1506. if (!succeeded || !conf.exists("backend")) {
  1507. // fall back to sqlite3
  1508. conf.set("backend", "sqlite3");
  1509. }
  1510. std::string backend = conf.get("backend");
  1511. dbase = createDatabase(backend, savedir, conf);
  1512. if (!conf.updateConfigFile(conf_path.c_str()))
  1513. errorstream << "ServerMap::ServerMap(): Failed to update world.mt!" << std::endl;
  1514. m_savedir = savedir;
  1515. m_map_saving_enabled = false;
  1516. try
  1517. {
  1518. // If directory exists, check contents and load if possible
  1519. if(fs::PathExists(m_savedir))
  1520. {
  1521. // If directory is empty, it is safe to save into it.
  1522. if(fs::GetDirListing(m_savedir).size() == 0)
  1523. {
  1524. infostream<<"ServerMap: Empty save directory is valid."
  1525. <<std::endl;
  1526. m_map_saving_enabled = true;
  1527. }
  1528. else
  1529. {
  1530. if (settings_mgr.loadMapMeta()) {
  1531. infostream << "ServerMap: Metadata loaded from "
  1532. << savedir << std::endl;
  1533. } else {
  1534. infostream << "ServerMap: Metadata could not be loaded "
  1535. "from " << savedir << ", assuming valid save "
  1536. "directory." << std::endl;
  1537. }
  1538. m_map_saving_enabled = true;
  1539. // Map loaded, not creating new one
  1540. return;
  1541. }
  1542. }
  1543. // If directory doesn't exist, it is safe to save to it
  1544. else{
  1545. m_map_saving_enabled = true;
  1546. }
  1547. }
  1548. catch(std::exception &e)
  1549. {
  1550. warningstream<<"ServerMap: Failed to load map from "<<savedir
  1551. <<", exception: "<<e.what()<<std::endl;
  1552. infostream<<"Please remove the map or fix it."<<std::endl;
  1553. warningstream<<"Map saving will be disabled."<<std::endl;
  1554. }
  1555. infostream<<"Initializing new map."<<std::endl;
  1556. // Create zero sector
  1557. emergeSector(v2s16(0,0));
  1558. // Initially write whole map
  1559. save(MOD_STATE_CLEAN);
  1560. }
  1561. ServerMap::~ServerMap()
  1562. {
  1563. verbosestream<<FUNCTION_NAME<<std::endl;
  1564. try
  1565. {
  1566. if(m_map_saving_enabled)
  1567. {
  1568. // Save only changed parts
  1569. save(MOD_STATE_WRITE_AT_UNLOAD);
  1570. infostream<<"ServerMap: Saved map to "<<m_savedir<<std::endl;
  1571. }
  1572. else
  1573. {
  1574. infostream<<"ServerMap: Map not saved"<<std::endl;
  1575. }
  1576. }
  1577. catch(std::exception &e)
  1578. {
  1579. infostream<<"ServerMap: Failed to save map to "<<m_savedir
  1580. <<", exception: "<<e.what()<<std::endl;
  1581. }
  1582. /*
  1583. Close database if it was opened
  1584. */
  1585. delete dbase;
  1586. #if 0
  1587. /*
  1588. Free all MapChunks
  1589. */
  1590. core::map<v2s16, MapChunk*>::Iterator i = m_chunks.getIterator();
  1591. for(; i.atEnd() == false; i++)
  1592. {
  1593. MapChunk *chunk = i.getNode()->getValue();
  1594. delete chunk;
  1595. }
  1596. #endif
  1597. }
  1598. MapgenParams *ServerMap::getMapgenParams()
  1599. {
  1600. // getMapgenParams() should only ever be called after Server is initialized
  1601. assert(settings_mgr.mapgen_params != NULL);
  1602. return settings_mgr.mapgen_params;
  1603. }
  1604. u64 ServerMap::getSeed()
  1605. {
  1606. return getMapgenParams()->seed;
  1607. }
  1608. s16 ServerMap::getWaterLevel()
  1609. {
  1610. return getMapgenParams()->water_level;
  1611. }
  1612. bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data)
  1613. {
  1614. s16 csize = getMapgenParams()->chunksize;
  1615. v3s16 bpmin = EmergeManager::getContainingChunk(blockpos, csize);
  1616. v3s16 bpmax = bpmin + v3s16(1, 1, 1) * (csize - 1);
  1617. bool enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info;
  1618. EMERGE_DBG_OUT("initBlockMake(): " PP(bpmin) " - " PP(bpmax));
  1619. v3s16 extra_borders(1, 1, 1);
  1620. v3s16 full_bpmin = bpmin - extra_borders;
  1621. v3s16 full_bpmax = bpmax + extra_borders;
  1622. // Do nothing if not inside limits (+-1 because of neighbors)
  1623. if (blockpos_over_limit(full_bpmin) ||
  1624. blockpos_over_limit(full_bpmax))
  1625. return false;
  1626. data->seed = getSeed();
  1627. data->blockpos_min = bpmin;
  1628. data->blockpos_max = bpmax;
  1629. data->blockpos_requested = blockpos;
  1630. data->nodedef = m_nodedef;
  1631. /*
  1632. Create the whole area of this and the neighboring blocks
  1633. */
  1634. for (s16 x = full_bpmin.X; x <= full_bpmax.X; x++)
  1635. for (s16 z = full_bpmin.Z; z <= full_bpmax.Z; z++) {
  1636. v2s16 sectorpos(x, z);
  1637. // Sector metadata is loaded from disk if not already loaded.
  1638. ServerMapSector *sector = createSector(sectorpos);
  1639. FATAL_ERROR_IF(sector == NULL, "createSector() failed");
  1640. for (s16 y = full_bpmin.Y; y <= full_bpmax.Y; y++) {
  1641. v3s16 p(x, y, z);
  1642. MapBlock *block = emergeBlock(p, false);
  1643. if (block == NULL) {
  1644. block = createBlock(p);
  1645. // Block gets sunlight if this is true.
  1646. // Refer to the map generator heuristics.
  1647. bool ug = m_emerge->isBlockUnderground(p);
  1648. block->setIsUnderground(ug);
  1649. }
  1650. }
  1651. }
  1652. /*
  1653. Now we have a big empty area.
  1654. Make a ManualMapVoxelManipulator that contains this and the
  1655. neighboring blocks
  1656. */
  1657. data->vmanip = new MMVManip(this);
  1658. data->vmanip->initialEmerge(full_bpmin, full_bpmax);
  1659. // Note: we may need this again at some point.
  1660. #if 0
  1661. // Ensure none of the blocks to be generated were marked as
  1662. // containing CONTENT_IGNORE
  1663. for (s16 z = blockpos_min.Z; z <= blockpos_max.Z; z++) {
  1664. for (s16 y = blockpos_min.Y; y <= blockpos_max.Y; y++) {
  1665. for (s16 x = blockpos_min.X; x <= blockpos_max.X; x++) {
  1666. core::map<v3s16, u8>::Node *n;
  1667. n = data->vmanip->m_loaded_blocks.find(v3s16(x, y, z));
  1668. if (n == NULL)
  1669. continue;
  1670. u8 flags = n->getValue();
  1671. flags &= ~VMANIP_BLOCK_CONTAINS_CIGNORE;
  1672. n->setValue(flags);
  1673. }
  1674. }
  1675. }
  1676. #endif
  1677. // Data is ready now.
  1678. return true;
  1679. }
  1680. void ServerMap::finishBlockMake(BlockMakeData *data,
  1681. std::map<v3s16, MapBlock*> *changed_blocks)
  1682. {
  1683. v3s16 bpmin = data->blockpos_min;
  1684. v3s16 bpmax = data->blockpos_max;
  1685. v3s16 extra_borders(1, 1, 1);
  1686. v3s16 full_bpmin = bpmin - extra_borders;
  1687. v3s16 full_bpmax = bpmax + extra_borders;
  1688. bool enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info;
  1689. EMERGE_DBG_OUT("finishBlockMake(): " PP(bpmin) " - " PP(bpmax));
  1690. /*
  1691. Set lighting to non-expired state in all of them.
  1692. This is cheating, but it is not fast enough if all of them
  1693. would actually be updated.
  1694. */
  1695. for (s16 x = full_bpmin.X; x <= full_bpmax.X; x++)
  1696. for (s16 z = full_bpmin.Z; z <= full_bpmax.Z; z++)
  1697. for (s16 y = full_bpmin.Y; y <= full_bpmax.Y; y++) {
  1698. MapBlock *block = emergeBlock(v3s16(x, y, z), false);
  1699. if (!block)
  1700. continue;
  1701. block->setLightingExpired(false);
  1702. }
  1703. /*
  1704. Blit generated stuff to map
  1705. NOTE: blitBackAll adds nearly everything to changed_blocks
  1706. */
  1707. data->vmanip->blitBackAll(changed_blocks);
  1708. EMERGE_DBG_OUT("finishBlockMake: changed_blocks.size()="
  1709. << changed_blocks->size());
  1710. /*
  1711. Copy transforming liquid information
  1712. */
  1713. while (data->transforming_liquid.size()) {
  1714. m_transforming_liquid.push_back(data->transforming_liquid.front());
  1715. data->transforming_liquid.pop_front();
  1716. }
  1717. for (std::map<v3s16, MapBlock *>::iterator
  1718. it = changed_blocks->begin();
  1719. it != changed_blocks->end(); ++it) {
  1720. MapBlock *block = it->second;
  1721. if (!block)
  1722. continue;
  1723. /*
  1724. Update day/night difference cache of the MapBlocks
  1725. */
  1726. block->expireDayNightDiff();
  1727. /*
  1728. Set block as modified
  1729. */
  1730. block->raiseModified(MOD_STATE_WRITE_NEEDED,
  1731. MOD_REASON_EXPIRE_DAYNIGHTDIFF);
  1732. }
  1733. /*
  1734. Set central blocks as generated
  1735. */
  1736. for (s16 x = bpmin.X; x <= bpmax.X; x++)
  1737. for (s16 z = bpmin.Z; z <= bpmax.Z; z++)
  1738. for (s16 y = bpmin.Y; y <= bpmax.Y; y++) {
  1739. MapBlock *block = getBlockNoCreateNoEx(v3s16(x, y, z));
  1740. if (!block)
  1741. continue;
  1742. block->setGenerated(true);
  1743. }
  1744. /*
  1745. Save changed parts of map
  1746. NOTE: Will be saved later.
  1747. */
  1748. //save(MOD_STATE_WRITE_AT_UNLOAD);
  1749. }
  1750. ServerMapSector *ServerMap::createSector(v2s16 p2d)
  1751. {
  1752. DSTACKF("%s: p2d=(%d,%d)",
  1753. FUNCTION_NAME,
  1754. p2d.X, p2d.Y);
  1755. /*
  1756. Check if it exists already in memory
  1757. */
  1758. ServerMapSector *sector = (ServerMapSector*)getSectorNoGenerateNoEx(p2d);
  1759. if(sector != NULL)
  1760. return sector;
  1761. /*
  1762. Try to load it from disk (with blocks)
  1763. */
  1764. //if(loadSectorFull(p2d) == true)
  1765. /*
  1766. Try to load metadata from disk
  1767. */
  1768. #if 0
  1769. if(loadSectorMeta(p2d) == true)
  1770. {
  1771. ServerMapSector *sector = (ServerMapSector*)getSectorNoGenerateNoEx(p2d);
  1772. if(sector == NULL)
  1773. {
  1774. infostream<<"ServerMap::createSector(): loadSectorFull didn't make a sector"<<std::endl;
  1775. throw InvalidPositionException("");
  1776. }
  1777. return sector;
  1778. }
  1779. #endif
  1780. /*
  1781. Do not create over-limit.
  1782. We are checking for any nodes of the mapblocks of the sector being beyond the limit.
  1783. A sector is a vertical column of mapblocks, so sectorpos is like a 2D blockpos.
  1784. At the negative limit we are checking for
  1785. block minimum nodepos < -mapgenlimit.
  1786. At the positive limit we are checking for
  1787. block maximum nodepos > mapgenlimit.
  1788. Block minimum nodepos = blockpos * mapblocksize.
  1789. Block maximum nodepos = (blockpos + 1) * mapblocksize - 1.
  1790. */
  1791. const u16 map_gen_limit = MYMIN(MAX_MAP_GENERATION_LIMIT,
  1792. g_settings->getU16("map_generation_limit"));
  1793. if (p2d.X * MAP_BLOCKSIZE < -map_gen_limit
  1794. || (p2d.X + 1) * MAP_BLOCKSIZE - 1 > map_gen_limit
  1795. || p2d.Y * MAP_BLOCKSIZE < -map_gen_limit
  1796. || (p2d.Y + 1) * MAP_BLOCKSIZE - 1 > map_gen_limit)
  1797. throw InvalidPositionException("createSector(): pos. over limit");
  1798. /*
  1799. Generate blank sector
  1800. */
  1801. sector = new ServerMapSector(this, p2d, m_gamedef);
  1802. // Sector position on map in nodes
  1803. //v2s16 nodepos2d = p2d * MAP_BLOCKSIZE;
  1804. /*
  1805. Insert to container
  1806. */
  1807. m_sectors[p2d] = sector;
  1808. return sector;
  1809. }
  1810. #if 0
  1811. /*
  1812. This is a quick-hand function for calling makeBlock().
  1813. */
  1814. MapBlock * ServerMap::generateBlock(
  1815. v3s16 p,
  1816. std::map<v3s16, MapBlock*> &modified_blocks
  1817. )
  1818. {
  1819. DSTACKF("%s: p=(%d,%d,%d)", FUNCTION_NAME, p.X, p.Y, p.Z);
  1820. /*infostream<<"generateBlock(): "
  1821. <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
  1822. <<std::endl;*/
  1823. bool enable_mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info");
  1824. TimeTaker timer("generateBlock");
  1825. //MapBlock *block = original_dummy;
  1826. v2s16 p2d(p.X, p.Z);
  1827. v2s16 p2d_nodes = p2d * MAP_BLOCKSIZE;
  1828. /*
  1829. Do not generate over-limit
  1830. */
  1831. if(blockpos_over_limit(p))
  1832. {
  1833. infostream<<FUNCTION_NAME<<": Block position over limit"<<std::endl;
  1834. throw InvalidPositionException("generateBlock(): pos. over limit");
  1835. }
  1836. /*
  1837. Create block make data
  1838. */
  1839. BlockMakeData data;
  1840. initBlockMake(&data, p);
  1841. /*
  1842. Generate block
  1843. */
  1844. {
  1845. TimeTaker t("mapgen::make_block()");
  1846. mapgen->makeChunk(&data);
  1847. //mapgen::make_block(&data);
  1848. if(enable_mapgen_debug_info == false)
  1849. t.stop(true); // Hide output
  1850. }
  1851. /*
  1852. Blit data back on map, update lighting, add mobs and whatever this does
  1853. */
  1854. finishBlockMake(&data, modified_blocks);
  1855. /*
  1856. Get central block
  1857. */
  1858. MapBlock *block = getBlockNoCreateNoEx(p);
  1859. #if 0
  1860. /*
  1861. Check result
  1862. */
  1863. if(block)
  1864. {
  1865. bool erroneus_content = false;
  1866. for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
  1867. for(s16 y0=0; y0<MAP_BLOCKSIZE; y0++)
  1868. for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
  1869. {
  1870. v3s16 p(x0,y0,z0);
  1871. MapNode n = block->getNode(p);
  1872. if(n.getContent() == CONTENT_IGNORE)
  1873. {
  1874. infostream<<"CONTENT_IGNORE at "
  1875. <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
  1876. <<std::endl;
  1877. erroneus_content = true;
  1878. assert(0);
  1879. }
  1880. }
  1881. if(erroneus_content)
  1882. {
  1883. assert(0);
  1884. }
  1885. }
  1886. #endif
  1887. #if 0
  1888. /*
  1889. Generate a completely empty block
  1890. */
  1891. if(block)
  1892. {
  1893. for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
  1894. for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
  1895. {
  1896. for(s16 y0=0; y0<MAP_BLOCKSIZE; y0++)
  1897. {
  1898. MapNode n;
  1899. n.setContent(CONTENT_AIR);
  1900. block->setNode(v3s16(x0,y0,z0), n);
  1901. }
  1902. }
  1903. }
  1904. #endif
  1905. if(enable_mapgen_debug_info == false)
  1906. timer.stop(true); // Hide output
  1907. return block;
  1908. }
  1909. #endif
  1910. MapBlock * ServerMap::createBlock(v3s16 p)
  1911. {
  1912. DSTACKF("%s: p=(%d,%d,%d)",
  1913. FUNCTION_NAME, p.X, p.Y, p.Z);
  1914. /*
  1915. Do not create over-limit
  1916. */
  1917. if (blockpos_over_limit(p))
  1918. throw InvalidPositionException("createBlock(): pos. over limit");
  1919. v2s16 p2d(p.X, p.Z);
  1920. s16 block_y = p.Y;
  1921. /*
  1922. This will create or load a sector if not found in memory.
  1923. If block exists on disk, it will be loaded.
  1924. NOTE: On old save formats, this will be slow, as it generates
  1925. lighting on blocks for them.
  1926. */
  1927. ServerMapSector *sector;
  1928. try {
  1929. sector = (ServerMapSector*)createSector(p2d);
  1930. assert(sector->getId() == MAPSECTOR_SERVER);
  1931. }
  1932. catch(InvalidPositionException &e)
  1933. {
  1934. infostream<<"createBlock: createSector() failed"<<std::endl;
  1935. throw e;
  1936. }
  1937. /*
  1938. NOTE: This should not be done, or at least the exception
  1939. should not be passed on as std::exception, because it
  1940. won't be catched at all.
  1941. */
  1942. /*catch(std::exception &e)
  1943. {
  1944. infostream<<"createBlock: createSector() failed: "
  1945. <<e.what()<<std::endl;
  1946. throw e;
  1947. }*/
  1948. /*
  1949. Try to get a block from the sector
  1950. */
  1951. MapBlock *block = sector->getBlockNoCreateNoEx(block_y);
  1952. if(block)
  1953. {
  1954. if(block->isDummy())
  1955. block->unDummify();
  1956. return block;
  1957. }
  1958. // Create blank
  1959. block = sector->createBlankBlock(block_y);
  1960. return block;
  1961. }
  1962. MapBlock * ServerMap::emergeBlock(v3s16 p, bool create_blank)
  1963. {
  1964. DSTACKF("%s: p=(%d,%d,%d), create_blank=%d",
  1965. FUNCTION_NAME,
  1966. p.X, p.Y, p.Z, create_blank);
  1967. {
  1968. MapBlock *block = getBlockNoCreateNoEx(p);
  1969. if(block && block->isDummy() == false)
  1970. return block;
  1971. }
  1972. {
  1973. MapBlock *block = loadBlock(p);
  1974. if(block)
  1975. return block;
  1976. }
  1977. if (create_blank) {
  1978. ServerMapSector *sector = createSector(v2s16(p.X, p.Z));
  1979. MapBlock *block = sector->createBlankBlock(p.Y);
  1980. return block;
  1981. }
  1982. #if 0
  1983. if(allow_generate)
  1984. {
  1985. std::map<v3s16, MapBlock*> modified_blocks;
  1986. MapBlock *block = generateBlock(p, modified_blocks);
  1987. if(block)
  1988. {
  1989. MapEditEvent event;
  1990. event.type = MEET_OTHER;
  1991. event.p = p;
  1992. // Copy modified_blocks to event
  1993. for(std::map<v3s16, MapBlock*>::iterator
  1994. i = modified_blocks.begin();
  1995. i != modified_blocks.end(); ++i)
  1996. {
  1997. event.modified_blocks.insert(i->first);
  1998. }
  1999. // Queue event
  2000. dispatchEvent(&event);
  2001. return block;
  2002. }
  2003. }
  2004. #endif
  2005. return NULL;
  2006. }
  2007. MapBlock *ServerMap::getBlockOrEmerge(v3s16 p3d)
  2008. {
  2009. MapBlock *block = getBlockNoCreateNoEx(p3d);
  2010. if (block == NULL)
  2011. m_emerge->enqueueBlockEmerge(PEER_ID_INEXISTENT, p3d, false);
  2012. return block;
  2013. }
  2014. void ServerMap::prepareBlock(MapBlock *block) {
  2015. }
  2016. // N.B. This requires no synchronization, since data will not be modified unless
  2017. // the VoxelManipulator being updated belongs to the same thread.
  2018. void ServerMap::updateVManip(v3s16 pos)
  2019. {
  2020. Mapgen *mg = m_emerge->getCurrentMapgen();
  2021. if (!mg)
  2022. return;
  2023. MMVManip *vm = mg->vm;
  2024. if (!vm)
  2025. return;
  2026. if (!vm->m_area.contains(pos))
  2027. return;
  2028. s32 idx = vm->m_area.index(pos);
  2029. vm->m_data[idx] = getNodeNoEx(pos);
  2030. vm->m_flags[idx] &= ~VOXELFLAG_NO_DATA;
  2031. vm->m_is_dirty = true;
  2032. }
  2033. s16 ServerMap::findGroundLevel(v2s16 p2d)
  2034. {
  2035. #if 0
  2036. /*
  2037. Uh, just do something random...
  2038. */
  2039. // Find existing map from top to down
  2040. s16 max=63;
  2041. s16 min=-64;
  2042. v3s16 p(p2d.X, max, p2d.Y);
  2043. for(; p.Y>min; p.Y--)
  2044. {
  2045. MapNode n = getNodeNoEx(p);
  2046. if(n.getContent() != CONTENT_IGNORE)
  2047. break;
  2048. }
  2049. if(p.Y == min)
  2050. goto plan_b;
  2051. // If this node is not air, go to plan b
  2052. if(getNodeNoEx(p).getContent() != CONTENT_AIR)
  2053. goto plan_b;
  2054. // Search existing walkable and return it
  2055. for(; p.Y>min; p.Y--)
  2056. {
  2057. MapNode n = getNodeNoEx(p);
  2058. if(content_walkable(n.d) && n.getContent() != CONTENT_IGNORE)
  2059. return p.Y;
  2060. }
  2061. // Move to plan b
  2062. plan_b:
  2063. #endif
  2064. /*
  2065. Determine from map generator noise functions
  2066. */
  2067. s16 level = m_emerge->getGroundLevelAtPoint(p2d);
  2068. return level;
  2069. //double level = base_rock_level_2d(m_seed, p2d) + AVERAGE_MUD_AMOUNT;
  2070. //return (s16)level;
  2071. }
  2072. bool ServerMap::loadFromFolders() {
  2073. if (!dbase->initialized() &&
  2074. !fs::PathExists(m_savedir + DIR_DELIM + "map.sqlite"))
  2075. return true;
  2076. return false;
  2077. }
  2078. void ServerMap::createDirs(std::string path)
  2079. {
  2080. if(fs::CreateAllDirs(path) == false)
  2081. {
  2082. m_dout<<"ServerMap: Failed to create directory "
  2083. <<"\""<<path<<"\""<<std::endl;
  2084. throw BaseException("ServerMap failed to create directory");
  2085. }
  2086. }
  2087. std::string ServerMap::getSectorDir(v2s16 pos, int layout)
  2088. {
  2089. char cc[9];
  2090. switch(layout)
  2091. {
  2092. case 1:
  2093. snprintf(cc, 9, "%.4x%.4x",
  2094. (unsigned int) pos.X & 0xffff,
  2095. (unsigned int) pos.Y & 0xffff);
  2096. return m_savedir + DIR_DELIM + "sectors" + DIR_DELIM + cc;
  2097. case 2:
  2098. snprintf(cc, 9, (std::string("%.3x") + DIR_DELIM + "%.3x").c_str(),
  2099. (unsigned int) pos.X & 0xfff,
  2100. (unsigned int) pos.Y & 0xfff);
  2101. return m_savedir + DIR_DELIM + "sectors2" + DIR_DELIM + cc;
  2102. default:
  2103. assert(false);
  2104. return "";
  2105. }
  2106. }
  2107. v2s16 ServerMap::getSectorPos(std::string dirname)
  2108. {
  2109. unsigned int x = 0, y = 0;
  2110. int r;
  2111. std::string component;
  2112. fs::RemoveLastPathComponent(dirname, &component, 1);
  2113. if(component.size() == 8)
  2114. {
  2115. // Old layout
  2116. r = sscanf(component.c_str(), "%4x%4x", &x, &y);
  2117. }
  2118. else if(component.size() == 3)
  2119. {
  2120. // New layout
  2121. fs::RemoveLastPathComponent(dirname, &component, 2);
  2122. r = sscanf(component.c_str(), (std::string("%3x") + DIR_DELIM + "%3x").c_str(), &x, &y);
  2123. // Sign-extend the 12 bit values up to 16 bits...
  2124. if(x & 0x800) x |= 0xF000;
  2125. if(y & 0x800) y |= 0xF000;
  2126. }
  2127. else
  2128. {
  2129. r = -1;
  2130. }
  2131. FATAL_ERROR_IF(r != 2, "getSectorPos()");
  2132. v2s16 pos((s16)x, (s16)y);
  2133. return pos;
  2134. }
  2135. v3s16 ServerMap::getBlockPos(std::string sectordir, std::string blockfile)
  2136. {
  2137. v2s16 p2d = getSectorPos(sectordir);
  2138. if(blockfile.size() != 4){
  2139. throw InvalidFilenameException("Invalid block filename");
  2140. }
  2141. unsigned int y;
  2142. int r = sscanf(blockfile.c_str(), "%4x", &y);
  2143. if(r != 1)
  2144. throw InvalidFilenameException("Invalid block filename");
  2145. return v3s16(p2d.X, y, p2d.Y);
  2146. }
  2147. std::string ServerMap::getBlockFilename(v3s16 p)
  2148. {
  2149. char cc[5];
  2150. snprintf(cc, 5, "%.4x", (unsigned int)p.Y&0xffff);
  2151. return cc;
  2152. }
  2153. void ServerMap::save(ModifiedState save_level)
  2154. {
  2155. DSTACK(FUNCTION_NAME);
  2156. if(m_map_saving_enabled == false) {
  2157. warningstream<<"Not saving map, saving disabled."<<std::endl;
  2158. return;
  2159. }
  2160. if(save_level == MOD_STATE_CLEAN)
  2161. infostream<<"ServerMap: Saving whole map, this can take time."
  2162. <<std::endl;
  2163. if (m_map_metadata_changed || save_level == MOD_STATE_CLEAN) {
  2164. if (settings_mgr.saveMapMeta())
  2165. m_map_metadata_changed = false;
  2166. }
  2167. // Profile modified reasons
  2168. Profiler modprofiler;
  2169. u32 sector_meta_count = 0;
  2170. u32 block_count = 0;
  2171. u32 block_count_all = 0; // Number of blocks in memory
  2172. // Don't do anything with sqlite unless something is really saved
  2173. bool save_started = false;
  2174. for(std::map<v2s16, MapSector*>::iterator i = m_sectors.begin();
  2175. i != m_sectors.end(); ++i) {
  2176. ServerMapSector *sector = (ServerMapSector*)i->second;
  2177. assert(sector->getId() == MAPSECTOR_SERVER);
  2178. if(sector->differs_from_disk || save_level == MOD_STATE_CLEAN) {
  2179. saveSectorMeta(sector);
  2180. sector_meta_count++;
  2181. }
  2182. MapBlockVect blocks;
  2183. sector->getBlocks(blocks);
  2184. for(MapBlockVect::iterator j = blocks.begin();
  2185. j != blocks.end(); ++j) {
  2186. MapBlock *block = *j;
  2187. block_count_all++;
  2188. if(block->getModified() >= (u32)save_level) {
  2189. // Lazy beginSave()
  2190. if(!save_started) {
  2191. beginSave();
  2192. save_started = true;
  2193. }
  2194. modprofiler.add(block->getModifiedReasonString(), 1);
  2195. saveBlock(block);
  2196. block_count++;
  2197. /*infostream<<"ServerMap: Written block ("
  2198. <<block->getPos().X<<","
  2199. <<block->getPos().Y<<","
  2200. <<block->getPos().Z<<")"
  2201. <<std::endl;*/
  2202. }
  2203. }
  2204. }
  2205. if(save_started)
  2206. endSave();
  2207. /*
  2208. Only print if something happened or saved whole map
  2209. */
  2210. if(save_level == MOD_STATE_CLEAN || sector_meta_count != 0
  2211. || block_count != 0) {
  2212. infostream<<"ServerMap: Written: "
  2213. <<sector_meta_count<<" sector metadata files, "
  2214. <<block_count<<" block files"
  2215. <<", "<<block_count_all<<" blocks in memory."
  2216. <<std::endl;
  2217. PrintInfo(infostream); // ServerMap/ClientMap:
  2218. infostream<<"Blocks modified by: "<<std::endl;
  2219. modprofiler.print(infostream);
  2220. }
  2221. }
  2222. void ServerMap::listAllLoadableBlocks(std::vector<v3s16> &dst)
  2223. {
  2224. if (loadFromFolders()) {
  2225. errorstream << "Map::listAllLoadableBlocks(): Result will be missing "
  2226. << "all blocks that are stored in flat files." << std::endl;
  2227. }
  2228. dbase->listAllLoadableBlocks(dst);
  2229. }
  2230. void ServerMap::listAllLoadedBlocks(std::vector<v3s16> &dst)
  2231. {
  2232. for(std::map<v2s16, MapSector*>::iterator si = m_sectors.begin();
  2233. si != m_sectors.end(); ++si)
  2234. {
  2235. MapSector *sector = si->second;
  2236. MapBlockVect blocks;
  2237. sector->getBlocks(blocks);
  2238. for(MapBlockVect::iterator i = blocks.begin();
  2239. i != blocks.end(); ++i) {
  2240. v3s16 p = (*i)->getPos();
  2241. dst.push_back(p);
  2242. }
  2243. }
  2244. }
  2245. void ServerMap::saveSectorMeta(ServerMapSector *sector)
  2246. {
  2247. DSTACK(FUNCTION_NAME);
  2248. // Format used for writing
  2249. u8 version = SER_FMT_VER_HIGHEST_WRITE;
  2250. // Get destination
  2251. v2s16 pos = sector->getPos();
  2252. std::string dir = getSectorDir(pos);
  2253. createDirs(dir);
  2254. std::string fullpath = dir + DIR_DELIM + "meta";
  2255. std::ostringstream ss(std::ios_base::binary);
  2256. sector->serialize(ss, version);
  2257. if(!fs::safeWriteToFile(fullpath, ss.str()))
  2258. throw FileNotGoodException("Cannot write sector metafile");
  2259. sector->differs_from_disk = false;
  2260. }
  2261. MapSector* ServerMap::loadSectorMeta(std::string sectordir, bool save_after_load)
  2262. {
  2263. DSTACK(FUNCTION_NAME);
  2264. // Get destination
  2265. v2s16 p2d = getSectorPos(sectordir);
  2266. ServerMapSector *sector = NULL;
  2267. std::string fullpath = sectordir + DIR_DELIM + "meta";
  2268. std::ifstream is(fullpath.c_str(), std::ios_base::binary);
  2269. if(is.good() == false)
  2270. {
  2271. // If the directory exists anyway, it probably is in some old
  2272. // format. Just go ahead and create the sector.
  2273. if(fs::PathExists(sectordir))
  2274. {
  2275. /*infostream<<"ServerMap::loadSectorMeta(): Sector metafile "
  2276. <<fullpath<<" doesn't exist but directory does."
  2277. <<" Continuing with a sector with no metadata."
  2278. <<std::endl;*/
  2279. sector = new ServerMapSector(this, p2d, m_gamedef);
  2280. m_sectors[p2d] = sector;
  2281. }
  2282. else
  2283. {
  2284. throw FileNotGoodException("Cannot open sector metafile");
  2285. }
  2286. }
  2287. else
  2288. {
  2289. sector = ServerMapSector::deSerialize
  2290. (is, this, p2d, m_sectors, m_gamedef);
  2291. if(save_after_load)
  2292. saveSectorMeta(sector);
  2293. }
  2294. sector->differs_from_disk = false;
  2295. return sector;
  2296. }
  2297. bool ServerMap::loadSectorMeta(v2s16 p2d)
  2298. {
  2299. DSTACK(FUNCTION_NAME);
  2300. // The directory layout we're going to load from.
  2301. // 1 - original sectors/xxxxzzzz/
  2302. // 2 - new sectors2/xxx/zzz/
  2303. // If we load from anything but the latest structure, we will
  2304. // immediately save to the new one, and remove the old.
  2305. int loadlayout = 1;
  2306. std::string sectordir1 = getSectorDir(p2d, 1);
  2307. std::string sectordir;
  2308. if(fs::PathExists(sectordir1))
  2309. {
  2310. sectordir = sectordir1;
  2311. }
  2312. else
  2313. {
  2314. loadlayout = 2;
  2315. sectordir = getSectorDir(p2d, 2);
  2316. }
  2317. try{
  2318. loadSectorMeta(sectordir, loadlayout != 2);
  2319. }
  2320. catch(InvalidFilenameException &e)
  2321. {
  2322. return false;
  2323. }
  2324. catch(FileNotGoodException &e)
  2325. {
  2326. return false;
  2327. }
  2328. catch(std::exception &e)
  2329. {
  2330. return false;
  2331. }
  2332. return true;
  2333. }
  2334. #if 0
  2335. bool ServerMap::loadSectorFull(v2s16 p2d)
  2336. {
  2337. DSTACK(FUNCTION_NAME);
  2338. MapSector *sector = NULL;
  2339. // The directory layout we're going to load from.
  2340. // 1 - original sectors/xxxxzzzz/
  2341. // 2 - new sectors2/xxx/zzz/
  2342. // If we load from anything but the latest structure, we will
  2343. // immediately save to the new one, and remove the old.
  2344. int loadlayout = 1;
  2345. std::string sectordir1 = getSectorDir(p2d, 1);
  2346. std::string sectordir;
  2347. if(fs::PathExists(sectordir1))
  2348. {
  2349. sectordir = sectordir1;
  2350. }
  2351. else
  2352. {
  2353. loadlayout = 2;
  2354. sectordir = getSectorDir(p2d, 2);
  2355. }
  2356. try{
  2357. sector = loadSectorMeta(sectordir, loadlayout != 2);
  2358. }
  2359. catch(InvalidFilenameException &e)
  2360. {
  2361. return false;
  2362. }
  2363. catch(FileNotGoodException &e)
  2364. {
  2365. return false;
  2366. }
  2367. catch(std::exception &e)
  2368. {
  2369. return false;
  2370. }
  2371. /*
  2372. Load blocks
  2373. */
  2374. std::vector<fs::DirListNode> list2 = fs::GetDirListing
  2375. (sectordir);
  2376. std::vector<fs::DirListNode>::iterator i2;
  2377. for(i2=list2.begin(); i2!=list2.end(); i2++)
  2378. {
  2379. // We want files
  2380. if(i2->dir)
  2381. continue;
  2382. try{
  2383. loadBlock(sectordir, i2->name, sector, loadlayout != 2);
  2384. }
  2385. catch(InvalidFilenameException &e)
  2386. {
  2387. // This catches unknown crap in directory
  2388. }
  2389. }
  2390. if(loadlayout != 2)
  2391. {
  2392. infostream<<"Sector converted to new layout - deleting "<<
  2393. sectordir1<<std::endl;
  2394. fs::RecursiveDelete(sectordir1);
  2395. }
  2396. return true;
  2397. }
  2398. #endif
  2399. Database *ServerMap::createDatabase(
  2400. const std::string &name,
  2401. const std::string &savedir,
  2402. Settings &conf)
  2403. {
  2404. if (name == "sqlite3")
  2405. return new Database_SQLite3(savedir);
  2406. if (name == "dummy")
  2407. return new Database_Dummy();
  2408. #if USE_LEVELDB
  2409. else if (name == "leveldb")
  2410. return new Database_LevelDB(savedir);
  2411. #endif
  2412. #if USE_REDIS
  2413. else if (name == "redis")
  2414. return new Database_Redis(conf);
  2415. #endif
  2416. #if USE_POSTGRESQL
  2417. else if (name == "postgresql")
  2418. return new Database_PostgreSQL(conf);
  2419. #endif
  2420. else
  2421. throw BaseException(std::string("Database backend ") + name + " not supported.");
  2422. }
  2423. void ServerMap::beginSave()
  2424. {
  2425. dbase->beginSave();
  2426. }
  2427. void ServerMap::endSave()
  2428. {
  2429. dbase->endSave();
  2430. }
  2431. bool ServerMap::saveBlock(MapBlock *block)
  2432. {
  2433. return saveBlock(block, dbase);
  2434. }
  2435. bool ServerMap::saveBlock(MapBlock *block, Database *db)
  2436. {
  2437. v3s16 p3d = block->getPos();
  2438. // Dummy blocks are not written
  2439. if (block->isDummy()) {
  2440. warningstream << "saveBlock: Not writing dummy block "
  2441. << PP(p3d) << std::endl;
  2442. return true;
  2443. }
  2444. // Format used for writing
  2445. u8 version = SER_FMT_VER_HIGHEST_WRITE;
  2446. /*
  2447. [0] u8 serialization version
  2448. [1] data
  2449. */
  2450. std::ostringstream o(std::ios_base::binary);
  2451. o.write((char*) &version, 1);
  2452. block->serialize(o, version, true);
  2453. std::string data = o.str();
  2454. bool ret = db->saveBlock(p3d, data);
  2455. if (ret) {
  2456. // We just wrote it to the disk so clear modified flag
  2457. block->resetModified();
  2458. }
  2459. return ret;
  2460. }
  2461. void ServerMap::loadBlock(std::string sectordir, std::string blockfile,
  2462. MapSector *sector, bool save_after_load)
  2463. {
  2464. DSTACK(FUNCTION_NAME);
  2465. std::string fullpath = sectordir + DIR_DELIM + blockfile;
  2466. try {
  2467. std::ifstream is(fullpath.c_str(), std::ios_base::binary);
  2468. if(is.good() == false)
  2469. throw FileNotGoodException("Cannot open block file");
  2470. v3s16 p3d = getBlockPos(sectordir, blockfile);
  2471. v2s16 p2d(p3d.X, p3d.Z);
  2472. assert(sector->getPos() == p2d);
  2473. u8 version = SER_FMT_VER_INVALID;
  2474. is.read((char*)&version, 1);
  2475. if(is.fail())
  2476. throw SerializationError("ServerMap::loadBlock(): Failed"
  2477. " to read MapBlock version");
  2478. /*u32 block_size = MapBlock::serializedLength(version);
  2479. SharedBuffer<u8> data(block_size);
  2480. is.read((char*)*data, block_size);*/
  2481. // This will always return a sector because we're the server
  2482. //MapSector *sector = emergeSector(p2d);
  2483. MapBlock *block = NULL;
  2484. bool created_new = false;
  2485. block = sector->getBlockNoCreateNoEx(p3d.Y);
  2486. if(block == NULL)
  2487. {
  2488. block = sector->createBlankBlockNoInsert(p3d.Y);
  2489. created_new = true;
  2490. }
  2491. // Read basic data
  2492. block->deSerialize(is, version, true);
  2493. // If it's a new block, insert it to the map
  2494. if (created_new) {
  2495. sector->insertBlock(block);
  2496. ReflowScan scanner(this, m_emerge->ndef);
  2497. scanner.scan(block, &m_transforming_liquid);
  2498. }
  2499. /*
  2500. Save blocks loaded in old format in new format
  2501. */
  2502. if(version < SER_FMT_VER_HIGHEST_WRITE || save_after_load)
  2503. {
  2504. saveBlock(block);
  2505. // Should be in database now, so delete the old file
  2506. fs::RecursiveDelete(fullpath);
  2507. }
  2508. // We just loaded it from the disk, so it's up-to-date.
  2509. block->resetModified();
  2510. }
  2511. catch(SerializationError &e)
  2512. {
  2513. warningstream<<"Invalid block data on disk "
  2514. <<"fullpath="<<fullpath
  2515. <<" (SerializationError). "
  2516. <<"what()="<<e.what()
  2517. <<std::endl;
  2518. // Ignoring. A new one will be generated.
  2519. abort();
  2520. // TODO: Backup file; name is in fullpath.
  2521. }
  2522. }
  2523. void ServerMap::loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool save_after_load)
  2524. {
  2525. DSTACK(FUNCTION_NAME);
  2526. try {
  2527. std::istringstream is(*blob, std::ios_base::binary);
  2528. u8 version = SER_FMT_VER_INVALID;
  2529. is.read((char*)&version, 1);
  2530. if(is.fail())
  2531. throw SerializationError("ServerMap::loadBlock(): Failed"
  2532. " to read MapBlock version");
  2533. /*u32 block_size = MapBlock::serializedLength(version);
  2534. SharedBuffer<u8> data(block_size);
  2535. is.read((char*)*data, block_size);*/
  2536. // This will always return a sector because we're the server
  2537. //MapSector *sector = emergeSector(p2d);
  2538. MapBlock *block = NULL;
  2539. bool created_new = false;
  2540. block = sector->getBlockNoCreateNoEx(p3d.Y);
  2541. if(block == NULL)
  2542. {
  2543. block = sector->createBlankBlockNoInsert(p3d.Y);
  2544. created_new = true;
  2545. }
  2546. // Read basic data
  2547. block->deSerialize(is, version, true);
  2548. // If it's a new block, insert it to the map
  2549. if (created_new) {
  2550. sector->insertBlock(block);
  2551. ReflowScan scanner(this, m_emerge->ndef);
  2552. scanner.scan(block, &m_transforming_liquid);
  2553. }
  2554. /*
  2555. Save blocks loaded in old format in new format
  2556. */
  2557. //if(version < SER_FMT_VER_HIGHEST_READ || save_after_load)
  2558. // Only save if asked to; no need to update version
  2559. if(save_after_load)
  2560. saveBlock(block);
  2561. // We just loaded it from, so it's up-to-date.
  2562. block->resetModified();
  2563. }
  2564. catch(SerializationError &e)
  2565. {
  2566. errorstream<<"Invalid block data in database"
  2567. <<" ("<<p3d.X<<","<<p3d.Y<<","<<p3d.Z<<")"
  2568. <<" (SerializationError): "<<e.what()<<std::endl;
  2569. // TODO: Block should be marked as invalid in memory so that it is
  2570. // not touched but the game can run
  2571. if(g_settings->getBool("ignore_world_load_errors")){
  2572. errorstream<<"Ignoring block load error. Duck and cover! "
  2573. <<"(ignore_world_load_errors)"<<std::endl;
  2574. } else {
  2575. throw SerializationError("Invalid block data in database");
  2576. }
  2577. }
  2578. }
  2579. MapBlock* ServerMap::loadBlock(v3s16 blockpos)
  2580. {
  2581. DSTACK(FUNCTION_NAME);
  2582. v2s16 p2d(blockpos.X, blockpos.Z);
  2583. std::string ret;
  2584. dbase->loadBlock(blockpos, &ret);
  2585. if (ret != "") {
  2586. loadBlock(&ret, blockpos, createSector(p2d), false);
  2587. return getBlockNoCreateNoEx(blockpos);
  2588. }
  2589. // Not found in database, try the files
  2590. // The directory layout we're going to load from.
  2591. // 1 - original sectors/xxxxzzzz/
  2592. // 2 - new sectors2/xxx/zzz/
  2593. // If we load from anything but the latest structure, we will
  2594. // immediately save to the new one, and remove the old.
  2595. int loadlayout = 1;
  2596. std::string sectordir1 = getSectorDir(p2d, 1);
  2597. std::string sectordir;
  2598. if(fs::PathExists(sectordir1))
  2599. {
  2600. sectordir = sectordir1;
  2601. }
  2602. else
  2603. {
  2604. loadlayout = 2;
  2605. sectordir = getSectorDir(p2d, 2);
  2606. }
  2607. /*
  2608. Make sure sector is loaded
  2609. */
  2610. MapSector *sector = getSectorNoGenerateNoEx(p2d);
  2611. if(sector == NULL)
  2612. {
  2613. try{
  2614. sector = loadSectorMeta(sectordir, loadlayout != 2);
  2615. }
  2616. catch(InvalidFilenameException &e)
  2617. {
  2618. return NULL;
  2619. }
  2620. catch(FileNotGoodException &e)
  2621. {
  2622. return NULL;
  2623. }
  2624. catch(std::exception &e)
  2625. {
  2626. return NULL;
  2627. }
  2628. }
  2629. /*
  2630. Make sure file exists
  2631. */
  2632. std::string blockfilename = getBlockFilename(blockpos);
  2633. if(fs::PathExists(sectordir + DIR_DELIM + blockfilename) == false)
  2634. return NULL;
  2635. /*
  2636. Load block and save it to the database
  2637. */
  2638. loadBlock(sectordir, blockfilename, sector, true);
  2639. return getBlockNoCreateNoEx(blockpos);
  2640. }
  2641. bool ServerMap::deleteBlock(v3s16 blockpos)
  2642. {
  2643. if (!dbase->deleteBlock(blockpos))
  2644. return false;
  2645. MapBlock *block = getBlockNoCreateNoEx(blockpos);
  2646. if (block) {
  2647. v2s16 p2d(blockpos.X, blockpos.Z);
  2648. MapSector *sector = getSectorNoGenerateNoEx(p2d);
  2649. if (!sector)
  2650. return false;
  2651. sector->deleteBlock(block);
  2652. }
  2653. return true;
  2654. }
  2655. void ServerMap::PrintInfo(std::ostream &out)
  2656. {
  2657. out<<"ServerMap: ";
  2658. }
  2659. MMVManip::MMVManip(Map *map):
  2660. VoxelManipulator(),
  2661. m_is_dirty(false),
  2662. m_create_area(false),
  2663. m_map(map)
  2664. {
  2665. }
  2666. MMVManip::~MMVManip()
  2667. {
  2668. }
  2669. void MMVManip::initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max,
  2670. bool load_if_inexistent)
  2671. {
  2672. TimeTaker timer1("initialEmerge", &emerge_time);
  2673. // Units of these are MapBlocks
  2674. v3s16 p_min = blockpos_min;
  2675. v3s16 p_max = blockpos_max;
  2676. VoxelArea block_area_nodes
  2677. (p_min*MAP_BLOCKSIZE, (p_max+1)*MAP_BLOCKSIZE-v3s16(1,1,1));
  2678. u32 size_MB = block_area_nodes.getVolume()*4/1000000;
  2679. if(size_MB >= 1)
  2680. {
  2681. infostream<<"initialEmerge: area: ";
  2682. block_area_nodes.print(infostream);
  2683. infostream<<" ("<<size_MB<<"MB)";
  2684. infostream<<std::endl;
  2685. }
  2686. addArea(block_area_nodes);
  2687. for(s32 z=p_min.Z; z<=p_max.Z; z++)
  2688. for(s32 y=p_min.Y; y<=p_max.Y; y++)
  2689. for(s32 x=p_min.X; x<=p_max.X; x++)
  2690. {
  2691. u8 flags = 0;
  2692. MapBlock *block;
  2693. v3s16 p(x,y,z);
  2694. std::map<v3s16, u8>::iterator n;
  2695. n = m_loaded_blocks.find(p);
  2696. if(n != m_loaded_blocks.end())
  2697. continue;
  2698. bool block_data_inexistent = false;
  2699. try
  2700. {
  2701. TimeTaker timer1("emerge load", &emerge_load_time);
  2702. block = m_map->getBlockNoCreate(p);
  2703. if(block->isDummy())
  2704. block_data_inexistent = true;
  2705. else
  2706. block->copyTo(*this);
  2707. }
  2708. catch(InvalidPositionException &e)
  2709. {
  2710. block_data_inexistent = true;
  2711. }
  2712. if(block_data_inexistent)
  2713. {
  2714. if (load_if_inexistent) {
  2715. ServerMap *svrmap = (ServerMap *)m_map;
  2716. block = svrmap->emergeBlock(p, false);
  2717. if (block == NULL)
  2718. block = svrmap->createBlock(p);
  2719. block->copyTo(*this);
  2720. } else {
  2721. flags |= VMANIP_BLOCK_DATA_INEXIST;
  2722. /*
  2723. Mark area inexistent
  2724. */
  2725. VoxelArea a(p*MAP_BLOCKSIZE, (p+1)*MAP_BLOCKSIZE-v3s16(1,1,1));
  2726. // Fill with VOXELFLAG_NO_DATA
  2727. for(s32 z=a.MinEdge.Z; z<=a.MaxEdge.Z; z++)
  2728. for(s32 y=a.MinEdge.Y; y<=a.MaxEdge.Y; y++)
  2729. {
  2730. s32 i = m_area.index(a.MinEdge.X,y,z);
  2731. memset(&m_flags[i], VOXELFLAG_NO_DATA, MAP_BLOCKSIZE);
  2732. }
  2733. }
  2734. }
  2735. /*else if (block->getNode(0, 0, 0).getContent() == CONTENT_IGNORE)
  2736. {
  2737. // Mark that block was loaded as blank
  2738. flags |= VMANIP_BLOCK_CONTAINS_CIGNORE;
  2739. }*/
  2740. m_loaded_blocks[p] = flags;
  2741. }
  2742. m_is_dirty = false;
  2743. }
  2744. void MMVManip::blitBackAll(std::map<v3s16, MapBlock*> *modified_blocks,
  2745. bool overwrite_generated)
  2746. {
  2747. if(m_area.getExtent() == v3s16(0,0,0))
  2748. return;
  2749. /*
  2750. Copy data of all blocks
  2751. */
  2752. for(std::map<v3s16, u8>::iterator
  2753. i = m_loaded_blocks.begin();
  2754. i != m_loaded_blocks.end(); ++i)
  2755. {
  2756. v3s16 p = i->first;
  2757. MapBlock *block = m_map->getBlockNoCreateNoEx(p);
  2758. bool existed = !(i->second & VMANIP_BLOCK_DATA_INEXIST);
  2759. if ((existed == false) || (block == NULL) ||
  2760. (overwrite_generated == false && block->isGenerated() == true))
  2761. continue;
  2762. block->copyFrom(*this);
  2763. if(modified_blocks)
  2764. (*modified_blocks)[p] = block;
  2765. }
  2766. }
  2767. //END