Skip to content

Commit e943fa2

Browse files
committed
networking: add a debug transmit pass
1 parent c1ea215 commit e943fa2

File tree

1 file changed

+105
-7
lines changed

1 file changed

+105
-7
lines changed

source/modules/networking.cpp

Lines changed: 105 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,6 +1795,7 @@ static inline void DoTransmitPVSCheck(edict_t* pEdict, CBaseEntity* pEnt, const
17951795
}
17961796
}
17971797

1798+
static ConVar networking_verifyshit("holylib_networking_verifyshit", "1", 0, "Experimental");
17981799
static ConVar networking_fastpath("holylib_networking_fastpath", "0", 0, "Experimental - If two players are in the same area, then it will reuse the transmit state of the first calculated player saving a lot of time");
17991800
static ConVar networking_fastpath_usecluster("holylib_networking_fastpath_usecluster", "1", 0, "Experimental - When using the fastpatth, it will compate against clients in the same cluster instead of area");
18001801
bool New_CServerGameEnts_CheckTransmit(IServerGameEnts* gameents, CCheckTransmitInfo *pInfo, const unsigned short *pEdictIndices, int nEdicts)
@@ -2085,15 +2086,112 @@ bool New_CServerGameEnts_CheckTransmit(IServerGameEnts* gameents, CCheckTransmit
20852086
#endif
20862087

20872088
#if 1 // I don't like this, useful for testing but not for actual prod
2088-
for (int i=0; i<MAX_EDICTS; ++i)
2089+
if (networking_verifyshit.GetBool())
20892090
{
2090-
if (pInfo->m_pTransmitEdict->IsBitSet(i) && !g_pEntityCache[i])
2091-
{ // g_pEntityCache is basically just a quicker form of (CBaseEntity*)(&world_edict[i])->GetUnknown();
2092-
Warning(PROJECT_NAME " - networking: Tried to network an Entity that does not exist! (%i)\n", i);
2093-
pInfo->m_pTransmitEdict->Clear(i);
2094-
if (bIsHLTV)
2095-
pInfo->m_pTransmitAlways->Clear(i);
2091+
for (int i=0; i<MAX_EDICTS; ++i)
2092+
{
2093+
if (pInfo->m_pTransmitEdict->IsBitSet(i) && !g_pEntityCache[i])
2094+
{ // g_pEntityCache is basically just a quicker form of (CBaseEntity*)(&world_edict[i])->GetUnknown();
2095+
Warning(PROJECT_NAME " - networking: Tried to network an Entity that does not exist! (%i)\n", i);
2096+
pInfo->m_pTransmitEdict->Clear(i);
2097+
if (bIsHLTV)
2098+
pInfo->m_pTransmitAlways->Clear(i);
2099+
}
20962100
}
2101+
2102+
CBitVec<MAX_EDICTS> pCurrentTransmit;
2103+
pInfo->m_pTransmitEdict->CopyTo(&pCurrentTransmit);
2104+
pInfo->m_pTransmitEdict->ClearAll();
2105+
2106+
// Now we do a second transmit to compare against.
2107+
2108+
for ( int i=0; i < nEdicts; ++i )
2109+
{
2110+
int iEdict = pEdictIndices[i];
2111+
2112+
edict_t *pEdict = &world_edict[iEdict]; // world_edict is already cached.
2113+
// Assert( pEdict == engine->PEntityOfEntIndex( iEdict ) );
2114+
int nFlags = pEdict->m_fStateFlags & (FL_EDICT_DONTSEND|FL_EDICT_ALWAYS|FL_EDICT_PVSCHECK|FL_EDICT_FULLCHECK);
2115+
2116+
if ( iEdict == clientEntIndex )
2117+
{
2118+
pInfo->m_pTransmitEdict->CopyTo(&pClientCache);
2119+
bWasTransmitToPlayer = true;
2120+
} else if ( bWasTransmitToPlayer ) {
2121+
// We Xor it so that the pClientCache contains all bits / entities
2122+
// that were sent specifically to our client in it's transmit check.
2123+
pInfo->m_pTransmitEdict->Xor(pClientCache, &pClientCache);
2124+
bWasTransmitToPlayer = false;
2125+
}
2126+
2127+
// entity needs no transmit
2128+
if ( nFlags & FL_EDICT_DONTSEND )
2129+
continue;
2130+
2131+
// entity is already marked for sending
2132+
if ( pInfo->m_pTransmitEdict->Get( iEdict ) )
2133+
continue;
2134+
2135+
if ( g_pDontTransmitCache.Get(iEdict) ) // Implements gmod's SetPreventTransmit but far faster.
2136+
continue;
2137+
2138+
if ( nFlags & FL_EDICT_ALWAYS )
2139+
{
2140+
// FIXME: Hey! Shouldn't this be using SetTransmit so as
2141+
// to also force network down dependent entities?
2142+
while ( true )
2143+
{
2144+
// mark entity for sending
2145+
pInfo->m_pTransmitEdict->Set( iEdict );
2146+
// g_pGlobalTransmitTickCache.g_pAlwaysTransmitCacheBitVec.Set( iEdict );
2147+
2148+
if ( bIsHLTV )
2149+
pInfo->m_pTransmitAlways->Set( iEdict );
2150+
2151+
CCServerNetworkProperty *pEnt = static_cast<CCServerNetworkProperty*>( pEdict->GetNetworkable() );
2152+
if ( !pEnt )
2153+
break;
2154+
2155+
CCServerNetworkProperty *pParent = pEnt->GetNetworkParent();
2156+
if ( !pParent )
2157+
break;
2158+
2159+
pEdict = pParent->edict();
2160+
iEdict = pEdict->m_EdictIndex;
2161+
}
2162+
continue;
2163+
}
2164+
2165+
// FIXME: Would like to remove all dependencies
2166+
CBaseEntity *pEnt = g_pEntityCache[iEdict];
2167+
if ( nFlags == FL_EDICT_FULLCHECK )
2168+
{
2169+
// do a full ShouldTransmit() check, may return FL_EDICT_CHECKPVS
2170+
nFlags = pEnt->ShouldTransmit( pInfo );
2171+
2172+
if ( nFlags & FL_EDICT_ALWAYS )
2173+
{
2174+
pEnt->SetTransmit( pInfo, true );
2175+
// g_pAlwaysTransmitCacheBitVec.Set( iEdict ); We do NOT do this since view models and such would also be included.
2176+
continue;
2177+
}
2178+
}
2179+
2180+
// don't send this entity
2181+
if ( !( nFlags & FL_EDICT_PVSCHECK ) )
2182+
continue;
2183+
2184+
DoTransmitPVSCheck(pEdict, pEnt, bIsHLTV, pInfo, bForceTransmit, skyBoxArea);
2185+
}
2186+
2187+
for (int i=0; i<MAX_EDICTS; ++i)
2188+
{
2189+
if (pCurrentTransmit.IsBitSet(i) != pInfo->m_pTransmitEdict->IsBitSet(i))
2190+
Msg(PROJECT_NAME " - networking: Entity failed our transmit code! Index %i (State: %i)\n", i, (&world_edict[i])->m_fStateFlags & (FL_EDICT_DONTSEND|FL_EDICT_ALWAYS|FL_EDICT_PVSCHECK|FL_EDICT_FULLCHECK));
2191+
}
2192+
2193+
// Use OUR transmit!
2194+
pCurrentTransmit.CopyTo(pInfo->m_pTransmitEdict);
20972195
}
20982196
#endif
20992197

0 commit comments

Comments
 (0)