server.cpp 129 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113
  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 "server.h"
  17. #include <iostream>
  18. #include <queue>
  19. #include <algorithm>
  20. #include "clientserver.h"
  21. #include "ban.h"
  22. #include "environment.h"
  23. #include "map.h"
  24. #include "jthread/jmutexautolock.h"
  25. #include "main.h"
  26. #include "constants.h"
  27. #include "voxel.h"
  28. #include "config.h"
  29. #include "version.h"
  30. #include "filesys.h"
  31. #include "mapblock.h"
  32. #include "serverobject.h"
  33. #include "genericobject.h"
  34. #include "settings.h"
  35. #include "profiler.h"
  36. #include "log.h"
  37. #include "scripting_game.h"
  38. #include "nodedef.h"
  39. #include "itemdef.h"
  40. #include "craftdef.h"
  41. #include "emerge.h"
  42. #include "mapgen.h"
  43. #include "biome.h"
  44. #include "content_mapnode.h"
  45. #include "content_nodemeta.h"
  46. #include "content_abm.h"
  47. #include "content_sao.h"
  48. #include "mods.h"
  49. #include "sha1.h"
  50. #include "base64.h"
  51. #include "tool.h"
  52. #include "sound.h" // dummySoundManager
  53. #include "event_manager.h"
  54. #include "hex.h"
  55. #include "serverlist.h"
  56. #include "util/string.h"
  57. #include "util/pointedthing.h"
  58. #include "util/mathconstants.h"
  59. #include "rollback.h"
  60. #include "util/serialize.h"
  61. #include "util/thread.h"
  62. #include "defaultsettings.h"
  63. class ClientNotFoundException : public BaseException
  64. {
  65. public:
  66. ClientNotFoundException(const char *s):
  67. BaseException(s)
  68. {}
  69. };
  70. class ServerThread : public JThread
  71. {
  72. Server *m_server;
  73. public:
  74. ServerThread(Server *server):
  75. JThread(),
  76. m_server(server)
  77. {
  78. }
  79. void * Thread();
  80. };
  81. void * ServerThread::Thread()
  82. {
  83. log_register_thread("ServerThread");
  84. DSTACK(__FUNCTION_NAME);
  85. BEGIN_DEBUG_EXCEPTION_HANDLER
  86. m_server->AsyncRunStep(true);
  87. ThreadStarted();
  88. porting::setThreadName("ServerThread");
  89. while(!StopRequested())
  90. {
  91. try{
  92. //TimeTaker timer("AsyncRunStep() + Receive()");
  93. m_server->AsyncRunStep();
  94. m_server->Receive();
  95. }
  96. catch(con::NoIncomingDataException &e)
  97. {
  98. }
  99. catch(con::PeerNotFoundException &e)
  100. {
  101. infostream<<"Server: PeerNotFoundException"<<std::endl;
  102. }
  103. catch(ClientNotFoundException &e)
  104. {
  105. }
  106. catch(con::ConnectionBindFailed &e)
  107. {
  108. m_server->setAsyncFatalError(e.what());
  109. }
  110. catch(LuaError &e)
  111. {
  112. m_server->setAsyncFatalError(e.what());
  113. }
  114. }
  115. END_DEBUG_EXCEPTION_HANDLER(errorstream)
  116. return NULL;
  117. }
  118. v3f ServerSoundParams::getPos(ServerEnvironment *env, bool *pos_exists) const
  119. {
  120. if(pos_exists) *pos_exists = false;
  121. switch(type){
  122. case SSP_LOCAL:
  123. return v3f(0,0,0);
  124. case SSP_POSITIONAL:
  125. if(pos_exists) *pos_exists = true;
  126. return pos;
  127. case SSP_OBJECT: {
  128. if(object == 0)
  129. return v3f(0,0,0);
  130. ServerActiveObject *sao = env->getActiveObject(object);
  131. if(!sao)
  132. return v3f(0,0,0);
  133. if(pos_exists) *pos_exists = true;
  134. return sao->getBasePosition(); }
  135. }
  136. return v3f(0,0,0);
  137. }
  138. /*
  139. Server
  140. */
  141. Server::Server(
  142. const std::string &path_world,
  143. const SubgameSpec &gamespec,
  144. bool simple_singleplayer_mode,
  145. bool ipv6
  146. ):
  147. m_path_world(path_world),
  148. m_gamespec(gamespec),
  149. m_simple_singleplayer_mode(simple_singleplayer_mode),
  150. m_async_fatal_error(""),
  151. m_env(NULL),
  152. m_con(PROTOCOL_ID,
  153. 512,
  154. CONNECTION_TIMEOUT,
  155. ipv6,
  156. this),
  157. m_banmanager(NULL),
  158. m_rollback(NULL),
  159. m_rollback_sink_enabled(true),
  160. m_enable_rollback_recording(false),
  161. m_emerge(NULL),
  162. m_script(NULL),
  163. m_itemdef(createItemDefManager()),
  164. m_nodedef(createNodeDefManager()),
  165. m_craftdef(createCraftDefManager()),
  166. m_event(new EventManager()),
  167. m_thread(NULL),
  168. m_time_of_day_send_timer(0),
  169. m_uptime(0),
  170. m_clients(&m_con),
  171. m_shutdown_requested(false),
  172. m_ignore_map_edit_events(false),
  173. m_ignore_map_edit_events_peer_id(0)
  174. {
  175. m_liquid_transform_timer = 0.0;
  176. m_liquid_transform_every = 1.0;
  177. m_print_info_timer = 0.0;
  178. m_masterserver_timer = 0.0;
  179. m_objectdata_timer = 0.0;
  180. m_emergethread_trigger_timer = 0.0;
  181. m_savemap_timer = 0.0;
  182. m_step_dtime = 0.0;
  183. m_lag = g_settings->getFloat("dedicated_server_step");
  184. if(path_world == "")
  185. throw ServerError("Supplied empty world path");
  186. if(!gamespec.isValid())
  187. throw ServerError("Supplied invalid gamespec");
  188. infostream<<"Server created for gameid \""<<m_gamespec.id<<"\"";
  189. if(m_simple_singleplayer_mode)
  190. infostream<<" in simple singleplayer mode"<<std::endl;
  191. else
  192. infostream<<std::endl;
  193. infostream<<"- world: "<<m_path_world<<std::endl;
  194. infostream<<"- game: "<<m_gamespec.path<<std::endl;
  195. // Initialize default settings and override defaults with those provided
  196. // by the game
  197. set_default_settings(g_settings);
  198. Settings gamedefaults;
  199. getGameMinetestConfig(gamespec.path, gamedefaults);
  200. override_default_settings(g_settings, &gamedefaults);
  201. // Create server thread
  202. m_thread = new ServerThread(this);
  203. // Create emerge manager
  204. m_emerge = new EmergeManager(this);
  205. // Create world if it doesn't exist
  206. if(!initializeWorld(m_path_world, m_gamespec.id))
  207. throw ServerError("Failed to initialize world");
  208. // Create ban manager
  209. std::string ban_path = m_path_world+DIR_DELIM+"ipban.txt";
  210. m_banmanager = new BanManager(ban_path);
  211. // Create rollback manager
  212. std::string rollback_path = m_path_world+DIR_DELIM+"rollback.txt";
  213. m_rollback = createRollbackManager(rollback_path, this);
  214. ModConfiguration modconf(m_path_world);
  215. m_mods = modconf.getMods();
  216. std::vector<ModSpec> unsatisfied_mods = modconf.getUnsatisfiedMods();
  217. // complain about mods with unsatisfied dependencies
  218. if(!modconf.isConsistent())
  219. {
  220. for(std::vector<ModSpec>::iterator it = unsatisfied_mods.begin();
  221. it != unsatisfied_mods.end(); ++it)
  222. {
  223. ModSpec mod = *it;
  224. errorstream << "mod \"" << mod.name << "\" has unsatisfied dependencies: ";
  225. for(std::set<std::string>::iterator dep_it = mod.unsatisfied_depends.begin();
  226. dep_it != mod.unsatisfied_depends.end(); ++dep_it)
  227. errorstream << " \"" << *dep_it << "\"";
  228. errorstream << std::endl;
  229. }
  230. }
  231. Settings worldmt_settings;
  232. std::string worldmt = m_path_world + DIR_DELIM + "world.mt";
  233. worldmt_settings.readConfigFile(worldmt.c_str());
  234. std::vector<std::string> names = worldmt_settings.getNames();
  235. std::set<std::string> load_mod_names;
  236. for(std::vector<std::string>::iterator it = names.begin();
  237. it != names.end(); ++it)
  238. {
  239. std::string name = *it;
  240. if(name.compare(0,9,"load_mod_")==0 && worldmt_settings.getBool(name))
  241. load_mod_names.insert(name.substr(9));
  242. }
  243. // complain about mods declared to be loaded, but not found
  244. for(std::vector<ModSpec>::iterator it = m_mods.begin();
  245. it != m_mods.end(); ++it)
  246. load_mod_names.erase((*it).name);
  247. for(std::vector<ModSpec>::iterator it = unsatisfied_mods.begin();
  248. it != unsatisfied_mods.end(); ++it)
  249. load_mod_names.erase((*it).name);
  250. if(!load_mod_names.empty())
  251. {
  252. errorstream << "The following mods could not be found:";
  253. for(std::set<std::string>::iterator it = load_mod_names.begin();
  254. it != load_mod_names.end(); ++it)
  255. errorstream << " \"" << (*it) << "\"";
  256. errorstream << std::endl;
  257. }
  258. // Lock environment
  259. JMutexAutoLock envlock(m_env_mutex);
  260. // Initialize scripting
  261. infostream<<"Server: Initializing Lua"<<std::endl;
  262. m_script = new GameScripting(this);
  263. std::string scriptpath = getBuiltinLuaPath() + DIR_DELIM "init.lua";
  264. if (!m_script->loadScript(scriptpath)) {
  265. throw ModError("Failed to load and run " + scriptpath);
  266. }
  267. // Print 'em
  268. infostream<<"Server: Loading mods: ";
  269. for(std::vector<ModSpec>::iterator i = m_mods.begin();
  270. i != m_mods.end(); i++){
  271. const ModSpec &mod = *i;
  272. infostream<<mod.name<<" ";
  273. }
  274. infostream<<std::endl;
  275. // Load and run "mod" scripts
  276. for(std::vector<ModSpec>::iterator i = m_mods.begin();
  277. i != m_mods.end(); i++){
  278. const ModSpec &mod = *i;
  279. std::string scriptpath = mod.path + DIR_DELIM + "init.lua";
  280. infostream<<" ["<<padStringRight(mod.name, 12)<<"] [\""
  281. <<scriptpath<<"\"]"<<std::endl;
  282. bool success = m_script->loadMod(scriptpath, mod.name);
  283. if(!success){
  284. errorstream<<"Server: Failed to load and run "
  285. <<scriptpath<<std::endl;
  286. throw ModError("Failed to load and run "+scriptpath);
  287. }
  288. }
  289. // Read Textures and calculate sha1 sums
  290. fillMediaCache();
  291. // Apply item aliases in the node definition manager
  292. m_nodedef->updateAliases(m_itemdef);
  293. // Load the mapgen params from global settings now after any
  294. // initial overrides have been set by the mods
  295. m_emerge->loadMapgenParams();
  296. // Initialize Environment
  297. ServerMap *servermap = new ServerMap(path_world, this, m_emerge);
  298. m_env = new ServerEnvironment(servermap, m_script, this, m_path_world);
  299. m_clients.setEnv(m_env);
  300. // Run some callbacks after the MG params have been set up but before activation
  301. m_script->environment_OnMapgenInit(&m_emerge->params);
  302. // Initialize mapgens
  303. m_emerge->initMapgens();
  304. // Give environment reference to scripting api
  305. m_script->initializeEnvironment(m_env);
  306. // Register us to receive map edit events
  307. servermap->addEventReceiver(this);
  308. // If file exists, load environment metadata
  309. if(fs::PathExists(m_path_world + DIR_DELIM "env_meta.txt"))
  310. {
  311. infostream<<"Server: Loading environment metadata"<<std::endl;
  312. m_env->loadMeta();
  313. }
  314. // Add some test ActiveBlockModifiers to environment
  315. add_legacy_abms(m_env, m_nodedef);
  316. m_liquid_transform_every = g_settings->getFloat("liquid_update");
  317. }
  318. Server::~Server()
  319. {
  320. infostream<<"Server destructing"<<std::endl;
  321. // Send shutdown message
  322. SendChatMessage(PEER_ID_INEXISTENT, L"*** Server shutting down");
  323. {
  324. JMutexAutoLock envlock(m_env_mutex);
  325. // Execute script shutdown hooks
  326. m_script->on_shutdown();
  327. infostream<<"Server: Saving players"<<std::endl;
  328. m_env->saveLoadedPlayers();
  329. infostream<<"Server: Saving environment metadata"<<std::endl;
  330. m_env->saveMeta();
  331. }
  332. // Stop threads
  333. stop();
  334. delete m_thread;
  335. // stop all emerge threads before deleting players that may have
  336. // requested blocks to be emerged
  337. m_emerge->stopThreads();
  338. // Delete things in the reverse order of creation
  339. delete m_env;
  340. // N.B. the EmergeManager should be deleted after the Environment since Map
  341. // depends on EmergeManager to write its current params to the map meta
  342. delete m_emerge;
  343. delete m_rollback;
  344. delete m_banmanager;
  345. delete m_event;
  346. delete m_itemdef;
  347. delete m_nodedef;
  348. delete m_craftdef;
  349. // Deinitialize scripting
  350. infostream<<"Server: Deinitializing scripting"<<std::endl;
  351. delete m_script;
  352. // Delete detached inventories
  353. for (std::map<std::string, Inventory*>::iterator
  354. i = m_detached_inventories.begin();
  355. i != m_detached_inventories.end(); i++) {
  356. delete i->second;
  357. }
  358. }
  359. void Server::start(Address bind_addr)
  360. {
  361. DSTACK(__FUNCTION_NAME);
  362. infostream<<"Starting server on "
  363. << bind_addr.serializeString() <<"..."<<std::endl;
  364. // Stop thread if already running
  365. m_thread->Stop();
  366. // Initialize connection
  367. m_con.SetTimeoutMs(30);
  368. m_con.Serve(bind_addr);
  369. // Start thread
  370. m_thread->Start();
  371. // ASCII art for the win!
  372. actionstream
  373. <<" .__ __ __ "<<std::endl
  374. <<" _____ |__| ____ _____/ |_ ____ _______/ |_ "<<std::endl
  375. <<" / \\| |/ \\_/ __ \\ __\\/ __ \\ / ___/\\ __\\"<<std::endl
  376. <<"| Y Y \\ | | \\ ___/| | \\ ___/ \\___ \\ | | "<<std::endl
  377. <<"|__|_| /__|___| /\\___ >__| \\___ >____ > |__| "<<std::endl
  378. <<" \\/ \\/ \\/ \\/ \\/ "<<std::endl;
  379. actionstream<<"World at ["<<m_path_world<<"]"<<std::endl;
  380. actionstream<<"Server for gameid=\""<<m_gamespec.id
  381. <<"\" listening on "<<bind_addr.serializeString()<<":"
  382. <<bind_addr.getPort() << "."<<std::endl;
  383. }
  384. void Server::stop()
  385. {
  386. DSTACK(__FUNCTION_NAME);
  387. infostream<<"Server: Stopping and waiting threads"<<std::endl;
  388. // Stop threads (set run=false first so both start stopping)
  389. m_thread->Stop();
  390. //m_emergethread.setRun(false);
  391. m_thread->Wait();
  392. //m_emergethread.stop();
  393. infostream<<"Server: Threads stopped"<<std::endl;
  394. }
  395. void Server::step(float dtime)
  396. {
  397. DSTACK(__FUNCTION_NAME);
  398. // Limit a bit
  399. if(dtime > 2.0)
  400. dtime = 2.0;
  401. {
  402. JMutexAutoLock lock(m_step_dtime_mutex);
  403. m_step_dtime += dtime;
  404. }
  405. // Throw if fatal error occurred in thread
  406. std::string async_err = m_async_fatal_error.get();
  407. if(async_err != ""){
  408. throw ServerError(async_err);
  409. }
  410. }
  411. void Server::AsyncRunStep(bool initial_step)
  412. {
  413. DSTACK(__FUNCTION_NAME);
  414. g_profiler->add("Server::AsyncRunStep (num)", 1);
  415. float dtime;
  416. {
  417. JMutexAutoLock lock1(m_step_dtime_mutex);
  418. dtime = m_step_dtime;
  419. }
  420. {
  421. // Send blocks to clients
  422. SendBlocks(dtime);
  423. }
  424. if((dtime < 0.001) && (initial_step == false))
  425. return;
  426. g_profiler->add("Server::AsyncRunStep with dtime (num)", 1);
  427. //infostream<<"Server steps "<<dtime<<std::endl;
  428. //infostream<<"Server::AsyncRunStep(): dtime="<<dtime<<std::endl;
  429. {
  430. JMutexAutoLock lock1(m_step_dtime_mutex);
  431. m_step_dtime -= dtime;
  432. }
  433. /*
  434. Update uptime
  435. */
  436. {
  437. m_uptime.set(m_uptime.get() + dtime);
  438. }
  439. handlePeerChanges();
  440. /*
  441. Update time of day and overall game time
  442. */
  443. {
  444. JMutexAutoLock envlock(m_env_mutex);
  445. m_env->setTimeOfDaySpeed(g_settings->getFloat("time_speed"));
  446. /*
  447. Send to clients at constant intervals
  448. */
  449. m_time_of_day_send_timer -= dtime;
  450. if(m_time_of_day_send_timer < 0.0)
  451. {
  452. m_time_of_day_send_timer = g_settings->getFloat("time_send_interval");
  453. u16 time = m_env->getTimeOfDay();
  454. float time_speed = g_settings->getFloat("time_speed");
  455. SendTimeOfDay(PEER_ID_INEXISTENT, time, time_speed);
  456. }
  457. }
  458. {
  459. JMutexAutoLock lock(m_env_mutex);
  460. // Figure out and report maximum lag to environment
  461. float max_lag = m_env->getMaxLagEstimate();
  462. max_lag *= 0.9998; // Decrease slowly (about half per 5 minutes)
  463. if(dtime > max_lag){
  464. if(dtime > 0.1 && dtime > max_lag * 2.0)
  465. infostream<<"Server: Maximum lag peaked to "<<dtime
  466. <<" s"<<std::endl;
  467. max_lag = dtime;
  468. }
  469. m_env->reportMaxLagEstimate(max_lag);
  470. // Step environment
  471. ScopeProfiler sp(g_profiler, "SEnv step");
  472. ScopeProfiler sp2(g_profiler, "SEnv step avg", SPT_AVG);
  473. m_env->step(dtime);
  474. }
  475. const float map_timer_and_unload_dtime = 2.92;
  476. if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime))
  477. {
  478. JMutexAutoLock lock(m_env_mutex);
  479. // Run Map's timers and unload unused data
  480. ScopeProfiler sp(g_profiler, "Server: map timer and unload");
  481. m_env->getMap().timerUpdate(map_timer_and_unload_dtime,
  482. g_settings->getFloat("server_unload_unused_data_timeout"));
  483. }
  484. /*
  485. Do background stuff
  486. */
  487. /*
  488. Handle players
  489. */
  490. {
  491. JMutexAutoLock lock(m_env_mutex);
  492. std::list<u16> clientids = m_clients.getClientIDs();
  493. ScopeProfiler sp(g_profiler, "Server: handle players");
  494. for(std::list<u16>::iterator
  495. i = clientids.begin();
  496. i != clientids.end(); ++i)
  497. {
  498. PlayerSAO *playersao = getPlayerSAO(*i);
  499. if(playersao == NULL)
  500. continue;
  501. /*
  502. Handle player HPs (die if hp=0)
  503. */
  504. if(playersao->m_hp_not_sent && g_settings->getBool("enable_damage"))
  505. {
  506. if(playersao->getHP() == 0)
  507. DiePlayer(*i);
  508. else
  509. SendPlayerHP(*i);
  510. }
  511. /*
  512. Send player breath if changed
  513. */
  514. if(playersao->m_breath_not_sent) {
  515. SendPlayerBreath(*i);
  516. }
  517. /*
  518. Send player inventories if necessary
  519. */
  520. if(playersao->m_moved){
  521. SendMovePlayer(*i);
  522. playersao->m_moved = false;
  523. }
  524. if(playersao->m_inventory_not_sent){
  525. UpdateCrafting(*i);
  526. SendInventory(*i);
  527. }
  528. }
  529. }
  530. /* Transform liquids */
  531. m_liquid_transform_timer += dtime;
  532. if(m_liquid_transform_timer >= m_liquid_transform_every)
  533. {
  534. m_liquid_transform_timer -= m_liquid_transform_every;
  535. JMutexAutoLock lock(m_env_mutex);
  536. ScopeProfiler sp(g_profiler, "Server: liquid transform");
  537. std::map<v3s16, MapBlock*> modified_blocks;
  538. m_env->getMap().transformLiquids(modified_blocks);
  539. #if 0
  540. /*
  541. Update lighting
  542. */
  543. core::map<v3s16, MapBlock*> lighting_modified_blocks;
  544. ServerMap &map = ((ServerMap&)m_env->getMap());
  545. map.updateLighting(modified_blocks, lighting_modified_blocks);
  546. // Add blocks modified by lighting to modified_blocks
  547. for(core::map<v3s16, MapBlock*>::Iterator
  548. i = lighting_modified_blocks.getIterator();
  549. i.atEnd() == false; i++)
  550. {
  551. MapBlock *block = i.getNode()->getValue();
  552. modified_blocks.insert(block->getPos(), block);
  553. }
  554. #endif
  555. /*
  556. Set the modified blocks unsent for all the clients
  557. */
  558. if(modified_blocks.size() > 0)
  559. {
  560. SetBlocksNotSent(modified_blocks);
  561. }
  562. }
  563. m_clients.step(dtime);
  564. m_lag += (m_lag > dtime ? -1 : 1) * dtime/100;
  565. #if USE_CURL
  566. // send masterserver announce
  567. {
  568. float &counter = m_masterserver_timer;
  569. if(!isSingleplayer() && (!counter || counter >= 300.0) &&
  570. g_settings->getBool("server_announce"))
  571. {
  572. ServerList::sendAnnounce(counter ? "update" : "start",
  573. m_clients.getPlayerNames(),
  574. m_uptime.get(),
  575. m_env->getGameTime(),
  576. m_lag,
  577. m_gamespec.id,
  578. m_mods);
  579. counter = 0.01;
  580. }
  581. counter += dtime;
  582. }
  583. #endif
  584. /*
  585. Check added and deleted active objects
  586. */
  587. {
  588. //infostream<<"Server: Checking added and deleted active objects"<<std::endl;
  589. JMutexAutoLock envlock(m_env_mutex);
  590. m_clients.Lock();
  591. std::map<u16, RemoteClient*> clients = m_clients.getClientList();
  592. ScopeProfiler sp(g_profiler, "Server: checking added and deleted objs");
  593. // Radius inside which objects are active
  594. s16 radius = g_settings->getS16("active_object_send_range_blocks");
  595. radius *= MAP_BLOCKSIZE;
  596. for(std::map<u16, RemoteClient*>::iterator
  597. i = clients.begin();
  598. i != clients.end(); ++i)
  599. {
  600. RemoteClient *client = i->second;
  601. // If definitions and textures have not been sent, don't
  602. // send objects either
  603. if (client->getState() < CS_DefinitionsSent)
  604. continue;
  605. Player *player = m_env->getPlayer(client->peer_id);
  606. if(player==NULL)
  607. {
  608. // This can happen if the client timeouts somehow
  609. /*infostream<<"WARNING: "<<__FUNCTION_NAME<<": Client "
  610. <<client->peer_id
  611. <<" has no associated player"<<std::endl;*/
  612. continue;
  613. }
  614. v3s16 pos = floatToInt(player->getPosition(), BS);
  615. std::set<u16> removed_objects;
  616. std::set<u16> added_objects;
  617. m_env->getRemovedActiveObjects(pos, radius,
  618. client->m_known_objects, removed_objects);
  619. m_env->getAddedActiveObjects(pos, radius,
  620. client->m_known_objects, added_objects);
  621. // Ignore if nothing happened
  622. if(removed_objects.size() == 0 && added_objects.size() == 0)
  623. {
  624. //infostream<<"active objects: none changed"<<std::endl;
  625. continue;
  626. }
  627. std::string data_buffer;
  628. char buf[4];
  629. // Handle removed objects
  630. writeU16((u8*)buf, removed_objects.size());
  631. data_buffer.append(buf, 2);
  632. for(std::set<u16>::iterator
  633. i = removed_objects.begin();
  634. i != removed_objects.end(); ++i)
  635. {
  636. // Get object
  637. u16 id = *i;
  638. ServerActiveObject* obj = m_env->getActiveObject(id);
  639. // Add to data buffer for sending
  640. writeU16((u8*)buf, id);
  641. data_buffer.append(buf, 2);
  642. // Remove from known objects
  643. client->m_known_objects.erase(id);
  644. if(obj && obj->m_known_by_count > 0)
  645. obj->m_known_by_count--;
  646. }
  647. // Handle added objects
  648. writeU16((u8*)buf, added_objects.size());
  649. data_buffer.append(buf, 2);
  650. for(std::set<u16>::iterator
  651. i = added_objects.begin();
  652. i != added_objects.end(); ++i)
  653. {
  654. // Get object
  655. u16 id = *i;
  656. ServerActiveObject* obj = m_env->getActiveObject(id);
  657. // Get object type
  658. u8 type = ACTIVEOBJECT_TYPE_INVALID;
  659. if(obj == NULL)
  660. infostream<<"WARNING: "<<__FUNCTION_NAME
  661. <<": NULL object"<<std::endl;
  662. else
  663. type = obj->getSendType();
  664. // Add to data buffer for sending
  665. writeU16((u8*)buf, id);
  666. data_buffer.append(buf, 2);
  667. writeU8((u8*)buf, type);
  668. data_buffer.append(buf, 1);
  669. if(obj)
  670. data_buffer.append(serializeLongString(
  671. obj->getClientInitializationData(client->net_proto_version)));
  672. else
  673. data_buffer.append(serializeLongString(""));
  674. // Add to known objects
  675. client->m_known_objects.insert(id);
  676. if(obj)
  677. obj->m_known_by_count++;
  678. }
  679. // Send packet
  680. SharedBuffer<u8> reply(2 + data_buffer.size());
  681. writeU16(&reply[0], TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD);
  682. memcpy((char*)&reply[2], data_buffer.c_str(),
  683. data_buffer.size());
  684. // Send as reliable
  685. m_clients.send(client->peer_id, 0, reply, true);
  686. verbosestream<<"Server: Sent object remove/add: "
  687. <<removed_objects.size()<<" removed, "
  688. <<added_objects.size()<<" added, "
  689. <<"packet size is "<<reply.getSize()<<std::endl;
  690. }
  691. m_clients.Unlock();
  692. #if 0
  693. /*
  694. Collect a list of all the objects known by the clients
  695. and report it back to the environment.
  696. */
  697. core::map<u16, bool> all_known_objects;
  698. for(core::map<u16, RemoteClient*>::Iterator
  699. i = m_clients.getIterator();
  700. i.atEnd() == false; i++)
  701. {
  702. RemoteClient *client = i.getNode()->getValue();
  703. // Go through all known objects of client
  704. for(core::map<u16, bool>::Iterator
  705. i = client->m_known_objects.getIterator();
  706. i.atEnd()==false; i++)
  707. {
  708. u16 id = i.getNode()->getKey();
  709. all_known_objects[id] = true;
  710. }
  711. }
  712. m_env->setKnownActiveObjects(whatever);
  713. #endif
  714. }
  715. /*
  716. Send object messages
  717. */
  718. {
  719. JMutexAutoLock envlock(m_env_mutex);
  720. ScopeProfiler sp(g_profiler, "Server: sending object messages");
  721. // Key = object id
  722. // Value = data sent by object
  723. std::map<u16, std::list<ActiveObjectMessage>* > buffered_messages;
  724. // Get active object messages from environment
  725. for(;;)
  726. {
  727. ActiveObjectMessage aom = m_env->getActiveObjectMessage();
  728. if(aom.id == 0)
  729. break;
  730. std::list<ActiveObjectMessage>* message_list = NULL;
  731. std::map<u16, std::list<ActiveObjectMessage>* >::iterator n;
  732. n = buffered_messages.find(aom.id);
  733. if(n == buffered_messages.end())
  734. {
  735. message_list = new std::list<ActiveObjectMessage>;
  736. buffered_messages[aom.id] = message_list;
  737. }
  738. else
  739. {
  740. message_list = n->second;
  741. }
  742. message_list->push_back(aom);
  743. }
  744. m_clients.Lock();
  745. std::map<u16, RemoteClient*> clients = m_clients.getClientList();
  746. // Route data to every client
  747. for(std::map<u16, RemoteClient*>::iterator
  748. i = clients.begin();
  749. i != clients.end(); ++i)
  750. {
  751. RemoteClient *client = i->second;
  752. std::string reliable_data;
  753. std::string unreliable_data;
  754. // Go through all objects in message buffer
  755. for(std::map<u16, std::list<ActiveObjectMessage>* >::iterator
  756. j = buffered_messages.begin();
  757. j != buffered_messages.end(); ++j)
  758. {
  759. // If object is not known by client, skip it
  760. u16 id = j->first;
  761. if(client->m_known_objects.find(id) == client->m_known_objects.end())
  762. continue;
  763. // Get message list of object
  764. std::list<ActiveObjectMessage>* list = j->second;
  765. // Go through every message
  766. for(std::list<ActiveObjectMessage>::iterator
  767. k = list->begin(); k != list->end(); ++k)
  768. {
  769. // Compose the full new data with header
  770. ActiveObjectMessage aom = *k;
  771. std::string new_data;
  772. // Add object id
  773. char buf[2];
  774. writeU16((u8*)&buf[0], aom.id);
  775. new_data.append(buf, 2);
  776. // Add data
  777. new_data += serializeString(aom.datastring);
  778. // Add data to buffer
  779. if(aom.reliable)
  780. reliable_data += new_data;
  781. else
  782. unreliable_data += new_data;
  783. }
  784. }
  785. /*
  786. reliable_data and unreliable_data are now ready.
  787. Send them.
  788. */
  789. if(reliable_data.size() > 0)
  790. {
  791. SharedBuffer<u8> reply(2 + reliable_data.size());
  792. writeU16(&reply[0], TOCLIENT_ACTIVE_OBJECT_MESSAGES);
  793. memcpy((char*)&reply[2], reliable_data.c_str(),
  794. reliable_data.size());
  795. // Send as reliable
  796. m_clients.send(client->peer_id, 0, reply, true);
  797. }
  798. if(unreliable_data.size() > 0)
  799. {
  800. SharedBuffer<u8> reply(2 + unreliable_data.size());
  801. writeU16(&reply[0], TOCLIENT_ACTIVE_OBJECT_MESSAGES);
  802. memcpy((char*)&reply[2], unreliable_data.c_str(),
  803. unreliable_data.size());
  804. // Send as unreliable
  805. m_clients.send(client->peer_id, 1, reply, false);
  806. }
  807. /*if(reliable_data.size() > 0 || unreliable_data.size() > 0)
  808. {
  809. infostream<<"Server: Size of object message data: "
  810. <<"reliable: "<<reliable_data.size()
  811. <<", unreliable: "<<unreliable_data.size()
  812. <<std::endl;
  813. }*/
  814. }
  815. m_clients.Unlock();
  816. // Clear buffered_messages
  817. for(std::map<u16, std::list<ActiveObjectMessage>* >::iterator
  818. i = buffered_messages.begin();
  819. i != buffered_messages.end(); ++i)
  820. {
  821. delete i->second;
  822. }
  823. }
  824. /*
  825. Send queued-for-sending map edit events.
  826. */
  827. {
  828. // We will be accessing the environment
  829. JMutexAutoLock lock(m_env_mutex);
  830. // Don't send too many at a time
  831. //u32 count = 0;
  832. // Single change sending is disabled if queue size is not small
  833. bool disable_single_change_sending = false;
  834. if(m_unsent_map_edit_queue.size() >= 4)
  835. disable_single_change_sending = true;
  836. int event_count = m_unsent_map_edit_queue.size();
  837. // We'll log the amount of each
  838. Profiler prof;
  839. while(m_unsent_map_edit_queue.size() != 0)
  840. {
  841. MapEditEvent* event = m_unsent_map_edit_queue.pop_front();
  842. // Players far away from the change are stored here.
  843. // Instead of sending the changes, MapBlocks are set not sent
  844. // for them.
  845. std::list<u16> far_players;
  846. if(event->type == MEET_ADDNODE || event->type == MEET_SWAPNODE)
  847. {
  848. //infostream<<"Server: MEET_ADDNODE"<<std::endl;
  849. prof.add("MEET_ADDNODE", 1);
  850. if(disable_single_change_sending)
  851. sendAddNode(event->p, event->n, event->already_known_by_peer,
  852. &far_players, 5, event->type == MEET_ADDNODE);
  853. else
  854. sendAddNode(event->p, event->n, event->already_known_by_peer,
  855. &far_players, 30, event->type == MEET_ADDNODE);
  856. }
  857. else if(event->type == MEET_REMOVENODE)
  858. {
  859. //infostream<<"Server: MEET_REMOVENODE"<<std::endl;
  860. prof.add("MEET_REMOVENODE", 1);
  861. if(disable_single_change_sending)
  862. sendRemoveNode(event->p, event->already_known_by_peer,
  863. &far_players, 5);
  864. else
  865. sendRemoveNode(event->p, event->already_known_by_peer,
  866. &far_players, 30);
  867. }
  868. else if(event->type == MEET_BLOCK_NODE_METADATA_CHANGED)
  869. {
  870. infostream<<"Server: MEET_BLOCK_NODE_METADATA_CHANGED"<<std::endl;
  871. prof.add("MEET_BLOCK_NODE_METADATA_CHANGED", 1);
  872. setBlockNotSent(event->p);
  873. }
  874. else if(event->type == MEET_OTHER)
  875. {
  876. infostream<<"Server: MEET_OTHER"<<std::endl;
  877. prof.add("MEET_OTHER", 1);
  878. for(std::set<v3s16>::iterator
  879. i = event->modified_blocks.begin();
  880. i != event->modified_blocks.end(); ++i)
  881. {
  882. setBlockNotSent(*i);
  883. }
  884. }
  885. else
  886. {
  887. prof.add("unknown", 1);
  888. infostream<<"WARNING: Server: Unknown MapEditEvent "
  889. <<((u32)event->type)<<std::endl;
  890. }
  891. /*
  892. Set blocks not sent to far players
  893. */
  894. if(far_players.size() > 0)
  895. {
  896. // Convert list format to that wanted by SetBlocksNotSent
  897. std::map<v3s16, MapBlock*> modified_blocks2;
  898. for(std::set<v3s16>::iterator
  899. i = event->modified_blocks.begin();
  900. i != event->modified_blocks.end(); ++i)
  901. {
  902. modified_blocks2[*i] =
  903. m_env->getMap().getBlockNoCreateNoEx(*i);
  904. }
  905. // Set blocks not sent
  906. for(std::list<u16>::iterator
  907. i = far_players.begin();
  908. i != far_players.end(); ++i)
  909. {
  910. u16 peer_id = *i;
  911. RemoteClient *client = getClient(peer_id);
  912. if(client==NULL)
  913. continue;
  914. client->SetBlocksNotSent(modified_blocks2);
  915. }
  916. }
  917. delete event;
  918. /*// Don't send too many at a time
  919. count++;
  920. if(count >= 1 && m_unsent_map_edit_queue.size() < 100)
  921. break;*/
  922. }
  923. if(event_count >= 5){
  924. infostream<<"Server: MapEditEvents:"<<std::endl;
  925. prof.print(infostream);
  926. } else if(event_count != 0){
  927. verbosestream<<"Server: MapEditEvents:"<<std::endl;
  928. prof.print(verbosestream);
  929. }
  930. }
  931. /*
  932. Trigger emergethread (it somehow gets to a non-triggered but
  933. bysy state sometimes)
  934. */
  935. {
  936. float &counter = m_emergethread_trigger_timer;
  937. counter += dtime;
  938. if(counter >= 2.0)
  939. {
  940. counter = 0.0;
  941. m_emerge->startThreads();
  942. // Update m_enable_rollback_recording here too
  943. m_enable_rollback_recording =
  944. g_settings->getBool("enable_rollback_recording");
  945. }
  946. }
  947. // Save map, players and auth stuff
  948. {
  949. float &counter = m_savemap_timer;
  950. counter += dtime;
  951. if(counter >= g_settings->getFloat("server_map_save_interval"))
  952. {
  953. counter = 0.0;
  954. JMutexAutoLock lock(m_env_mutex);
  955. ScopeProfiler sp(g_profiler, "Server: saving stuff");
  956. // Save ban file
  957. if (m_banmanager->isModified()) {
  958. m_banmanager->save();
  959. }
  960. // Save changed parts of map
  961. m_env->getMap().save(MOD_STATE_WRITE_NEEDED);
  962. // Save players
  963. m_env->saveLoadedPlayers();
  964. // Save environment metadata
  965. m_env->saveMeta();
  966. }
  967. }
  968. }
  969. void Server::Receive()
  970. {
  971. DSTACK(__FUNCTION_NAME);
  972. SharedBuffer<u8> data;
  973. u16 peer_id;
  974. u32 datasize;
  975. try{
  976. datasize = m_con.Receive(peer_id,data);
  977. ProcessData(*data, datasize, peer_id);
  978. }
  979. catch(con::InvalidIncomingDataException &e)
  980. {
  981. infostream<<"Server::Receive(): "
  982. "InvalidIncomingDataException: what()="
  983. <<e.what()<<std::endl;
  984. }
  985. catch(SerializationError &e) {
  986. infostream<<"Server::Receive(): "
  987. "SerializationError: what()="
  988. <<e.what()<<std::endl;
  989. }
  990. catch(ClientStateError &e)
  991. {
  992. errorstream << "ProcessData: peer=" << peer_id << e.what() << std::endl;
  993. DenyAccess(peer_id, L"Your client sent something server didn't expect."
  994. L"Try reconnecting or updating your client");
  995. }
  996. catch(con::PeerNotFoundException &e)
  997. {
  998. // Do nothing
  999. }
  1000. }
  1001. PlayerSAO* Server::StageTwoClientInit(u16 peer_id)
  1002. {
  1003. std::string playername = "";
  1004. PlayerSAO *playersao = NULL;
  1005. m_clients.Lock();
  1006. RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_InitDone);
  1007. if (client != NULL) {
  1008. playername = client->getName();
  1009. playersao = emergePlayer(playername.c_str(), peer_id);
  1010. }
  1011. m_clients.Unlock();
  1012. RemotePlayer *player =
  1013. static_cast<RemotePlayer*>(m_env->getPlayer(playername.c_str()));
  1014. // If failed, cancel
  1015. if((playersao == NULL) || (player == NULL))
  1016. {
  1017. if(player && player->peer_id != 0){
  1018. errorstream<<"Server: "<<playername<<": Failed to emerge player"
  1019. <<" (player allocated to an another client)"<<std::endl;
  1020. DenyAccess(peer_id, L"Another client is connected with this "
  1021. L"name. If your client closed unexpectedly, try again in "
  1022. L"a minute.");
  1023. } else {
  1024. errorstream<<"Server: "<<playername<<": Failed to emerge player"
  1025. <<std::endl;
  1026. DenyAccess(peer_id, L"Could not allocate player.");
  1027. }
  1028. return NULL;
  1029. }
  1030. /*
  1031. Send complete position information
  1032. */
  1033. SendMovePlayer(peer_id);
  1034. // Send privileges
  1035. SendPlayerPrivileges(peer_id);
  1036. // Send inventory formspec
  1037. SendPlayerInventoryFormspec(peer_id);
  1038. // Send inventory
  1039. UpdateCrafting(peer_id);
  1040. SendInventory(peer_id);
  1041. // Send HP
  1042. if(g_settings->getBool("enable_damage"))
  1043. SendPlayerHP(peer_id);
  1044. // Send Breath
  1045. SendPlayerBreath(peer_id);
  1046. // Show death screen if necessary
  1047. if(player->hp == 0)
  1048. SendDeathscreen(peer_id, false, v3f(0,0,0));
  1049. // Note things in chat if not in simple singleplayer mode
  1050. if(!m_simple_singleplayer_mode)
  1051. {
  1052. // Send information about server to player in chat
  1053. SendChatMessage(peer_id, getStatusString());
  1054. // Send information about joining in chat
  1055. {
  1056. std::wstring name = L"unknown";
  1057. Player *player = m_env->getPlayer(peer_id);
  1058. if(player != NULL)
  1059. name = narrow_to_wide(player->getName());
  1060. std::wstring message;
  1061. message += L"*** ";
  1062. message += name;
  1063. message += L" joined the game.";
  1064. SendChatMessage(PEER_ID_INEXISTENT,message);
  1065. }
  1066. }
  1067. Address addr = getPeerAddress(player->peer_id);
  1068. std::string ip_str = addr.serializeString();
  1069. actionstream<<player->getName() <<" [" << ip_str << "] joins game. " << std::endl;
  1070. /*
  1071. Print out action
  1072. */
  1073. {
  1074. std::vector<std::string> names = m_clients.getPlayerNames();
  1075. actionstream<<player->getName() <<" joins game. List of players: ";
  1076. for (std::vector<std::string>::iterator i = names.begin();
  1077. i != names.end(); i++)
  1078. {
  1079. actionstream << *i << " ";
  1080. }
  1081. actionstream << player->getName() <<std::endl;
  1082. }
  1083. return playersao;
  1084. }
  1085. void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
  1086. {
  1087. DSTACK(__FUNCTION_NAME);
  1088. // Environment is locked first.
  1089. JMutexAutoLock envlock(m_env_mutex);
  1090. ScopeProfiler sp(g_profiler, "Server::ProcessData");
  1091. std::string addr_s;
  1092. try{
  1093. Address address = getPeerAddress(peer_id);
  1094. addr_s = address.serializeString();
  1095. // drop player if is ip is banned
  1096. if(m_banmanager->isIpBanned(addr_s)){
  1097. std::string ban_name = m_banmanager->getBanName(addr_s);
  1098. infostream<<"Server: A banned client tried to connect from "
  1099. <<addr_s<<"; banned name was "
  1100. <<ban_name<<std::endl;
  1101. // This actually doesn't seem to transfer to the client
  1102. DenyAccess(peer_id, L"Your ip is banned. Banned name was "
  1103. +narrow_to_wide(ban_name));
  1104. return;
  1105. }
  1106. }
  1107. catch(con::PeerNotFoundException &e)
  1108. {
  1109. /*
  1110. * no peer for this packet found
  1111. * most common reason is peer timeout, e.g. peer didn't
  1112. * respond for some time, your server was overloaded or
  1113. * things like that.
  1114. */
  1115. infostream<<"Server::ProcessData(): Cancelling: peer "
  1116. <<peer_id<<" not found"<<std::endl;
  1117. return;
  1118. }
  1119. try
  1120. {
  1121. if(datasize < 2)
  1122. return;
  1123. ToServerCommand command = (ToServerCommand)readU16(&data[0]);
  1124. if(command == TOSERVER_INIT)
  1125. {
  1126. // [0] u16 TOSERVER_INIT
  1127. // [2] u8 SER_FMT_VER_HIGHEST_READ
  1128. // [3] u8[20] player_name
  1129. // [23] u8[28] password <--- can be sent without this, from old versions
  1130. if(datasize < 2+1+PLAYERNAME_SIZE)
  1131. return;
  1132. RemoteClient* client = getClient(peer_id, CS_Created);
  1133. // If net_proto_version is set, this client has already been handled
  1134. if(client->getState() > CS_Created)
  1135. {
  1136. verbosestream<<"Server: Ignoring multiple TOSERVER_INITs from "
  1137. <<addr_s<<" (peer_id="<<peer_id<<")"<<std::endl;
  1138. return;
  1139. }
  1140. verbosestream<<"Server: Got TOSERVER_INIT from "<<addr_s<<" (peer_id="
  1141. <<peer_id<<")"<<std::endl;
  1142. // Do not allow multiple players in simple singleplayer mode.
  1143. // This isn't a perfect way to do it, but will suffice for now
  1144. if(m_simple_singleplayer_mode && m_clients.getClientIDs().size() > 1){
  1145. infostream<<"Server: Not allowing another client ("<<addr_s
  1146. <<") to connect in simple singleplayer mode"<<std::endl;
  1147. DenyAccess(peer_id, L"Running in simple singleplayer mode.");
  1148. return;
  1149. }
  1150. // First byte after command is maximum supported
  1151. // serialization version
  1152. u8 client_max = data[2];
  1153. u8 our_max = SER_FMT_VER_HIGHEST_READ;
  1154. // Use the highest version supported by both
  1155. u8 deployed = std::min(client_max, our_max);
  1156. // If it's lower than the lowest supported, give up.
  1157. if(deployed < SER_FMT_VER_LOWEST)
  1158. deployed = SER_FMT_VER_INVALID;
  1159. if(deployed == SER_FMT_VER_INVALID)
  1160. {
  1161. actionstream<<"Server: A mismatched client tried to connect from "
  1162. <<addr_s<<std::endl;
  1163. infostream<<"Server: Cannot negotiate serialization version with "
  1164. <<addr_s<<std::endl;
  1165. DenyAccess(peer_id, std::wstring(
  1166. L"Your client's version is not supported.\n"
  1167. L"Server version is ")
  1168. + narrow_to_wide(minetest_version_simple) + L"."
  1169. );
  1170. return;
  1171. }
  1172. client->setPendingSerializationVersion(deployed);
  1173. /*
  1174. Read and check network protocol version
  1175. */
  1176. u16 min_net_proto_version = 0;
  1177. if(datasize >= 2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2)
  1178. min_net_proto_version = readU16(&data[2+1+PLAYERNAME_SIZE+PASSWORD_SIZE]);
  1179. // Use same version as minimum and maximum if maximum version field
  1180. // doesn't exist (backwards compatibility)
  1181. u16 max_net_proto_version = min_net_proto_version;
  1182. if(datasize >= 2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2+2)
  1183. max_net_proto_version = readU16(&data[2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2]);
  1184. // Start with client's maximum version
  1185. u16 net_proto_version = max_net_proto_version;
  1186. // Figure out a working version if it is possible at all
  1187. if(max_net_proto_version >= SERVER_PROTOCOL_VERSION_MIN ||
  1188. min_net_proto_version <= SERVER_PROTOCOL_VERSION_MAX)
  1189. {
  1190. // If maximum is larger than our maximum, go with our maximum
  1191. if(max_net_proto_version > SERVER_PROTOCOL_VERSION_MAX)
  1192. net_proto_version = SERVER_PROTOCOL_VERSION_MAX;
  1193. // Else go with client's maximum
  1194. else
  1195. net_proto_version = max_net_proto_version;
  1196. }
  1197. verbosestream<<"Server: "<<addr_s<<": Protocol version: min: "
  1198. <<min_net_proto_version<<", max: "<<max_net_proto_version
  1199. <<", chosen: "<<net_proto_version<<std::endl;
  1200. client->net_proto_version = net_proto_version;
  1201. if(net_proto_version < SERVER_PROTOCOL_VERSION_MIN ||
  1202. net_proto_version > SERVER_PROTOCOL_VERSION_MAX)
  1203. {
  1204. actionstream<<"Server: A mismatched client tried to connect from "
  1205. <<addr_s<<std::endl;
  1206. DenyAccess(peer_id, std::wstring(
  1207. L"Your client's version is not supported.\n"
  1208. L"Server version is ")
  1209. + narrow_to_wide(minetest_version_simple) + L",\n"
  1210. + L"server's PROTOCOL_VERSION is "
  1211. + narrow_to_wide(itos(SERVER_PROTOCOL_VERSION_MIN))
  1212. + L"..."
  1213. + narrow_to_wide(itos(SERVER_PROTOCOL_VERSION_MAX))
  1214. + L", client's PROTOCOL_VERSION is "
  1215. + narrow_to_wide(itos(min_net_proto_version))
  1216. + L"..."
  1217. + narrow_to_wide(itos(max_net_proto_version))
  1218. );
  1219. return;
  1220. }
  1221. if(g_settings->getBool("strict_protocol_version_checking"))
  1222. {
  1223. if(net_proto_version != LATEST_PROTOCOL_VERSION)
  1224. {
  1225. actionstream<<"Server: A mismatched (strict) client tried to "
  1226. <<"connect from "<<addr_s<<std::endl;
  1227. DenyAccess(peer_id, std::wstring(
  1228. L"Your client's version is not supported.\n"
  1229. L"Server version is ")
  1230. + narrow_to_wide(minetest_version_simple) + L",\n"
  1231. + L"server's PROTOCOL_VERSION (strict) is "
  1232. + narrow_to_wide(itos(LATEST_PROTOCOL_VERSION))
  1233. + L", client's PROTOCOL_VERSION is "
  1234. + narrow_to_wide(itos(min_net_proto_version))
  1235. + L"..."
  1236. + narrow_to_wide(itos(max_net_proto_version))
  1237. );
  1238. return;
  1239. }
  1240. }
  1241. /*
  1242. Set up player
  1243. */
  1244. char playername[PLAYERNAME_SIZE];
  1245. unsigned int playername_length = 0;
  1246. for (; playername_length < PLAYERNAME_SIZE; playername_length++ ) {
  1247. playername[playername_length] = data[3+playername_length];
  1248. if (data[3+playername_length] == 0)
  1249. break;
  1250. }
  1251. if (playername_length == PLAYERNAME_SIZE) {
  1252. actionstream<<"Server: Player with name exceeding max length "
  1253. <<"tried to connect from "<<addr_s<<std::endl;
  1254. DenyAccess(peer_id, L"Name too long");
  1255. return;
  1256. }
  1257. if(playername[0]=='\0')
  1258. {
  1259. actionstream<<"Server: Player with an empty name "
  1260. <<"tried to connect from "<<addr_s<<std::endl;
  1261. DenyAccess(peer_id, L"Empty name");
  1262. return;
  1263. }
  1264. if(string_allowed(playername, PLAYERNAME_ALLOWED_CHARS)==false)
  1265. {
  1266. actionstream<<"Server: Player with an invalid name "
  1267. <<"tried to connect from "<<addr_s<<std::endl;
  1268. DenyAccess(peer_id, L"Name contains unallowed characters");
  1269. return;
  1270. }
  1271. if(!isSingleplayer() && strcasecmp(playername, "singleplayer") == 0)
  1272. {
  1273. actionstream<<"Server: Player with the name \"singleplayer\" "
  1274. <<"tried to connect from "<<addr_s<<std::endl;
  1275. DenyAccess(peer_id, L"Name is not allowed");
  1276. return;
  1277. }
  1278. {
  1279. std::string reason;
  1280. if(m_script->on_prejoinplayer(playername, addr_s, reason))
  1281. {
  1282. actionstream<<"Server: Player with the name \""<<playername<<"\" "
  1283. <<"tried to connect from "<<addr_s<<" "
  1284. <<"but it was disallowed for the following reason: "
  1285. <<reason<<std::endl;
  1286. DenyAccess(peer_id, narrow_to_wide(reason.c_str()));
  1287. return;
  1288. }
  1289. }
  1290. infostream<<"Server: New connection: \""<<playername<<"\" from "
  1291. <<addr_s<<" (peer_id="<<peer_id<<")"<<std::endl;
  1292. // Get password
  1293. char given_password[PASSWORD_SIZE];
  1294. if(datasize < 2+1+PLAYERNAME_SIZE+PASSWORD_SIZE)
  1295. {
  1296. // old version - assume blank password
  1297. given_password[0] = 0;
  1298. }
  1299. else
  1300. {
  1301. for(u32 i=0; i<PASSWORD_SIZE-1; i++)
  1302. {
  1303. given_password[i] = data[23+i];
  1304. }
  1305. given_password[PASSWORD_SIZE-1] = 0;
  1306. }
  1307. if(!base64_is_valid(given_password)){
  1308. actionstream<<"Server: "<<playername
  1309. <<" supplied invalid password hash"<<std::endl;
  1310. DenyAccess(peer_id, L"Invalid password hash");
  1311. return;
  1312. }
  1313. // Enforce user limit.
  1314. // Don't enforce for users that have some admin right
  1315. if(m_clients.getClientIDs(CS_Created).size() >= g_settings->getU16("max_users") &&
  1316. !checkPriv(playername, "server") &&
  1317. !checkPriv(playername, "ban") &&
  1318. !checkPriv(playername, "privs") &&
  1319. !checkPriv(playername, "password") &&
  1320. playername != g_settings->get("name"))
  1321. {
  1322. actionstream<<"Server: "<<playername<<" tried to join, but there"
  1323. <<" are already max_users="
  1324. <<g_settings->getU16("max_users")<<" players."<<std::endl;
  1325. DenyAccess(peer_id, L"Too many users.");
  1326. return;
  1327. }
  1328. std::string checkpwd; // Password hash to check against
  1329. bool has_auth = m_script->getAuth(playername, &checkpwd, NULL);
  1330. // If no authentication info exists for user, create it
  1331. if(!has_auth){
  1332. if(!isSingleplayer() &&
  1333. g_settings->getBool("disallow_empty_password") &&
  1334. std::string(given_password) == ""){
  1335. actionstream<<"Server: "<<playername
  1336. <<" supplied empty password"<<std::endl;
  1337. DenyAccess(peer_id, L"Empty passwords are "
  1338. L"disallowed. Set a password and try again.");
  1339. return;
  1340. }
  1341. std::wstring raw_default_password =
  1342. narrow_to_wide(g_settings->get("default_password"));
  1343. std::string initial_password =
  1344. translatePassword(playername, raw_default_password);
  1345. // If default_password is empty, allow any initial password
  1346. if (raw_default_password.length() == 0)
  1347. initial_password = given_password;
  1348. m_script->createAuth(playername, initial_password);
  1349. }
  1350. has_auth = m_script->getAuth(playername, &checkpwd, NULL);
  1351. if(!has_auth){
  1352. actionstream<<"Server: "<<playername<<" cannot be authenticated"
  1353. <<" (auth handler does not work?)"<<std::endl;
  1354. DenyAccess(peer_id, L"Not allowed to login");
  1355. return;
  1356. }
  1357. if(given_password != checkpwd){
  1358. actionstream<<"Server: "<<playername<<" supplied wrong password"
  1359. <<std::endl;
  1360. DenyAccess(peer_id, L"Wrong password");
  1361. return;
  1362. }
  1363. RemotePlayer *player =
  1364. static_cast<RemotePlayer*>(m_env->getPlayer(playername));
  1365. if(player && player->peer_id != 0){
  1366. errorstream<<"Server: "<<playername<<": Failed to emerge player"
  1367. <<" (player allocated to an another client)"<<std::endl;
  1368. DenyAccess(peer_id, L"Another client is connected with this "
  1369. L"name. If your client closed unexpectedly, try again in "
  1370. L"a minute.");
  1371. }
  1372. m_clients.setPlayerName(peer_id,playername);
  1373. /*
  1374. Answer with a TOCLIENT_INIT
  1375. */
  1376. {
  1377. SharedBuffer<u8> reply(2+1+6+8+4);
  1378. writeU16(&reply[0], TOCLIENT_INIT);
  1379. writeU8(&reply[2], deployed);
  1380. //send dummy pos for legacy reasons only
  1381. writeV3S16(&reply[2+1], floatToInt(v3f(0,0,0), BS));
  1382. writeU64(&reply[2+1+6], m_env->getServerMap().getSeed());
  1383. writeF1000(&reply[2+1+6+8], g_settings->getFloat("dedicated_server_step"));
  1384. // Send as reliable
  1385. m_clients.send(peer_id, 0, reply, true);
  1386. m_clients.event(peer_id, CSE_Init);
  1387. }
  1388. return;
  1389. }
  1390. if(command == TOSERVER_INIT2)
  1391. {
  1392. verbosestream<<"Server: Got TOSERVER_INIT2 from "
  1393. <<peer_id<<std::endl;
  1394. m_clients.event(peer_id, CSE_GotInit2);
  1395. u16 protocol_version = m_clients.getProtocolVersion(peer_id);
  1396. ///// begin compatibility code
  1397. PlayerSAO* playersao = NULL;
  1398. if (protocol_version <= 22) {
  1399. playersao = StageTwoClientInit(peer_id);
  1400. if (playersao == NULL) {
  1401. errorstream
  1402. << "TOSERVER_INIT2 stage 2 client init failed for peer "
  1403. << peer_id << std::endl;
  1404. return;
  1405. }
  1406. }
  1407. ///// end compatibility code
  1408. /*
  1409. Send some initialization data
  1410. */
  1411. infostream<<"Server: Sending content to "
  1412. <<getPlayerName(peer_id)<<std::endl;
  1413. // Send player movement settings
  1414. SendMovement(peer_id);
  1415. // Send item definitions
  1416. SendItemDef(peer_id, m_itemdef, protocol_version);
  1417. // Send node definitions
  1418. SendNodeDef(peer_id, m_nodedef, protocol_version);
  1419. m_clients.event(peer_id, CSE_SetDefinitionsSent);
  1420. // Send media announcement
  1421. sendMediaAnnouncement(peer_id);
  1422. // Send detached inventories
  1423. sendDetachedInventories(peer_id);
  1424. // Send time of day
  1425. u16 time = m_env->getTimeOfDay();
  1426. float time_speed = g_settings->getFloat("time_speed");
  1427. SendTimeOfDay(peer_id, time, time_speed);
  1428. ///// begin compatibility code
  1429. if (protocol_version <= 22) {
  1430. m_clients.event(peer_id, CSE_SetClientReady);
  1431. m_script->on_joinplayer(playersao);
  1432. }
  1433. ///// end compatibility code
  1434. // Warnings about protocol version can be issued here
  1435. if(getClient(peer_id)->net_proto_version < LATEST_PROTOCOL_VERSION)
  1436. {
  1437. SendChatMessage(peer_id, L"# Server: WARNING: YOUR CLIENT'S "
  1438. L"VERSION MAY NOT BE FULLY COMPATIBLE WITH THIS SERVER!");
  1439. }
  1440. return;
  1441. }
  1442. u8 peer_ser_ver = getClient(peer_id, CS_InitDone)->serialization_version;
  1443. u16 peer_proto_ver = getClient(peer_id, CS_InitDone)->net_proto_version;
  1444. if(peer_ser_ver == SER_FMT_VER_INVALID)
  1445. {
  1446. errorstream<<"Server::ProcessData(): Cancelling: Peer"
  1447. " serialization format invalid or not initialized."
  1448. " Skipping incoming command="<<command<<std::endl;
  1449. return;
  1450. }
  1451. /* Handle commands relate to client startup */
  1452. if(command == TOSERVER_REQUEST_MEDIA) {
  1453. std::string datastring((char*)&data[2], datasize-2);
  1454. std::istringstream is(datastring, std::ios_base::binary);
  1455. std::list<std::string> tosend;
  1456. u16 numfiles = readU16(is);
  1457. infostream<<"Sending "<<numfiles<<" files to "
  1458. <<getPlayerName(peer_id)<<std::endl;
  1459. verbosestream<<"TOSERVER_REQUEST_MEDIA: "<<std::endl;
  1460. for(int i = 0; i < numfiles; i++) {
  1461. std::string name = deSerializeString(is);
  1462. tosend.push_back(name);
  1463. verbosestream<<"TOSERVER_REQUEST_MEDIA: requested file "
  1464. <<name<<std::endl;
  1465. }
  1466. sendRequestedMedia(peer_id, tosend);
  1467. return;
  1468. }
  1469. else if(command == TOSERVER_RECEIVED_MEDIA) {
  1470. return;
  1471. }
  1472. else if(command == TOSERVER_CLIENT_READY) {
  1473. // clients <= protocol version 22 did not send ready message,
  1474. // they're already initialized
  1475. if (peer_proto_ver <= 22) {
  1476. infostream << "Client sent message not expected by a "
  1477. << "client using protocol version <= 22,"
  1478. << "disconnecing peer_id: " << peer_id << std::endl;
  1479. m_con.DisconnectPeer(peer_id);
  1480. return;
  1481. }
  1482. PlayerSAO* playersao = StageTwoClientInit(peer_id);
  1483. if (playersao == NULL) {
  1484. errorstream
  1485. << "TOSERVER_CLIENT_READY stage 2 client init failed for peer_id: "
  1486. << peer_id << std::endl;
  1487. m_con.DisconnectPeer(peer_id);
  1488. return;
  1489. }
  1490. if(datasize < 2+8) {
  1491. errorstream
  1492. << "TOSERVER_CLIENT_READY client sent inconsistent data, disconnecting peer_id: "
  1493. << peer_id << std::endl;
  1494. m_con.DisconnectPeer(peer_id);
  1495. return;
  1496. }
  1497. m_clients.setClientVersion(
  1498. peer_id,
  1499. data[2], data[3], data[4],
  1500. std::string((char*) &data[8],(u16) data[6]));
  1501. m_clients.event(peer_id, CSE_SetClientReady);
  1502. m_script->on_joinplayer(playersao);
  1503. }
  1504. else if(command == TOSERVER_GOTBLOCKS)
  1505. {
  1506. if(datasize < 2+1)
  1507. return;
  1508. /*
  1509. [0] u16 command
  1510. [2] u8 count
  1511. [3] v3s16 pos_0
  1512. [3+6] v3s16 pos_1
  1513. ...
  1514. */
  1515. u16 count = data[2];
  1516. for(u16 i=0; i<count; i++)
  1517. {
  1518. if((s16)datasize < 2+1+(i+1)*6)
  1519. throw con::InvalidIncomingDataException
  1520. ("GOTBLOCKS length is too short");
  1521. v3s16 p = readV3S16(&data[2+1+i*6]);
  1522. /*infostream<<"Server: GOTBLOCKS ("
  1523. <<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
  1524. RemoteClient *client = getClient(peer_id);
  1525. client->GotBlock(p);
  1526. }
  1527. return;
  1528. }
  1529. if (m_clients.getClientState(peer_id) < CS_Active)
  1530. {
  1531. if (command == TOSERVER_PLAYERPOS) return;
  1532. errorstream<<"Got packet command: " << command << " for peer id "
  1533. << peer_id << " but client isn't active yet. Dropping packet "
  1534. <<std::endl;
  1535. return;
  1536. }
  1537. Player *player = m_env->getPlayer(peer_id);
  1538. if(player == NULL) {
  1539. errorstream<<"Server::ProcessData(): Cancelling: "
  1540. "No player for peer_id="<<peer_id
  1541. << " disconnecting peer!" <<std::endl;
  1542. m_con.DisconnectPeer(peer_id);
  1543. return;
  1544. }
  1545. PlayerSAO *playersao = player->getPlayerSAO();
  1546. if(playersao == NULL) {
  1547. errorstream<<"Server::ProcessData(): Cancelling: "
  1548. "No player object for peer_id="<<peer_id
  1549. << " disconnecting peer!" <<std::endl;
  1550. m_con.DisconnectPeer(peer_id);
  1551. return;
  1552. }
  1553. if(command == TOSERVER_PLAYERPOS)
  1554. {
  1555. if(datasize < 2+12+12+4+4)
  1556. return;
  1557. u32 start = 0;
  1558. v3s32 ps = readV3S32(&data[start+2]);
  1559. v3s32 ss = readV3S32(&data[start+2+12]);
  1560. f32 pitch = (f32)readS32(&data[2+12+12]) / 100.0;
  1561. f32 yaw = (f32)readS32(&data[2+12+12+4]) / 100.0;
  1562. u32 keyPressed = 0;
  1563. if(datasize >= 2+12+12+4+4+4)
  1564. keyPressed = (u32)readU32(&data[2+12+12+4+4]);
  1565. v3f position((f32)ps.X/100., (f32)ps.Y/100., (f32)ps.Z/100.);
  1566. v3f speed((f32)ss.X/100., (f32)ss.Y/100., (f32)ss.Z/100.);
  1567. pitch = wrapDegrees(pitch);
  1568. yaw = wrapDegrees(yaw);
  1569. player->setPosition(position);
  1570. player->setSpeed(speed);
  1571. player->setPitch(pitch);
  1572. player->setYaw(yaw);
  1573. player->keyPressed=keyPressed;
  1574. player->control.up = (bool)(keyPressed&1);
  1575. player->control.down = (bool)(keyPressed&2);
  1576. player->control.left = (bool)(keyPressed&4);
  1577. player->control.right = (bool)(keyPressed&8);
  1578. player->control.jump = (bool)(keyPressed&16);
  1579. player->control.aux1 = (bool)(keyPressed&32);
  1580. player->control.sneak = (bool)(keyPressed&64);
  1581. player->control.LMB = (bool)(keyPressed&128);
  1582. player->control.RMB = (bool)(keyPressed&256);
  1583. bool cheated = playersao->checkMovementCheat();
  1584. if(cheated){
  1585. // Call callbacks
  1586. m_script->on_cheat(playersao, "moved_too_fast");
  1587. }
  1588. /*infostream<<"Server::ProcessData(): Moved player "<<peer_id<<" to "
  1589. <<"("<<position.X<<","<<position.Y<<","<<position.Z<<")"
  1590. <<" pitch="<<pitch<<" yaw="<<yaw<<std::endl;*/
  1591. }
  1592. else if(command == TOSERVER_DELETEDBLOCKS)
  1593. {
  1594. if(datasize < 2+1)
  1595. return;
  1596. /*
  1597. [0] u16 command
  1598. [2] u8 count
  1599. [3] v3s16 pos_0
  1600. [3+6] v3s16 pos_1
  1601. ...
  1602. */
  1603. u16 count = data[2];
  1604. for(u16 i=0; i<count; i++)
  1605. {
  1606. if((s16)datasize < 2+1+(i+1)*6)
  1607. throw con::InvalidIncomingDataException
  1608. ("DELETEDBLOCKS length is too short");
  1609. v3s16 p = readV3S16(&data[2+1+i*6]);
  1610. /*infostream<<"Server: DELETEDBLOCKS ("
  1611. <<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
  1612. RemoteClient *client = getClient(peer_id);
  1613. client->SetBlockNotSent(p);
  1614. }
  1615. }
  1616. else if(command == TOSERVER_CLICK_OBJECT)
  1617. {
  1618. infostream<<"Server: CLICK_OBJECT not supported anymore"<<std::endl;
  1619. return;
  1620. }
  1621. else if(command == TOSERVER_CLICK_ACTIVEOBJECT)
  1622. {
  1623. infostream<<"Server: CLICK_ACTIVEOBJECT not supported anymore"<<std::endl;
  1624. return;
  1625. }
  1626. else if(command == TOSERVER_GROUND_ACTION)
  1627. {
  1628. infostream<<"Server: GROUND_ACTION not supported anymore"<<std::endl;
  1629. return;
  1630. }
  1631. else if(command == TOSERVER_RELEASE)
  1632. {
  1633. infostream<<"Server: RELEASE not supported anymore"<<std::endl;
  1634. return;
  1635. }
  1636. else if(command == TOSERVER_SIGNTEXT)
  1637. {
  1638. infostream<<"Server: SIGNTEXT not supported anymore"
  1639. <<std::endl;
  1640. return;
  1641. }
  1642. else if(command == TOSERVER_SIGNNODETEXT)
  1643. {
  1644. infostream<<"Server: SIGNNODETEXT not supported anymore"
  1645. <<std::endl;
  1646. return;
  1647. }
  1648. else if(command == TOSERVER_INVENTORY_ACTION)
  1649. {
  1650. // Strip command and create a stream
  1651. std::string datastring((char*)&data[2], datasize-2);
  1652. verbosestream<<"TOSERVER_INVENTORY_ACTION: data="<<datastring<<std::endl;
  1653. std::istringstream is(datastring, std::ios_base::binary);
  1654. // Create an action
  1655. InventoryAction *a = InventoryAction::deSerialize(is);
  1656. if(a == NULL)
  1657. {
  1658. infostream<<"TOSERVER_INVENTORY_ACTION: "
  1659. <<"InventoryAction::deSerialize() returned NULL"
  1660. <<std::endl;
  1661. return;
  1662. }
  1663. // If something goes wrong, this player is to blame
  1664. RollbackScopeActor rollback_scope(m_rollback,
  1665. std::string("player:")+player->getName());
  1666. /*
  1667. Note: Always set inventory not sent, to repair cases
  1668. where the client made a bad prediction.
  1669. */
  1670. /*
  1671. Handle restrictions and special cases of the move action
  1672. */
  1673. if(a->getType() == IACTION_MOVE)
  1674. {
  1675. IMoveAction *ma = (IMoveAction*)a;
  1676. ma->from_inv.applyCurrentPlayer(player->getName());
  1677. ma->to_inv.applyCurrentPlayer(player->getName());
  1678. setInventoryModified(ma->from_inv);
  1679. setInventoryModified(ma->to_inv);
  1680. bool from_inv_is_current_player =
  1681. (ma->from_inv.type == InventoryLocation::PLAYER) &&
  1682. (ma->from_inv.name == player->getName());
  1683. bool to_inv_is_current_player =
  1684. (ma->to_inv.type == InventoryLocation::PLAYER) &&
  1685. (ma->to_inv.name == player->getName());
  1686. /*
  1687. Disable moving items out of craftpreview
  1688. */
  1689. if(ma->from_list == "craftpreview")
  1690. {
  1691. infostream<<"Ignoring IMoveAction from "
  1692. <<(ma->from_inv.dump())<<":"<<ma->from_list
  1693. <<" to "<<(ma->to_inv.dump())<<":"<<ma->to_list
  1694. <<" because src is "<<ma->from_list<<std::endl;
  1695. delete a;
  1696. return;
  1697. }
  1698. /*
  1699. Disable moving items into craftresult and craftpreview
  1700. */
  1701. if(ma->to_list == "craftpreview" || ma->to_list == "craftresult")
  1702. {
  1703. infostream<<"Ignoring IMoveAction from "
  1704. <<(ma->from_inv.dump())<<":"<<ma->from_list
  1705. <<" to "<<(ma->to_inv.dump())<<":"<<ma->to_list
  1706. <<" because dst is "<<ma->to_list<<std::endl;
  1707. delete a;
  1708. return;
  1709. }
  1710. // Disallow moving items in elsewhere than player's inventory
  1711. // if not allowed to interact
  1712. if(!checkPriv(player->getName(), "interact") &&
  1713. (!from_inv_is_current_player ||
  1714. !to_inv_is_current_player))
  1715. {
  1716. infostream<<"Cannot move outside of player's inventory: "
  1717. <<"No interact privilege"<<std::endl;
  1718. delete a;
  1719. return;
  1720. }
  1721. }
  1722. /*
  1723. Handle restrictions and special cases of the drop action
  1724. */
  1725. else if(a->getType() == IACTION_DROP)
  1726. {
  1727. IDropAction *da = (IDropAction*)a;
  1728. da->from_inv.applyCurrentPlayer(player->getName());
  1729. setInventoryModified(da->from_inv);
  1730. /*
  1731. Disable dropping items out of craftpreview
  1732. */
  1733. if(da->from_list == "craftpreview")
  1734. {
  1735. infostream<<"Ignoring IDropAction from "
  1736. <<(da->from_inv.dump())<<":"<<da->from_list
  1737. <<" because src is "<<da->from_list<<std::endl;
  1738. delete a;
  1739. return;
  1740. }
  1741. // Disallow dropping items if not allowed to interact
  1742. if(!checkPriv(player->getName(), "interact"))
  1743. {
  1744. delete a;
  1745. return;
  1746. }
  1747. }
  1748. /*
  1749. Handle restrictions and special cases of the craft action
  1750. */
  1751. else if(a->getType() == IACTION_CRAFT)
  1752. {
  1753. ICraftAction *ca = (ICraftAction*)a;
  1754. ca->craft_inv.applyCurrentPlayer(player->getName());
  1755. setInventoryModified(ca->craft_inv);
  1756. //bool craft_inv_is_current_player =
  1757. // (ca->craft_inv.type == InventoryLocation::PLAYER) &&
  1758. // (ca->craft_inv.name == player->getName());
  1759. // Disallow crafting if not allowed to interact
  1760. if(!checkPriv(player->getName(), "interact"))
  1761. {
  1762. infostream<<"Cannot craft: "
  1763. <<"No interact privilege"<<std::endl;
  1764. delete a;
  1765. return;
  1766. }
  1767. }
  1768. // Do the action
  1769. a->apply(this, playersao, this);
  1770. // Eat the action
  1771. delete a;
  1772. }
  1773. else if(command == TOSERVER_CHAT_MESSAGE)
  1774. {
  1775. /*
  1776. u16 command
  1777. u16 length
  1778. wstring message
  1779. */
  1780. u8 buf[6];
  1781. std::string datastring((char*)&data[2], datasize-2);
  1782. std::istringstream is(datastring, std::ios_base::binary);
  1783. // Read stuff
  1784. is.read((char*)buf, 2);
  1785. u16 len = readU16(buf);
  1786. std::wstring message;
  1787. for(u16 i=0; i<len; i++)
  1788. {
  1789. is.read((char*)buf, 2);
  1790. message += (wchar_t)readU16(buf);
  1791. }
  1792. // If something goes wrong, this player is to blame
  1793. RollbackScopeActor rollback_scope(m_rollback,
  1794. std::string("player:")+player->getName());
  1795. // Get player name of this client
  1796. std::wstring name = narrow_to_wide(player->getName());
  1797. // Run script hook
  1798. bool ate = m_script->on_chat_message(player->getName(),
  1799. wide_to_narrow(message));
  1800. // If script ate the message, don't proceed
  1801. if(ate)
  1802. return;
  1803. // Line to send to players
  1804. std::wstring line;
  1805. // Whether to send to the player that sent the line
  1806. bool send_to_sender_only = false;
  1807. // Commands are implemented in Lua, so only catch invalid
  1808. // commands that were not "eaten" and send an error back
  1809. if(message[0] == L'/')
  1810. {
  1811. message = message.substr(1);
  1812. send_to_sender_only = true;
  1813. if(message.length() == 0)
  1814. line += L"-!- Empty command";
  1815. else
  1816. line += L"-!- Invalid command: " + str_split(message, L' ')[0];
  1817. }
  1818. else
  1819. {
  1820. if(checkPriv(player->getName(), "shout")){
  1821. line += L"<";
  1822. line += name;
  1823. line += L"> ";
  1824. line += message;
  1825. } else {
  1826. line += L"-!- You don't have permission to shout.";
  1827. send_to_sender_only = true;
  1828. }
  1829. }
  1830. if(line != L"")
  1831. {
  1832. /*
  1833. Send the message to sender
  1834. */
  1835. if (send_to_sender_only)
  1836. {
  1837. SendChatMessage(peer_id, line);
  1838. }
  1839. /*
  1840. Send the message to others
  1841. */
  1842. else
  1843. {
  1844. actionstream<<"CHAT: "<<wide_to_narrow(line)<<std::endl;
  1845. std::list<u16> clients = m_clients.getClientIDs();
  1846. for(std::list<u16>::iterator
  1847. i = clients.begin();
  1848. i != clients.end(); ++i)
  1849. {
  1850. if (*i != peer_id)
  1851. SendChatMessage(*i, line);
  1852. }
  1853. }
  1854. }
  1855. }
  1856. else if(command == TOSERVER_DAMAGE)
  1857. {
  1858. std::string datastring((char*)&data[2], datasize-2);
  1859. std::istringstream is(datastring, std::ios_base::binary);
  1860. u8 damage = readU8(is);
  1861. if(g_settings->getBool("enable_damage"))
  1862. {
  1863. actionstream<<player->getName()<<" damaged by "
  1864. <<(int)damage<<" hp at "<<PP(player->getPosition()/BS)
  1865. <<std::endl;
  1866. playersao->setHP(playersao->getHP() - damage);
  1867. if(playersao->getHP() == 0 && playersao->m_hp_not_sent)
  1868. DiePlayer(peer_id);
  1869. if(playersao->m_hp_not_sent)
  1870. SendPlayerHP(peer_id);
  1871. }
  1872. }
  1873. else if(command == TOSERVER_BREATH)
  1874. {
  1875. std::string datastring((char*)&data[2], datasize-2);
  1876. std::istringstream is(datastring, std::ios_base::binary);
  1877. u16 breath = readU16(is);
  1878. playersao->setBreath(breath);
  1879. m_script->player_event(playersao,"breath_changed");
  1880. }
  1881. else if(command == TOSERVER_PASSWORD)
  1882. {
  1883. /*
  1884. [0] u16 TOSERVER_PASSWORD
  1885. [2] u8[28] old password
  1886. [30] u8[28] new password
  1887. */
  1888. if(datasize != 2+PASSWORD_SIZE*2)
  1889. return;
  1890. /*char password[PASSWORD_SIZE];
  1891. for(u32 i=0; i<PASSWORD_SIZE-1; i++)
  1892. password[i] = data[2+i];
  1893. password[PASSWORD_SIZE-1] = 0;*/
  1894. std::string oldpwd;
  1895. for(u32 i=0; i<PASSWORD_SIZE-1; i++)
  1896. {
  1897. char c = data[2+i];
  1898. if(c == 0)
  1899. break;
  1900. oldpwd += c;
  1901. }
  1902. std::string newpwd;
  1903. for(u32 i=0; i<PASSWORD_SIZE-1; i++)
  1904. {
  1905. char c = data[2+PASSWORD_SIZE+i];
  1906. if(c == 0)
  1907. break;
  1908. newpwd += c;
  1909. }
  1910. if(!base64_is_valid(newpwd)){
  1911. infostream<<"Server: "<<player->getName()<<" supplied invalid password hash"<<std::endl;
  1912. // Wrong old password supplied!!
  1913. SendChatMessage(peer_id, L"Invalid new password hash supplied. Password NOT changed.");
  1914. return;
  1915. }
  1916. infostream<<"Server: Client requests a password change from "
  1917. <<"'"<<oldpwd<<"' to '"<<newpwd<<"'"<<std::endl;
  1918. std::string playername = player->getName();
  1919. std::string checkpwd;
  1920. m_script->getAuth(playername, &checkpwd, NULL);
  1921. if(oldpwd != checkpwd)
  1922. {
  1923. infostream<<"Server: invalid old password"<<std::endl;
  1924. // Wrong old password supplied!!
  1925. SendChatMessage(peer_id, L"Invalid old password supplied. Password NOT changed.");
  1926. return;
  1927. }
  1928. bool success = m_script->setPassword(playername, newpwd);
  1929. if(success){
  1930. actionstream<<player->getName()<<" changes password"<<std::endl;
  1931. SendChatMessage(peer_id, L"Password change successful.");
  1932. } else {
  1933. actionstream<<player->getName()<<" tries to change password but "
  1934. <<"it fails"<<std::endl;
  1935. SendChatMessage(peer_id, L"Password change failed or inavailable.");
  1936. }
  1937. }
  1938. else if(command == TOSERVER_PLAYERITEM)
  1939. {
  1940. if (datasize < 2+2)
  1941. return;
  1942. u16 item = readU16(&data[2]);
  1943. playersao->setWieldIndex(item);
  1944. }
  1945. else if(command == TOSERVER_RESPAWN)
  1946. {
  1947. if(player->hp != 0 || !g_settings->getBool("enable_damage"))
  1948. return;
  1949. RespawnPlayer(peer_id);
  1950. actionstream<<player->getName()<<" respawns at "
  1951. <<PP(player->getPosition()/BS)<<std::endl;
  1952. // ActiveObject is added to environment in AsyncRunStep after
  1953. // the previous addition has been succesfully removed
  1954. }
  1955. else if(command == TOSERVER_INTERACT)
  1956. {
  1957. std::string datastring((char*)&data[2], datasize-2);
  1958. std::istringstream is(datastring, std::ios_base::binary);
  1959. /*
  1960. [0] u16 command
  1961. [2] u8 action
  1962. [3] u16 item
  1963. [5] u32 length of the next item
  1964. [9] serialized PointedThing
  1965. actions:
  1966. 0: start digging (from undersurface) or use
  1967. 1: stop digging (all parameters ignored)
  1968. 2: digging completed
  1969. 3: place block or item (to abovesurface)
  1970. 4: use item
  1971. */
  1972. u8 action = readU8(is);
  1973. u16 item_i = readU16(is);
  1974. std::istringstream tmp_is(deSerializeLongString(is), std::ios::binary);
  1975. PointedThing pointed;
  1976. pointed.deSerialize(tmp_is);
  1977. verbosestream<<"TOSERVER_INTERACT: action="<<(int)action<<", item="
  1978. <<item_i<<", pointed="<<pointed.dump()<<std::endl;
  1979. if(player->hp == 0)
  1980. {
  1981. verbosestream<<"TOSERVER_INTERACT: "<<player->getName()
  1982. <<" tried to interact, but is dead!"<<std::endl;
  1983. return;
  1984. }
  1985. v3f player_pos = playersao->getLastGoodPosition();
  1986. // Update wielded item
  1987. playersao->setWieldIndex(item_i);
  1988. // Get pointed to node (undefined if not POINTEDTYPE_NODE)
  1989. v3s16 p_under = pointed.node_undersurface;
  1990. v3s16 p_above = pointed.node_abovesurface;
  1991. // Get pointed to object (NULL if not POINTEDTYPE_OBJECT)
  1992. ServerActiveObject *pointed_object = NULL;
  1993. if(pointed.type == POINTEDTHING_OBJECT)
  1994. {
  1995. pointed_object = m_env->getActiveObject(pointed.object_id);
  1996. if(pointed_object == NULL)
  1997. {
  1998. verbosestream<<"TOSERVER_INTERACT: "
  1999. "pointed object is NULL"<<std::endl;
  2000. return;
  2001. }
  2002. }
  2003. v3f pointed_pos_under = player_pos;
  2004. v3f pointed_pos_above = player_pos;
  2005. if(pointed.type == POINTEDTHING_NODE)
  2006. {
  2007. pointed_pos_under = intToFloat(p_under, BS);
  2008. pointed_pos_above = intToFloat(p_above, BS);
  2009. }
  2010. else if(pointed.type == POINTEDTHING_OBJECT)
  2011. {
  2012. pointed_pos_under = pointed_object->getBasePosition();
  2013. pointed_pos_above = pointed_pos_under;
  2014. }
  2015. /*
  2016. Check that target is reasonably close
  2017. (only when digging or placing things)
  2018. */
  2019. if(action == 0 || action == 2 || action == 3)
  2020. {
  2021. float d = player_pos.getDistanceFrom(pointed_pos_under);
  2022. float max_d = BS * 14; // Just some large enough value
  2023. if(d > max_d){
  2024. actionstream<<"Player "<<player->getName()
  2025. <<" tried to access "<<pointed.dump()
  2026. <<" from too far: "
  2027. <<"d="<<d<<", max_d="<<max_d
  2028. <<". ignoring."<<std::endl;
  2029. // Re-send block to revert change on client-side
  2030. RemoteClient *client = getClient(peer_id);
  2031. v3s16 blockpos = getNodeBlockPos(floatToInt(pointed_pos_under, BS));
  2032. client->SetBlockNotSent(blockpos);
  2033. // Call callbacks
  2034. m_script->on_cheat(playersao, "interacted_too_far");
  2035. // Do nothing else
  2036. return;
  2037. }
  2038. }
  2039. /*
  2040. Make sure the player is allowed to do it
  2041. */
  2042. if(!checkPriv(player->getName(), "interact"))
  2043. {
  2044. actionstream<<player->getName()<<" attempted to interact with "
  2045. <<pointed.dump()<<" without 'interact' privilege"
  2046. <<std::endl;
  2047. // Re-send block to revert change on client-side
  2048. RemoteClient *client = getClient(peer_id);
  2049. // Digging completed -> under
  2050. if(action == 2){
  2051. v3s16 blockpos = getNodeBlockPos(floatToInt(pointed_pos_under, BS));
  2052. client->SetBlockNotSent(blockpos);
  2053. }
  2054. // Placement -> above
  2055. if(action == 3){
  2056. v3s16 blockpos = getNodeBlockPos(floatToInt(pointed_pos_above, BS));
  2057. client->SetBlockNotSent(blockpos);
  2058. }
  2059. return;
  2060. }
  2061. /*
  2062. If something goes wrong, this player is to blame
  2063. */
  2064. RollbackScopeActor rollback_scope(m_rollback,
  2065. std::string("player:")+player->getName());
  2066. /*
  2067. 0: start digging or punch object
  2068. */
  2069. if(action == 0)
  2070. {
  2071. if(pointed.type == POINTEDTHING_NODE)
  2072. {
  2073. /*
  2074. NOTE: This can be used in the future to check if
  2075. somebody is cheating, by checking the timing.
  2076. */
  2077. MapNode n(CONTENT_IGNORE);
  2078. try
  2079. {
  2080. n = m_env->getMap().getNode(p_under);
  2081. }
  2082. catch(InvalidPositionException &e)
  2083. {
  2084. infostream<<"Server: Not punching: Node not found."
  2085. <<" Adding block to emerge queue."
  2086. <<std::endl;
  2087. m_emerge->enqueueBlockEmerge(peer_id, getNodeBlockPos(p_above), false);
  2088. }
  2089. if(n.getContent() != CONTENT_IGNORE)
  2090. m_script->node_on_punch(p_under, n, playersao, pointed);
  2091. // Cheat prevention
  2092. playersao->noCheatDigStart(p_under);
  2093. }
  2094. else if(pointed.type == POINTEDTHING_OBJECT)
  2095. {
  2096. // Skip if object has been removed
  2097. if(pointed_object->m_removed)
  2098. return;
  2099. actionstream<<player->getName()<<" punches object "
  2100. <<pointed.object_id<<": "
  2101. <<pointed_object->getDescription()<<std::endl;
  2102. ItemStack punchitem = playersao->getWieldedItem();
  2103. ToolCapabilities toolcap =
  2104. punchitem.getToolCapabilities(m_itemdef);
  2105. v3f dir = (pointed_object->getBasePosition() -
  2106. (player->getPosition() + player->getEyeOffset())
  2107. ).normalize();
  2108. float time_from_last_punch =
  2109. playersao->resetTimeFromLastPunch();
  2110. pointed_object->punch(dir, &toolcap, playersao,
  2111. time_from_last_punch);
  2112. }
  2113. } // action == 0
  2114. /*
  2115. 1: stop digging
  2116. */
  2117. else if(action == 1)
  2118. {
  2119. } // action == 1
  2120. /*
  2121. 2: Digging completed
  2122. */
  2123. else if(action == 2)
  2124. {
  2125. // Only digging of nodes
  2126. if(pointed.type == POINTEDTHING_NODE)
  2127. {
  2128. MapNode n(CONTENT_IGNORE);
  2129. try
  2130. {
  2131. n = m_env->getMap().getNode(p_under);
  2132. }
  2133. catch(InvalidPositionException &e)
  2134. {
  2135. infostream<<"Server: Not finishing digging: Node not found."
  2136. <<" Adding block to emerge queue."
  2137. <<std::endl;
  2138. m_emerge->enqueueBlockEmerge(peer_id, getNodeBlockPos(p_above), false);
  2139. }
  2140. /* Cheat prevention */
  2141. bool is_valid_dig = true;
  2142. if(!isSingleplayer() && !g_settings->getBool("disable_anticheat"))
  2143. {
  2144. v3s16 nocheat_p = playersao->getNoCheatDigPos();
  2145. float nocheat_t = playersao->getNoCheatDigTime();
  2146. playersao->noCheatDigEnd();
  2147. // If player didn't start digging this, ignore dig
  2148. if(nocheat_p != p_under){
  2149. infostream<<"Server: NoCheat: "<<player->getName()
  2150. <<" started digging "
  2151. <<PP(nocheat_p)<<" and completed digging "
  2152. <<PP(p_under)<<"; not digging."<<std::endl;
  2153. is_valid_dig = false;
  2154. // Call callbacks
  2155. m_script->on_cheat(playersao, "finished_unknown_dig");
  2156. }
  2157. // Get player's wielded item
  2158. ItemStack playeritem;
  2159. InventoryList *mlist = playersao->getInventory()->getList("main");
  2160. if(mlist != NULL)
  2161. playeritem = mlist->getItem(playersao->getWieldIndex());
  2162. ToolCapabilities playeritem_toolcap =
  2163. playeritem.getToolCapabilities(m_itemdef);
  2164. // Get diggability and expected digging time
  2165. DigParams params = getDigParams(m_nodedef->get(n).groups,
  2166. &playeritem_toolcap);
  2167. // If can't dig, try hand
  2168. if(!params.diggable){
  2169. const ItemDefinition &hand = m_itemdef->get("");
  2170. const ToolCapabilities *tp = hand.tool_capabilities;
  2171. if(tp)
  2172. params = getDigParams(m_nodedef->get(n).groups, tp);
  2173. }
  2174. // If can't dig, ignore dig
  2175. if(!params.diggable){
  2176. infostream<<"Server: NoCheat: "<<player->getName()
  2177. <<" completed digging "<<PP(p_under)
  2178. <<", which is not diggable with tool. not digging."
  2179. <<std::endl;
  2180. is_valid_dig = false;
  2181. // Call callbacks
  2182. m_script->on_cheat(playersao, "dug_unbreakable");
  2183. }
  2184. // Check digging time
  2185. // If already invalidated, we don't have to
  2186. if(!is_valid_dig){
  2187. // Well not our problem then
  2188. }
  2189. // Clean and long dig
  2190. else if(params.time > 2.0 && nocheat_t * 1.2 > params.time){
  2191. // All is good, but grab time from pool; don't care if
  2192. // it's actually available
  2193. playersao->getDigPool().grab(params.time);
  2194. }
  2195. // Short or laggy dig
  2196. // Try getting the time from pool
  2197. else if(playersao->getDigPool().grab(params.time)){
  2198. // All is good
  2199. }
  2200. // Dig not possible
  2201. else{
  2202. infostream<<"Server: NoCheat: "<<player->getName()
  2203. <<" completed digging "<<PP(p_under)
  2204. <<"too fast; not digging."<<std::endl;
  2205. is_valid_dig = false;
  2206. // Call callbacks
  2207. m_script->on_cheat(playersao, "dug_too_fast");
  2208. }
  2209. }
  2210. /* Actually dig node */
  2211. if(is_valid_dig && n.getContent() != CONTENT_IGNORE)
  2212. m_script->node_on_dig(p_under, n, playersao);
  2213. v3s16 blockpos = getNodeBlockPos(floatToInt(pointed_pos_under, BS));
  2214. RemoteClient *client = getClient(peer_id);
  2215. // Send unusual result (that is, node not being removed)
  2216. if(m_env->getMap().getNodeNoEx(p_under).getContent() != CONTENT_AIR)
  2217. {
  2218. // Re-send block to revert change on client-side
  2219. client->SetBlockNotSent(blockpos);
  2220. }
  2221. else {
  2222. client->ResendBlockIfOnWire(blockpos);
  2223. }
  2224. }
  2225. } // action == 2
  2226. /*
  2227. 3: place block or right-click object
  2228. */
  2229. else if(action == 3)
  2230. {
  2231. ItemStack item = playersao->getWieldedItem();
  2232. // Reset build time counter
  2233. if(pointed.type == POINTEDTHING_NODE &&
  2234. item.getDefinition(m_itemdef).type == ITEM_NODE)
  2235. getClient(peer_id)->m_time_from_building = 0.0;
  2236. if(pointed.type == POINTEDTHING_OBJECT)
  2237. {
  2238. // Right click object
  2239. // Skip if object has been removed
  2240. if(pointed_object->m_removed)
  2241. return;
  2242. actionstream<<player->getName()<<" right-clicks object "
  2243. <<pointed.object_id<<": "
  2244. <<pointed_object->getDescription()<<std::endl;
  2245. // Do stuff
  2246. pointed_object->rightClick(playersao);
  2247. }
  2248. else if(m_script->item_OnPlace(
  2249. item, playersao, pointed))
  2250. {
  2251. // Placement was handled in lua
  2252. // Apply returned ItemStack
  2253. playersao->setWieldedItem(item);
  2254. }
  2255. // If item has node placement prediction, always send the
  2256. // blocks to make sure the client knows what exactly happened
  2257. RemoteClient *client = getClient(peer_id);
  2258. v3s16 blockpos = getNodeBlockPos(floatToInt(pointed_pos_above, BS));
  2259. v3s16 blockpos2 = getNodeBlockPos(floatToInt(pointed_pos_under, BS));
  2260. if(item.getDefinition(m_itemdef).node_placement_prediction != "") {
  2261. client->SetBlockNotSent(blockpos);
  2262. if(blockpos2 != blockpos) {
  2263. client->SetBlockNotSent(blockpos2);
  2264. }
  2265. }
  2266. else {
  2267. client->ResendBlockIfOnWire(blockpos);
  2268. if(blockpos2 != blockpos) {
  2269. client->ResendBlockIfOnWire(blockpos2);
  2270. }
  2271. }
  2272. } // action == 3
  2273. /*
  2274. 4: use
  2275. */
  2276. else if(action == 4)
  2277. {
  2278. ItemStack item = playersao->getWieldedItem();
  2279. actionstream<<player->getName()<<" uses "<<item.name
  2280. <<", pointing at "<<pointed.dump()<<std::endl;
  2281. if(m_script->item_OnUse(
  2282. item, playersao, pointed))
  2283. {
  2284. // Apply returned ItemStack
  2285. playersao->setWieldedItem(item);
  2286. }
  2287. } // action == 4
  2288. /*
  2289. Catch invalid actions
  2290. */
  2291. else
  2292. {
  2293. infostream<<"WARNING: Server: Invalid action "
  2294. <<action<<std::endl;
  2295. }
  2296. }
  2297. else if(command == TOSERVER_REMOVED_SOUNDS)
  2298. {
  2299. std::string datastring((char*)&data[2], datasize-2);
  2300. std::istringstream is(datastring, std::ios_base::binary);
  2301. int num = readU16(is);
  2302. for(int k=0; k<num; k++){
  2303. s32 id = readS32(is);
  2304. std::map<s32, ServerPlayingSound>::iterator i =
  2305. m_playing_sounds.find(id);
  2306. if(i == m_playing_sounds.end())
  2307. continue;
  2308. ServerPlayingSound &psound = i->second;
  2309. psound.clients.erase(peer_id);
  2310. if(psound.clients.size() == 0)
  2311. m_playing_sounds.erase(i++);
  2312. }
  2313. }
  2314. else if(command == TOSERVER_NODEMETA_FIELDS)
  2315. {
  2316. std::string datastring((char*)&data[2], datasize-2);
  2317. std::istringstream is(datastring, std::ios_base::binary);
  2318. v3s16 p = readV3S16(is);
  2319. std::string formname = deSerializeString(is);
  2320. int num = readU16(is);
  2321. std::map<std::string, std::string> fields;
  2322. for(int k=0; k<num; k++){
  2323. std::string fieldname = deSerializeString(is);
  2324. std::string fieldvalue = deSerializeLongString(is);
  2325. fields[fieldname] = fieldvalue;
  2326. }
  2327. // If something goes wrong, this player is to blame
  2328. RollbackScopeActor rollback_scope(m_rollback,
  2329. std::string("player:")+player->getName());
  2330. // Check the target node for rollback data; leave others unnoticed
  2331. RollbackNode rn_old(&m_env->getMap(), p, this);
  2332. m_script->node_on_receive_fields(p, formname, fields,playersao);
  2333. // Report rollback data
  2334. RollbackNode rn_new(&m_env->getMap(), p, this);
  2335. if(rollback() && rn_new != rn_old){
  2336. RollbackAction action;
  2337. action.setSetNode(p, rn_old, rn_new);
  2338. rollback()->reportAction(action);
  2339. }
  2340. }
  2341. else if(command == TOSERVER_INVENTORY_FIELDS)
  2342. {
  2343. std::string datastring((char*)&data[2], datasize-2);
  2344. std::istringstream is(datastring, std::ios_base::binary);
  2345. std::string formname = deSerializeString(is);
  2346. int num = readU16(is);
  2347. std::map<std::string, std::string> fields;
  2348. for(int k=0; k<num; k++){
  2349. std::string fieldname = deSerializeString(is);
  2350. std::string fieldvalue = deSerializeLongString(is);
  2351. fields[fieldname] = fieldvalue;
  2352. }
  2353. m_script->on_playerReceiveFields(playersao, formname, fields);
  2354. }
  2355. else
  2356. {
  2357. infostream<<"Server::ProcessData(): Ignoring "
  2358. "unknown command "<<command<<std::endl;
  2359. }
  2360. } //try
  2361. catch(SendFailedException &e)
  2362. {
  2363. errorstream<<"Server::ProcessData(): SendFailedException: "
  2364. <<"what="<<e.what()
  2365. <<std::endl;
  2366. }
  2367. }
  2368. void Server::setTimeOfDay(u32 time)
  2369. {
  2370. m_env->setTimeOfDay(time);
  2371. m_time_of_day_send_timer = 0;
  2372. }
  2373. void Server::onMapEditEvent(MapEditEvent *event)
  2374. {
  2375. //infostream<<"Server::onMapEditEvent()"<<std::endl;
  2376. if(m_ignore_map_edit_events)
  2377. return;
  2378. if(m_ignore_map_edit_events_area.contains(event->getArea()))
  2379. return;
  2380. MapEditEvent *e = event->clone();
  2381. m_unsent_map_edit_queue.push_back(e);
  2382. }
  2383. Inventory* Server::getInventory(const InventoryLocation &loc)
  2384. {
  2385. switch(loc.type){
  2386. case InventoryLocation::UNDEFINED:
  2387. {}
  2388. break;
  2389. case InventoryLocation::CURRENT_PLAYER:
  2390. {}
  2391. break;
  2392. case InventoryLocation::PLAYER:
  2393. {
  2394. Player *player = m_env->getPlayer(loc.name.c_str());
  2395. if(!player)
  2396. return NULL;
  2397. PlayerSAO *playersao = player->getPlayerSAO();
  2398. if(!playersao)
  2399. return NULL;
  2400. return playersao->getInventory();
  2401. }
  2402. break;
  2403. case InventoryLocation::NODEMETA:
  2404. {
  2405. NodeMetadata *meta = m_env->getMap().getNodeMetadata(loc.p);
  2406. if(!meta)
  2407. return NULL;
  2408. return meta->getInventory();
  2409. }
  2410. break;
  2411. case InventoryLocation::DETACHED:
  2412. {
  2413. if(m_detached_inventories.count(loc.name) == 0)
  2414. return NULL;
  2415. return m_detached_inventories[loc.name];
  2416. }
  2417. break;
  2418. default:
  2419. assert(0);
  2420. }
  2421. return NULL;
  2422. }
  2423. void Server::setInventoryModified(const InventoryLocation &loc)
  2424. {
  2425. switch(loc.type){
  2426. case InventoryLocation::UNDEFINED:
  2427. {}
  2428. break;
  2429. case InventoryLocation::PLAYER:
  2430. {
  2431. Player *player = m_env->getPlayer(loc.name.c_str());
  2432. if(!player)
  2433. return;
  2434. PlayerSAO *playersao = player->getPlayerSAO();
  2435. if(!playersao)
  2436. return;
  2437. playersao->m_inventory_not_sent = true;
  2438. playersao->m_wielded_item_not_sent = true;
  2439. }
  2440. break;
  2441. case InventoryLocation::NODEMETA:
  2442. {
  2443. v3s16 blockpos = getNodeBlockPos(loc.p);
  2444. MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(blockpos);
  2445. if(block)
  2446. block->raiseModified(MOD_STATE_WRITE_NEEDED);
  2447. setBlockNotSent(blockpos);
  2448. }
  2449. break;
  2450. case InventoryLocation::DETACHED:
  2451. {
  2452. sendDetachedInventory(loc.name,PEER_ID_INEXISTENT);
  2453. }
  2454. break;
  2455. default:
  2456. assert(0);
  2457. }
  2458. }
  2459. void Server::SetBlocksNotSent(std::map<v3s16, MapBlock *>& block)
  2460. {
  2461. std::list<u16> clients = m_clients.getClientIDs();
  2462. m_clients.Lock();
  2463. // Set the modified blocks unsent for all the clients
  2464. for (std::list<u16>::iterator
  2465. i = clients.begin();
  2466. i != clients.end(); ++i) {
  2467. RemoteClient *client = m_clients.lockedGetClientNoEx(*i);
  2468. if (client != NULL)
  2469. client->SetBlocksNotSent(block);
  2470. }
  2471. m_clients.Unlock();
  2472. }
  2473. void Server::peerAdded(con::Peer *peer)
  2474. {
  2475. DSTACK(__FUNCTION_NAME);
  2476. verbosestream<<"Server::peerAdded(): peer->id="
  2477. <<peer->id<<std::endl;
  2478. con::PeerChange c;
  2479. c.type = con::PEER_ADDED;
  2480. c.peer_id = peer->id;
  2481. c.timeout = false;
  2482. m_peer_change_queue.push_back(c);
  2483. }
  2484. void Server::deletingPeer(con::Peer *peer, bool timeout)
  2485. {
  2486. DSTACK(__FUNCTION_NAME);
  2487. verbosestream<<"Server::deletingPeer(): peer->id="
  2488. <<peer->id<<", timeout="<<timeout<<std::endl;
  2489. m_clients.event(peer->id, CSE_Disconnect);
  2490. con::PeerChange c;
  2491. c.type = con::PEER_REMOVED;
  2492. c.peer_id = peer->id;
  2493. c.timeout = timeout;
  2494. m_peer_change_queue.push_back(c);
  2495. }
  2496. bool Server::getClientConInfo(u16 peer_id, con::rtt_stat_type type, float* retval)
  2497. {
  2498. *retval = m_con.getPeerStat(peer_id,type);
  2499. if (*retval == -1) return false;
  2500. return true;
  2501. }
  2502. bool Server::getClientInfo(
  2503. u16 peer_id,
  2504. ClientState* state,
  2505. u32* uptime,
  2506. u8* ser_vers,
  2507. u16* prot_vers,
  2508. u8* major,
  2509. u8* minor,
  2510. u8* patch,
  2511. std::string* vers_string
  2512. )
  2513. {
  2514. *state = m_clients.getClientState(peer_id);
  2515. m_clients.Lock();
  2516. RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_Invalid);
  2517. if (client == NULL) {
  2518. m_clients.Unlock();
  2519. return false;
  2520. }
  2521. *uptime = client->uptime();
  2522. *ser_vers = client->serialization_version;
  2523. *prot_vers = client->net_proto_version;
  2524. *major = client->getMajor();
  2525. *minor = client->getMinor();
  2526. *patch = client->getPatch();
  2527. *vers_string = client->getPatch();
  2528. m_clients.Unlock();
  2529. return true;
  2530. }
  2531. void Server::handlePeerChanges()
  2532. {
  2533. while(m_peer_change_queue.size() > 0)
  2534. {
  2535. con::PeerChange c = m_peer_change_queue.pop_front();
  2536. verbosestream<<"Server: Handling peer change: "
  2537. <<"id="<<c.peer_id<<", timeout="<<c.timeout
  2538. <<std::endl;
  2539. switch(c.type)
  2540. {
  2541. case con::PEER_ADDED:
  2542. m_clients.CreateClient(c.peer_id);
  2543. break;
  2544. case con::PEER_REMOVED:
  2545. DeleteClient(c.peer_id, c.timeout?CDR_TIMEOUT:CDR_LEAVE);
  2546. break;
  2547. default:
  2548. assert("Invalid peer change event received!" == 0);
  2549. break;
  2550. }
  2551. }
  2552. }
  2553. void Server::SendMovement(u16 peer_id)
  2554. {
  2555. DSTACK(__FUNCTION_NAME);
  2556. std::ostringstream os(std::ios_base::binary);
  2557. writeU16(os, TOCLIENT_MOVEMENT);
  2558. writeF1000(os, g_settings->getFloat("movement_acceleration_default"));
  2559. writeF1000(os, g_settings->getFloat("movement_acceleration_air"));
  2560. writeF1000(os, g_settings->getFloat("movement_acceleration_fast"));
  2561. writeF1000(os, g_settings->getFloat("movement_speed_walk"));
  2562. writeF1000(os, g_settings->getFloat("movement_speed_crouch"));
  2563. writeF1000(os, g_settings->getFloat("movement_speed_fast"));
  2564. writeF1000(os, g_settings->getFloat("movement_speed_climb"));
  2565. writeF1000(os, g_settings->getFloat("movement_speed_jump"));
  2566. writeF1000(os, g_settings->getFloat("movement_liquid_fluidity"));
  2567. writeF1000(os, g_settings->getFloat("movement_liquid_fluidity_smooth"));
  2568. writeF1000(os, g_settings->getFloat("movement_liquid_sink"));
  2569. writeF1000(os, g_settings->getFloat("movement_gravity"));
  2570. // Make data buffer
  2571. std::string s = os.str();
  2572. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  2573. // Send as reliable
  2574. m_clients.send(peer_id, 0, data, true);
  2575. }
  2576. void Server::SendHP(u16 peer_id, u8 hp)
  2577. {
  2578. DSTACK(__FUNCTION_NAME);
  2579. std::ostringstream os(std::ios_base::binary);
  2580. writeU16(os, TOCLIENT_HP);
  2581. writeU8(os, hp);
  2582. // Make data buffer
  2583. std::string s = os.str();
  2584. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  2585. // Send as reliable
  2586. m_clients.send(peer_id, 0, data, true);
  2587. }
  2588. void Server::SendBreath(u16 peer_id, u16 breath)
  2589. {
  2590. DSTACK(__FUNCTION_NAME);
  2591. std::ostringstream os(std::ios_base::binary);
  2592. writeU16(os, TOCLIENT_BREATH);
  2593. writeU16(os, breath);
  2594. // Make data buffer
  2595. std::string s = os.str();
  2596. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  2597. // Send as reliable
  2598. m_clients.send(peer_id, 0, data, true);
  2599. }
  2600. void Server::SendAccessDenied(u16 peer_id,const std::wstring &reason)
  2601. {
  2602. DSTACK(__FUNCTION_NAME);
  2603. std::ostringstream os(std::ios_base::binary);
  2604. writeU16(os, TOCLIENT_ACCESS_DENIED);
  2605. os<<serializeWideString(reason);
  2606. // Make data buffer
  2607. std::string s = os.str();
  2608. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  2609. // Send as reliable
  2610. m_clients.send(peer_id, 0, data, true);
  2611. }
  2612. void Server::SendDeathscreen(u16 peer_id,bool set_camera_point_target,
  2613. v3f camera_point_target)
  2614. {
  2615. DSTACK(__FUNCTION_NAME);
  2616. std::ostringstream os(std::ios_base::binary);
  2617. writeU16(os, TOCLIENT_DEATHSCREEN);
  2618. writeU8(os, set_camera_point_target);
  2619. writeV3F1000(os, camera_point_target);
  2620. // Make data buffer
  2621. std::string s = os.str();
  2622. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  2623. // Send as reliable
  2624. m_clients.send(peer_id, 0, data, true);
  2625. }
  2626. void Server::SendItemDef(u16 peer_id,
  2627. IItemDefManager *itemdef, u16 protocol_version)
  2628. {
  2629. DSTACK(__FUNCTION_NAME);
  2630. std::ostringstream os(std::ios_base::binary);
  2631. /*
  2632. u16 command
  2633. u32 length of the next item
  2634. zlib-compressed serialized ItemDefManager
  2635. */
  2636. writeU16(os, TOCLIENT_ITEMDEF);
  2637. std::ostringstream tmp_os(std::ios::binary);
  2638. itemdef->serialize(tmp_os, protocol_version);
  2639. std::ostringstream tmp_os2(std::ios::binary);
  2640. compressZlib(tmp_os.str(), tmp_os2);
  2641. os<<serializeLongString(tmp_os2.str());
  2642. // Make data buffer
  2643. std::string s = os.str();
  2644. verbosestream<<"Server: Sending item definitions to id("<<peer_id
  2645. <<"): size="<<s.size()<<std::endl;
  2646. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  2647. // Send as reliable
  2648. m_clients.send(peer_id, 0, data, true);
  2649. }
  2650. void Server::SendNodeDef(u16 peer_id,
  2651. INodeDefManager *nodedef, u16 protocol_version)
  2652. {
  2653. DSTACK(__FUNCTION_NAME);
  2654. std::ostringstream os(std::ios_base::binary);
  2655. /*
  2656. u16 command
  2657. u32 length of the next item
  2658. zlib-compressed serialized NodeDefManager
  2659. */
  2660. writeU16(os, TOCLIENT_NODEDEF);
  2661. std::ostringstream tmp_os(std::ios::binary);
  2662. nodedef->serialize(tmp_os, protocol_version);
  2663. std::ostringstream tmp_os2(std::ios::binary);
  2664. compressZlib(tmp_os.str(), tmp_os2);
  2665. os<<serializeLongString(tmp_os2.str());
  2666. // Make data buffer
  2667. std::string s = os.str();
  2668. verbosestream<<"Server: Sending node definitions to id("<<peer_id
  2669. <<"): size="<<s.size()<<std::endl;
  2670. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  2671. // Send as reliable
  2672. m_clients.send(peer_id, 0, data, true);
  2673. }
  2674. /*
  2675. Non-static send methods
  2676. */
  2677. void Server::SendInventory(u16 peer_id)
  2678. {
  2679. DSTACK(__FUNCTION_NAME);
  2680. PlayerSAO *playersao = getPlayerSAO(peer_id);
  2681. assert(playersao);
  2682. playersao->m_inventory_not_sent = false;
  2683. /*
  2684. Serialize it
  2685. */
  2686. std::ostringstream os;
  2687. playersao->getInventory()->serialize(os);
  2688. std::string s = os.str();
  2689. SharedBuffer<u8> data(s.size()+2);
  2690. writeU16(&data[0], TOCLIENT_INVENTORY);
  2691. memcpy(&data[2], s.c_str(), s.size());
  2692. // Send as reliable
  2693. m_clients.send(peer_id, 0, data, true);
  2694. }
  2695. void Server::SendChatMessage(u16 peer_id, const std::wstring &message)
  2696. {
  2697. DSTACK(__FUNCTION_NAME);
  2698. std::ostringstream os(std::ios_base::binary);
  2699. u8 buf[12];
  2700. // Write command
  2701. writeU16(buf, TOCLIENT_CHAT_MESSAGE);
  2702. os.write((char*)buf, 2);
  2703. // Write length
  2704. writeU16(buf, message.size());
  2705. os.write((char*)buf, 2);
  2706. // Write string
  2707. for(u32 i=0; i<message.size(); i++)
  2708. {
  2709. u16 w = message[i];
  2710. writeU16(buf, w);
  2711. os.write((char*)buf, 2);
  2712. }
  2713. // Make data buffer
  2714. std::string s = os.str();
  2715. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  2716. if (peer_id != PEER_ID_INEXISTENT)
  2717. {
  2718. // Send as reliable
  2719. m_clients.send(peer_id, 0, data, true);
  2720. }
  2721. else
  2722. {
  2723. m_clients.sendToAll(0,data,true);
  2724. }
  2725. }
  2726. void Server::SendShowFormspecMessage(u16 peer_id, const std::string &formspec,
  2727. const std::string &formname)
  2728. {
  2729. DSTACK(__FUNCTION_NAME);
  2730. std::ostringstream os(std::ios_base::binary);
  2731. u8 buf[12];
  2732. // Write command
  2733. writeU16(buf, TOCLIENT_SHOW_FORMSPEC);
  2734. os.write((char*)buf, 2);
  2735. os<<serializeLongString(FORMSPEC_VERSION_STRING + formspec);
  2736. os<<serializeString(formname);
  2737. // Make data buffer
  2738. std::string s = os.str();
  2739. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  2740. // Send as reliable
  2741. m_clients.send(peer_id, 0, data, true);
  2742. }
  2743. // Spawns a particle on peer with peer_id
  2744. void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f acceleration,
  2745. float expirationtime, float size, bool collisiondetection,
  2746. bool vertical, std::string texture)
  2747. {
  2748. DSTACK(__FUNCTION_NAME);
  2749. std::ostringstream os(std::ios_base::binary);
  2750. writeU16(os, TOCLIENT_SPAWN_PARTICLE);
  2751. writeV3F1000(os, pos);
  2752. writeV3F1000(os, velocity);
  2753. writeV3F1000(os, acceleration);
  2754. writeF1000(os, expirationtime);
  2755. writeF1000(os, size);
  2756. writeU8(os, collisiondetection);
  2757. os<<serializeLongString(texture);
  2758. writeU8(os, vertical);
  2759. // Make data buffer
  2760. std::string s = os.str();
  2761. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  2762. if (peer_id != PEER_ID_INEXISTENT)
  2763. {
  2764. // Send as reliable
  2765. m_clients.send(peer_id, 0, data, true);
  2766. }
  2767. else
  2768. {
  2769. m_clients.sendToAll(0,data,true);
  2770. }
  2771. }
  2772. // Adds a ParticleSpawner on peer with peer_id
  2773. void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3f minpos, v3f maxpos,
  2774. v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime,
  2775. float minsize, float maxsize, bool collisiondetection, bool vertical, std::string texture, u32 id)
  2776. {
  2777. DSTACK(__FUNCTION_NAME);
  2778. std::ostringstream os(std::ios_base::binary);
  2779. writeU16(os, TOCLIENT_ADD_PARTICLESPAWNER);
  2780. writeU16(os, amount);
  2781. writeF1000(os, spawntime);
  2782. writeV3F1000(os, minpos);
  2783. writeV3F1000(os, maxpos);
  2784. writeV3F1000(os, minvel);
  2785. writeV3F1000(os, maxvel);
  2786. writeV3F1000(os, minacc);
  2787. writeV3F1000(os, maxacc);
  2788. writeF1000(os, minexptime);
  2789. writeF1000(os, maxexptime);
  2790. writeF1000(os, minsize);
  2791. writeF1000(os, maxsize);
  2792. writeU8(os, collisiondetection);
  2793. os<<serializeLongString(texture);
  2794. writeU32(os, id);
  2795. writeU8(os, vertical);
  2796. // Make data buffer
  2797. std::string s = os.str();
  2798. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  2799. if (peer_id != PEER_ID_INEXISTENT)
  2800. {
  2801. // Send as reliable
  2802. m_clients.send(peer_id, 0, data, true);
  2803. }
  2804. else {
  2805. m_clients.sendToAll(0,data,true);
  2806. }
  2807. }
  2808. void Server::SendDeleteParticleSpawner(u16 peer_id, u32 id)
  2809. {
  2810. DSTACK(__FUNCTION_NAME);
  2811. std::ostringstream os(std::ios_base::binary);
  2812. writeU16(os, TOCLIENT_DELETE_PARTICLESPAWNER);
  2813. writeU16(os, id);
  2814. // Make data buffer
  2815. std::string s = os.str();
  2816. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  2817. if (peer_id != PEER_ID_INEXISTENT) {
  2818. // Send as reliable
  2819. m_clients.send(peer_id, 0, data, true);
  2820. }
  2821. else {
  2822. m_clients.sendToAll(0,data,true);
  2823. }
  2824. }
  2825. void Server::SendHUDAdd(u16 peer_id, u32 id, HudElement *form)
  2826. {
  2827. std::ostringstream os(std::ios_base::binary);
  2828. // Write command
  2829. writeU16(os, TOCLIENT_HUDADD);
  2830. writeU32(os, id);
  2831. writeU8(os, (u8)form->type);
  2832. writeV2F1000(os, form->pos);
  2833. os << serializeString(form->name);
  2834. writeV2F1000(os, form->scale);
  2835. os << serializeString(form->text);
  2836. writeU32(os, form->number);
  2837. writeU32(os, form->item);
  2838. writeU32(os, form->dir);
  2839. writeV2F1000(os, form->align);
  2840. writeV2F1000(os, form->offset);
  2841. writeV3F1000(os, form->world_pos);
  2842. writeV2S32(os,form->size);
  2843. // Make data buffer
  2844. std::string s = os.str();
  2845. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  2846. // Send as reliable
  2847. m_clients.send(peer_id, 1, data, true);
  2848. }
  2849. void Server::SendHUDRemove(u16 peer_id, u32 id)
  2850. {
  2851. std::ostringstream os(std::ios_base::binary);
  2852. // Write command
  2853. writeU16(os, TOCLIENT_HUDRM);
  2854. writeU32(os, id);
  2855. // Make data buffer
  2856. std::string s = os.str();
  2857. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  2858. // Send as reliable
  2859. m_clients.send(peer_id, 1, data, true);
  2860. }
  2861. void Server::SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value)
  2862. {
  2863. std::ostringstream os(std::ios_base::binary);
  2864. // Write command
  2865. writeU16(os, TOCLIENT_HUDCHANGE);
  2866. writeU32(os, id);
  2867. writeU8(os, (u8)stat);
  2868. switch (stat) {
  2869. case HUD_STAT_POS:
  2870. case HUD_STAT_SCALE:
  2871. case HUD_STAT_ALIGN:
  2872. case HUD_STAT_OFFSET:
  2873. writeV2F1000(os, *(v2f *)value);
  2874. break;
  2875. case HUD_STAT_NAME:
  2876. case HUD_STAT_TEXT:
  2877. os << serializeString(*(std::string *)value);
  2878. break;
  2879. case HUD_STAT_WORLD_POS:
  2880. writeV3F1000(os, *(v3f *)value);
  2881. break;
  2882. case HUD_STAT_SIZE:
  2883. writeV2S32(os,*(v2s32 *)value);
  2884. break;
  2885. case HUD_STAT_NUMBER:
  2886. case HUD_STAT_ITEM:
  2887. case HUD_STAT_DIR:
  2888. default:
  2889. writeU32(os, *(u32 *)value);
  2890. break;
  2891. }
  2892. // Make data buffer
  2893. std::string s = os.str();
  2894. SharedBuffer<u8> data((u8 *)s.c_str(), s.size());
  2895. // Send as reliable
  2896. m_clients.send(peer_id, 0, data, true);
  2897. }
  2898. void Server::SendHUDSetFlags(u16 peer_id, u32 flags, u32 mask)
  2899. {
  2900. std::ostringstream os(std::ios_base::binary);
  2901. // Write command
  2902. writeU16(os, TOCLIENT_HUD_SET_FLAGS);
  2903. //////////////////////////// compatibility code to be removed //////////////
  2904. flags &= ~(HUD_FLAG_HEALTHBAR_VISIBLE | HUD_FLAG_BREATHBAR_VISIBLE);
  2905. ////////////////////////////////////////////////////////////////////////////
  2906. writeU32(os, flags);
  2907. writeU32(os, mask);
  2908. // Make data buffer
  2909. std::string s = os.str();
  2910. SharedBuffer<u8> data((u8 *)s.c_str(), s.size());
  2911. // Send as reliable
  2912. m_clients.send(peer_id, 0, data, true);
  2913. }
  2914. void Server::SendHUDSetParam(u16 peer_id, u16 param, const std::string &value)
  2915. {
  2916. std::ostringstream os(std::ios_base::binary);
  2917. // Write command
  2918. writeU16(os, TOCLIENT_HUD_SET_PARAM);
  2919. writeU16(os, param);
  2920. os<<serializeString(value);
  2921. // Make data buffer
  2922. std::string s = os.str();
  2923. SharedBuffer<u8> data((u8 *)s.c_str(), s.size());
  2924. // Send as reliable
  2925. m_clients.send(peer_id, 0, data, true);
  2926. }
  2927. void Server::SendSetSky(u16 peer_id, const video::SColor &bgcolor,
  2928. const std::string &type, const std::vector<std::string> &params)
  2929. {
  2930. std::ostringstream os(std::ios_base::binary);
  2931. // Write command
  2932. writeU16(os, TOCLIENT_SET_SKY);
  2933. writeARGB8(os, bgcolor);
  2934. os<<serializeString(type);
  2935. writeU16(os, params.size());
  2936. for(size_t i=0; i<params.size(); i++)
  2937. os<<serializeString(params[i]);
  2938. // Make data buffer
  2939. std::string s = os.str();
  2940. SharedBuffer<u8> data((u8 *)s.c_str(), s.size());
  2941. // Send as reliable
  2942. m_clients.send(peer_id, 0, data, true);
  2943. }
  2944. void Server::SendOverrideDayNightRatio(u16 peer_id, bool do_override,
  2945. float ratio)
  2946. {
  2947. std::ostringstream os(std::ios_base::binary);
  2948. // Write command
  2949. writeU16(os, TOCLIENT_OVERRIDE_DAY_NIGHT_RATIO);
  2950. writeU8(os, do_override);
  2951. writeU16(os, ratio*65535);
  2952. // Make data buffer
  2953. std::string s = os.str();
  2954. SharedBuffer<u8> data((u8 *)s.c_str(), s.size());
  2955. // Send as reliable
  2956. m_clients.send(peer_id, 0, data, true);
  2957. }
  2958. void Server::SendTimeOfDay(u16 peer_id, u16 time, f32 time_speed)
  2959. {
  2960. DSTACK(__FUNCTION_NAME);
  2961. // Make packet
  2962. SharedBuffer<u8> data(2+2+4);
  2963. writeU16(&data[0], TOCLIENT_TIME_OF_DAY);
  2964. writeU16(&data[2], time);
  2965. writeF1000(&data[4], time_speed);
  2966. if (peer_id == PEER_ID_INEXISTENT) {
  2967. m_clients.sendToAll(0,data,true);
  2968. }
  2969. else {
  2970. // Send as reliable
  2971. m_clients.send(peer_id, 0, data, true);
  2972. }
  2973. }
  2974. void Server::SendPlayerHP(u16 peer_id)
  2975. {
  2976. DSTACK(__FUNCTION_NAME);
  2977. PlayerSAO *playersao = getPlayerSAO(peer_id);
  2978. assert(playersao);
  2979. playersao->m_hp_not_sent = false;
  2980. SendHP(peer_id, playersao->getHP());
  2981. m_script->player_event(playersao,"health_changed");
  2982. // Send to other clients
  2983. std::string str = gob_cmd_punched(playersao->readDamage(), playersao->getHP());
  2984. ActiveObjectMessage aom(playersao->getId(), true, str);
  2985. playersao->m_messages_out.push_back(aom);
  2986. }
  2987. void Server::SendPlayerBreath(u16 peer_id)
  2988. {
  2989. DSTACK(__FUNCTION_NAME);
  2990. PlayerSAO *playersao = getPlayerSAO(peer_id);
  2991. assert(playersao);
  2992. playersao->m_breath_not_sent = false;
  2993. m_script->player_event(playersao,"breath_changed");
  2994. SendBreath(peer_id, playersao->getBreath());
  2995. }
  2996. void Server::SendMovePlayer(u16 peer_id)
  2997. {
  2998. DSTACK(__FUNCTION_NAME);
  2999. Player *player = m_env->getPlayer(peer_id);
  3000. assert(player);
  3001. std::ostringstream os(std::ios_base::binary);
  3002. writeU16(os, TOCLIENT_MOVE_PLAYER);
  3003. writeV3F1000(os, player->getPosition());
  3004. writeF1000(os, player->getPitch());
  3005. writeF1000(os, player->getYaw());
  3006. {
  3007. v3f pos = player->getPosition();
  3008. f32 pitch = player->getPitch();
  3009. f32 yaw = player->getYaw();
  3010. verbosestream<<"Server: Sending TOCLIENT_MOVE_PLAYER"
  3011. <<" pos=("<<pos.X<<","<<pos.Y<<","<<pos.Z<<")"
  3012. <<" pitch="<<pitch
  3013. <<" yaw="<<yaw
  3014. <<std::endl;
  3015. }
  3016. // Make data buffer
  3017. std::string s = os.str();
  3018. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  3019. // Send as reliable
  3020. m_clients.send(peer_id, 0, data, true);
  3021. }
  3022. void Server::SendLocalPlayerAnimations(u16 peer_id, v2s32 animation_frames[4], f32 animation_speed)
  3023. {
  3024. std::ostringstream os(std::ios_base::binary);
  3025. writeU16(os, TOCLIENT_LOCAL_PLAYER_ANIMATIONS);
  3026. writeV2S32(os, animation_frames[0]);
  3027. writeV2S32(os, animation_frames[1]);
  3028. writeV2S32(os, animation_frames[2]);
  3029. writeV2S32(os, animation_frames[3]);
  3030. writeF1000(os, animation_speed);
  3031. // Make data buffer
  3032. std::string s = os.str();
  3033. SharedBuffer<u8> data((u8 *)s.c_str(), s.size());
  3034. // Send as reliable
  3035. m_clients.send(peer_id, 0, data, true);
  3036. }
  3037. void Server::SendEyeOffset(u16 peer_id, v3f first, v3f third)
  3038. {
  3039. std::ostringstream os(std::ios_base::binary);
  3040. writeU16(os, TOCLIENT_EYE_OFFSET);
  3041. writeV3F1000(os, first);
  3042. writeV3F1000(os, third);
  3043. // Make data buffer
  3044. std::string s = os.str();
  3045. SharedBuffer<u8> data((u8 *)s.c_str(), s.size());
  3046. // Send as reliable
  3047. m_clients.send(peer_id, 0, data, true);
  3048. }
  3049. void Server::SendPlayerPrivileges(u16 peer_id)
  3050. {
  3051. Player *player = m_env->getPlayer(peer_id);
  3052. assert(player);
  3053. if(player->peer_id == PEER_ID_INEXISTENT)
  3054. return;
  3055. std::set<std::string> privs;
  3056. m_script->getAuth(player->getName(), NULL, &privs);
  3057. std::ostringstream os(std::ios_base::binary);
  3058. writeU16(os, TOCLIENT_PRIVILEGES);
  3059. writeU16(os, privs.size());
  3060. for(std::set<std::string>::const_iterator i = privs.begin();
  3061. i != privs.end(); i++){
  3062. os<<serializeString(*i);
  3063. }
  3064. // Make data buffer
  3065. std::string s = os.str();
  3066. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  3067. // Send as reliable
  3068. m_clients.send(peer_id, 0, data, true);
  3069. }
  3070. void Server::SendPlayerInventoryFormspec(u16 peer_id)
  3071. {
  3072. Player *player = m_env->getPlayer(peer_id);
  3073. assert(player);
  3074. if(player->peer_id == PEER_ID_INEXISTENT)
  3075. return;
  3076. std::ostringstream os(std::ios_base::binary);
  3077. writeU16(os, TOCLIENT_INVENTORY_FORMSPEC);
  3078. os<<serializeLongString(FORMSPEC_VERSION_STRING + player->inventory_formspec);
  3079. // Make data buffer
  3080. std::string s = os.str();
  3081. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  3082. // Send as reliable
  3083. m_clients.send(peer_id, 0, data, true);
  3084. }
  3085. s32 Server::playSound(const SimpleSoundSpec &spec,
  3086. const ServerSoundParams &params)
  3087. {
  3088. // Find out initial position of sound
  3089. bool pos_exists = false;
  3090. v3f pos = params.getPos(m_env, &pos_exists);
  3091. // If position is not found while it should be, cancel sound
  3092. if(pos_exists != (params.type != ServerSoundParams::SSP_LOCAL))
  3093. return -1;
  3094. // Filter destination clients
  3095. std::list<u16> dst_clients;
  3096. if(params.to_player != "")
  3097. {
  3098. Player *player = m_env->getPlayer(params.to_player.c_str());
  3099. if(!player){
  3100. infostream<<"Server::playSound: Player \""<<params.to_player
  3101. <<"\" not found"<<std::endl;
  3102. return -1;
  3103. }
  3104. if(player->peer_id == PEER_ID_INEXISTENT){
  3105. infostream<<"Server::playSound: Player \""<<params.to_player
  3106. <<"\" not connected"<<std::endl;
  3107. return -1;
  3108. }
  3109. dst_clients.push_back(player->peer_id);
  3110. }
  3111. else
  3112. {
  3113. std::list<u16> clients = m_clients.getClientIDs();
  3114. for(std::list<u16>::iterator
  3115. i = clients.begin(); i != clients.end(); ++i)
  3116. {
  3117. Player *player = m_env->getPlayer(*i);
  3118. if(!player)
  3119. continue;
  3120. if(pos_exists){
  3121. if(player->getPosition().getDistanceFrom(pos) >
  3122. params.max_hear_distance)
  3123. continue;
  3124. }
  3125. dst_clients.push_back(*i);
  3126. }
  3127. }
  3128. if(dst_clients.size() == 0)
  3129. return -1;
  3130. // Create the sound
  3131. s32 id = m_next_sound_id++;
  3132. // The sound will exist as a reference in m_playing_sounds
  3133. m_playing_sounds[id] = ServerPlayingSound();
  3134. ServerPlayingSound &psound = m_playing_sounds[id];
  3135. psound.params = params;
  3136. for(std::list<u16>::iterator i = dst_clients.begin();
  3137. i != dst_clients.end(); i++)
  3138. psound.clients.insert(*i);
  3139. // Create packet
  3140. std::ostringstream os(std::ios_base::binary);
  3141. writeU16(os, TOCLIENT_PLAY_SOUND);
  3142. writeS32(os, id);
  3143. os<<serializeString(spec.name);
  3144. writeF1000(os, spec.gain * params.gain);
  3145. writeU8(os, params.type);
  3146. writeV3F1000(os, pos);
  3147. writeU16(os, params.object);
  3148. writeU8(os, params.loop);
  3149. // Make data buffer
  3150. std::string s = os.str();
  3151. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  3152. // Send
  3153. for(std::list<u16>::iterator i = dst_clients.begin();
  3154. i != dst_clients.end(); i++){
  3155. // Send as reliable
  3156. m_clients.send(*i, 0, data, true);
  3157. }
  3158. return id;
  3159. }
  3160. void Server::stopSound(s32 handle)
  3161. {
  3162. // Get sound reference
  3163. std::map<s32, ServerPlayingSound>::iterator i =
  3164. m_playing_sounds.find(handle);
  3165. if(i == m_playing_sounds.end())
  3166. return;
  3167. ServerPlayingSound &psound = i->second;
  3168. // Create packet
  3169. std::ostringstream os(std::ios_base::binary);
  3170. writeU16(os, TOCLIENT_STOP_SOUND);
  3171. writeS32(os, handle);
  3172. // Make data buffer
  3173. std::string s = os.str();
  3174. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  3175. // Send
  3176. for(std::set<u16>::iterator i = psound.clients.begin();
  3177. i != psound.clients.end(); i++){
  3178. // Send as reliable
  3179. m_clients.send(*i, 0, data, true);
  3180. }
  3181. // Remove sound reference
  3182. m_playing_sounds.erase(i);
  3183. }
  3184. void Server::sendRemoveNode(v3s16 p, u16 ignore_id,
  3185. std::list<u16> *far_players, float far_d_nodes)
  3186. {
  3187. float maxd = far_d_nodes*BS;
  3188. v3f p_f = intToFloat(p, BS);
  3189. // Create packet
  3190. u32 replysize = 8;
  3191. SharedBuffer<u8> reply(replysize);
  3192. writeU16(&reply[0], TOCLIENT_REMOVENODE);
  3193. writeS16(&reply[2], p.X);
  3194. writeS16(&reply[4], p.Y);
  3195. writeS16(&reply[6], p.Z);
  3196. std::list<u16> clients = m_clients.getClientIDs();
  3197. for(std::list<u16>::iterator
  3198. i = clients.begin();
  3199. i != clients.end(); ++i)
  3200. {
  3201. if(far_players)
  3202. {
  3203. // Get player
  3204. Player *player = m_env->getPlayer(*i);
  3205. if(player)
  3206. {
  3207. // If player is far away, only set modified blocks not sent
  3208. v3f player_pos = player->getPosition();
  3209. if(player_pos.getDistanceFrom(p_f) > maxd)
  3210. {
  3211. far_players->push_back(*i);
  3212. continue;
  3213. }
  3214. }
  3215. }
  3216. // Send as reliable
  3217. m_clients.send(*i, 0, reply, true);
  3218. }
  3219. }
  3220. void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id,
  3221. std::list<u16> *far_players, float far_d_nodes,
  3222. bool remove_metadata)
  3223. {
  3224. float maxd = far_d_nodes*BS;
  3225. v3f p_f = intToFloat(p, BS);
  3226. std::list<u16> clients = m_clients.getClientIDs();
  3227. for(std::list<u16>::iterator
  3228. i = clients.begin();
  3229. i != clients.end(); ++i)
  3230. {
  3231. if(far_players)
  3232. {
  3233. // Get player
  3234. Player *player = m_env->getPlayer(*i);
  3235. if(player)
  3236. {
  3237. // If player is far away, only set modified blocks not sent
  3238. v3f player_pos = player->getPosition();
  3239. if(player_pos.getDistanceFrom(p_f) > maxd)
  3240. {
  3241. far_players->push_back(*i);
  3242. continue;
  3243. }
  3244. }
  3245. }
  3246. SharedBuffer<u8> reply(0);
  3247. m_clients.Lock();
  3248. RemoteClient* client = m_clients.lockedGetClientNoEx(*i);
  3249. if (client != 0)
  3250. {
  3251. // Create packet
  3252. u32 replysize = 9 + MapNode::serializedLength(client->serialization_version);
  3253. reply = SharedBuffer<u8>(replysize);
  3254. writeU16(&reply[0], TOCLIENT_ADDNODE);
  3255. writeS16(&reply[2], p.X);
  3256. writeS16(&reply[4], p.Y);
  3257. writeS16(&reply[6], p.Z);
  3258. n.serialize(&reply[8], client->serialization_version);
  3259. u32 index = 8 + MapNode::serializedLength(client->serialization_version);
  3260. writeU8(&reply[index], remove_metadata ? 0 : 1);
  3261. if (!remove_metadata) {
  3262. if (client->net_proto_version <= 21) {
  3263. // Old clients always clear metadata; fix it
  3264. // by sending the full block again.
  3265. client->SetBlockNotSent(p);
  3266. }
  3267. }
  3268. }
  3269. m_clients.Unlock();
  3270. // Send as reliable
  3271. if (reply.getSize() > 0)
  3272. m_clients.send(*i, 0, reply, true);
  3273. }
  3274. }
  3275. void Server::setBlockNotSent(v3s16 p)
  3276. {
  3277. std::list<u16> clients = m_clients.getClientIDs();
  3278. m_clients.Lock();
  3279. for(std::list<u16>::iterator
  3280. i = clients.begin();
  3281. i != clients.end(); ++i)
  3282. {
  3283. RemoteClient *client = m_clients.lockedGetClientNoEx(*i);
  3284. client->SetBlockNotSent(p);
  3285. }
  3286. m_clients.Unlock();
  3287. }
  3288. void Server::SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver, u16 net_proto_version)
  3289. {
  3290. DSTACK(__FUNCTION_NAME);
  3291. v3s16 p = block->getPos();
  3292. #if 0
  3293. // Analyze it a bit
  3294. bool completely_air = true;
  3295. for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
  3296. for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
  3297. for(s16 y0=0; y0<MAP_BLOCKSIZE; y0++)
  3298. {
  3299. if(block->getNodeNoEx(v3s16(x0,y0,z0)).d != CONTENT_AIR)
  3300. {
  3301. completely_air = false;
  3302. x0 = y0 = z0 = MAP_BLOCKSIZE; // Break out
  3303. }
  3304. }
  3305. // Print result
  3306. infostream<<"Server: Sending block ("<<p.X<<","<<p.Y<<","<<p.Z<<"): ";
  3307. if(completely_air)
  3308. infostream<<"[completely air] ";
  3309. infostream<<std::endl;
  3310. #endif
  3311. /*
  3312. Create a packet with the block in the right format
  3313. */
  3314. std::ostringstream os(std::ios_base::binary);
  3315. block->serialize(os, ver, false);
  3316. block->serializeNetworkSpecific(os, net_proto_version);
  3317. std::string s = os.str();
  3318. SharedBuffer<u8> blockdata((u8*)s.c_str(), s.size());
  3319. u32 replysize = 8 + blockdata.getSize();
  3320. SharedBuffer<u8> reply(replysize);
  3321. writeU16(&reply[0], TOCLIENT_BLOCKDATA);
  3322. writeS16(&reply[2], p.X);
  3323. writeS16(&reply[4], p.Y);
  3324. writeS16(&reply[6], p.Z);
  3325. memcpy(&reply[8], *blockdata, blockdata.getSize());
  3326. /*infostream<<"Server: Sending block ("<<p.X<<","<<p.Y<<","<<p.Z<<")"
  3327. <<": \tpacket size: "<<replysize<<std::endl;*/
  3328. /*
  3329. Send packet
  3330. */
  3331. m_clients.send(peer_id, 2, reply, true);
  3332. }
  3333. void Server::SendBlocks(float dtime)
  3334. {
  3335. DSTACK(__FUNCTION_NAME);
  3336. JMutexAutoLock envlock(m_env_mutex);
  3337. //TODO check if one big lock could be faster then multiple small ones
  3338. ScopeProfiler sp(g_profiler, "Server: sel and send blocks to clients");
  3339. std::vector<PrioritySortedBlockTransfer> queue;
  3340. s32 total_sending = 0;
  3341. {
  3342. ScopeProfiler sp(g_profiler, "Server: selecting blocks for sending");
  3343. std::list<u16> clients = m_clients.getClientIDs();
  3344. m_clients.Lock();
  3345. for(std::list<u16>::iterator
  3346. i = clients.begin();
  3347. i != clients.end(); ++i)
  3348. {
  3349. RemoteClient *client = m_clients.lockedGetClientNoEx(*i, CS_Active);
  3350. if (client == NULL)
  3351. return;
  3352. total_sending += client->SendingCount();
  3353. client->GetNextBlocks(m_env,m_emerge, dtime, queue);
  3354. }
  3355. m_clients.Unlock();
  3356. }
  3357. // Sort.
  3358. // Lowest priority number comes first.
  3359. // Lowest is most important.
  3360. std::sort(queue.begin(), queue.end());
  3361. m_clients.Lock();
  3362. for(u32 i=0; i<queue.size(); i++)
  3363. {
  3364. //TODO: Calculate limit dynamically
  3365. if(total_sending >= g_settings->getS32
  3366. ("max_simultaneous_block_sends_server_total"))
  3367. break;
  3368. PrioritySortedBlockTransfer q = queue[i];
  3369. MapBlock *block = NULL;
  3370. try
  3371. {
  3372. block = m_env->getMap().getBlockNoCreate(q.pos);
  3373. }
  3374. catch(InvalidPositionException &e)
  3375. {
  3376. continue;
  3377. }
  3378. RemoteClient *client = m_clients.lockedGetClientNoEx(q.peer_id, CS_Active);
  3379. if(!client)
  3380. continue;
  3381. SendBlockNoLock(q.peer_id, block, client->serialization_version, client->net_proto_version);
  3382. client->SentBlock(q.pos);
  3383. total_sending++;
  3384. }
  3385. m_clients.Unlock();
  3386. }
  3387. void Server::fillMediaCache()
  3388. {
  3389. DSTACK(__FUNCTION_NAME);
  3390. infostream<<"Server: Calculating media file checksums"<<std::endl;
  3391. // Collect all media file paths
  3392. std::list<std::string> paths;
  3393. for(std::vector<ModSpec>::iterator i = m_mods.begin();
  3394. i != m_mods.end(); i++){
  3395. const ModSpec &mod = *i;
  3396. paths.push_back(mod.path + DIR_DELIM + "textures");
  3397. paths.push_back(mod.path + DIR_DELIM + "sounds");
  3398. paths.push_back(mod.path + DIR_DELIM + "media");
  3399. paths.push_back(mod.path + DIR_DELIM + "models");
  3400. }
  3401. paths.push_back(porting::path_user + DIR_DELIM + "textures" + DIR_DELIM + "server");
  3402. // Collect media file information from paths into cache
  3403. for(std::list<std::string>::iterator i = paths.begin();
  3404. i != paths.end(); i++)
  3405. {
  3406. std::string mediapath = *i;
  3407. std::vector<fs::DirListNode> dirlist = fs::GetDirListing(mediapath);
  3408. for(u32 j=0; j<dirlist.size(); j++){
  3409. if(dirlist[j].dir) // Ignode dirs
  3410. continue;
  3411. std::string filename = dirlist[j].name;
  3412. // If name contains illegal characters, ignore the file
  3413. if(!string_allowed(filename, TEXTURENAME_ALLOWED_CHARS)){
  3414. infostream<<"Server: ignoring illegal file name: \""
  3415. <<filename<<"\""<<std::endl;
  3416. continue;
  3417. }
  3418. // If name is not in a supported format, ignore it
  3419. const char *supported_ext[] = {
  3420. ".png", ".jpg", ".bmp", ".tga",
  3421. ".pcx", ".ppm", ".psd", ".wal", ".rgb",
  3422. ".ogg",
  3423. ".x", ".b3d", ".md2", ".obj",
  3424. NULL
  3425. };
  3426. if(removeStringEnd(filename, supported_ext) == ""){
  3427. infostream<<"Server: ignoring unsupported file extension: \""
  3428. <<filename<<"\""<<std::endl;
  3429. continue;
  3430. }
  3431. // Ok, attempt to load the file and add to cache
  3432. std::string filepath = mediapath + DIR_DELIM + filename;
  3433. // Read data
  3434. std::ifstream fis(filepath.c_str(), std::ios_base::binary);
  3435. if(fis.good() == false){
  3436. errorstream<<"Server::fillMediaCache(): Could not open \""
  3437. <<filename<<"\" for reading"<<std::endl;
  3438. continue;
  3439. }
  3440. std::ostringstream tmp_os(std::ios_base::binary);
  3441. bool bad = false;
  3442. for(;;){
  3443. char buf[1024];
  3444. fis.read(buf, 1024);
  3445. std::streamsize len = fis.gcount();
  3446. tmp_os.write(buf, len);
  3447. if(fis.eof())
  3448. break;
  3449. if(!fis.good()){
  3450. bad = true;
  3451. break;
  3452. }
  3453. }
  3454. if(bad){
  3455. errorstream<<"Server::fillMediaCache(): Failed to read \""
  3456. <<filename<<"\""<<std::endl;
  3457. continue;
  3458. }
  3459. if(tmp_os.str().length() == 0){
  3460. errorstream<<"Server::fillMediaCache(): Empty file \""
  3461. <<filepath<<"\""<<std::endl;
  3462. continue;
  3463. }
  3464. SHA1 sha1;
  3465. sha1.addBytes(tmp_os.str().c_str(), tmp_os.str().length());
  3466. unsigned char *digest = sha1.getDigest();
  3467. std::string sha1_base64 = base64_encode(digest, 20);
  3468. std::string sha1_hex = hex_encode((char*)digest, 20);
  3469. free(digest);
  3470. // Put in list
  3471. this->m_media[filename] = MediaInfo(filepath, sha1_base64);
  3472. verbosestream<<"Server: "<<sha1_hex<<" is "<<filename<<std::endl;
  3473. }
  3474. }
  3475. }
  3476. struct SendableMediaAnnouncement
  3477. {
  3478. std::string name;
  3479. std::string sha1_digest;
  3480. SendableMediaAnnouncement(const std::string &name_="",
  3481. const std::string &sha1_digest_=""):
  3482. name(name_),
  3483. sha1_digest(sha1_digest_)
  3484. {}
  3485. };
  3486. void Server::sendMediaAnnouncement(u16 peer_id)
  3487. {
  3488. DSTACK(__FUNCTION_NAME);
  3489. verbosestream<<"Server: Announcing files to id("<<peer_id<<")"
  3490. <<std::endl;
  3491. std::list<SendableMediaAnnouncement> file_announcements;
  3492. for(std::map<std::string, MediaInfo>::iterator i = m_media.begin();
  3493. i != m_media.end(); i++){
  3494. // Put in list
  3495. file_announcements.push_back(
  3496. SendableMediaAnnouncement(i->first, i->second.sha1_digest));
  3497. }
  3498. // Make packet
  3499. std::ostringstream os(std::ios_base::binary);
  3500. /*
  3501. u16 command
  3502. u32 number of files
  3503. for each texture {
  3504. u16 length of name
  3505. string name
  3506. u16 length of sha1_digest
  3507. string sha1_digest
  3508. }
  3509. */
  3510. writeU16(os, TOCLIENT_ANNOUNCE_MEDIA);
  3511. writeU16(os, file_announcements.size());
  3512. for(std::list<SendableMediaAnnouncement>::iterator
  3513. j = file_announcements.begin();
  3514. j != file_announcements.end(); ++j){
  3515. os<<serializeString(j->name);
  3516. os<<serializeString(j->sha1_digest);
  3517. }
  3518. os<<serializeString(g_settings->get("remote_media"));
  3519. // Make data buffer
  3520. std::string s = os.str();
  3521. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  3522. // Send as reliable
  3523. m_clients.send(peer_id, 0, data, true);
  3524. }
  3525. struct SendableMedia
  3526. {
  3527. std::string name;
  3528. std::string path;
  3529. std::string data;
  3530. SendableMedia(const std::string &name_="", const std::string &path_="",
  3531. const std::string &data_=""):
  3532. name(name_),
  3533. path(path_),
  3534. data(data_)
  3535. {}
  3536. };
  3537. void Server::sendRequestedMedia(u16 peer_id,
  3538. const std::list<std::string> &tosend)
  3539. {
  3540. DSTACK(__FUNCTION_NAME);
  3541. verbosestream<<"Server::sendRequestedMedia(): "
  3542. <<"Sending files to client"<<std::endl;
  3543. /* Read files */
  3544. // Put 5kB in one bunch (this is not accurate)
  3545. u32 bytes_per_bunch = 5000;
  3546. std::vector< std::list<SendableMedia> > file_bunches;
  3547. file_bunches.push_back(std::list<SendableMedia>());
  3548. u32 file_size_bunch_total = 0;
  3549. for(std::list<std::string>::const_iterator i = tosend.begin();
  3550. i != tosend.end(); ++i)
  3551. {
  3552. const std::string &name = *i;
  3553. if(m_media.find(name) == m_media.end()){
  3554. errorstream<<"Server::sendRequestedMedia(): Client asked for "
  3555. <<"unknown file \""<<(name)<<"\""<<std::endl;
  3556. continue;
  3557. }
  3558. //TODO get path + name
  3559. std::string tpath = m_media[name].path;
  3560. // Read data
  3561. std::ifstream fis(tpath.c_str(), std::ios_base::binary);
  3562. if(fis.good() == false){
  3563. errorstream<<"Server::sendRequestedMedia(): Could not open \""
  3564. <<tpath<<"\" for reading"<<std::endl;
  3565. continue;
  3566. }
  3567. std::ostringstream tmp_os(std::ios_base::binary);
  3568. bool bad = false;
  3569. for(;;){
  3570. char buf[1024];
  3571. fis.read(buf, 1024);
  3572. std::streamsize len = fis.gcount();
  3573. tmp_os.write(buf, len);
  3574. file_size_bunch_total += len;
  3575. if(fis.eof())
  3576. break;
  3577. if(!fis.good()){
  3578. bad = true;
  3579. break;
  3580. }
  3581. }
  3582. if(bad){
  3583. errorstream<<"Server::sendRequestedMedia(): Failed to read \""
  3584. <<name<<"\""<<std::endl;
  3585. continue;
  3586. }
  3587. /*infostream<<"Server::sendRequestedMedia(): Loaded \""
  3588. <<tname<<"\""<<std::endl;*/
  3589. // Put in list
  3590. file_bunches[file_bunches.size()-1].push_back(
  3591. SendableMedia(name, tpath, tmp_os.str()));
  3592. // Start next bunch if got enough data
  3593. if(file_size_bunch_total >= bytes_per_bunch){
  3594. file_bunches.push_back(std::list<SendableMedia>());
  3595. file_size_bunch_total = 0;
  3596. }
  3597. }
  3598. /* Create and send packets */
  3599. u32 num_bunches = file_bunches.size();
  3600. for(u32 i=0; i<num_bunches; i++)
  3601. {
  3602. std::ostringstream os(std::ios_base::binary);
  3603. /*
  3604. u16 command
  3605. u16 total number of texture bunches
  3606. u16 index of this bunch
  3607. u32 number of files in this bunch
  3608. for each file {
  3609. u16 length of name
  3610. string name
  3611. u32 length of data
  3612. data
  3613. }
  3614. */
  3615. writeU16(os, TOCLIENT_MEDIA);
  3616. writeU16(os, num_bunches);
  3617. writeU16(os, i);
  3618. writeU32(os, file_bunches[i].size());
  3619. for(std::list<SendableMedia>::iterator
  3620. j = file_bunches[i].begin();
  3621. j != file_bunches[i].end(); ++j){
  3622. os<<serializeString(j->name);
  3623. os<<serializeLongString(j->data);
  3624. }
  3625. // Make data buffer
  3626. std::string s = os.str();
  3627. verbosestream<<"Server::sendRequestedMedia(): bunch "
  3628. <<i<<"/"<<num_bunches
  3629. <<" files="<<file_bunches[i].size()
  3630. <<" size=" <<s.size()<<std::endl;
  3631. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  3632. // Send as reliable
  3633. m_clients.send(peer_id, 2, data, true);
  3634. }
  3635. }
  3636. void Server::sendDetachedInventory(const std::string &name, u16 peer_id)
  3637. {
  3638. if(m_detached_inventories.count(name) == 0){
  3639. errorstream<<__FUNCTION_NAME<<": \""<<name<<"\" not found"<<std::endl;
  3640. return;
  3641. }
  3642. Inventory *inv = m_detached_inventories[name];
  3643. std::ostringstream os(std::ios_base::binary);
  3644. writeU16(os, TOCLIENT_DETACHED_INVENTORY);
  3645. os<<serializeString(name);
  3646. inv->serialize(os);
  3647. // Make data buffer
  3648. std::string s = os.str();
  3649. SharedBuffer<u8> data((u8*)s.c_str(), s.size());
  3650. if (peer_id != PEER_ID_INEXISTENT)
  3651. {
  3652. // Send as reliable
  3653. m_clients.send(peer_id, 0, data, true);
  3654. }
  3655. else
  3656. {
  3657. m_clients.sendToAll(0,data,true);
  3658. }
  3659. }
  3660. void Server::sendDetachedInventories(u16 peer_id)
  3661. {
  3662. DSTACK(__FUNCTION_NAME);
  3663. for(std::map<std::string, Inventory*>::iterator
  3664. i = m_detached_inventories.begin();
  3665. i != m_detached_inventories.end(); i++){
  3666. const std::string &name = i->first;
  3667. //Inventory *inv = i->second;
  3668. sendDetachedInventory(name, peer_id);
  3669. }
  3670. }
  3671. /*
  3672. Something random
  3673. */
  3674. void Server::DiePlayer(u16 peer_id)
  3675. {
  3676. DSTACK(__FUNCTION_NAME);
  3677. PlayerSAO *playersao = getPlayerSAO(peer_id);
  3678. assert(playersao);
  3679. infostream<<"Server::DiePlayer(): Player "
  3680. <<playersao->getPlayer()->getName()
  3681. <<" dies"<<std::endl;
  3682. playersao->setHP(0);
  3683. // Trigger scripted stuff
  3684. m_script->on_dieplayer(playersao);
  3685. SendPlayerHP(peer_id);
  3686. SendDeathscreen(peer_id, false, v3f(0,0,0));
  3687. }
  3688. void Server::RespawnPlayer(u16 peer_id)
  3689. {
  3690. DSTACK(__FUNCTION_NAME);
  3691. PlayerSAO *playersao = getPlayerSAO(peer_id);
  3692. assert(playersao);
  3693. infostream<<"Server::RespawnPlayer(): Player "
  3694. <<playersao->getPlayer()->getName()
  3695. <<" respawns"<<std::endl;
  3696. playersao->setHP(PLAYER_MAX_HP);
  3697. bool repositioned = m_script->on_respawnplayer(playersao);
  3698. if(!repositioned){
  3699. v3f pos = findSpawnPos(m_env->getServerMap());
  3700. playersao->setPos(pos);
  3701. }
  3702. }
  3703. void Server::DenyAccess(u16 peer_id, const std::wstring &reason)
  3704. {
  3705. DSTACK(__FUNCTION_NAME);
  3706. SendAccessDenied(peer_id, reason);
  3707. m_clients.event(peer_id, CSE_SetDenied);
  3708. m_con.DisconnectPeer(peer_id);
  3709. }
  3710. void Server::DeleteClient(u16 peer_id, ClientDeletionReason reason)
  3711. {
  3712. DSTACK(__FUNCTION_NAME);
  3713. std::wstring message;
  3714. {
  3715. /*
  3716. Clear references to playing sounds
  3717. */
  3718. for(std::map<s32, ServerPlayingSound>::iterator
  3719. i = m_playing_sounds.begin();
  3720. i != m_playing_sounds.end();)
  3721. {
  3722. ServerPlayingSound &psound = i->second;
  3723. psound.clients.erase(peer_id);
  3724. if(psound.clients.size() == 0)
  3725. m_playing_sounds.erase(i++);
  3726. else
  3727. i++;
  3728. }
  3729. Player *player = m_env->getPlayer(peer_id);
  3730. // Collect information about leaving in chat
  3731. {
  3732. if(player != NULL && reason != CDR_DENY)
  3733. {
  3734. std::wstring name = narrow_to_wide(player->getName());
  3735. message += L"*** ";
  3736. message += name;
  3737. message += L" left the game.";
  3738. if(reason == CDR_TIMEOUT)
  3739. message += L" (timed out)";
  3740. }
  3741. }
  3742. /* Run scripts and remove from environment */
  3743. {
  3744. if(player != NULL)
  3745. {
  3746. PlayerSAO *playersao = player->getPlayerSAO();
  3747. assert(playersao);
  3748. m_script->on_leaveplayer(playersao);
  3749. playersao->disconnected();
  3750. }
  3751. }
  3752. /*
  3753. Print out action
  3754. */
  3755. {
  3756. if(player != NULL && reason != CDR_DENY)
  3757. {
  3758. std::ostringstream os(std::ios_base::binary);
  3759. std::list<u16> clients = m_clients.getClientIDs();
  3760. for(std::list<u16>::iterator
  3761. i = clients.begin();
  3762. i != clients.end(); ++i)
  3763. {
  3764. // Get player
  3765. Player *player = m_env->getPlayer(*i);
  3766. if(!player)
  3767. continue;
  3768. // Get name of player
  3769. os<<player->getName()<<" ";
  3770. }
  3771. actionstream<<player->getName()<<" "
  3772. <<(reason==CDR_TIMEOUT?"times out.":"leaves game.")
  3773. <<" List of players: "<<os.str()<<std::endl;
  3774. }
  3775. }
  3776. {
  3777. JMutexAutoLock env_lock(m_env_mutex);
  3778. m_clients.DeleteClient(peer_id);
  3779. }
  3780. }
  3781. // Send leave chat message to all remaining clients
  3782. if(message.length() != 0)
  3783. SendChatMessage(PEER_ID_INEXISTENT,message);
  3784. }
  3785. void Server::UpdateCrafting(u16 peer_id)
  3786. {
  3787. DSTACK(__FUNCTION_NAME);
  3788. Player* player = m_env->getPlayer(peer_id);
  3789. assert(player);
  3790. // Get a preview for crafting
  3791. ItemStack preview;
  3792. InventoryLocation loc;
  3793. loc.setPlayer(player->getName());
  3794. getCraftingResult(&player->inventory, preview, false, this);
  3795. m_env->getScriptIface()->item_CraftPredict(preview, player->getPlayerSAO(), (&player->inventory)->getList("craft"), loc);
  3796. // Put the new preview in
  3797. InventoryList *plist = player->inventory.getList("craftpreview");
  3798. assert(plist);
  3799. assert(plist->getSize() >= 1);
  3800. plist->changeItem(0, preview);
  3801. }
  3802. RemoteClient* Server::getClient(u16 peer_id, ClientState state_min)
  3803. {
  3804. RemoteClient *client = getClientNoEx(peer_id,state_min);
  3805. if(!client)
  3806. throw ClientNotFoundException("Client not found");
  3807. return client;
  3808. }
  3809. RemoteClient* Server::getClientNoEx(u16 peer_id, ClientState state_min)
  3810. {
  3811. return m_clients.getClientNoEx(peer_id, state_min);
  3812. }
  3813. std::string Server::getPlayerName(u16 peer_id)
  3814. {
  3815. Player *player = m_env->getPlayer(peer_id);
  3816. if(player == NULL)
  3817. return "[id="+itos(peer_id)+"]";
  3818. return player->getName();
  3819. }
  3820. PlayerSAO* Server::getPlayerSAO(u16 peer_id)
  3821. {
  3822. Player *player = m_env->getPlayer(peer_id);
  3823. if(player == NULL)
  3824. return NULL;
  3825. return player->getPlayerSAO();
  3826. }
  3827. std::wstring Server::getStatusString()
  3828. {
  3829. std::wostringstream os(std::ios_base::binary);
  3830. os<<L"# Server: ";
  3831. // Version
  3832. os<<L"version="<<narrow_to_wide(minetest_version_simple);
  3833. // Uptime
  3834. os<<L", uptime="<<m_uptime.get();
  3835. // Max lag estimate
  3836. os<<L", max_lag="<<m_env->getMaxLagEstimate();
  3837. // Information about clients
  3838. bool first = true;
  3839. os<<L", clients={";
  3840. std::list<u16> clients = m_clients.getClientIDs();
  3841. for(std::list<u16>::iterator i = clients.begin();
  3842. i != clients.end(); ++i)
  3843. {
  3844. // Get player
  3845. Player *player = m_env->getPlayer(*i);
  3846. // Get name of player
  3847. std::wstring name = L"unknown";
  3848. if(player != NULL)
  3849. name = narrow_to_wide(player->getName());
  3850. // Add name to information string
  3851. if(!first)
  3852. os<<L",";
  3853. else
  3854. first = false;
  3855. os<<name;
  3856. }
  3857. os<<L"}";
  3858. if(((ServerMap*)(&m_env->getMap()))->isSavingEnabled() == false)
  3859. os<<std::endl<<L"# Server: "<<" WARNING: Map saving is disabled.";
  3860. if(g_settings->get("motd") != "")
  3861. os<<std::endl<<L"# Server: "<<narrow_to_wide(g_settings->get("motd"));
  3862. return os.str();
  3863. }
  3864. std::set<std::string> Server::getPlayerEffectivePrivs(const std::string &name)
  3865. {
  3866. std::set<std::string> privs;
  3867. m_script->getAuth(name, NULL, &privs);
  3868. return privs;
  3869. }
  3870. bool Server::checkPriv(const std::string &name, const std::string &priv)
  3871. {
  3872. std::set<std::string> privs = getPlayerEffectivePrivs(name);
  3873. return (privs.count(priv) != 0);
  3874. }
  3875. void Server::reportPrivsModified(const std::string &name)
  3876. {
  3877. if(name == ""){
  3878. std::list<u16> clients = m_clients.getClientIDs();
  3879. for(std::list<u16>::iterator
  3880. i = clients.begin();
  3881. i != clients.end(); ++i){
  3882. Player *player = m_env->getPlayer(*i);
  3883. reportPrivsModified(player->getName());
  3884. }
  3885. } else {
  3886. Player *player = m_env->getPlayer(name.c_str());
  3887. if(!player)
  3888. return;
  3889. SendPlayerPrivileges(player->peer_id);
  3890. PlayerSAO *sao = player->getPlayerSAO();
  3891. if(!sao)
  3892. return;
  3893. sao->updatePrivileges(
  3894. getPlayerEffectivePrivs(name),
  3895. isSingleplayer());
  3896. }
  3897. }
  3898. void Server::reportInventoryFormspecModified(const std::string &name)
  3899. {
  3900. Player *player = m_env->getPlayer(name.c_str());
  3901. if(!player)
  3902. return;
  3903. SendPlayerInventoryFormspec(player->peer_id);
  3904. }
  3905. void Server::setIpBanned(const std::string &ip, const std::string &name)
  3906. {
  3907. m_banmanager->add(ip, name);
  3908. }
  3909. void Server::unsetIpBanned(const std::string &ip_or_name)
  3910. {
  3911. m_banmanager->remove(ip_or_name);
  3912. }
  3913. std::string Server::getBanDescription(const std::string &ip_or_name)
  3914. {
  3915. return m_banmanager->getBanDescription(ip_or_name);
  3916. }
  3917. void Server::notifyPlayer(const char *name, const std::wstring &msg)
  3918. {
  3919. Player *player = m_env->getPlayer(name);
  3920. if(!player)
  3921. return;
  3922. if (player->peer_id == PEER_ID_INEXISTENT)
  3923. return;
  3924. SendChatMessage(player->peer_id, msg);
  3925. }
  3926. bool Server::showFormspec(const char *playername, const std::string &formspec, const std::string &formname)
  3927. {
  3928. Player *player = m_env->getPlayer(playername);
  3929. if(!player)
  3930. {
  3931. infostream<<"showFormspec: couldn't find player:"<<playername<<std::endl;
  3932. return false;
  3933. }
  3934. SendShowFormspecMessage(player->peer_id, formspec, formname);
  3935. return true;
  3936. }
  3937. u32 Server::hudAdd(Player *player, HudElement *form) {
  3938. if (!player)
  3939. return -1;
  3940. u32 id = player->addHud(form);
  3941. SendHUDAdd(player->peer_id, id, form);
  3942. return id;
  3943. }
  3944. bool Server::hudRemove(Player *player, u32 id) {
  3945. if (!player)
  3946. return false;
  3947. HudElement* todel = player->removeHud(id);
  3948. if (!todel)
  3949. return false;
  3950. delete todel;
  3951. SendHUDRemove(player->peer_id, id);
  3952. return true;
  3953. }
  3954. bool Server::hudChange(Player *player, u32 id, HudElementStat stat, void *data) {
  3955. if (!player)
  3956. return false;
  3957. SendHUDChange(player->peer_id, id, stat, data);
  3958. return true;
  3959. }
  3960. bool Server::hudSetFlags(Player *player, u32 flags, u32 mask) {
  3961. if (!player)
  3962. return false;
  3963. SendHUDSetFlags(player->peer_id, flags, mask);
  3964. player->hud_flags = flags;
  3965. PlayerSAO* playersao = player->getPlayerSAO();
  3966. if (playersao == NULL)
  3967. return false;
  3968. m_script->player_event(playersao, "hud_changed");
  3969. return true;
  3970. }
  3971. bool Server::hudSetHotbarItemcount(Player *player, s32 hotbar_itemcount) {
  3972. if (!player)
  3973. return false;
  3974. if (hotbar_itemcount <= 0 || hotbar_itemcount > HUD_HOTBAR_ITEMCOUNT_MAX)
  3975. return false;
  3976. std::ostringstream os(std::ios::binary);
  3977. writeS32(os, hotbar_itemcount);
  3978. SendHUDSetParam(player->peer_id, HUD_PARAM_HOTBAR_ITEMCOUNT, os.str());
  3979. return true;
  3980. }
  3981. void Server::hudSetHotbarImage(Player *player, std::string name) {
  3982. if (!player)
  3983. return;
  3984. SendHUDSetParam(player->peer_id, HUD_PARAM_HOTBAR_IMAGE, name);
  3985. }
  3986. void Server::hudSetHotbarSelectedImage(Player *player, std::string name) {
  3987. if (!player)
  3988. return;
  3989. SendHUDSetParam(player->peer_id, HUD_PARAM_HOTBAR_SELECTED_IMAGE, name);
  3990. }
  3991. bool Server::setLocalPlayerAnimations(Player *player, v2s32 animation_frames[4], f32 frame_speed)
  3992. {
  3993. if (!player)
  3994. return false;
  3995. SendLocalPlayerAnimations(player->peer_id, animation_frames, frame_speed);
  3996. return true;
  3997. }
  3998. bool Server::setPlayerEyeOffset(Player *player, v3f first, v3f third)
  3999. {
  4000. if (!player)
  4001. return false;
  4002. SendEyeOffset(player->peer_id, first, third);
  4003. return true;
  4004. }
  4005. bool Server::setSky(Player *player, const video::SColor &bgcolor,
  4006. const std::string &type, const std::vector<std::string> &params)
  4007. {
  4008. if (!player)
  4009. return false;
  4010. SendSetSky(player->peer_id, bgcolor, type, params);
  4011. return true;
  4012. }
  4013. bool Server::overrideDayNightRatio(Player *player, bool do_override,
  4014. float ratio)
  4015. {
  4016. if (!player)
  4017. return false;
  4018. SendOverrideDayNightRatio(player->peer_id, do_override, ratio);
  4019. return true;
  4020. }
  4021. void Server::notifyPlayers(const std::wstring &msg)
  4022. {
  4023. SendChatMessage(PEER_ID_INEXISTENT,msg);
  4024. }
  4025. void Server::spawnParticle(const char *playername, v3f pos,
  4026. v3f velocity, v3f acceleration,
  4027. float expirationtime, float size, bool
  4028. collisiondetection, bool vertical, std::string texture)
  4029. {
  4030. Player *player = m_env->getPlayer(playername);
  4031. if(!player)
  4032. return;
  4033. SendSpawnParticle(player->peer_id, pos, velocity, acceleration,
  4034. expirationtime, size, collisiondetection, vertical, texture);
  4035. }
  4036. void Server::spawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
  4037. float expirationtime, float size,
  4038. bool collisiondetection, bool vertical, std::string texture)
  4039. {
  4040. SendSpawnParticle(PEER_ID_INEXISTENT,pos, velocity, acceleration,
  4041. expirationtime, size, collisiondetection, vertical, texture);
  4042. }
  4043. u32 Server::addParticleSpawner(const char *playername,
  4044. u16 amount, float spawntime,
  4045. v3f minpos, v3f maxpos,
  4046. v3f minvel, v3f maxvel,
  4047. v3f minacc, v3f maxacc,
  4048. float minexptime, float maxexptime,
  4049. float minsize, float maxsize,
  4050. bool collisiondetection, bool vertical, std::string texture)
  4051. {
  4052. Player *player = m_env->getPlayer(playername);
  4053. if(!player)
  4054. return -1;
  4055. u32 id = 0;
  4056. for(;;) // look for unused particlespawner id
  4057. {
  4058. id++;
  4059. if (std::find(m_particlespawner_ids.begin(),
  4060. m_particlespawner_ids.end(), id)
  4061. == m_particlespawner_ids.end())
  4062. {
  4063. m_particlespawner_ids.push_back(id);
  4064. break;
  4065. }
  4066. }
  4067. SendAddParticleSpawner(player->peer_id, amount, spawntime,
  4068. minpos, maxpos, minvel, maxvel, minacc, maxacc,
  4069. minexptime, maxexptime, minsize, maxsize,
  4070. collisiondetection, vertical, texture, id);
  4071. return id;
  4072. }
  4073. u32 Server::addParticleSpawnerAll(u16 amount, float spawntime,
  4074. v3f minpos, v3f maxpos,
  4075. v3f minvel, v3f maxvel,
  4076. v3f minacc, v3f maxacc,
  4077. float minexptime, float maxexptime,
  4078. float minsize, float maxsize,
  4079. bool collisiondetection, bool vertical, std::string texture)
  4080. {
  4081. u32 id = 0;
  4082. for(;;) // look for unused particlespawner id
  4083. {
  4084. id++;
  4085. if (std::find(m_particlespawner_ids.begin(),
  4086. m_particlespawner_ids.end(), id)
  4087. == m_particlespawner_ids.end())
  4088. {
  4089. m_particlespawner_ids.push_back(id);
  4090. break;
  4091. }
  4092. }
  4093. SendAddParticleSpawner(PEER_ID_INEXISTENT, amount, spawntime,
  4094. minpos, maxpos, minvel, maxvel, minacc, maxacc,
  4095. minexptime, maxexptime, minsize, maxsize,
  4096. collisiondetection, vertical, texture, id);
  4097. return id;
  4098. }
  4099. void Server::deleteParticleSpawner(const char *playername, u32 id)
  4100. {
  4101. Player *player = m_env->getPlayer(playername);
  4102. if(!player)
  4103. return;
  4104. m_particlespawner_ids.erase(
  4105. std::remove(m_particlespawner_ids.begin(),
  4106. m_particlespawner_ids.end(), id),
  4107. m_particlespawner_ids.end());
  4108. SendDeleteParticleSpawner(player->peer_id, id);
  4109. }
  4110. void Server::deleteParticleSpawnerAll(u32 id)
  4111. {
  4112. m_particlespawner_ids.erase(
  4113. std::remove(m_particlespawner_ids.begin(),
  4114. m_particlespawner_ids.end(), id),
  4115. m_particlespawner_ids.end());
  4116. SendDeleteParticleSpawner(PEER_ID_INEXISTENT, id);
  4117. }
  4118. Inventory* Server::createDetachedInventory(const std::string &name)
  4119. {
  4120. if(m_detached_inventories.count(name) > 0){
  4121. infostream<<"Server clearing detached inventory \""<<name<<"\""<<std::endl;
  4122. delete m_detached_inventories[name];
  4123. } else {
  4124. infostream<<"Server creating detached inventory \""<<name<<"\""<<std::endl;
  4125. }
  4126. Inventory *inv = new Inventory(m_itemdef);
  4127. assert(inv);
  4128. m_detached_inventories[name] = inv;
  4129. //TODO find a better way to do this
  4130. sendDetachedInventory(name,PEER_ID_INEXISTENT);
  4131. return inv;
  4132. }
  4133. class BoolScopeSet
  4134. {
  4135. public:
  4136. BoolScopeSet(bool *dst, bool val):
  4137. m_dst(dst)
  4138. {
  4139. m_orig_state = *m_dst;
  4140. *m_dst = val;
  4141. }
  4142. ~BoolScopeSet()
  4143. {
  4144. *m_dst = m_orig_state;
  4145. }
  4146. private:
  4147. bool *m_dst;
  4148. bool m_orig_state;
  4149. };
  4150. // actions: time-reversed list
  4151. // Return value: success/failure
  4152. bool Server::rollbackRevertActions(const std::list<RollbackAction> &actions,
  4153. std::list<std::string> *log)
  4154. {
  4155. infostream<<"Server::rollbackRevertActions(len="<<actions.size()<<")"<<std::endl;
  4156. ServerMap *map = (ServerMap*)(&m_env->getMap());
  4157. // Disable rollback report sink while reverting
  4158. BoolScopeSet rollback_scope_disable(&m_rollback_sink_enabled, false);
  4159. // Fail if no actions to handle
  4160. if(actions.empty()){
  4161. log->push_back("Nothing to do.");
  4162. return false;
  4163. }
  4164. int num_tried = 0;
  4165. int num_failed = 0;
  4166. for(std::list<RollbackAction>::const_iterator
  4167. i = actions.begin();
  4168. i != actions.end(); i++)
  4169. {
  4170. const RollbackAction &action = *i;
  4171. num_tried++;
  4172. bool success = action.applyRevert(map, this, this);
  4173. if(!success){
  4174. num_failed++;
  4175. std::ostringstream os;
  4176. os<<"Revert of step ("<<num_tried<<") "<<action.toString()<<" failed";
  4177. infostream<<"Map::rollbackRevertActions(): "<<os.str()<<std::endl;
  4178. if(log)
  4179. log->push_back(os.str());
  4180. }else{
  4181. std::ostringstream os;
  4182. os<<"Successfully reverted step ("<<num_tried<<") "<<action.toString();
  4183. infostream<<"Map::rollbackRevertActions(): "<<os.str()<<std::endl;
  4184. if(log)
  4185. log->push_back(os.str());
  4186. }
  4187. }
  4188. infostream<<"Map::rollbackRevertActions(): "<<num_failed<<"/"<<num_tried
  4189. <<" failed"<<std::endl;
  4190. // Call it done if less than half failed
  4191. return num_failed <= num_tried/2;
  4192. }
  4193. // IGameDef interface
  4194. // Under envlock
  4195. IItemDefManager* Server::getItemDefManager()
  4196. {
  4197. return m_itemdef;
  4198. }
  4199. INodeDefManager* Server::getNodeDefManager()
  4200. {
  4201. return m_nodedef;
  4202. }
  4203. ICraftDefManager* Server::getCraftDefManager()
  4204. {
  4205. return m_craftdef;
  4206. }
  4207. ITextureSource* Server::getTextureSource()
  4208. {
  4209. return NULL;
  4210. }
  4211. IShaderSource* Server::getShaderSource()
  4212. {
  4213. return NULL;
  4214. }
  4215. u16 Server::allocateUnknownNodeId(const std::string &name)
  4216. {
  4217. return m_nodedef->allocateDummy(name);
  4218. }
  4219. ISoundManager* Server::getSoundManager()
  4220. {
  4221. return &dummySoundManager;
  4222. }
  4223. MtEventManager* Server::getEventManager()
  4224. {
  4225. return m_event;
  4226. }
  4227. IRollbackReportSink* Server::getRollbackReportSink()
  4228. {
  4229. if(!m_enable_rollback_recording)
  4230. return NULL;
  4231. if(!m_rollback_sink_enabled)
  4232. return NULL;
  4233. return m_rollback;
  4234. }
  4235. IWritableItemDefManager* Server::getWritableItemDefManager()
  4236. {
  4237. return m_itemdef;
  4238. }
  4239. IWritableNodeDefManager* Server::getWritableNodeDefManager()
  4240. {
  4241. return m_nodedef;
  4242. }
  4243. IWritableCraftDefManager* Server::getWritableCraftDefManager()
  4244. {
  4245. return m_craftdef;
  4246. }
  4247. const ModSpec* Server::getModSpec(const std::string &modname)
  4248. {
  4249. for(std::vector<ModSpec>::iterator i = m_mods.begin();
  4250. i != m_mods.end(); i++){
  4251. const ModSpec &mod = *i;
  4252. if(mod.name == modname)
  4253. return &mod;
  4254. }
  4255. return NULL;
  4256. }
  4257. void Server::getModNames(std::list<std::string> &modlist)
  4258. {
  4259. for(std::vector<ModSpec>::iterator i = m_mods.begin(); i != m_mods.end(); i++)
  4260. {
  4261. modlist.push_back(i->name);
  4262. }
  4263. }
  4264. std::string Server::getBuiltinLuaPath()
  4265. {
  4266. return porting::path_share + DIR_DELIM + "builtin";
  4267. }
  4268. v3f findSpawnPos(ServerMap &map)
  4269. {
  4270. //return v3f(50,50,50)*BS;
  4271. v3s16 nodepos;
  4272. #if 0
  4273. nodepos = v2s16(0,0);
  4274. groundheight = 20;
  4275. #endif
  4276. #if 1
  4277. s16 water_level = map.getWaterLevel();
  4278. // Try to find a good place a few times
  4279. for(s32 i=0; i<1000; i++)
  4280. {
  4281. s32 range = 1 + i;
  4282. // We're going to try to throw the player to this position
  4283. v2s16 nodepos2d = v2s16(
  4284. -range + (myrand() % (range * 2)),
  4285. -range + (myrand() % (range * 2)));
  4286. // Get ground height at point
  4287. s16 groundheight = map.findGroundLevel(nodepos2d);
  4288. if (groundheight <= water_level) // Don't go underwater
  4289. continue;
  4290. if (groundheight > water_level + 6) // Don't go to high places
  4291. continue;
  4292. nodepos = v3s16(nodepos2d.X, groundheight, nodepos2d.Y);
  4293. bool is_good = false;
  4294. s32 air_count = 0;
  4295. for (s32 i = 0; i < 10; i++) {
  4296. v3s16 blockpos = getNodeBlockPos(nodepos);
  4297. map.emergeBlock(blockpos, true);
  4298. content_t c = map.getNodeNoEx(nodepos).getContent();
  4299. if (c == CONTENT_AIR || c == CONTENT_IGNORE) {
  4300. air_count++;
  4301. if (air_count >= 2){
  4302. is_good = true;
  4303. break;
  4304. }
  4305. }
  4306. nodepos.Y++;
  4307. }
  4308. if(is_good){
  4309. // Found a good place
  4310. //infostream<<"Searched through "<<i<<" places."<<std::endl;
  4311. break;
  4312. }
  4313. }
  4314. #endif
  4315. return intToFloat(nodepos, BS);
  4316. }
  4317. PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id)
  4318. {
  4319. RemotePlayer *player = NULL;
  4320. bool newplayer = false;
  4321. /*
  4322. Try to get an existing player
  4323. */
  4324. player = static_cast<RemotePlayer*>(m_env->getPlayer(name));
  4325. // If player is already connected, cancel
  4326. if(player != NULL && player->peer_id != 0)
  4327. {
  4328. infostream<<"emergePlayer(): Player already connected"<<std::endl;
  4329. return NULL;
  4330. }
  4331. /*
  4332. If player with the wanted peer_id already exists, cancel.
  4333. */
  4334. if(m_env->getPlayer(peer_id) != NULL)
  4335. {
  4336. infostream<<"emergePlayer(): Player with wrong name but same"
  4337. " peer_id already exists"<<std::endl;
  4338. return NULL;
  4339. }
  4340. // Load player if it isn't already loaded
  4341. if (!player) {
  4342. player = static_cast<RemotePlayer*>(m_env->loadPlayer(name));
  4343. }
  4344. // Create player if it doesn't exist
  4345. if (!player) {
  4346. newplayer = true;
  4347. player = new RemotePlayer(this);
  4348. player->updateName(name);
  4349. /* Set player position */
  4350. infostream<<"Server: Finding spawn place for player \""
  4351. <<name<<"\""<<std::endl;
  4352. v3f pos = findSpawnPos(m_env->getServerMap());
  4353. player->setPosition(pos);
  4354. /* Add player to environment */
  4355. m_env->addPlayer(player);
  4356. }
  4357. // Create a new player active object
  4358. PlayerSAO *playersao = new PlayerSAO(m_env, player, peer_id,
  4359. getPlayerEffectivePrivs(player->getName()),
  4360. isSingleplayer());
  4361. /* Clean up old HUD elements from previous sessions */
  4362. player->clearHud();
  4363. /* Add object to environment */
  4364. m_env->addActiveObject(playersao);
  4365. /* Run scripts */
  4366. if (newplayer) {
  4367. m_script->on_newplayer(playersao);
  4368. }
  4369. return playersao;
  4370. }
  4371. void dedicated_server_loop(Server &server, bool &kill)
  4372. {
  4373. DSTACK(__FUNCTION_NAME);
  4374. verbosestream<<"dedicated_server_loop()"<<std::endl;
  4375. IntervalLimiter m_profiler_interval;
  4376. for(;;)
  4377. {
  4378. float steplen = g_settings->getFloat("dedicated_server_step");
  4379. // This is kind of a hack but can be done like this
  4380. // because server.step() is very light
  4381. {
  4382. ScopeProfiler sp(g_profiler, "dedicated server sleep");
  4383. sleep_ms((int)(steplen*1000.0));
  4384. }
  4385. server.step(steplen);
  4386. if(server.getShutdownRequested() || kill)
  4387. {
  4388. infostream<<"Dedicated server quitting"<<std::endl;
  4389. #if USE_CURL
  4390. if(g_settings->getBool("server_announce") == true)
  4391. ServerList::sendAnnounce("delete");
  4392. #endif
  4393. break;
  4394. }
  4395. /*
  4396. Profiler
  4397. */
  4398. float profiler_print_interval =
  4399. g_settings->getFloat("profiler_print_interval");
  4400. if(profiler_print_interval != 0)
  4401. {
  4402. if(m_profiler_interval.step(steplen, profiler_print_interval))
  4403. {
  4404. infostream<<"Profiler:"<<std::endl;
  4405. g_profiler->print(infostream);
  4406. g_profiler->clear();
  4407. }
  4408. }
  4409. }
  4410. }