networkpacket.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  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(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. const char* NetworkPacket::getString(u32 from_offset)
  57. {
  58. checkReadOffset(from_offset, 0);
  59. return (char*)&m_data[from_offset];
  60. }
  61. void NetworkPacket::putRawString(const char* src, u32 len)
  62. {
  63. if (m_read_offset + len > m_datasize) {
  64. m_datasize = m_read_offset + len;
  65. m_data.resize(m_datasize);
  66. }
  67. if (len == 0)
  68. return;
  69. memcpy(&m_data[m_read_offset], src, len);
  70. m_read_offset += len;
  71. }
  72. NetworkPacket& NetworkPacket::operator>>(std::string& dst)
  73. {
  74. checkReadOffset(m_read_offset, 2);
  75. u16 strLen = readU16(&m_data[m_read_offset]);
  76. m_read_offset += 2;
  77. dst.clear();
  78. if (strLen == 0) {
  79. return *this;
  80. }
  81. checkReadOffset(m_read_offset, strLen);
  82. dst.reserve(strLen);
  83. dst.append((char*)&m_data[m_read_offset], strLen);
  84. m_read_offset += strLen;
  85. return *this;
  86. }
  87. NetworkPacket& NetworkPacket::operator<<(const std::string &src)
  88. {
  89. u16 msgsize = src.size();
  90. if (msgsize > STRING_MAX_LEN) {
  91. throw PacketError("String too long");
  92. }
  93. *this << msgsize;
  94. putRawString(src.c_str(), (u32)msgsize);
  95. return *this;
  96. }
  97. void NetworkPacket::putLongString(const std::string &src)
  98. {
  99. u32 msgsize = src.size();
  100. if (msgsize > LONG_STRING_MAX_LEN) {
  101. throw PacketError("String too long");
  102. }
  103. *this << msgsize;
  104. putRawString(src.c_str(), msgsize);
  105. }
  106. NetworkPacket& NetworkPacket::operator>>(std::wstring& dst)
  107. {
  108. checkReadOffset(m_read_offset, 2);
  109. u16 strLen = readU16(&m_data[m_read_offset]);
  110. m_read_offset += 2;
  111. dst.clear();
  112. if (strLen == 0) {
  113. return *this;
  114. }
  115. checkReadOffset(m_read_offset, strLen * 2);
  116. dst.reserve(strLen);
  117. for(u16 i=0; i<strLen; i++) {
  118. wchar_t c16 = readU16(&m_data[m_read_offset]);
  119. dst.append(&c16, 1);
  120. m_read_offset += sizeof(u16);
  121. }
  122. return *this;
  123. }
  124. NetworkPacket& NetworkPacket::operator<<(const std::wstring &src)
  125. {
  126. u16 msgsize = src.size();
  127. if (msgsize > WIDE_STRING_MAX_LEN) {
  128. throw PacketError("String too long");
  129. }
  130. *this << msgsize;
  131. // Write string
  132. for (u16 i=0; i<msgsize; i++) {
  133. *this << (u16) src[i];
  134. }
  135. return *this;
  136. }
  137. std::string NetworkPacket::readLongString()
  138. {
  139. checkReadOffset(m_read_offset, 4);
  140. u32 strLen = readU32(&m_data[m_read_offset]);
  141. m_read_offset += 4;
  142. if (strLen == 0) {
  143. return "";
  144. }
  145. if (strLen > LONG_STRING_MAX_LEN) {
  146. throw PacketError("String too long");
  147. }
  148. checkReadOffset(m_read_offset, strLen);
  149. std::string dst;
  150. dst.reserve(strLen);
  151. dst.append((char*)&m_data[m_read_offset], strLen);
  152. m_read_offset += strLen;
  153. return dst;
  154. }
  155. NetworkPacket& NetworkPacket::operator>>(char& dst)
  156. {
  157. checkReadOffset(m_read_offset, 1);
  158. dst = readU8(&m_data[m_read_offset]);
  159. m_read_offset += 1;
  160. return *this;
  161. }
  162. char NetworkPacket::getChar(u32 offset)
  163. {
  164. checkReadOffset(offset, 1);
  165. return readU8(&m_data[offset]);
  166. }
  167. NetworkPacket& NetworkPacket::operator<<(char src)
  168. {
  169. checkDataSize(1);
  170. writeU8(&m_data[m_read_offset], src);
  171. m_read_offset += 1;
  172. return *this;
  173. }
  174. NetworkPacket& NetworkPacket::operator<<(u8 src)
  175. {
  176. checkDataSize(1);
  177. writeU8(&m_data[m_read_offset], src);
  178. m_read_offset += 1;
  179. return *this;
  180. }
  181. NetworkPacket& NetworkPacket::operator<<(bool src)
  182. {
  183. checkDataSize(1);
  184. writeU8(&m_data[m_read_offset], src);
  185. m_read_offset += 1;
  186. return *this;
  187. }
  188. NetworkPacket& NetworkPacket::operator<<(u16 src)
  189. {
  190. checkDataSize(2);
  191. writeU16(&m_data[m_read_offset], src);
  192. m_read_offset += 2;
  193. return *this;
  194. }
  195. NetworkPacket& NetworkPacket::operator<<(u32 src)
  196. {
  197. checkDataSize(4);
  198. writeU32(&m_data[m_read_offset], src);
  199. m_read_offset += 4;
  200. return *this;
  201. }
  202. NetworkPacket& NetworkPacket::operator<<(u64 src)
  203. {
  204. checkDataSize(8);
  205. writeU64(&m_data[m_read_offset], src);
  206. m_read_offset += 8;
  207. return *this;
  208. }
  209. NetworkPacket& NetworkPacket::operator<<(std::time_t src)
  210. {
  211. *this << (u64) src;
  212. return *this;
  213. }
  214. NetworkPacket& NetworkPacket::operator<<(float src)
  215. {
  216. checkDataSize(4);
  217. writeF1000(&m_data[m_read_offset], src);
  218. m_read_offset += 4;
  219. return *this;
  220. }
  221. NetworkPacket& NetworkPacket::operator>>(bool& dst)
  222. {
  223. checkReadOffset(m_read_offset, 1);
  224. dst = readU8(&m_data[m_read_offset]);
  225. m_read_offset += 1;
  226. return *this;
  227. }
  228. NetworkPacket& NetworkPacket::operator>>(u8& dst)
  229. {
  230. checkReadOffset(m_read_offset, 1);
  231. dst = readU8(&m_data[m_read_offset]);
  232. m_read_offset += 1;
  233. return *this;
  234. }
  235. u8 NetworkPacket::getU8(u32 offset)
  236. {
  237. checkReadOffset(offset, 1);
  238. return readU8(&m_data[offset]);
  239. }
  240. u8* NetworkPacket::getU8Ptr(u32 from_offset)
  241. {
  242. if (m_datasize == 0) {
  243. return NULL;
  244. }
  245. checkReadOffset(from_offset, 1);
  246. return (u8*)&m_data[from_offset];
  247. }
  248. NetworkPacket& NetworkPacket::operator>>(u16& dst)
  249. {
  250. checkReadOffset(m_read_offset, 2);
  251. dst = readU16(&m_data[m_read_offset]);
  252. m_read_offset += 2;
  253. return *this;
  254. }
  255. u16 NetworkPacket::getU16(u32 from_offset)
  256. {
  257. checkReadOffset(from_offset, 2);
  258. return readU16(&m_data[from_offset]);
  259. }
  260. NetworkPacket& NetworkPacket::operator>>(u32& dst)
  261. {
  262. checkReadOffset(m_read_offset, 4);
  263. dst = readU32(&m_data[m_read_offset]);
  264. m_read_offset += 4;
  265. return *this;
  266. }
  267. NetworkPacket& NetworkPacket::operator>>(u64& dst)
  268. {
  269. checkReadOffset(m_read_offset, 8);
  270. dst = readU64(&m_data[m_read_offset]);
  271. m_read_offset += 8;
  272. return *this;
  273. }
  274. NetworkPacket& NetworkPacket::operator>>(std::time_t& dst)
  275. {
  276. checkReadOffset(m_read_offset, 8);
  277. dst = readU64(&m_data[m_read_offset]);
  278. m_read_offset += 8;
  279. return *this;
  280. }
  281. NetworkPacket& NetworkPacket::operator>>(float& dst)
  282. {
  283. checkReadOffset(m_read_offset, 4);
  284. dst = readF1000(&m_data[m_read_offset]);
  285. m_read_offset += 4;
  286. return *this;
  287. }
  288. NetworkPacket& NetworkPacket::operator>>(v2f& dst)
  289. {
  290. checkReadOffset(m_read_offset, 8);
  291. dst = readV2F1000(&m_data[m_read_offset]);
  292. m_read_offset += 8;
  293. return *this;
  294. }
  295. NetworkPacket& NetworkPacket::operator>>(v3f& dst)
  296. {
  297. checkReadOffset(m_read_offset, 12);
  298. dst = readV3F1000(&m_data[m_read_offset]);
  299. m_read_offset += 12;
  300. return *this;
  301. }
  302. NetworkPacket& NetworkPacket::operator>>(s16& dst)
  303. {
  304. checkReadOffset(m_read_offset, 2);
  305. dst = readS16(&m_data[m_read_offset]);
  306. m_read_offset += 2;
  307. return *this;
  308. }
  309. NetworkPacket& NetworkPacket::operator<<(s16 src)
  310. {
  311. *this << (u16) src;
  312. return *this;
  313. }
  314. NetworkPacket& NetworkPacket::operator>>(s32& dst)
  315. {
  316. checkReadOffset(m_read_offset, 4);
  317. dst = readS32(&m_data[m_read_offset]);
  318. m_read_offset += 4;
  319. return *this;
  320. }
  321. NetworkPacket& NetworkPacket::operator<<(s32 src)
  322. {
  323. *this << (u32) src;
  324. return *this;
  325. }
  326. NetworkPacket& NetworkPacket::operator>>(v3s16& dst)
  327. {
  328. checkReadOffset(m_read_offset, 6);
  329. dst = readV3S16(&m_data[m_read_offset]);
  330. m_read_offset += 6;
  331. return *this;
  332. }
  333. NetworkPacket& NetworkPacket::operator>>(v2s32& dst)
  334. {
  335. checkReadOffset(m_read_offset, 8);
  336. dst = readV2S32(&m_data[m_read_offset]);
  337. m_read_offset += 8;
  338. return *this;
  339. }
  340. NetworkPacket& NetworkPacket::operator>>(v3s32& dst)
  341. {
  342. checkReadOffset(m_read_offset, 12);
  343. dst = readV3S32(&m_data[m_read_offset]);
  344. m_read_offset += 12;
  345. return *this;
  346. }
  347. NetworkPacket& NetworkPacket::operator<<(v2f src)
  348. {
  349. *this << (float) src.X;
  350. *this << (float) src.Y;
  351. return *this;
  352. }
  353. NetworkPacket& NetworkPacket::operator<<(v3f src)
  354. {
  355. *this << (float) src.X;
  356. *this << (float) src.Y;
  357. *this << (float) src.Z;
  358. return *this;
  359. }
  360. NetworkPacket& NetworkPacket::operator<<(v3s16 src)
  361. {
  362. *this << (s16) src.X;
  363. *this << (s16) src.Y;
  364. *this << (s16) src.Z;
  365. return *this;
  366. }
  367. NetworkPacket& NetworkPacket::operator<<(v2s32 src)
  368. {
  369. *this << (s32) src.X;
  370. *this << (s32) src.Y;
  371. return *this;
  372. }
  373. NetworkPacket& NetworkPacket::operator<<(v3s32 src)
  374. {
  375. *this << (s32) src.X;
  376. *this << (s32) src.Y;
  377. *this << (s32) src.Z;
  378. return *this;
  379. }
  380. NetworkPacket& NetworkPacket::operator>>(video::SColor& dst)
  381. {
  382. checkReadOffset(m_read_offset, 4);
  383. dst = readARGB8(&m_data[m_read_offset]);
  384. m_read_offset += 4;
  385. return *this;
  386. }
  387. NetworkPacket& NetworkPacket::operator<<(video::SColor src)
  388. {
  389. checkDataSize(4);
  390. writeU32(&m_data[m_read_offset], src.color);
  391. m_read_offset += 4;
  392. return *this;
  393. }
  394. SharedBuffer<u8> NetworkPacket::oldForgePacket()
  395. {
  396. SharedBuffer<u8> sb(m_datasize + 2);
  397. writeU16(&sb[0], m_command);
  398. u8* datas = getU8Ptr(0);
  399. if (datas != NULL)
  400. memcpy(&sb[2], datas, m_datasize);
  401. return sb;
  402. }