@@ -386,6 +386,48 @@ std::list<BufferedPacket> ReliablePacketBuffer::getTimedOuts(float timeout,
386
386
return timed_outs;
387
387
}
388
388
389
+ /*
390
+ IncomingSplitPacket
391
+ */
392
+
393
+ bool IncomingSplitPacket::insert (u32 chunk_num, SharedBuffer<u8> &chunkdata)
394
+ {
395
+ sanity_check (chunk_num < chunk_count);
396
+
397
+ // If chunk already exists, ignore it.
398
+ // Sometimes two identical packets may arrive when there is network
399
+ // lag and the server re-sends stuff.
400
+ if (chunks.find (chunk_num) != chunks.end ())
401
+ return false ;
402
+
403
+ // Set chunk data in buffer
404
+ chunks[chunk_num] = chunkdata;
405
+
406
+ return true ;
407
+ }
408
+
409
+ SharedBuffer<u8> IncomingSplitPacket::reassemble ()
410
+ {
411
+ sanity_check (allReceived ());
412
+
413
+ // Calculate total size
414
+ u32 totalsize = 0 ;
415
+ for (const auto &chunk : chunks)
416
+ totalsize += chunk.second .getSize ();
417
+
418
+ SharedBuffer<u8> fulldata (totalsize);
419
+
420
+ // Copy chunks to data buffer
421
+ u32 start = 0 ;
422
+ for (u32 chunk_i = 0 ; chunk_i < chunk_count; chunk_i++) {
423
+ const SharedBuffer<u8> &buf = chunks[chunk_i];
424
+ memcpy (&fulldata[start], *buf, buf.getSize ());
425
+ start += buf.getSize ();
426
+ }
427
+
428
+ return fulldata;
429
+ }
430
+
389
431
/*
390
432
IncomingSplitBuffer
391
433
*/
@@ -397,10 +439,7 @@ IncomingSplitBuffer::~IncomingSplitBuffer()
397
439
delete i.second ;
398
440
}
399
441
}
400
- /*
401
- This will throw a GotSplitPacketException when a full
402
- split packet is constructed.
403
- */
442
+
404
443
SharedBuffer<u8> IncomingSplitBuffer::insert (const BufferedPacket &p, bool reliable)
405
444
{
406
445
MutexAutoLock listlock (m_map_mutex);
@@ -426,12 +465,14 @@ SharedBuffer<u8> IncomingSplitBuffer::insert(const BufferedPacket &p, bool relia
426
465
}
427
466
428
467
// Add if doesn't exist
468
+ IncomingSplitPacket *sp;
429
469
if (m_buf.find (seqnum) == m_buf.end ()) {
430
- m_buf[seqnum] = new IncomingSplitPacket (chunk_count, reliable);
470
+ sp = new IncomingSplitPacket (chunk_count, reliable);
471
+ m_buf[seqnum] = sp;
472
+ } else {
473
+ sp = m_buf[seqnum];
431
474
}
432
475
433
- IncomingSplitPacket *sp = m_buf[seqnum];
434
-
435
476
if (chunk_count != sp->chunk_count ) {
436
477
errorstream << " IncomingSplitBuffer::insert(): chunk_count="
437
478
<< chunk_count << " != sp->chunk_count=" << sp->chunk_count
@@ -443,47 +484,27 @@ SharedBuffer<u8> IncomingSplitBuffer::insert(const BufferedPacket &p, bool relia
443
484
<<" != sp->reliable=" <<sp->reliable
444
485
<<std::endl);
445
486
446
- // If chunk already exists, ignore it.
447
- // Sometimes two identical packets may arrive when there is network
448
- // lag and the server re-sends stuff.
449
- if (sp->chunks .find (chunk_num) != sp->chunks .end ())
450
- return SharedBuffer<u8>();
451
-
452
487
// Cut chunk data out of packet
453
488
u32 chunkdatasize = p.data .getSize () - headersize;
454
489
SharedBuffer<u8> chunkdata (chunkdatasize);
455
490
memcpy (*chunkdata, &(p.data [headersize]), chunkdatasize);
456
491
457
- // Set chunk data in buffer
458
- sp-> chunks [chunk_num] = chunkdata ;
492
+ if (!sp-> insert (chunk_num, chunkdata))
493
+ return SharedBuffer<u8>() ;
459
494
460
495
// If not all chunks are received, return empty buffer
461
496
if (!sp->allReceived ())
462
497
return SharedBuffer<u8>();
463
498
464
- // Calculate total size
465
- u32 totalsize = 0 ;
466
- for (const auto &chunk : sp->chunks ) {
467
- totalsize += chunk.second .getSize ();
468
- }
469
-
470
- SharedBuffer<u8> fulldata (totalsize);
471
-
472
- // Copy chunks to data buffer
473
- u32 start = 0 ;
474
- for (u32 chunk_i=0 ; chunk_i<sp->chunk_count ; chunk_i++) {
475
- const SharedBuffer<u8> &buf = sp->chunks [chunk_i];
476
- u16 buf_chunkdatasize = buf.getSize ();
477
- memcpy (&fulldata[start], *buf, buf_chunkdatasize);
478
- start += buf_chunkdatasize;
479
- }
499
+ SharedBuffer<u8> fulldata = sp->reassemble ();
480
500
481
501
// Remove sp from buffer
482
502
m_buf.erase (seqnum);
483
503
delete sp;
484
504
485
505
return fulldata;
486
506
}
507
+
487
508
void IncomingSplitBuffer::removeUnreliableTimedOuts (float dtime, float timeout)
488
509
{
489
510
std::deque<u16> remove_queue;
0 commit comments