clientpackethandler.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389
  1. /*
  2. Minetest
  3. Copyright (C) 2015 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
  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 "client.h"
  17. #include "util/base64.h"
  18. #include "chatmessage.h"
  19. #include "clientmedia.h"
  20. #include "log.h"
  21. #include "map.h"
  22. #include "mapsector.h"
  23. #include "minimap.h"
  24. #include "nodedef.h"
  25. #include "serialization.h"
  26. #include "server.h"
  27. #include "util/strfnd.h"
  28. #include "network/clientopcodes.h"
  29. #include "network/connection.h"
  30. #include "script/scripting_client.h"
  31. #include "util/serialize.h"
  32. #include "util/srp.h"
  33. #include "tileanimation.h"
  34. void Client::handleCommand_Deprecated(NetworkPacket* pkt)
  35. {
  36. infostream << "Got deprecated command "
  37. << toClientCommandTable[pkt->getCommand()].name << " from peer "
  38. << pkt->getPeerId() << "!" << std::endl;
  39. }
  40. void Client::handleCommand_Hello(NetworkPacket* pkt)
  41. {
  42. if (pkt->getSize() < 1)
  43. return;
  44. u8 serialization_ver;
  45. u16 proto_ver;
  46. u16 compression_mode;
  47. u32 auth_mechs;
  48. std::string username_legacy; // for case insensitivity
  49. *pkt >> serialization_ver >> compression_mode >> proto_ver
  50. >> auth_mechs >> username_legacy;
  51. // Chose an auth method we support
  52. AuthMechanism chosen_auth_mechanism = choseAuthMech(auth_mechs);
  53. infostream << "Client: TOCLIENT_HELLO received with "
  54. << "serialization_ver=" << (u32)serialization_ver
  55. << ", auth_mechs=" << auth_mechs
  56. << ", proto_ver=" << proto_ver
  57. << ", compression_mode=" << compression_mode
  58. << ". Doing auth with mech " << chosen_auth_mechanism << std::endl;
  59. if (!ser_ver_supported(serialization_ver)) {
  60. infostream << "Client: TOCLIENT_HELLO: Server sent "
  61. << "unsupported ser_fmt_ver"<< std::endl;
  62. return;
  63. }
  64. m_server_ser_ver = serialization_ver;
  65. m_proto_ver = proto_ver;
  66. //TODO verify that username_legacy matches sent username, only
  67. // differs in casing (make both uppercase and compare)
  68. // This is only neccessary though when we actually want to add casing support
  69. if (m_chosen_auth_mech != AUTH_MECHANISM_NONE) {
  70. // we recieved a TOCLIENT_HELLO while auth was already going on
  71. errorstream << "Client: TOCLIENT_HELLO while auth was already going on"
  72. << "(chosen_mech=" << m_chosen_auth_mech << ")." << std::endl;
  73. if ((m_chosen_auth_mech == AUTH_MECHANISM_SRP)
  74. || (m_chosen_auth_mech == AUTH_MECHANISM_LEGACY_PASSWORD)) {
  75. srp_user_delete((SRPUser *) m_auth_data);
  76. m_auth_data = 0;
  77. }
  78. }
  79. // Authenticate using that method, or abort if there wasn't any method found
  80. if (chosen_auth_mechanism != AUTH_MECHANISM_NONE) {
  81. startAuth(chosen_auth_mechanism);
  82. } else {
  83. m_chosen_auth_mech = AUTH_MECHANISM_NONE;
  84. m_access_denied = true;
  85. m_access_denied_reason = "Unknown";
  86. m_con->Disconnect();
  87. }
  88. }
  89. void Client::handleCommand_AuthAccept(NetworkPacket* pkt)
  90. {
  91. deleteAuthData();
  92. v3f playerpos;
  93. *pkt >> playerpos >> m_map_seed >> m_recommended_send_interval
  94. >> m_sudo_auth_methods;
  95. playerpos -= v3f(0, BS / 2, 0);
  96. // Set player position
  97. LocalPlayer *player = m_env.getLocalPlayer();
  98. assert(player != NULL);
  99. player->setPosition(playerpos);
  100. infostream << "Client: received map seed: " << m_map_seed << std::endl;
  101. infostream << "Client: received recommended send interval "
  102. << m_recommended_send_interval<<std::endl;
  103. // Reply to server
  104. NetworkPacket resp_pkt(TOSERVER_INIT2, 0);
  105. Send(&resp_pkt);
  106. m_state = LC_Init;
  107. }
  108. void Client::handleCommand_AcceptSudoMode(NetworkPacket* pkt)
  109. {
  110. deleteAuthData();
  111. m_password = m_new_password;
  112. verbosestream << "Client: Recieved TOCLIENT_ACCEPT_SUDO_MODE." << std::endl;
  113. // send packet to actually set the password
  114. startAuth(AUTH_MECHANISM_FIRST_SRP);
  115. // reset again
  116. m_chosen_auth_mech = AUTH_MECHANISM_NONE;
  117. }
  118. void Client::handleCommand_DenySudoMode(NetworkPacket* pkt)
  119. {
  120. ChatMessage *chatMessage = new ChatMessage(CHATMESSAGE_TYPE_SYSTEM,
  121. L"Password change denied. Password NOT changed.");
  122. pushToChatQueue(chatMessage);
  123. // reset everything and be sad
  124. deleteAuthData();
  125. }
  126. void Client::handleCommand_InitLegacy(NetworkPacket* pkt)
  127. {
  128. if (pkt->getSize() < 1)
  129. return;
  130. u8 server_ser_ver;
  131. *pkt >> server_ser_ver;
  132. infostream << "Client: TOCLIENT_INIT_LEGACY received with "
  133. "server_ser_ver=" << ((int)server_ser_ver & 0xff) << std::endl;
  134. if (!ser_ver_supported(server_ser_ver)) {
  135. infostream << "Client: TOCLIENT_INIT_LEGACY: Server sent "
  136. << "unsupported ser_fmt_ver"<< std::endl;
  137. return;
  138. }
  139. m_server_ser_ver = server_ser_ver;
  140. // We can be totally wrong with this guess
  141. // but we only need some value < 25.
  142. m_proto_ver = 24;
  143. // Get player position
  144. v3s16 playerpos_s16(0, BS * 2 + BS * 20, 0);
  145. if (pkt->getSize() >= 1 + 6) {
  146. *pkt >> playerpos_s16;
  147. }
  148. v3f playerpos_f = intToFloat(playerpos_s16, BS) - v3f(0, BS / 2, 0);
  149. // Set player position
  150. LocalPlayer *player = m_env.getLocalPlayer();
  151. assert(player != NULL);
  152. player->setPosition(playerpos_f);
  153. if (pkt->getSize() >= 1 + 6 + 8) {
  154. // Get map seed
  155. *pkt >> m_map_seed;
  156. infostream << "Client: received map seed: " << m_map_seed << std::endl;
  157. }
  158. if (pkt->getSize() >= 1 + 6 + 8 + 4) {
  159. *pkt >> m_recommended_send_interval;
  160. infostream << "Client: received recommended send interval "
  161. << m_recommended_send_interval<<std::endl;
  162. }
  163. // Reply to server
  164. NetworkPacket resp_pkt(TOSERVER_INIT2, 0);
  165. Send(&resp_pkt);
  166. m_state = LC_Init;
  167. }
  168. void Client::handleCommand_AccessDenied(NetworkPacket* pkt)
  169. {
  170. // The server didn't like our password. Note, this needs
  171. // to be processed even if the serialisation format has
  172. // not been agreed yet, the same as TOCLIENT_INIT.
  173. m_access_denied = true;
  174. m_access_denied_reason = "Unknown";
  175. if (pkt->getCommand() == TOCLIENT_ACCESS_DENIED) {
  176. if (pkt->getSize() < 1)
  177. return;
  178. u8 denyCode = SERVER_ACCESSDENIED_UNEXPECTED_DATA;
  179. *pkt >> denyCode;
  180. if (denyCode == SERVER_ACCESSDENIED_SHUTDOWN ||
  181. denyCode == SERVER_ACCESSDENIED_CRASH) {
  182. *pkt >> m_access_denied_reason;
  183. if (m_access_denied_reason.empty()) {
  184. m_access_denied_reason = accessDeniedStrings[denyCode];
  185. }
  186. u8 reconnect;
  187. *pkt >> reconnect;
  188. m_access_denied_reconnect = reconnect & 1;
  189. } else if (denyCode == SERVER_ACCESSDENIED_CUSTOM_STRING) {
  190. *pkt >> m_access_denied_reason;
  191. } else if (denyCode < SERVER_ACCESSDENIED_MAX) {
  192. m_access_denied_reason = accessDeniedStrings[denyCode];
  193. } else {
  194. // Allow us to add new error messages to the
  195. // protocol without raising the protocol version, if we want to.
  196. // Until then (which may be never), this is outside
  197. // of the defined protocol.
  198. *pkt >> m_access_denied_reason;
  199. if (m_access_denied_reason.empty()) {
  200. m_access_denied_reason = "Unknown";
  201. }
  202. }
  203. }
  204. // 13/03/15 Legacy code from 0.4.12 and lesser. must stay 1 year
  205. // for compat with old clients
  206. else {
  207. if (pkt->getSize() >= 2) {
  208. std::wstring wide_reason;
  209. *pkt >> wide_reason;
  210. m_access_denied_reason = wide_to_utf8(wide_reason);
  211. }
  212. }
  213. }
  214. void Client::handleCommand_RemoveNode(NetworkPacket* pkt)
  215. {
  216. if (pkt->getSize() < 6)
  217. return;
  218. v3s16 p;
  219. *pkt >> p;
  220. removeNode(p);
  221. }
  222. void Client::handleCommand_AddNode(NetworkPacket* pkt)
  223. {
  224. if (pkt->getSize() < 6 + MapNode::serializedLength(m_server_ser_ver))
  225. return;
  226. v3s16 p;
  227. *pkt >> p;
  228. MapNode n;
  229. n.deSerialize(pkt->getU8Ptr(6), m_server_ser_ver);
  230. bool remove_metadata = true;
  231. u32 index = 6 + MapNode::serializedLength(m_server_ser_ver);
  232. if ((pkt->getSize() >= index + 1) && pkt->getU8(index)) {
  233. remove_metadata = false;
  234. }
  235. addNode(p, n, remove_metadata);
  236. }
  237. void Client::handleCommand_BlockData(NetworkPacket* pkt)
  238. {
  239. // Ignore too small packet
  240. if (pkt->getSize() < 6)
  241. return;
  242. v3s16 p;
  243. *pkt >> p;
  244. std::string datastring(pkt->getString(6), pkt->getSize() - 6);
  245. std::istringstream istr(datastring, std::ios_base::binary);
  246. MapSector *sector;
  247. MapBlock *block;
  248. v2s16 p2d(p.X, p.Z);
  249. sector = m_env.getMap().emergeSector(p2d);
  250. assert(sector->getPos() == p2d);
  251. block = sector->getBlockNoCreateNoEx(p.Y);
  252. if (block) {
  253. /*
  254. Update an existing block
  255. */
  256. block->deSerialize(istr, m_server_ser_ver, false);
  257. block->deSerializeNetworkSpecific(istr);
  258. }
  259. else {
  260. /*
  261. Create a new block
  262. */
  263. block = new MapBlock(&m_env.getMap(), p, this);
  264. block->deSerialize(istr, m_server_ser_ver, false);
  265. block->deSerializeNetworkSpecific(istr);
  266. sector->insertBlock(block);
  267. }
  268. if (m_localdb) {
  269. ServerMap::saveBlock(block, m_localdb);
  270. }
  271. /*
  272. Add it to mesh update queue and set it to be acknowledged after update.
  273. */
  274. addUpdateMeshTaskWithEdge(p, true);
  275. }
  276. void Client::handleCommand_Inventory(NetworkPacket* pkt)
  277. {
  278. if (pkt->getSize() < 1)
  279. return;
  280. std::string datastring(pkt->getString(0), pkt->getSize());
  281. std::istringstream is(datastring, std::ios_base::binary);
  282. LocalPlayer *player = m_env.getLocalPlayer();
  283. assert(player != NULL);
  284. player->inventory.deSerialize(is);
  285. m_inventory_updated = true;
  286. delete m_inventory_from_server;
  287. m_inventory_from_server = new Inventory(player->inventory);
  288. m_inventory_from_server_age = 0.0;
  289. }
  290. void Client::handleCommand_TimeOfDay(NetworkPacket* pkt)
  291. {
  292. if (pkt->getSize() < 2)
  293. return;
  294. u16 time_of_day;
  295. *pkt >> time_of_day;
  296. time_of_day = time_of_day % 24000;
  297. float time_speed = 0;
  298. if (pkt->getSize() >= 2 + 4) {
  299. *pkt >> time_speed;
  300. }
  301. else {
  302. // Old message; try to approximate speed of time by ourselves
  303. float time_of_day_f = (float)time_of_day / 24000.0;
  304. float tod_diff_f = 0;
  305. if (time_of_day_f < 0.2 && m_last_time_of_day_f > 0.8)
  306. tod_diff_f = time_of_day_f - m_last_time_of_day_f + 1.0;
  307. else
  308. tod_diff_f = time_of_day_f - m_last_time_of_day_f;
  309. m_last_time_of_day_f = time_of_day_f;
  310. float time_diff = m_time_of_day_update_timer;
  311. m_time_of_day_update_timer = 0;
  312. if (m_time_of_day_set) {
  313. time_speed = (3600.0 * 24.0) * tod_diff_f / time_diff;
  314. infostream << "Client: Measured time_of_day speed (old format): "
  315. << time_speed << " tod_diff_f=" << tod_diff_f
  316. << " time_diff=" << time_diff << std::endl;
  317. }
  318. }
  319. // Update environment
  320. m_env.setTimeOfDay(time_of_day);
  321. m_env.setTimeOfDaySpeed(time_speed);
  322. m_time_of_day_set = true;
  323. u32 dr = m_env.getDayNightRatio();
  324. infostream << "Client: time_of_day=" << time_of_day
  325. << " time_speed=" << time_speed
  326. << " dr=" << dr << std::endl;
  327. }
  328. void Client::handleCommand_ChatMessageOld(NetworkPacket *pkt)
  329. {
  330. /*
  331. u16 command
  332. u16 length
  333. wstring message
  334. */
  335. u16 len, read_wchar;
  336. *pkt >> len;
  337. std::wstring message;
  338. for (u32 i = 0; i < len; i++) {
  339. *pkt >> read_wchar;
  340. message += (wchar_t)read_wchar;
  341. }
  342. // If chat message not consummed by client lua API
  343. // @TODO send this to CSM using ChatMessage object
  344. if (!moddingEnabled() || !m_script->on_receiving_message(wide_to_utf8(message))) {
  345. pushToChatQueue(new ChatMessage(message));
  346. }
  347. }
  348. void Client::handleCommand_ChatMessage(NetworkPacket *pkt)
  349. {
  350. /*
  351. u8 version
  352. u8 message_type
  353. u16 sendername length
  354. wstring sendername
  355. u16 length
  356. wstring message
  357. */
  358. ChatMessage *chatMessage = new ChatMessage();
  359. u8 version, message_type;
  360. *pkt >> version >> message_type;
  361. if (version != 1 || message_type >= CHATMESSAGE_TYPE_MAX) {
  362. delete chatMessage;
  363. return;
  364. }
  365. *pkt >> chatMessage->sender >> chatMessage->message >> chatMessage->timestamp;
  366. chatMessage->type = (ChatMessageType) message_type;
  367. // @TODO send this to CSM using ChatMessage object
  368. if (!moddingEnabled() || !m_script->on_receiving_message(
  369. wide_to_utf8(chatMessage->message))) {
  370. pushToChatQueue(chatMessage);
  371. } else {
  372. // Message was consumed by CSM and should not handled by client, destroying
  373. delete chatMessage;
  374. }
  375. }
  376. void Client::handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt)
  377. {
  378. /*
  379. u16 count of removed objects
  380. for all removed objects {
  381. u16 id
  382. }
  383. u16 count of added objects
  384. for all added objects {
  385. u16 id
  386. u8 type
  387. u32 initialization data length
  388. string initialization data
  389. }
  390. */
  391. try {
  392. u8 type;
  393. u16 removed_count, added_count, id;
  394. // Read removed objects
  395. *pkt >> removed_count;
  396. for (u16 i = 0; i < removed_count; i++) {
  397. *pkt >> id;
  398. m_env.removeActiveObject(id);
  399. }
  400. // Read added objects
  401. *pkt >> added_count;
  402. for (u16 i = 0; i < added_count; i++) {
  403. *pkt >> id >> type;
  404. m_env.addActiveObject(id, type, pkt->readLongString());
  405. }
  406. } catch (PacketError &e) {
  407. infostream << "handleCommand_ActiveObjectRemoveAdd: " << e.what()
  408. << ". The packet is unreliable, ignoring" << std::endl;
  409. }
  410. }
  411. void Client::handleCommand_ActiveObjectMessages(NetworkPacket* pkt)
  412. {
  413. /*
  414. for all objects
  415. {
  416. u16 id
  417. u16 message length
  418. string message
  419. }
  420. */
  421. std::string datastring(pkt->getString(0), pkt->getSize());
  422. std::istringstream is(datastring, std::ios_base::binary);
  423. try {
  424. while (is.good()) {
  425. u16 id = readU16(is);
  426. if (!is.good())
  427. break;
  428. std::string message = deSerializeString(is);
  429. // Pass on to the environment
  430. m_env.processActiveObjectMessage(id, message);
  431. }
  432. } catch (SerializationError &e) {
  433. errorstream << "Client::handleCommand_ActiveObjectMessages: "
  434. << "caught SerializationError: " << e.what() << std::endl;
  435. }
  436. }
  437. void Client::handleCommand_Movement(NetworkPacket* pkt)
  438. {
  439. LocalPlayer *player = m_env.getLocalPlayer();
  440. assert(player != NULL);
  441. float mad, maa, maf, msw, mscr, msf, mscl, msj, lf, lfs, ls, g;
  442. *pkt >> mad >> maa >> maf >> msw >> mscr >> msf >> mscl >> msj
  443. >> lf >> lfs >> ls >> g;
  444. player->movement_acceleration_default = mad * BS;
  445. player->movement_acceleration_air = maa * BS;
  446. player->movement_acceleration_fast = maf * BS;
  447. player->movement_speed_walk = msw * BS;
  448. player->movement_speed_crouch = mscr * BS;
  449. player->movement_speed_fast = msf * BS;
  450. player->movement_speed_climb = mscl * BS;
  451. player->movement_speed_jump = msj * BS;
  452. player->movement_liquid_fluidity = lf * BS;
  453. player->movement_liquid_fluidity_smooth = lfs * BS;
  454. player->movement_liquid_sink = ls * BS;
  455. player->movement_gravity = g * BS;
  456. }
  457. void Client::handleCommand_HP(NetworkPacket* pkt)
  458. {
  459. LocalPlayer *player = m_env.getLocalPlayer();
  460. assert(player != NULL);
  461. u8 oldhp = player->hp;
  462. u8 hp;
  463. *pkt >> hp;
  464. player->hp = hp;
  465. if (moddingEnabled()) {
  466. m_script->on_hp_modification(hp);
  467. }
  468. if (hp < oldhp) {
  469. // Add to ClientEvent queue
  470. ClientEvent event;
  471. event.type = CE_PLAYER_DAMAGE;
  472. event.player_damage.amount = oldhp - hp;
  473. m_client_event_queue.push(event);
  474. }
  475. }
  476. void Client::handleCommand_Breath(NetworkPacket* pkt)
  477. {
  478. LocalPlayer *player = m_env.getLocalPlayer();
  479. assert(player != NULL);
  480. u16 breath;
  481. *pkt >> breath;
  482. player->setBreath(breath);
  483. }
  484. void Client::handleCommand_MovePlayer(NetworkPacket* pkt)
  485. {
  486. LocalPlayer *player = m_env.getLocalPlayer();
  487. assert(player != NULL);
  488. v3f pos;
  489. f32 pitch, yaw;
  490. *pkt >> pos >> pitch >> yaw;
  491. player->setPosition(pos);
  492. infostream << "Client got TOCLIENT_MOVE_PLAYER"
  493. << " pos=(" << pos.X << "," << pos.Y << "," << pos.Z << ")"
  494. << " pitch=" << pitch
  495. << " yaw=" << yaw
  496. << std::endl;
  497. /*
  498. Add to ClientEvent queue.
  499. This has to be sent to the main program because otherwise
  500. it would just force the pitch and yaw values to whatever
  501. the camera points to.
  502. */
  503. ClientEvent event;
  504. event.type = CE_PLAYER_FORCE_MOVE;
  505. event.player_force_move.pitch = pitch;
  506. event.player_force_move.yaw = yaw;
  507. m_client_event_queue.push(event);
  508. // Ignore damage for a few seconds, so that the player doesn't
  509. // get damage from falling on ground
  510. m_ignore_damage_timer = 3.0;
  511. }
  512. void Client::handleCommand_DeathScreen(NetworkPacket* pkt)
  513. {
  514. bool set_camera_point_target;
  515. v3f camera_point_target;
  516. *pkt >> set_camera_point_target;
  517. *pkt >> camera_point_target;
  518. ClientEvent event;
  519. event.type = CE_DEATHSCREEN;
  520. event.deathscreen.set_camera_point_target = set_camera_point_target;
  521. event.deathscreen.camera_point_target_x = camera_point_target.X;
  522. event.deathscreen.camera_point_target_y = camera_point_target.Y;
  523. event.deathscreen.camera_point_target_z = camera_point_target.Z;
  524. m_client_event_queue.push(event);
  525. }
  526. void Client::handleCommand_AnnounceMedia(NetworkPacket* pkt)
  527. {
  528. u16 num_files;
  529. *pkt >> num_files;
  530. infostream << "Client: Received media announcement: packet size: "
  531. << pkt->getSize() << std::endl;
  532. if (m_media_downloader == NULL ||
  533. m_media_downloader->isStarted()) {
  534. const char *problem = m_media_downloader ?
  535. "we already saw another announcement" :
  536. "all media has been received already";
  537. errorstream << "Client: Received media announcement but "
  538. << problem << "! "
  539. << " files=" << num_files
  540. << " size=" << pkt->getSize() << std::endl;
  541. return;
  542. }
  543. // Mesh update thread must be stopped while
  544. // updating content definitions
  545. sanity_check(!m_mesh_update_thread.isRunning());
  546. for (u16 i = 0; i < num_files; i++) {
  547. std::string name, sha1_base64;
  548. *pkt >> name >> sha1_base64;
  549. std::string sha1_raw = base64_decode(sha1_base64);
  550. m_media_downloader->addFile(name, sha1_raw);
  551. }
  552. try {
  553. std::string str;
  554. *pkt >> str;
  555. Strfnd sf(str);
  556. while(!sf.at_end()) {
  557. std::string baseurl = trim(sf.next(","));
  558. if (!baseurl.empty())
  559. m_media_downloader->addRemoteServer(baseurl);
  560. }
  561. }
  562. catch(SerializationError& e) {
  563. // not supported by server or turned off
  564. }
  565. m_media_downloader->step(this);
  566. }
  567. void Client::handleCommand_Media(NetworkPacket* pkt)
  568. {
  569. /*
  570. u16 command
  571. u16 total number of file bunches
  572. u16 index of this bunch
  573. u32 number of files in this bunch
  574. for each file {
  575. u16 length of name
  576. string name
  577. u32 length of data
  578. data
  579. }
  580. */
  581. u16 num_bunches;
  582. u16 bunch_i;
  583. u32 num_files;
  584. *pkt >> num_bunches >> bunch_i >> num_files;
  585. infostream << "Client: Received files: bunch " << bunch_i << "/"
  586. << num_bunches << " files=" << num_files
  587. << " size=" << pkt->getSize() << std::endl;
  588. if (num_files == 0)
  589. return;
  590. if (!m_media_downloader || !m_media_downloader->isStarted()) {
  591. const char *problem = m_media_downloader ?
  592. "media has not been requested" :
  593. "all media has been received already";
  594. errorstream << "Client: Received media but "
  595. << problem << "! "
  596. << " bunch " << bunch_i << "/" << num_bunches
  597. << " files=" << num_files
  598. << " size=" << pkt->getSize() << std::endl;
  599. return;
  600. }
  601. // Mesh update thread must be stopped while
  602. // updating content definitions
  603. sanity_check(!m_mesh_update_thread.isRunning());
  604. for (u32 i=0; i < num_files; i++) {
  605. std::string name;
  606. *pkt >> name;
  607. std::string data = pkt->readLongString();
  608. m_media_downloader->conventionalTransferDone(
  609. name, data, this);
  610. }
  611. }
  612. void Client::handleCommand_NodeDef(NetworkPacket* pkt)
  613. {
  614. infostream << "Client: Received node definitions: packet size: "
  615. << pkt->getSize() << std::endl;
  616. // Mesh update thread must be stopped while
  617. // updating content definitions
  618. sanity_check(!m_mesh_update_thread.isRunning());
  619. // Decompress node definitions
  620. std::istringstream tmp_is(pkt->readLongString(), std::ios::binary);
  621. std::ostringstream tmp_os;
  622. decompressZlib(tmp_is, tmp_os);
  623. // Deserialize node definitions
  624. std::istringstream tmp_is2(tmp_os.str());
  625. m_nodedef->deSerialize(tmp_is2);
  626. m_nodedef_received = true;
  627. }
  628. void Client::handleCommand_ItemDef(NetworkPacket* pkt)
  629. {
  630. infostream << "Client: Received item definitions: packet size: "
  631. << pkt->getSize() << std::endl;
  632. // Mesh update thread must be stopped while
  633. // updating content definitions
  634. sanity_check(!m_mesh_update_thread.isRunning());
  635. // Decompress item definitions
  636. std::istringstream tmp_is(pkt->readLongString(), std::ios::binary);
  637. std::ostringstream tmp_os;
  638. decompressZlib(tmp_is, tmp_os);
  639. // Deserialize node definitions
  640. std::istringstream tmp_is2(tmp_os.str());
  641. m_itemdef->deSerialize(tmp_is2);
  642. m_itemdef_received = true;
  643. }
  644. void Client::handleCommand_PlaySound(NetworkPacket* pkt)
  645. {
  646. /*
  647. [0] u32 server_id
  648. [4] u16 name length
  649. [6] char name[len]
  650. [ 6 + len] f32 gain
  651. [10 + len] u8 type
  652. [11 + len] (f32 * 3) pos
  653. [23 + len] u16 object_id
  654. [25 + len] bool loop
  655. [26 + len] f32 fade
  656. [30 + len] f32 pitch
  657. */
  658. s32 server_id;
  659. std::string name;
  660. float gain;
  661. u8 type; // 0=local, 1=positional, 2=object
  662. v3f pos;
  663. u16 object_id;
  664. bool loop;
  665. float fade = 0.0f;
  666. float pitch = 1.0f;
  667. *pkt >> server_id >> name >> gain >> type >> pos >> object_id >> loop;
  668. try {
  669. *pkt >> fade;
  670. *pkt >> pitch;
  671. } catch (PacketError &e) {};
  672. // Start playing
  673. int client_id = -1;
  674. switch(type) {
  675. case 0: // local
  676. client_id = m_sound->playSound(name, loop, gain, fade, pitch);
  677. break;
  678. case 1: // positional
  679. client_id = m_sound->playSoundAt(name, loop, gain, pos, pitch);
  680. break;
  681. case 2:
  682. { // object
  683. ClientActiveObject *cao = m_env.getActiveObject(object_id);
  684. if (cao)
  685. pos = cao->getPosition();
  686. client_id = m_sound->playSoundAt(name, loop, gain, pos, pitch);
  687. // TODO: Set up sound to move with object
  688. break;
  689. }
  690. default:
  691. break;
  692. }
  693. if (client_id != -1) {
  694. m_sounds_server_to_client[server_id] = client_id;
  695. m_sounds_client_to_server[client_id] = server_id;
  696. if (object_id != 0)
  697. m_sounds_to_objects[client_id] = object_id;
  698. }
  699. }
  700. void Client::handleCommand_StopSound(NetworkPacket* pkt)
  701. {
  702. s32 server_id;
  703. *pkt >> server_id;
  704. std::unordered_map<s32, int>::iterator i = m_sounds_server_to_client.find(server_id);
  705. if (i != m_sounds_server_to_client.end()) {
  706. int client_id = i->second;
  707. m_sound->stopSound(client_id);
  708. }
  709. }
  710. void Client::handleCommand_FadeSound(NetworkPacket *pkt)
  711. {
  712. s32 sound_id;
  713. float step;
  714. float gain;
  715. *pkt >> sound_id >> step >> gain;
  716. std::unordered_map<s32, int>::const_iterator i =
  717. m_sounds_server_to_client.find(sound_id);
  718. if (i != m_sounds_server_to_client.end())
  719. m_sound->fadeSound(i->second, step, gain);
  720. }
  721. void Client::handleCommand_Privileges(NetworkPacket* pkt)
  722. {
  723. m_privileges.clear();
  724. infostream << "Client: Privileges updated: ";
  725. u16 num_privileges;
  726. *pkt >> num_privileges;
  727. for (u16 i = 0; i < num_privileges; i++) {
  728. std::string priv;
  729. *pkt >> priv;
  730. m_privileges.insert(priv);
  731. infostream << priv << " ";
  732. }
  733. infostream << std::endl;
  734. }
  735. void Client::handleCommand_InventoryFormSpec(NetworkPacket* pkt)
  736. {
  737. LocalPlayer *player = m_env.getLocalPlayer();
  738. assert(player != NULL);
  739. // Store formspec in LocalPlayer
  740. player->inventory_formspec = pkt->readLongString();
  741. }
  742. void Client::handleCommand_DetachedInventory(NetworkPacket* pkt)
  743. {
  744. std::string datastring(pkt->getString(0), pkt->getSize());
  745. std::istringstream is(datastring, std::ios_base::binary);
  746. std::string name = deSerializeString(is);
  747. infostream << "Client: Detached inventory update: \"" << name
  748. << "\"" << std::endl;
  749. Inventory *inv = NULL;
  750. if (m_detached_inventories.count(name) > 0)
  751. inv = m_detached_inventories[name];
  752. else {
  753. inv = new Inventory(m_itemdef);
  754. m_detached_inventories[name] = inv;
  755. }
  756. inv->deSerialize(is);
  757. }
  758. void Client::handleCommand_ShowFormSpec(NetworkPacket* pkt)
  759. {
  760. std::string formspec = pkt->readLongString();
  761. std::string formname;
  762. *pkt >> formname;
  763. ClientEvent event;
  764. event.type = CE_SHOW_FORMSPEC;
  765. // pointer is required as event is a struct only!
  766. // adding a std:string to a struct isn't possible
  767. event.show_formspec.formspec = new std::string(formspec);
  768. event.show_formspec.formname = new std::string(formname);
  769. m_client_event_queue.push(event);
  770. }
  771. void Client::handleCommand_SpawnParticle(NetworkPacket* pkt)
  772. {
  773. std::string datastring(pkt->getString(0), pkt->getSize());
  774. std::istringstream is(datastring, std::ios_base::binary);
  775. v3f pos = readV3F1000(is);
  776. v3f vel = readV3F1000(is);
  777. v3f acc = readV3F1000(is);
  778. float expirationtime = readF1000(is);
  779. float size = readF1000(is);
  780. bool collisiondetection = readU8(is);
  781. std::string texture = deSerializeLongString(is);
  782. bool vertical = false;
  783. bool collision_removal = false;
  784. struct TileAnimationParams animation;
  785. animation.type = TAT_NONE;
  786. u8 glow = 0;
  787. try {
  788. vertical = readU8(is);
  789. collision_removal = readU8(is);
  790. animation.deSerialize(is, m_proto_ver);
  791. glow = readU8(is);
  792. } catch (...) {}
  793. ClientEvent event;
  794. event.type = CE_SPAWN_PARTICLE;
  795. event.spawn_particle.pos = new v3f (pos);
  796. event.spawn_particle.vel = new v3f (vel);
  797. event.spawn_particle.acc = new v3f (acc);
  798. event.spawn_particle.expirationtime = expirationtime;
  799. event.spawn_particle.size = size;
  800. event.spawn_particle.collisiondetection = collisiondetection;
  801. event.spawn_particle.collision_removal = collision_removal;
  802. event.spawn_particle.vertical = vertical;
  803. event.spawn_particle.texture = new std::string(texture);
  804. event.spawn_particle.animation = animation;
  805. event.spawn_particle.glow = glow;
  806. m_client_event_queue.push(event);
  807. }
  808. void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
  809. {
  810. u16 amount;
  811. float spawntime;
  812. v3f minpos;
  813. v3f maxpos;
  814. v3f minvel;
  815. v3f maxvel;
  816. v3f minacc;
  817. v3f maxacc;
  818. float minexptime;
  819. float maxexptime;
  820. float minsize;
  821. float maxsize;
  822. bool collisiondetection;
  823. u32 id;
  824. *pkt >> amount >> spawntime >> minpos >> maxpos >> minvel >> maxvel
  825. >> minacc >> maxacc >> minexptime >> maxexptime >> minsize
  826. >> maxsize >> collisiondetection;
  827. std::string texture = pkt->readLongString();
  828. *pkt >> id;
  829. bool vertical = false;
  830. bool collision_removal = false;
  831. struct TileAnimationParams animation;
  832. animation.type = TAT_NONE;
  833. u8 glow = 0;
  834. u16 attached_id = 0;
  835. try {
  836. *pkt >> vertical;
  837. *pkt >> collision_removal;
  838. *pkt >> attached_id;
  839. // This is horrible but required (why are there two ways to deserialize pkts?)
  840. std::string datastring(pkt->getRemainingString(), pkt->getRemainingBytes());
  841. std::istringstream is(datastring, std::ios_base::binary);
  842. animation.deSerialize(is, m_proto_ver);
  843. glow = readU8(is);
  844. } catch (...) {}
  845. ClientEvent event;
  846. event.type = CE_ADD_PARTICLESPAWNER;
  847. event.add_particlespawner.amount = amount;
  848. event.add_particlespawner.spawntime = spawntime;
  849. event.add_particlespawner.minpos = new v3f (minpos);
  850. event.add_particlespawner.maxpos = new v3f (maxpos);
  851. event.add_particlespawner.minvel = new v3f (minvel);
  852. event.add_particlespawner.maxvel = new v3f (maxvel);
  853. event.add_particlespawner.minacc = new v3f (minacc);
  854. event.add_particlespawner.maxacc = new v3f (maxacc);
  855. event.add_particlespawner.minexptime = minexptime;
  856. event.add_particlespawner.maxexptime = maxexptime;
  857. event.add_particlespawner.minsize = minsize;
  858. event.add_particlespawner.maxsize = maxsize;
  859. event.add_particlespawner.collisiondetection = collisiondetection;
  860. event.add_particlespawner.collision_removal = collision_removal;
  861. event.add_particlespawner.attached_id = attached_id;
  862. event.add_particlespawner.vertical = vertical;
  863. event.add_particlespawner.texture = new std::string(texture);
  864. event.add_particlespawner.id = id;
  865. event.add_particlespawner.animation = animation;
  866. event.add_particlespawner.glow = glow;
  867. m_client_event_queue.push(event);
  868. }
  869. void Client::handleCommand_DeleteParticleSpawner(NetworkPacket* pkt)
  870. {
  871. u16 legacy_id;
  872. u32 id;
  873. // Modification set 13/03/15, 1 year of compat for protocol v24
  874. if (pkt->getCommand() == TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY) {
  875. *pkt >> legacy_id;
  876. }
  877. else {
  878. *pkt >> id;
  879. }
  880. ClientEvent event;
  881. event.type = CE_DELETE_PARTICLESPAWNER;
  882. event.delete_particlespawner.id =
  883. (pkt->getCommand() == TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY ? (u32) legacy_id : id);
  884. m_client_event_queue.push(event);
  885. }
  886. void Client::handleCommand_HudAdd(NetworkPacket* pkt)
  887. {
  888. std::string datastring(pkt->getString(0), pkt->getSize());
  889. std::istringstream is(datastring, std::ios_base::binary);
  890. u32 id;
  891. u8 type;
  892. v2f pos;
  893. std::string name;
  894. v2f scale;
  895. std::string text;
  896. u32 number;
  897. u32 item;
  898. u32 dir;
  899. v2f align;
  900. v2f offset;
  901. v3f world_pos;
  902. v2s32 size;
  903. *pkt >> id >> type >> pos >> name >> scale >> text >> number >> item
  904. >> dir >> align >> offset;
  905. try {
  906. *pkt >> world_pos;
  907. }
  908. catch(SerializationError &e) {};
  909. try {
  910. *pkt >> size;
  911. } catch(SerializationError &e) {};
  912. ClientEvent event;
  913. event.type = CE_HUDADD;
  914. event.hudadd.id = id;
  915. event.hudadd.type = type;
  916. event.hudadd.pos = new v2f(pos);
  917. event.hudadd.name = new std::string(name);
  918. event.hudadd.scale = new v2f(scale);
  919. event.hudadd.text = new std::string(text);
  920. event.hudadd.number = number;
  921. event.hudadd.item = item;
  922. event.hudadd.dir = dir;
  923. event.hudadd.align = new v2f(align);
  924. event.hudadd.offset = new v2f(offset);
  925. event.hudadd.world_pos = new v3f(world_pos);
  926. event.hudadd.size = new v2s32(size);
  927. m_client_event_queue.push(event);
  928. }
  929. void Client::handleCommand_HudRemove(NetworkPacket* pkt)
  930. {
  931. u32 id;
  932. *pkt >> id;
  933. ClientEvent event;
  934. event.type = CE_HUDRM;
  935. event.hudrm.id = id;
  936. m_client_event_queue.push(event);
  937. }
  938. void Client::handleCommand_HudChange(NetworkPacket* pkt)
  939. {
  940. std::string sdata;
  941. v2f v2fdata;
  942. v3f v3fdata;
  943. u32 intdata = 0;
  944. v2s32 v2s32data;
  945. u32 id;
  946. u8 stat;
  947. *pkt >> id >> stat;
  948. if (stat == HUD_STAT_POS || stat == HUD_STAT_SCALE ||
  949. stat == HUD_STAT_ALIGN || stat == HUD_STAT_OFFSET)
  950. *pkt >> v2fdata;
  951. else if (stat == HUD_STAT_NAME || stat == HUD_STAT_TEXT)
  952. *pkt >> sdata;
  953. else if (stat == HUD_STAT_WORLD_POS)
  954. *pkt >> v3fdata;
  955. else if (stat == HUD_STAT_SIZE )
  956. *pkt >> v2s32data;
  957. else
  958. *pkt >> intdata;
  959. ClientEvent event;
  960. event.type = CE_HUDCHANGE;
  961. event.hudchange.id = id;
  962. event.hudchange.stat = (HudElementStat)stat;
  963. event.hudchange.v2fdata = new v2f(v2fdata);
  964. event.hudchange.v3fdata = new v3f(v3fdata);
  965. event.hudchange.sdata = new std::string(sdata);
  966. event.hudchange.data = intdata;
  967. event.hudchange.v2s32data = new v2s32(v2s32data);
  968. m_client_event_queue.push(event);
  969. }
  970. void Client::handleCommand_HudSetFlags(NetworkPacket* pkt)
  971. {
  972. u32 flags, mask;
  973. *pkt >> flags >> mask;
  974. LocalPlayer *player = m_env.getLocalPlayer();
  975. assert(player != NULL);
  976. bool was_minimap_visible = player->hud_flags & HUD_FLAG_MINIMAP_VISIBLE;
  977. bool was_minimap_radar_visible = player->hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE;
  978. player->hud_flags &= ~mask;
  979. player->hud_flags |= flags;
  980. m_minimap_disabled_by_server = !(player->hud_flags & HUD_FLAG_MINIMAP_VISIBLE);
  981. bool m_minimap_radar_disabled_by_server = !(player->hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE);
  982. // Hide minimap if it has been disabled by the server
  983. if (m_minimap && m_minimap_disabled_by_server && was_minimap_visible)
  984. // defers a minimap update, therefore only call it if really
  985. // needed, by checking that minimap was visible before
  986. m_minimap->setMinimapMode(MINIMAP_MODE_OFF);
  987. // Switch to surface mode if radar disabled by server
  988. if (m_minimap && m_minimap_radar_disabled_by_server && was_minimap_radar_visible)
  989. m_minimap->setMinimapMode(MINIMAP_MODE_SURFACEx1);
  990. }
  991. void Client::handleCommand_HudSetParam(NetworkPacket* pkt)
  992. {
  993. u16 param; std::string value;
  994. *pkt >> param >> value;
  995. LocalPlayer *player = m_env.getLocalPlayer();
  996. assert(player != NULL);
  997. if (param == HUD_PARAM_HOTBAR_ITEMCOUNT && value.size() == 4) {
  998. s32 hotbar_itemcount = readS32((u8*) value.c_str());
  999. if (hotbar_itemcount > 0 && hotbar_itemcount <= HUD_HOTBAR_ITEMCOUNT_MAX)
  1000. player->hud_hotbar_itemcount = hotbar_itemcount;
  1001. }
  1002. else if (param == HUD_PARAM_HOTBAR_IMAGE) {
  1003. // If value not empty verify image exists in texture source
  1004. if (!value.empty() && !getTextureSource()->isKnownSourceImage(value)) {
  1005. errorstream << "Server sent wrong Hud hotbar image (sent value: '"
  1006. << value << "')" << std::endl;
  1007. return;
  1008. }
  1009. player->hotbar_image = value;
  1010. }
  1011. else if (param == HUD_PARAM_HOTBAR_SELECTED_IMAGE) {
  1012. // If value not empty verify image exists in texture source
  1013. if (!value.empty() && !getTextureSource()->isKnownSourceImage(value)) {
  1014. errorstream << "Server sent wrong Hud hotbar selected image (sent value: '"
  1015. << value << "')" << std::endl;
  1016. return;
  1017. }
  1018. player->hotbar_selected_image = value;
  1019. }
  1020. }
  1021. void Client::handleCommand_HudSetSky(NetworkPacket* pkt)
  1022. {
  1023. std::string datastring(pkt->getString(0), pkt->getSize());
  1024. std::istringstream is(datastring, std::ios_base::binary);
  1025. video::SColor *bgcolor = new video::SColor(readARGB8(is));
  1026. std::string *type = new std::string(deSerializeString(is));
  1027. u16 count = readU16(is);
  1028. std::vector<std::string> *params = new std::vector<std::string>;
  1029. for (size_t i = 0; i < count; i++)
  1030. params->push_back(deSerializeString(is));
  1031. bool clouds = true;
  1032. try {
  1033. clouds = readU8(is);
  1034. } catch (...) {}
  1035. ClientEvent event;
  1036. event.type = CE_SET_SKY;
  1037. event.set_sky.bgcolor = bgcolor;
  1038. event.set_sky.type = type;
  1039. event.set_sky.params = params;
  1040. event.set_sky.clouds = clouds;
  1041. m_client_event_queue.push(event);
  1042. }
  1043. void Client::handleCommand_CloudParams(NetworkPacket* pkt)
  1044. {
  1045. f32 density;
  1046. video::SColor color_bright;
  1047. video::SColor color_ambient;
  1048. f32 height;
  1049. f32 thickness;
  1050. v2f speed;
  1051. *pkt >> density >> color_bright >> color_ambient
  1052. >> height >> thickness >> speed;
  1053. ClientEvent event;
  1054. event.type = CE_CLOUD_PARAMS;
  1055. event.cloud_params.density = density;
  1056. // use the underlying u32 representation, because we can't
  1057. // use struct members with constructors here, and this way
  1058. // we avoid using new() and delete() for no good reason
  1059. event.cloud_params.color_bright = color_bright.color;
  1060. event.cloud_params.color_ambient = color_ambient.color;
  1061. event.cloud_params.height = height;
  1062. event.cloud_params.thickness = thickness;
  1063. // same here: deconstruct to skip constructor
  1064. event.cloud_params.speed_x = speed.X;
  1065. event.cloud_params.speed_y = speed.Y;
  1066. m_client_event_queue.push(event);
  1067. }
  1068. void Client::handleCommand_OverrideDayNightRatio(NetworkPacket* pkt)
  1069. {
  1070. bool do_override;
  1071. u16 day_night_ratio_u;
  1072. *pkt >> do_override >> day_night_ratio_u;
  1073. float day_night_ratio_f = (float)day_night_ratio_u / 65536;
  1074. ClientEvent event;
  1075. event.type = CE_OVERRIDE_DAY_NIGHT_RATIO;
  1076. event.override_day_night_ratio.do_override = do_override;
  1077. event.override_day_night_ratio.ratio_f = day_night_ratio_f;
  1078. m_client_event_queue.push(event);
  1079. }
  1080. void Client::handleCommand_LocalPlayerAnimations(NetworkPacket* pkt)
  1081. {
  1082. LocalPlayer *player = m_env.getLocalPlayer();
  1083. assert(player != NULL);
  1084. *pkt >> player->local_animations[0];
  1085. *pkt >> player->local_animations[1];
  1086. *pkt >> player->local_animations[2];
  1087. *pkt >> player->local_animations[3];
  1088. *pkt >> player->local_animation_speed;
  1089. }
  1090. void Client::handleCommand_EyeOffset(NetworkPacket* pkt)
  1091. {
  1092. LocalPlayer *player = m_env.getLocalPlayer();
  1093. assert(player != NULL);
  1094. *pkt >> player->eye_offset_first >> player->eye_offset_third;
  1095. }
  1096. void Client::handleCommand_UpdatePlayerList(NetworkPacket* pkt)
  1097. {
  1098. u8 type;
  1099. u16 num_players;
  1100. *pkt >> type >> num_players;
  1101. PlayerListModifer notice_type = (PlayerListModifer) type;
  1102. for (u16 i = 0; i < num_players; i++) {
  1103. std::string name;
  1104. *pkt >> name;
  1105. switch (notice_type) {
  1106. case PLAYER_LIST_INIT:
  1107. case PLAYER_LIST_ADD:
  1108. m_env.addPlayerName(name);
  1109. continue;
  1110. case PLAYER_LIST_REMOVE:
  1111. m_env.removePlayerName(name);
  1112. continue;
  1113. }
  1114. }
  1115. }
  1116. void Client::handleCommand_SrpBytesSandB(NetworkPacket* pkt)
  1117. {
  1118. if ((m_chosen_auth_mech != AUTH_MECHANISM_LEGACY_PASSWORD)
  1119. && (m_chosen_auth_mech != AUTH_MECHANISM_SRP)) {
  1120. errorstream << "Client: Recieved SRP S_B login message,"
  1121. << " but wasn't supposed to (chosen_mech="
  1122. << m_chosen_auth_mech << ")." << std::endl;
  1123. return;
  1124. }
  1125. char *bytes_M = 0;
  1126. size_t len_M = 0;
  1127. SRPUser *usr = (SRPUser *) m_auth_data;
  1128. std::string s;
  1129. std::string B;
  1130. *pkt >> s >> B;
  1131. infostream << "Client: Recieved TOCLIENT_SRP_BYTES_S_B." << std::endl;
  1132. srp_user_process_challenge(usr, (const unsigned char *) s.c_str(), s.size(),
  1133. (const unsigned char *) B.c_str(), B.size(),
  1134. (unsigned char **) &bytes_M, &len_M);
  1135. if ( !bytes_M ) {
  1136. errorstream << "Client: SRP-6a S_B safety check violation!" << std::endl;
  1137. return;
  1138. }
  1139. NetworkPacket resp_pkt(TOSERVER_SRP_BYTES_M, 0);
  1140. resp_pkt << std::string(bytes_M, len_M);
  1141. Send(&resp_pkt);
  1142. }
  1143. void Client::handleCommand_CSMFlavourLimits(NetworkPacket *pkt)
  1144. {
  1145. *pkt >> m_csm_flavour_limits >> m_csm_noderange_limit;
  1146. }