@@ -809,39 +809,52 @@ private void SendBundle(NetworkBundle bundle, GameMessageGroup group)
809809 {
810810 packetLog . DebugFormat ( "[{0}] Sending Bundle" , session . LoggingIdentifier ) ;
811811
812- bool writeOptionalHeaders = true ;
813-
814- List < MessageFragment > fragments = new List < MessageFragment > ( ) ;
815-
816812 // Pull all messages out and create MessageFragment objects
817- while ( bundle . HasMoreMessages )
818- {
819- var message = bundle . Dequeue ( ) ;
813+ var totalFragments = bundle . MessageCount ;
814+ var fragments = new MessageFragment [ totalFragments ] ;
815+ for ( int i = 0 ; i < totalFragments ; i ++ )
816+ fragments [ i ] = new MessageFragment ( bundle . Dequeue ( ) , ConnectionData . FragmentSequence ++ ) ;
820817
821- var fragment = new MessageFragment ( message , ConnectionData . FragmentSequence ++ ) ;
822- fragments . Add ( fragment ) ;
823- }
818+ packetLog . DebugFormat ( "[{0}] Bundle Fragment Count: {1}" , session . LoggingIdentifier , totalFragments ) ;
824819
825- packetLog . DebugFormat ( "[{0}] Bundle Fragment Count: {1}" , session . LoggingIdentifier , fragments . Count ) ;
820+ var hdrSize = PacketFragmentHeader . HeaderSize ;
821+ int processedCount = 0 ;
822+ int lowerBoundIdx = 0 ;
823+ int seekIdx = 0 ;
824+ bool writeOptionalHeaders = true ;
826825
827826 // Loop through while we have fragements
828- while ( fragments . Count > 0 || writeOptionalHeaders )
827+ while ( processedCount < totalFragments || writeOptionalHeaders )
829828 {
829+ if ( isReleased )
830+ return ;
831+
830832 ServerPacket packet = new ServerPacket ( ) ;
831833 PacketHeader packetHeader = packet . Header ;
832834
833- if ( fragments . Count > 0 )
835+ if ( processedCount < totalFragments )
834836 packetHeader . Flags |= PacketHeaderFlags . BlobFragments ;
835837
836838 if ( bundle . EncryptedChecksum )
837839 packetHeader . Flags |= PacketHeaderFlags . EncryptedChecksum ;
838840
839- int availableSpace = ServerPacket . MaxPacketSize ;
841+ seekIdx = lowerBoundIdx ;
840842
841843 // Pull first message and see if it is a large one
842- var firstMessage = fragments . FirstOrDefault ( ) ;
844+ MessageFragment firstMessage = null ;
845+ while ( seekIdx < totalFragments )
846+ {
847+ firstMessage = fragments [ seekIdx ] ;
848+ if ( firstMessage != null )
849+ break ;
850+ seekIdx ++ ;
851+ lowerBoundIdx ++ ;
852+ }
853+
843854 if ( firstMessage != null )
844855 {
856+ int availableSpace = ServerPacket . MaxPacketSize ;
857+
845858 // If a large message send only this one, filling the whole packet
846859 if ( firstMessage . DataRemaining >= availableSpace )
847860 {
@@ -850,7 +863,11 @@ private void SendBundle(NetworkBundle bundle, GameMessageGroup group)
850863 packet . Fragments . Add ( spf ) ;
851864 availableSpace -= spf . Length ;
852865 if ( firstMessage . DataRemaining <= 0 )
853- fragments . Remove ( firstMessage ) ;
866+ {
867+ processedCount ++ ;
868+ lowerBoundIdx ++ ;
869+ fragments [ seekIdx ++ ] = null ;
870+ }
854871 }
855872 // Otherwise we'll write any optional headers and process any small messages that will fit
856873 else
@@ -863,23 +880,28 @@ private void SendBundle(NetworkBundle bundle, GameMessageGroup group)
863880 availableSpace -= ( int ) packet . Data . Length ;
864881 }
865882
866- // Create a list to remove completed messages after iterator
867- List < MessageFragment > removeList = new List < MessageFragment > ( ) ;
868-
869- foreach ( MessageFragment fragment in fragments )
883+ while ( seekIdx < totalFragments )
870884 {
885+ var fragment = fragments [ seekIdx ] ;
886+ if ( fragment == null )
887+ {
888+ seekIdx ++ ;
889+ continue ;
890+ }
891+
871892 bool fragmentSkipped = false ;
872893
894+
873895 // Is this a large fragment and does it have a tail that needs sending?
874- if ( ! fragment . TailSent && availableSpace >= fragment . TailSize )
896+ if ( availableSpace >= hdrSize && ! fragment . TailSent && availableSpace >= fragment . TailSize )
875897 {
876898 packetLog . DebugFormat ( "[{0}] Sending tail fragment" , session . LoggingIdentifier ) ;
877899 ServerPacketFragment spf = fragment . GetTailFragment ( ) ;
878900 packet . Fragments . Add ( spf ) ;
879901 availableSpace -= spf . Length ;
880902 }
881903 // Otherwise will this message fit in the remaining space?
882- else if ( availableSpace >= fragment . NextSize )
904+ else if ( availableSpace >= hdrSize && availableSpace >= fragment . NextSize )
883905 {
884906 packetLog . DebugFormat ( "[{0}] Sending small message" , session . LoggingIdentifier ) ;
885907 ServerPacketFragment spf = fragment . GetNextFragment ( ) ;
@@ -891,28 +913,27 @@ private void SendBundle(NetworkBundle bundle, GameMessageGroup group)
891913
892914 // If message is out of data, set to remove it
893915 if ( fragment . DataRemaining <= 0 )
894- removeList . Add ( fragment ) ;
916+ {
917+ processedCount ++ ;
918+ if ( seekIdx == lowerBoundIdx )
919+ lowerBoundIdx ++ ;
920+ fragments [ seekIdx ] = null ;
921+ }
895922
896923 // UIQueue messages must go out in order. Otherwise, you might see an NPC's tells in an order that doesn't match their defined emotes.
897924 if ( fragmentSkipped && group == GameMessageGroup . UIQueue )
898925 break ;
899- }
900926
901- // Remove all completed messages
902- fragments . RemoveAll ( x => removeList . Contains ( x ) ) ;
927+ seekIdx ++ ;
928+ }
903929 }
904930 }
905931 // If no messages, write optional headers
906- else
932+ else if ( writeOptionalHeaders )
907933 {
908934 packetLog . DebugFormat ( "[{0}] No messages, just sending optional headers" , session . LoggingIdentifier ) ;
909- if ( writeOptionalHeaders )
910- {
911- writeOptionalHeaders = false ;
912- WriteOptionalHeaders ( bundle , packet ) ;
913- if ( packet . Data != null )
914- availableSpace -= ( int ) packet . Data . Length ;
915- }
935+ writeOptionalHeaders = false ;
936+ WriteOptionalHeaders ( bundle , packet ) ;
916937 }
917938 EnqueueSend ( packet ) ;
918939 }
0 commit comments