Update lua versions
[ryzomcore.git] / nel / samples / net / udp / simlag.cpp
blobf13b26e3a0f89b75cb30214d04d603cda2543c83
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2016 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
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/>.
21 // Includes
24 #include <string>
25 #include <queue>
27 #include <nel/misc/types_nl.h>
28 #include <nel/misc/debug.h>
30 #include <nel/net/udp_sock.h>
33 // Using
36 using namespace std;
38 using namespace NLMISC;
39 using namespace NLNET;
42 // Variables
45 static uint32 Lag = 0;
46 static uint8 PacketLoss = 0;
47 static uint8 PacketDuplication = 0;
48 static uint8 PacketDisordering = 0;
51 // Class
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);
66 if (addr != NULL)
68 Addr = new CInetAddress;
69 *Addr = *addr;
71 else
73 Addr = NULL;
77 ~CBufferizedPacket ()
79 nlassert (Packet != NULL);
80 delete [] Packet;
81 Packet = NULL;
82 Client = NULL;
83 PacketSize = 0;
84 Time = 0;
85 if (Addr != NULL)
86 delete Addr;
89 CUdpSock *Client;
90 uint8 *Packet;
91 uint32 PacketSize;
92 TTime Time;
93 CInetAddress *Addr;
97 // Variables
100 static queue<CBufferizedPacket*> BufferizedPackets;
103 // Prototypes
106 void sendUDPNow (CUdpSock *client, const uint8 *packet, uint32 packetSize, const CInetAddress *addr);
109 // Functions
112 void updateBufferizedPackets ()
114 TTime ct = CTime::getLocalTime ();
115 while (!BufferizedPackets.empty())
117 CBufferizedPacket *bp = BufferizedPackets.front ();
118 if (bp->Time <= ct)
120 // time to send the message
121 sendUDPNow (bp->Client, bp->Packet, bp->PacketSize, bp->Addr);
122 delete bp;
123 BufferizedPackets.pop ();
125 else
127 break;
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)
142 if (addr == NULL)
143 client->send (packet, packetSize);
144 else
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
161 if (lag > 100)
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();
172 // exange the time
173 TTime t = bp->Time;
174 bp->Time = bp2->Time;
175 bp2->Time = t;
177 // exange packet in the buffer
178 BufferizedPackets.back() = bp;
179 bp = bp2;
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);
191 else
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);