@@ -112,6 +112,16 @@ SH_DECL_MANUALHOOK2(SendNetMessage, 15, 0, 0, bool, CNetMessage *, NetChannelBuf
112
112
SH_DECL_MANUALHOOK2 (SendNetMessage, 16 , 0 , 0 , bool , CNetMessage *, NetChannelBufType_t);
113
113
#endif
114
114
115
+ struct ClientJoinInfo_t
116
+ {
117
+ uint64 steamid;
118
+ double signon_timestamp;
119
+ int addon;
120
+ };
121
+
122
+ CUtlVector<ClientJoinInfo_t> g_ClientsPendingAddon; // List of clients who are still downloading addons
123
+ std::set<uint64> g_ClientsWithAddons; // List of clients who already downloaded everything so they don't get reconnects on mapchange/rejoin
124
+
115
125
MultiAddonManager g_MultiAddonManager;
116
126
INetworkGameServer *g_pNetworkGameServer = nullptr ;
117
127
CSteamGameServerAPIContext g_SteamAPI;
@@ -462,6 +472,9 @@ bool MultiAddonManager::AddAddon(const char *pszAddon, bool bRefresh = false)
462
472
463
473
m_ExtraAddons.AddToTail (pszAddon);
464
474
475
+ g_ClientsWithAddons.clear ();
476
+ Message (" Clearing client cache due to addons changing" );
477
+
465
478
if (bRefresh)
466
479
RefreshAddons ();
467
480
@@ -482,6 +495,9 @@ bool MultiAddonManager::RemoveAddon(const char *pszAddon, bool bRefresh = false)
482
495
483
496
m_ExtraAddons.Remove (index);
484
497
498
+ g_ClientsWithAddons.clear ();
499
+ Message (" Clearing client cache due to addons changing" );
500
+
485
501
if (bRefresh)
486
502
RefreshAddons ();
487
503
@@ -496,6 +512,9 @@ CON_COMMAND_F(mm_extra_addons, "The workshop IDs of extra addons separated by co
496
512
return ;
497
513
}
498
514
515
+ g_ClientsWithAddons.clear ();
516
+ Message (" Clearing client cache due to addons changing" );
517
+
499
518
StringToVector (args[1 ], g_MultiAddonManager.m_ExtraAddons );
500
519
501
520
g_MultiAddonManager.RefreshAddons ();
@@ -568,15 +587,6 @@ CServerSideClient *GetClientBySlot(CPlayerSlot slot)
568
587
return pClients->Element (slot.Get ());
569
588
}
570
589
571
- struct ClientJoinInfo_t
572
- {
573
- uint64 steamid;
574
- double signon_timestamp;
575
- int addon;
576
- };
577
-
578
- CUtlVector<ClientJoinInfo_t> g_ClientsPendingAddon;
579
-
580
590
void AddPendingClient (uint64 steamid)
581
591
{
582
592
ClientJoinInfo_t PendingCLient{steamid, 0 .f , 0 };
@@ -697,6 +707,9 @@ void* FASTCALL Hook_HostStateRequest(void *a1, void **pRequest)
697
707
float g_flRejoinTimeout = 10 .f;
698
708
FAKE_FLOAT_CVAR (mm_extra_addons_timeout, " How long until clients are timed out in between connects for extra addons, requires mm_extra_addons to be used" , g_flRejoinTimeout, 10 .f, false );
699
709
710
+ bool g_bCacheClients = false ;
711
+ FAKE_FLOAT_CVAR (mm_cache_clients_with_addons, " Whether to cache clients who downloaded all addons, this will prevent reconnects on mapchange/rejoin" , g_flRejoinTimeout, false , false );
712
+
700
713
bool MultiAddonManager::Hook_ClientConnect ( CPlayerSlot slot, const char *pszName, uint64 xuid, const char *pszNetworkID, bool unk1, CBufferString *pRejectReason )
701
714
{
702
715
// We don't have an extra addon set so do nothing here, also don't do anything if we're a listenserver
@@ -710,6 +723,12 @@ bool MultiAddonManager::Hook_ClientConnect( CPlayerSlot slot, const char *pszNam
710
723
711
724
Message (" Client %s (%lli) connected:\n " , pszName, xuid);
712
725
726
+ if (g_bCacheClients && g_ClientsWithAddons.find (xuid) != g_ClientsWithAddons.end ())
727
+ {
728
+ Message (" new connection but client was cached earlier so allowing immediately\n " );
729
+ RETURN_META_VALUE (MRES_IGNORED, true );
730
+ }
731
+
713
732
// Store the client's ID temporarily as they will get reconnected once an extra addon is sent
714
733
// This gets checked for in SendNetMessage so we don't repeatedly send the changelevel signon state for the same addon
715
734
// The only caveat to this is that there's no way for us to verify if the client has actually downloaded the extra addon
@@ -737,6 +756,9 @@ bool MultiAddonManager::Hook_ClientConnect( CPlayerSlot slot, const char *pszNam
737
756
{
738
757
Message (" reconnected within the interval and has all addons, allowing\n " );
739
758
g_ClientsPendingAddon.FastRemove (index);
759
+
760
+ if (g_bCacheClients)
761
+ g_ClientsWithAddons.insert (xuid);
740
762
}
741
763
}
742
764
else
0 commit comments