map.cpp 84 KB

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