1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2016 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include <nel/misc/types_nl.h>
28 #include <nel/misc/debug.h>
30 #include <nel/net/udp_sock.h>
38 using namespace NLMISC
;
39 using namespace NLNET
;
45 static uint32 Lag
= 0;
46 static uint8 PacketLoss
= 0;
47 static uint8 PacketDuplication
= 0;
48 static uint8 PacketDisordering
= 0;
54 struct CBufferizedPacket
56 CBufferizedPacket (CUdpSock
*client
, const uint8
*packet
, uint32 packetSize
, uint32 delay
, const CInetAddress
*addr
):
57 Client(client
), PacketSize(packetSize
), Time(CTime::getLocalTime()+delay
)
59 nlassert (packetSize
> 0);
60 nlassert (packet
!= NULL
);
61 nlassert (client
!= NULL
);
63 Packet
= new uint8
[packetSize
];
64 memcpy (Packet
, packet
, packetSize
);
68 Addr
= new CInetAddress
;
79 nlassert (Packet
!= NULL
);
100 static queue
<CBufferizedPacket
*> BufferizedPackets
;
106 void sendUDPNow (CUdpSock
*client
, const uint8
*packet
, uint32 packetSize
, const CInetAddress
*addr
);
112 void updateBufferizedPackets ()
114 TTime ct
= CTime::getLocalTime ();
115 while (!BufferizedPackets
.empty())
117 CBufferizedPacket
*bp
= BufferizedPackets
.front ();
120 // time to send the message
121 sendUDPNow (bp
->Client
, bp
->Packet
, bp
->PacketSize
, bp
->Addr
);
123 BufferizedPackets
.pop ();
132 void setSimlagValues (sint32 lag
, sint8 packetLoss
, sint8 packetDuplication
, sint8 packetDisordering
)
134 if (lag
!= -1) Lag
= lag
;
135 if (packetLoss
!= -1) PacketLoss
= packetLoss
;
136 if (packetDuplication
!= -1) PacketDuplication
= packetDuplication
;
137 if (packetDisordering
!= -1) PacketDisordering
= packetDisordering
;
140 void sendUDPNow (CUdpSock
*client
, const uint8
*packet
, uint32 packetSize
, const CInetAddress
*addr
)
143 client
->send (packet
, packetSize
);
145 client
->sendTo (packet
, packetSize
, *addr
);
147 uint32 packetNumber
= *(uint32
*)packet
;
148 // nlinfo ("time %" NL_I64 "u sending now packet %5u", CTime::getLocalTime (), packetNumber);
151 void sendUDP (CUdpSock
*client
, const uint8
*packet
, uint32 packetSize
, const CInetAddress
*addr
)
153 nlassert (client
!= NULL
);
154 nlassert (packet
!= NULL
);
155 nlassert (packetSize
> 0);
157 if ((float)rand()/(float)(RAND_MAX
)*100.0f
>= PacketLoss
)
159 sint32 lag
= Lag
/*+ (rand()%40) - 20*/;// void disordering
163 // send the packet later
165 CBufferizedPacket
*bp
= new CBufferizedPacket (client
, packet
, packetSize
, lag
, addr
);
167 // duplicate the packet
168 if ((float)rand()/(float)(RAND_MAX
)*100.0f
< PacketDisordering
&& BufferizedPackets
.size() > 0)
170 CBufferizedPacket
*bp2
= BufferizedPackets
.back();
174 bp
->Time
= bp2
->Time
;
177 // exange packet in the buffer
178 BufferizedPackets
.back() = bp
;
182 BufferizedPackets
.push (bp
);
184 // duplicate the packet
185 if ((float)rand()/(float)(RAND_MAX
)*100.0f
< PacketDuplication
)
187 CBufferizedPacket
*bp
= new CBufferizedPacket (client
, packet
, packetSize
, lag
, addr
);
188 BufferizedPackets
.push (bp
);
193 // send the packet NOW
195 sendUDPNow (client
, packet
, packetSize
, addr
);
197 // duplicate the packet
198 if ((float)rand()/(float)(RAND_MAX
)*100.0f
< PacketDuplication
)
200 sendUDPNow (client
, packet
, packetSize
, addr
);