78
78
#include " c_cvars.h"
79
79
#include " version.h"
80
80
#include " i_net.h"
81
+ #include " m_random.h"
81
82
82
83
/* [Petteri] Get more portable: */
83
84
#ifndef __WIN32__
@@ -162,13 +163,14 @@ int consoleplayer = 0;
162
163
int Net_Arbitrator = 0 ;
163
164
FClientStack NetworkClients = {};
164
165
165
- uint32_t GameID = DEFAULT_GAME_ID ;
166
+ uint64_t GameID = 0u ;
166
167
uint8_t TicDup = 1u ;
167
168
int MaxClients = 1 ;
168
169
int RemoteClient = -1 ;
169
170
size_t NetBufferLength = 0u ;
170
171
uint8_t NetBuffer[MAX_MSGLEN] = {};
171
172
173
+ static FRandom GameIDGen = {};
172
174
static u_short GamePort = (IPPORT_USERRESERVED + 29 );
173
175
static SOCKET MySocket = INVALID_SOCKET;
174
176
static FConnection Connected[MAXPLAYERS] = {};
@@ -483,22 +485,34 @@ static void SendPacket(const sockaddr_in& to)
483
485
484
486
assert (!(NetBuffer[0 ] & NCMD_COMPRESSED));
485
487
486
- uLong size = MaxTransmitSize - 1u ;
487
- int res = - 1 ;
488
+ uint8_t * dataStart = &TransmitBuffer[ 4 ] ;
489
+ uLong size = MaxTransmitSize - 5u ;
488
490
if (NetBufferLength >= MinCompressionSize)
489
491
{
490
- TransmitBuffer[0 ] = NetBuffer[0 ] | NCMD_COMPRESSED;
492
+ *dataStart = NetBuffer[0 ] | NCMD_COMPRESSED;
493
+ const int res = compress2 (dataStart + 1 , &size, NetBuffer + 1 , NetBufferLength - 1u , 9 );
494
+ if (res != Z_OK)
495
+ I_Error (" Net compression failed (zlib error %d)" , res);
491
496
492
- res = compress2 (TransmitBuffer + 1 , &size, NetBuffer + 1 , uint32_t (NetBufferLength - 1u ), 9 );
493
497
++size;
494
498
}
495
-
496
- if (res == Z_OK && size < static_cast <uLong>(NetBufferLength))
497
- res = sendto (MySocket, (const char *)TransmitBuffer, (int )size, 0 , (const sockaddr*)&to, sizeof (to));
498
- else if (NetBufferLength > MaxTransmitSize)
499
- I_Error (" Net compression failed (zlib error %d)" , res);
500
499
else
501
- res = sendto (MySocket, (const char *)NetBuffer, (int )NetBufferLength, 0 , (const sockaddr*)&to, sizeof (to));
500
+ {
501
+ memcpy (dataStart, NetBuffer, NetBufferLength);
502
+ size = NetBufferLength;
503
+ }
504
+
505
+ if (size + 4 > MaxTransmitSize)
506
+ I_Error (" Failed to compress data down to acceptable transmission size" );
507
+
508
+ // If a connection packet, don't check the game id since they might not have it yet.
509
+ const uint32_t crc = (NetBuffer[0 ] & NCMD_SETUP) ? CalcCRC32 (dataStart, size) : AddCRC32 (CalcCRC32 (dataStart, size), (uint8_t *)&GameID, sizeof (GameID));
510
+ TransmitBuffer[0 ] = crc >> 24 ;
511
+ TransmitBuffer[1 ] = crc >> 16 ;
512
+ TransmitBuffer[2 ] = crc >> 8 ;
513
+ TransmitBuffer[3 ] = crc;
514
+
515
+ sendto (MySocket, (const char *)TransmitBuffer, size + 4 , 0 , (const sockaddr*)&to, sizeof (to));
502
516
}
503
517
504
518
static void GetPacket (sockaddr_in* const from = nullptr )
@@ -544,7 +558,8 @@ static void GetPacket(sockaddr_in* const from = nullptr)
544
558
}
545
559
else if (msgSize > 0 )
546
560
{
547
- if (client == -1 && !(TransmitBuffer[0 ] & NCMD_SETUP))
561
+ const uint8_t * dataStart = &TransmitBuffer[4 ];
562
+ if (client == -1 && !(*dataStart & NCMD_SETUP))
548
563
{
549
564
msgSize = 0 ;
550
565
}
@@ -558,26 +573,38 @@ static void GetPacket(sockaddr_in* const from = nullptr)
558
573
}
559
574
else
560
575
{
561
- NetBuffer[0 ] = (TransmitBuffer[0 ] & ~NCMD_COMPRESSED);
562
- if (TransmitBuffer[0 ] & NCMD_COMPRESSED)
576
+ const uint32_t check = (*dataStart & NCMD_SETUP) ? CalcCRC32 (dataStart, msgSize - 4 ) : AddCRC32 (CalcCRC32 (dataStart, msgSize - 4 ), (uint8_t *)GameID, sizeof (GameID));
577
+ const uint32_t crc = (TransmitBuffer[0 ] << 24 ) | (TransmitBuffer[1 ] << 16 ) | (TransmitBuffer[2 ] << 8 ) | TransmitBuffer[3 ];
578
+ if (check != crc)
579
+ {
580
+ DPrintf (DMSG_NOTIFY, " Checksum on packet failed: expected %u, got %u" , check, crc);
581
+ client = -1 ;
582
+ msgSize = 0 ;
583
+ }
584
+ else
563
585
{
564
- uLongf size = MAX_MSGLEN - 1 ;
565
- int err = uncompress (NetBuffer + 1 , &size, TransmitBuffer + 1 , msgSize - 1 );
566
- if (err != Z_OK)
586
+ NetBuffer[0 ] = (*dataStart & ~NCMD_COMPRESSED);
587
+ if (*dataStart & NCMD_COMPRESSED)
567
588
{
568
- Printf (" Net decompression failed (zlib error %s)\n " , M_ZLibError (err).GetChars ());
569
- client = -1 ;
570
- msgSize = 0 ;
589
+ uLongf size = MAX_MSGLEN - 1 ;
590
+ int err = uncompress (NetBuffer + 1 , &size, dataStart + 1 , msgSize - 5 );
591
+ if (err != Z_OK)
592
+ {
593
+ Printf (" Net decompression failed (zlib error %s)\n " , M_ZLibError (err).GetChars ());
594
+ client = -1 ;
595
+ msgSize = 0 ;
596
+ }
597
+ else
598
+ {
599
+ msgSize = size + 1 ;
600
+ }
571
601
}
572
602
else
573
603
{
574
- msgSize = size + 1 ;
604
+ msgSize -= 4 ;
605
+ memcpy (NetBuffer + 1 , dataStart + 1 , msgSize - 1 );
575
606
}
576
607
}
577
- else
578
- {
579
- memcpy (NetBuffer + 1 , TransmitBuffer + 1 , msgSize - 1 );
580
- }
581
608
}
582
609
}
583
610
else
@@ -847,7 +874,15 @@ static bool Host_CheckForConnections(void* connected)
847
874
{
848
875
NetBuffer[1 ] = PRE_GAME_INFO;
849
876
NetBuffer[2 ] = TicDup;
850
- NetBufferLength = 3u ;
877
+ NetBuffer[3 ] = GameID >> 56 ;
878
+ NetBuffer[4 ] = GameID >> 48 ;
879
+ NetBuffer[5 ] = GameID >> 40 ;
880
+ NetBuffer[6 ] = GameID >> 32 ;
881
+ NetBuffer[7 ] = GameID >> 24 ;
882
+ NetBuffer[8 ] = GameID >> 16 ;
883
+ NetBuffer[9 ] = GameID >> 8 ;
884
+ NetBuffer[10 ] = GameID;
885
+ NetBufferLength = 11u ;
851
886
852
887
uint8_t * stream = &NetBuffer[NetBufferLength];
853
888
NetBufferLength += Net_SetGameInfo (stream);
@@ -931,6 +966,7 @@ static bool HostGame(int arg, bool forcedNetMode)
931
966
if (MaxClients > MAXPLAYERS)
932
967
I_FatalError (" Cannot host a game with %u players. The limit is currently %u" , MaxClients, MAXPLAYERS);
933
968
969
+ GameID = GameIDGen.GenRand64 ();
934
970
NetworkClients += 0 ;
935
971
Connected[consoleplayer].Status = CSTAT_READY;
936
972
Net_SetupUserInfo ();
@@ -1092,7 +1128,9 @@ static bool Guest_ContactHost(void* unused)
1092
1128
if (!Connected[consoleplayer].bHasGameInfo )
1093
1129
{
1094
1130
TicDup = clamp<int >(NetBuffer[2 ], 1 , MAXTICDUP);
1095
- uint8_t * stream = &NetBuffer[3 ];
1131
+ GameID = ((uint64_t )NetBuffer[3 ] << 56 ) | ((uint64_t )NetBuffer[4 ] << 48 ) | ((uint64_t )NetBuffer[5 ] << 40 ) | ((uint64_t )NetBuffer[6 ] << 32 )
1132
+ | ((uint64_t )NetBuffer[7 ] << 24 ) | ((uint64_t )NetBuffer[8 ] << 16 ) | ((uint64_t )NetBuffer[9 ] << 8 ) | (uint64_t )NetBuffer[10 ];
1133
+ uint8_t * stream = &NetBuffer[11 ];
1096
1134
Net_ReadGameInfo (stream);
1097
1135
Connected[consoleplayer].bHasGameInfo = true ;
1098
1136
}
@@ -1255,6 +1293,7 @@ bool I_InitNetwork()
1255
1293
else
1256
1294
{
1257
1295
// single player game
1296
+ GameID = GameIDGen.GenRand64 ();
1258
1297
TicDup = 1 ;
1259
1298
NetworkClients += 0 ;
1260
1299
Connected[0 ].Status = CSTAT_READY;
0 commit comments