Line data Source code
1 : /*
2 : Minetest
3 : Copyright (C) 2015 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
4 :
5 : This program is free software; you can redistribute it and/or modify
6 : it under the terms of the GNU Lesser General Public License as published by
7 : the Free Software Foundation; either version 2.1 of the License, or
8 : (at your option) any later version.
9 :
10 : This program is distributed in the hope that it will be useful,
11 : but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 : GNU Lesser General Public License for more details.
14 :
15 : You should have received a copy of the GNU Lesser General Public License along
16 : with this program; if not, write to the Free Software Foundation, Inc.,
17 : 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 : */
19 :
20 : #include "networkpacket.h"
21 : #include "debug.h"
22 : #include "exceptions.h"
23 : #include "util/serialize.h"
24 :
25 0 : NetworkPacket::NetworkPacket(u16 command, u32 datasize, u16 peer_id):
26 0 : m_datasize(datasize), m_read_offset(0), m_command(command), m_peer_id(peer_id)
27 : {
28 0 : m_data.resize(m_datasize);
29 0 : }
30 :
31 992 : NetworkPacket::NetworkPacket(u16 command, u32 datasize):
32 992 : m_datasize(datasize), m_read_offset(0), m_command(command), m_peer_id(0)
33 : {
34 992 : m_data.resize(m_datasize);
35 992 : }
36 :
37 7006 : NetworkPacket::~NetworkPacket()
38 : {
39 3503 : m_data.clear();
40 3503 : }
41 :
42 3777 : void NetworkPacket::checkReadOffset(u32 from_offset)
43 : {
44 3777 : if (from_offset >= m_datasize) {
45 0 : std::stringstream ss;
46 0 : ss << "Reading outside packet (offset: " <<
47 0 : from_offset << ", packet size: " << getSize() << ")";
48 0 : throw PacketError(ss.str());
49 : }
50 3777 : }
51 :
52 1321 : void NetworkPacket::putRawPacket(u8 *data, u32 datasize, u16 peer_id)
53 : {
54 : // If a m_command is already set, we are rewriting on same packet
55 : // This is not permitted
56 : assert(m_command == 0);
57 :
58 1321 : m_datasize = datasize - 2;
59 1321 : m_peer_id = peer_id;
60 :
61 : // split command and datas
62 1321 : m_command = readU16(&data[0]);
63 1321 : m_data = std::vector<u8>(&data[2], &data[2 + m_datasize]);
64 1321 : }
65 :
66 1177 : char* NetworkPacket::getString(u32 from_offset)
67 : {
68 1177 : checkReadOffset(from_offset);
69 :
70 1177 : return (char*)&m_data[from_offset];
71 : }
72 :
73 4 : void NetworkPacket::putRawString(const char* src, u32 len)
74 : {
75 4 : if (m_read_offset + len > m_datasize) {
76 1 : m_datasize = m_read_offset + len;
77 1 : m_data.resize(m_datasize);
78 : }
79 :
80 4 : memcpy(&m_data[m_read_offset], src, len);
81 4 : m_read_offset += len;
82 4 : }
83 :
84 5313 : NetworkPacket& NetworkPacket::operator>>(std::string& dst)
85 : {
86 5313 : u16 strLen = readU16(&m_data[m_read_offset]);
87 5313 : m_read_offset += sizeof(u16);
88 :
89 5313 : dst.clear();
90 :
91 5313 : if (strLen == 0) {
92 8 : return *this;
93 : }
94 :
95 5305 : dst.reserve(strLen);
96 5305 : dst.append((char*)&m_data[m_read_offset], strLen);
97 :
98 5305 : m_read_offset += strLen;
99 5305 : return *this;
100 : }
101 :
102 1 : NetworkPacket& NetworkPacket::operator<<(std::string src)
103 : {
104 1 : u16 msgsize = src.size();
105 : if (msgsize > 0xFFFF) {
106 : msgsize = 0xFFFF;
107 : }
108 :
109 1 : *this << msgsize;
110 :
111 1 : putRawString(src.c_str(), (u32)msgsize);
112 :
113 1 : return *this;
114 : }
115 :
116 0 : void NetworkPacket::putLongString(std::string src)
117 : {
118 0 : u32 msgsize = src.size();
119 : if (msgsize > 0xFFFFFFFF) {
120 : msgsize = 0xFFFFFFFF;
121 : }
122 :
123 0 : *this << msgsize;
124 :
125 0 : putRawString(src.c_str(), msgsize);
126 0 : }
127 :
128 0 : NetworkPacket& NetworkPacket::operator>>(std::wstring& dst)
129 : {
130 0 : u16 strLen = readU16(&m_data[m_read_offset]);
131 0 : m_read_offset += sizeof(u16);
132 :
133 0 : dst.clear();
134 :
135 0 : if (strLen == 0) {
136 0 : return *this;
137 : }
138 :
139 0 : dst.reserve(strLen);
140 0 : for(u16 i=0; i<strLen; i++) {
141 0 : wchar_t c16 = readU16(&m_data[m_read_offset]);
142 0 : dst.append(&c16, 1);
143 0 : m_read_offset += sizeof(u16);
144 : }
145 :
146 0 : return *this;
147 : }
148 :
149 0 : NetworkPacket& NetworkPacket::operator<<(std::wstring src)
150 : {
151 0 : u16 msgsize = src.size();
152 : if (msgsize > 0xFFFF) {
153 : msgsize = 0xFFFF;
154 : }
155 :
156 0 : *this << msgsize;
157 :
158 : // Write string
159 0 : for (u16 i=0; i<msgsize; i++) {
160 0 : *this << (u16) src[i];
161 : }
162 :
163 0 : return *this;
164 : }
165 :
166 57 : std::string NetworkPacket::readLongString()
167 : {
168 57 : u32 strLen = readU32(&m_data[m_read_offset]);
169 57 : m_read_offset += sizeof(u32);
170 :
171 57 : if (strLen == 0) {
172 0 : return "";
173 : }
174 :
175 114 : std::string dst;
176 :
177 57 : dst.reserve(strLen);
178 57 : dst.append((char*)&m_data[m_read_offset], strLen);
179 :
180 57 : m_read_offset += strLen;
181 :
182 57 : return dst;
183 : }
184 :
185 0 : NetworkPacket& NetworkPacket::operator>>(char& dst)
186 : {
187 0 : checkReadOffset(m_read_offset);
188 :
189 0 : dst = readU8(&m_data[m_read_offset]);
190 :
191 0 : incrOffset<char>();
192 0 : return *this;
193 : }
194 :
195 0 : char NetworkPacket::getChar(u32 offset)
196 : {
197 0 : checkReadOffset(offset);
198 :
199 0 : return readU8(&m_data[offset]);
200 : }
201 :
202 0 : NetworkPacket& NetworkPacket::operator<<(char src)
203 : {
204 0 : checkDataSize<u8>();
205 :
206 0 : writeU8(&m_data[m_read_offset], src);
207 :
208 0 : incrOffset<char>();
209 0 : return *this;
210 : }
211 :
212 774 : NetworkPacket& NetworkPacket::operator<<(u8 src)
213 : {
214 774 : checkDataSize<u8>();
215 :
216 774 : writeU8(&m_data[m_read_offset], src);
217 :
218 774 : incrOffset<u8>();
219 774 : return *this;
220 : }
221 :
222 0 : NetworkPacket& NetworkPacket::operator<<(bool src)
223 : {
224 0 : checkDataSize<u8>();
225 :
226 0 : writeU8(&m_data[m_read_offset], src);
227 :
228 0 : incrOffset<u8>();
229 0 : return *this;
230 : }
231 :
232 2332 : NetworkPacket& NetworkPacket::operator<<(u16 src)
233 : {
234 2332 : checkDataSize<u16>();
235 :
236 2332 : writeU16(&m_data[m_read_offset], src);
237 :
238 2332 : incrOffset<u16>();
239 2332 : return *this;
240 : }
241 :
242 1774 : NetworkPacket& NetworkPacket::operator<<(u32 src)
243 : {
244 1774 : checkDataSize<u32>();
245 :
246 1774 : writeU32(&m_data[m_read_offset], src);
247 :
248 1774 : incrOffset<u32>();
249 1774 : return *this;
250 : }
251 :
252 0 : NetworkPacket& NetworkPacket::operator<<(u64 src)
253 : {
254 0 : checkDataSize<u64>();
255 :
256 0 : writeU64(&m_data[m_read_offset], src);
257 :
258 0 : incrOffset<u64>();
259 0 : return *this;
260 : }
261 :
262 0 : NetworkPacket& NetworkPacket::operator<<(float src)
263 : {
264 0 : checkDataSize<float>();
265 :
266 0 : writeF1000(&m_data[m_read_offset], src);
267 :
268 0 : incrOffset<float>();
269 0 : return *this;
270 : }
271 :
272 20 : NetworkPacket& NetworkPacket::operator>>(bool& dst)
273 : {
274 20 : checkReadOffset(m_read_offset);
275 :
276 20 : dst = readU8(&m_data[m_read_offset]);
277 :
278 20 : incrOffset<u8>();
279 20 : return *this;
280 : }
281 :
282 65 : NetworkPacket& NetworkPacket::operator>>(u8& dst)
283 : {
284 65 : checkReadOffset(m_read_offset);
285 :
286 65 : dst = readU8(&m_data[m_read_offset]);
287 :
288 65 : incrOffset<u8>();
289 65 : return *this;
290 : }
291 :
292 49 : u8 NetworkPacket::getU8(u32 offset)
293 : {
294 49 : checkReadOffset(offset);
295 :
296 49 : return readU8(&m_data[offset]);
297 : }
298 :
299 1041 : u8* NetworkPacket::getU8Ptr(u32 from_offset)
300 : {
301 1041 : if (m_datasize == 0) {
302 3 : return NULL;
303 : }
304 :
305 1038 : checkReadOffset(from_offset);
306 :
307 1038 : return (u8*)&m_data[from_offset];
308 : }
309 :
310 408 : NetworkPacket& NetworkPacket::operator>>(u16& dst)
311 : {
312 408 : checkReadOffset(m_read_offset);
313 :
314 408 : dst = readU16(&m_data[m_read_offset]);
315 :
316 408 : incrOffset<u16>();
317 408 : return *this;
318 : }
319 :
320 0 : u16 NetworkPacket::getU16(u32 from_offset)
321 : {
322 0 : checkReadOffset(from_offset);
323 :
324 0 : return readU16(&m_data[from_offset]);
325 : }
326 :
327 35 : NetworkPacket& NetworkPacket::operator>>(u32& dst)
328 : {
329 35 : checkReadOffset(m_read_offset);
330 :
331 35 : dst = readU32(&m_data[m_read_offset]);
332 :
333 35 : incrOffset<u32>();
334 35 : return *this;
335 : }
336 :
337 1 : NetworkPacket& NetworkPacket::operator>>(u64& dst)
338 : {
339 1 : checkReadOffset(m_read_offset);
340 :
341 1 : dst = readU64(&m_data[m_read_offset]);
342 :
343 1 : incrOffset<u64>();
344 1 : return *this;
345 : }
346 :
347 73 : NetworkPacket& NetworkPacket::operator>>(float& dst)
348 : {
349 73 : checkReadOffset(m_read_offset);
350 :
351 73 : dst = readF1000(&m_data[m_read_offset]);
352 :
353 73 : incrOffset<float>();
354 73 : return *this;
355 : }
356 :
357 8 : NetworkPacket& NetworkPacket::operator>>(v2f& dst)
358 : {
359 8 : checkReadOffset(m_read_offset);
360 :
361 8 : dst = readV2F1000(&m_data[m_read_offset]);
362 :
363 8 : incrOffset<v2f>();
364 8 : return *this;
365 : }
366 :
367 59 : NetworkPacket& NetworkPacket::operator>>(v3f& dst)
368 : {
369 59 : checkReadOffset(m_read_offset);
370 :
371 59 : dst = readV3F1000(&m_data[m_read_offset]);
372 :
373 59 : incrOffset<v3f>();
374 59 : return *this;
375 : }
376 :
377 0 : NetworkPacket& NetworkPacket::operator>>(s16& dst)
378 : {
379 0 : checkReadOffset(m_read_offset);
380 :
381 0 : dst = readS16(&m_data[m_read_offset]);
382 :
383 0 : incrOffset<s16>();
384 0 : return *this;
385 : }
386 :
387 2304 : NetworkPacket& NetworkPacket::operator<<(s16 src)
388 : {
389 2304 : *this << (u16) src;
390 2304 : return *this;
391 : }
392 :
393 2 : NetworkPacket& NetworkPacket::operator>>(s32& dst)
394 : {
395 2 : checkReadOffset(m_read_offset);
396 :
397 2 : dst = readS32(&m_data[m_read_offset]);
398 :
399 2 : incrOffset<s32>();
400 2 : return *this;
401 : }
402 :
403 1577 : NetworkPacket& NetworkPacket::operator<<(s32 src)
404 : {
405 1577 : *this << (u32) src;
406 1577 : return *this;
407 : }
408 :
409 842 : NetworkPacket& NetworkPacket::operator>>(v3s16& dst)
410 : {
411 842 : checkReadOffset(m_read_offset);
412 :
413 842 : dst = readV3S16(&m_data[m_read_offset]);
414 :
415 842 : incrOffset<v3s16>();
416 842 : return *this;
417 : }
418 :
419 6 : NetworkPacket& NetworkPacket::operator>>(v2s32& dst)
420 : {
421 6 : dst = readV2S32(&m_data[m_read_offset]);
422 :
423 6 : incrOffset<v2s32>();
424 6 : return *this;
425 : }
426 :
427 0 : NetworkPacket& NetworkPacket::operator>>(v3s32& dst)
428 : {
429 0 : checkReadOffset(m_read_offset);
430 :
431 0 : dst = readV3S32(&m_data[m_read_offset]);
432 :
433 0 : incrOffset<v3s32>();
434 0 : return *this;
435 : }
436 :
437 0 : NetworkPacket& NetworkPacket::operator<<(v2f src)
438 : {
439 0 : *this << (float) src.X;
440 0 : *this << (float) src.Y;
441 0 : return *this;
442 : }
443 :
444 0 : NetworkPacket& NetworkPacket::operator<<(v3f src)
445 : {
446 0 : *this << (float) src.X;
447 0 : *this << (float) src.Y;
448 0 : *this << (float) src.Z;
449 0 : return *this;
450 : }
451 :
452 768 : NetworkPacket& NetworkPacket::operator<<(v3s16 src)
453 : {
454 768 : *this << (s16) src.X;
455 768 : *this << (s16) src.Y;
456 768 : *this << (s16) src.Z;
457 768 : return *this;
458 : }
459 :
460 0 : NetworkPacket& NetworkPacket::operator<<(v2s32 src)
461 : {
462 0 : *this << (s32) src.X;
463 0 : *this << (s32) src.Y;
464 0 : return *this;
465 : }
466 :
467 394 : NetworkPacket& NetworkPacket::operator<<(v3s32 src)
468 : {
469 394 : *this << (s32) src.X;
470 394 : *this << (s32) src.Y;
471 394 : *this << (s32) src.Z;
472 394 : return *this;
473 : }
474 :
475 0 : NetworkPacket& NetworkPacket::operator>>(video::SColor& dst)
476 : {
477 0 : checkReadOffset(m_read_offset);
478 :
479 0 : dst = readARGB8(&m_data[m_read_offset]);
480 :
481 0 : incrOffset<u32>();
482 0 : return *this;
483 : }
484 :
485 0 : NetworkPacket& NetworkPacket::operator<<(video::SColor src)
486 : {
487 0 : checkDataSize<u32>();
488 :
489 0 : writeU32(&m_data[m_read_offset], src.color);
490 :
491 0 : incrOffset<u32>();
492 0 : return *this;
493 : }
494 :
495 992 : Buffer<u8> NetworkPacket::oldForgePacket()
496 : {
497 992 : Buffer<u8> sb(m_datasize + 2);
498 992 : writeU16(&sb[0], m_command);
499 :
500 992 : u8* datas = getU8Ptr(0);
501 :
502 992 : if (datas != NULL)
503 989 : memcpy(&sb[2], datas, m_datasize);
504 992 : return sb;
505 3 : }
|