networkpacket.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  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 "networkpacket.h"
  17. #include <sstream>
  18. #include "networkexceptions.h"
  19. #include "util/serialize.h"
  20. #include "networkprotocol.h"
  21. NetworkPacket::NetworkPacket(u16 command, u32 datasize, session_t peer_id):
  22. m_datasize(datasize), m_command(command), m_peer_id(peer_id)
  23. {
  24. m_data.resize(m_datasize);
  25. }
  26. NetworkPacket::NetworkPacket(u16 command, u32 datasize):
  27. m_datasize(datasize), m_command(command)
  28. {
  29. m_data.resize(m_datasize);
  30. }
  31. NetworkPacket::~NetworkPacket()
  32. {
  33. m_data.clear();
  34. }
  35. void NetworkPacket::checkReadOffset(u32 from_offset, u32 field_size)
  36. {
  37. if (from_offset + field_size > m_datasize) {
  38. std::stringstream ss;
  39. ss << "Reading outside packet (offset: " <<
  40. from_offset << ", packet size: " << getSize() << ")";
  41. throw PacketError(ss.str());
  42. }
  43. }
  44. void NetworkPacket::putRawPacket(const u8 *data, u32 datasize, session_t peer_id)
  45. {
  46. // If a m_command is already set, we are rewriting on same packet
  47. // This is not permitted
  48. assert(m_command == 0);
  49. m_datasize = datasize - 2;
  50. m_peer_id = peer_id;
  51. m_data.resize(m_datasize);
  52. // split command and datas
  53. m_command = readU16(&data[0]);
  54. memcpy(m_data.data(), &data[2], m_datasize);
  55. }
  56. void NetworkPacket::clear()
  57. {
  58. m_data.clear();
  59. m_datasize = 0;
  60. m_read_offset = 0;
  61. m_command = 0;
  62. m_peer_id = 0;
  63. }
  64. const char* NetworkPacket::getString(u32 from_offset)
  65. {
  66. checkReadOffset(from_offset, 0);
  67. return (char*)&m_data[from_offset];
  68. }
  69. void NetworkPacket::putRawString(const char* src, u32 len)
  70. {
  71. if (m_read_offset + len > m_datasize) {
  72. m_datasize = m_read_offset + len;
  73. m_data.resize(m_datasize);
  74. }
  75. if (len == 0)
  76. return;
  77. memcpy(&m_data[m_read_offset], src, len);
  78. m_read_offset += len;
  79. }
  80. NetworkPacket& NetworkPacket::operator>>(std::string& dst)
  81. {
  82. checkReadOffset(m_read_offset, 2);
  83. u16 strLen = readU16(&m_data[m_read_offset]);
  84. m_read_offset += 2;
  85. dst.clear();
  86. if (strLen == 0) {
  87. return *this;
  88. }
  89. checkReadOffset(m_read_offset, strLen);
  90. dst.reserve(strLen);
  91. dst.append((char*)&m_data[m_read_offset], strLen);
  92. m_read_offset += strLen;
  93. return *this;
  94. }
  95. NetworkPacket& NetworkPacket::operator<<(const std::string &src)
  96. {
  97. if (src.size() > STRING_MAX_LEN) {
  98. throw PacketError("String too long");
  99. }
  100. u16 msgsize = src.size();
  101. *this << msgsize;
  102. putRawString(src.c_str(), (u32)msgsize);
  103. return *this;
  104. }
  105. void NetworkPacket::putLongString(const std::string &src)
  106. {
  107. if (src.size() > LONG_STRING_MAX_LEN) {
  108. throw PacketError("String too long");
  109. }
  110. u32 msgsize = src.size();
  111. *this << msgsize;
  112. putRawString(src.c_str(), msgsize);
  113. }
  114. static constexpr bool NEED_SURROGATE_CODING = sizeof(wchar_t) > 2;
  115. NetworkPacket& NetworkPacket::operator>>(std::wstring& dst)
  116. {
  117. checkReadOffset(m_read_offset, 2);
  118. u16 strLen = readU16(&m_data[m_read_offset]);
  119. m_read_offset += 2;
  120. dst.clear();
  121. if (strLen == 0) {
  122. return *this;
  123. }
  124. checkReadOffset(m_read_offset, strLen * 2);
  125. dst.reserve(strLen);
  126. for (u16 i = 0; i < strLen; i++) {
  127. wchar_t c = readU16(&m_data[m_read_offset]);
  128. if (NEED_SURROGATE_CODING && c >= 0xD800 && c < 0xDC00 && i+1 < strLen) {
  129. i++;
  130. m_read_offset += sizeof(u16);
  131. wchar_t c2 = readU16(&m_data[m_read_offset]);
  132. c = 0x10000 + ( ((c & 0x3ff) << 10) | (c2 & 0x3ff) );
  133. }
  134. dst.push_back(c);
  135. m_read_offset += sizeof(u16);
  136. }
  137. return *this;
  138. }
  139. NetworkPacket& NetworkPacket::operator<<(const std::wstring &src)
  140. {
  141. if (src.size() > WIDE_STRING_MAX_LEN) {
  142. throw PacketError("String too long");
  143. }
  144. if (!NEED_SURROGATE_CODING || src.size() == 0) {
  145. *this << static_cast<u16>(src.size());
  146. for (u16 i = 0; i < src.size(); i++)
  147. *this << static_cast<u16>(src[i]);
  148. return *this;
  149. }
  150. // write dummy value, to be overwritten later
  151. const u32 len_offset = m_read_offset;
  152. u32 written = 0;
  153. *this << static_cast<u16>(0xfff0);
  154. for (u16 i = 0; i < src.size(); i++) {
  155. wchar_t c = src[i];
  156. if (c > 0xffff) {
  157. // Encode high code-points as surrogate pairs
  158. u32 n = c - 0x10000;
  159. *this << static_cast<u16>(0xD800 | (n >> 10))
  160. << static_cast<u16>(0xDC00 | (n & 0x3ff));
  161. written += 2;
  162. } else {
  163. *this << static_cast<u16>(c);
  164. written++;
  165. }
  166. }
  167. if (written > WIDE_STRING_MAX_LEN)
  168. throw PacketError("String too long");
  169. writeU16(&m_data[len_offset], written);
  170. return *this;
  171. }
  172. std::string NetworkPacket::readLongString()
  173. {
  174. checkReadOffset(m_read_offset, 4);
  175. u32 strLen = readU32(&m_data[m_read_offset]);
  176. m_read_offset += 4;
  177. if (strLen == 0) {
  178. return "";
  179. }
  180. if (strLen > LONG_STRING_MAX_LEN) {
  181. throw PacketError("String too long");
  182. }
  183. checkReadOffset(m_read_offset, strLen);
  184. std::string dst;
  185. dst.reserve(strLen);
  186. dst.append((char*)&m_data[m_read_offset], strLen);
  187. m_read_offset += strLen;
  188. return dst;
  189. }
  190. NetworkPacket& NetworkPacket::operator>>(char& dst)
  191. {
  192. checkReadOffset(m_read_offset, 1);
  193. dst = readU8(&m_data[m_read_offset]);
  194. m_read_offset += 1;
  195. return *this;
  196. }
  197. NetworkPacket& NetworkPacket::operator<<(char src)
  198. {
  199. checkDataSize(1);
  200. writeU8(&m_data[m_read_offset], src);
  201. m_read_offset += 1;
  202. return *this;
  203. }
  204. NetworkPacket& NetworkPacket::operator<<(u8 src)
  205. {
  206. checkDataSize(1);
  207. writeU8(&m_data[m_read_offset], src);
  208. m_read_offset += 1;
  209. return *this;
  210. }
  211. NetworkPacket& NetworkPacket::operator<<(bool src)
  212. {
  213. checkDataSize(1);
  214. writeU8(&m_data[m_read_offset], src);
  215. m_read_offset += 1;
  216. return *this;
  217. }
  218. NetworkPacket& NetworkPacket::operator<<(u16 src)
  219. {
  220. checkDataSize(2);
  221. writeU16(&m_data[m_read_offset], src);
  222. m_read_offset += 2;
  223. return *this;
  224. }
  225. NetworkPacket& NetworkPacket::operator<<(u32 src)
  226. {
  227. checkDataSize(4);
  228. writeU32(&m_data[m_read_offset], src);
  229. m_read_offset += 4;
  230. return *this;
  231. }
  232. NetworkPacket& NetworkPacket::operator<<(u64 src)
  233. {
  234. checkDataSize(8);
  235. writeU64(&m_data[m_read_offset], src);
  236. m_read_offset += 8;
  237. return *this;
  238. }
  239. NetworkPacket& NetworkPacket::operator<<(float src)
  240. {
  241. checkDataSize(4);
  242. writeF32(&m_data[m_read_offset], src);
  243. m_read_offset += 4;
  244. return *this;
  245. }
  246. NetworkPacket& NetworkPacket::operator>>(bool& dst)
  247. {
  248. checkReadOffset(m_read_offset, 1);
  249. dst = readU8(&m_data[m_read_offset]);
  250. m_read_offset += 1;
  251. return *this;
  252. }
  253. NetworkPacket& NetworkPacket::operator>>(u8& dst)
  254. {
  255. checkReadOffset(m_read_offset, 1);
  256. dst = readU8(&m_data[m_read_offset]);
  257. m_read_offset += 1;
  258. return *this;
  259. }
  260. u8 NetworkPacket::getU8(u32 offset)
  261. {
  262. checkReadOffset(offset, 1);
  263. return readU8(&m_data[offset]);
  264. }
  265. u8* NetworkPacket::getU8Ptr(u32 from_offset)
  266. {
  267. if (m_datasize == 0) {
  268. return NULL;
  269. }
  270. checkReadOffset(from_offset, 1);
  271. return (u8*)&m_data[from_offset];
  272. }
  273. NetworkPacket& NetworkPacket::operator>>(u16& dst)
  274. {
  275. checkReadOffset(m_read_offset, 2);
  276. dst = readU16(&m_data[m_read_offset]);
  277. m_read_offset += 2;
  278. return *this;
  279. }
  280. u16 NetworkPacket::getU16(u32 from_offset)
  281. {
  282. checkReadOffset(from_offset, 2);
  283. return readU16(&m_data[from_offset]);
  284. }
  285. NetworkPacket& NetworkPacket::operator>>(u32& dst)
  286. {
  287. checkReadOffset(m_read_offset, 4);
  288. dst = readU32(&m_data[m_read_offset]);
  289. m_read_offset += 4;
  290. return *this;
  291. }
  292. NetworkPacket& NetworkPacket::operator>>(u64& dst)
  293. {
  294. checkReadOffset(m_read_offset, 8);
  295. dst = readU64(&m_data[m_read_offset]);
  296. m_read_offset += 8;
  297. return *this;
  298. }
  299. NetworkPacket& NetworkPacket::operator>>(float& dst)
  300. {
  301. checkReadOffset(m_read_offset, 4);
  302. dst = readF32(&m_data[m_read_offset]);
  303. m_read_offset += 4;
  304. return *this;
  305. }
  306. NetworkPacket& NetworkPacket::operator>>(v2f& dst)
  307. {
  308. checkReadOffset(m_read_offset, 8);
  309. dst = readV2F32(&m_data[m_read_offset]);
  310. m_read_offset += 8;
  311. return *this;
  312. }
  313. NetworkPacket& NetworkPacket::operator>>(v3f& dst)
  314. {
  315. checkReadOffset(m_read_offset, 12);
  316. dst = readV3F32(&m_data[m_read_offset]);
  317. m_read_offset += 12;
  318. return *this;
  319. }
  320. NetworkPacket& NetworkPacket::operator>>(s16& dst)
  321. {
  322. checkReadOffset(m_read_offset, 2);
  323. dst = readS16(&m_data[m_read_offset]);
  324. m_read_offset += 2;
  325. return *this;
  326. }
  327. NetworkPacket& NetworkPacket::operator<<(s16 src)
  328. {
  329. *this << (u16) src;
  330. return *this;
  331. }
  332. NetworkPacket& NetworkPacket::operator>>(s32& dst)
  333. {
  334. checkReadOffset(m_read_offset, 4);
  335. dst = readS32(&m_data[m_read_offset]);
  336. m_read_offset += 4;
  337. return *this;
  338. }
  339. NetworkPacket& NetworkPacket::operator<<(s32 src)
  340. {
  341. *this << (u32) src;
  342. return *this;
  343. }
  344. NetworkPacket& NetworkPacket::operator>>(v3s16& dst)
  345. {
  346. checkReadOffset(m_read_offset, 6);
  347. dst = readV3S16(&m_data[m_read_offset]);
  348. m_read_offset += 6;
  349. return *this;
  350. }
  351. NetworkPacket& NetworkPacket::operator>>(v2s32& dst)
  352. {
  353. checkReadOffset(m_read_offset, 8);
  354. dst = readV2S32(&m_data[m_read_offset]);
  355. m_read_offset += 8;
  356. return *this;
  357. }
  358. NetworkPacket& NetworkPacket::operator>>(v3s32& dst)
  359. {
  360. checkReadOffset(m_read_offset, 12);
  361. dst = readV3S32(&m_data[m_read_offset]);
  362. m_read_offset += 12;
  363. return *this;
  364. }
  365. NetworkPacket& NetworkPacket::operator<<(v2f src)
  366. {
  367. *this << (float) src.X;
  368. *this << (float) src.Y;
  369. return *this;
  370. }
  371. NetworkPacket& NetworkPacket::operator<<(v3f src)
  372. {
  373. *this << (float) src.X;
  374. *this << (float) src.Y;
  375. *this << (float) src.Z;
  376. return *this;
  377. }
  378. NetworkPacket& NetworkPacket::operator<<(v3s16 src)
  379. {
  380. *this << (s16) src.X;
  381. *this << (s16) src.Y;
  382. *this << (s16) src.Z;
  383. return *this;
  384. }
  385. NetworkPacket& NetworkPacket::operator<<(v2s32 src)
  386. {
  387. *this << (s32) src.X;
  388. *this << (s32) src.Y;
  389. return *this;
  390. }
  391. NetworkPacket& NetworkPacket::operator<<(v3s32 src)
  392. {
  393. *this << (s32) src.X;
  394. *this << (s32) src.Y;
  395. *this << (s32) src.Z;
  396. return *this;
  397. }
  398. NetworkPacket& NetworkPacket::operator>>(video::SColor& dst)
  399. {
  400. checkReadOffset(m_read_offset, 4);
  401. dst = readARGB8(&m_data[m_read_offset]);
  402. m_read_offset += 4;
  403. return *this;
  404. }
  405. NetworkPacket& NetworkPacket::operator<<(video::SColor src)
  406. {
  407. checkDataSize(4);
  408. writeU32(&m_data[m_read_offset], src.color);
  409. m_read_offset += 4;
  410. return *this;
  411. }
  412. Buffer<u8> NetworkPacket::oldForgePacket()
  413. {
  414. Buffer<u8> sb(m_datasize + 2);
  415. writeU16(&sb[0], m_command);
  416. memcpy(&sb[2], m_data.data(), m_datasize);
  417. return sb;
  418. }