Skip to content

Commit 3f0bebe

Browse files
committed
pvs: add ForceWeaponTransmit function
1 parent c27eed4 commit 3f0bebe

File tree

3 files changed

+51
-29
lines changed

3 files changed

+51
-29
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,6 +1021,11 @@ Forces a full update for the specific client.<br>
10211021
#### table pvs.GetEntitesFromTransmit()
10221022
Returns a table containing all entities that will be networked.<br>
10231023

1024+
#### pvs.ForceWeaponTransmit(Entity weapon, bool forceTransmit = false)
1025+
Allows you to mark a weapon to be forcefully transmitted even when offhand.<br>
1026+
The weapon will remain to be forcefully transmitted until this is called with false again or the weapon is removed!<br>
1027+
This is only useful if you use the `networking` module with the `holylib_networking_transmit_all_weapons 0` and `holylib_networking_transmit_all_weapons_to_owner 0`<br>
1028+
10241029
#### pvs.EnablePreTransmitHook(bool enable = false)
10251030
Enables/Disables the `HolyLib:PreCheckTransmit` hook.<br>
10261031
The internal value is reset on mapchange, so you need to set it always again on Lua startup.<br>

source/modules/networking.cpp

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,16 @@ struct EntityTransmitCache // Well.... Still kinda acts as a tick-based cache, t
12721272
};
12731273
static EntityTransmitCache g_nEntityTransmitCache;
12741274

1275+
static CBitVec<MAX_EDICTS> g_pForceWeaponTransmitIndexes;
1276+
void Networking_ForceWeaponTransmit(int entIndex, bool bForceTransmit) // Exposed for pvs.ForceWeaponTransmit
1277+
{
1278+
if (bForceTransmit) {
1279+
g_pForceWeaponTransmitIndexes.Set(entIndex);
1280+
} else {
1281+
g_pForceWeaponTransmitIndexes.Clear(entIndex);
1282+
}
1283+
}
1284+
12751285
// Full cache persisting across ticks, reset only when the player disconnects.
12761286
static ConVar* sv_stressbots = nullptr;
12771287
static ConVar networking_transmit_newweapons("holylib_networking_transmit_newweapons", "1", 0, "Experimental - If enabled, weapons that a player equipped/was given are networked for the first x ticks");
@@ -1319,10 +1329,13 @@ struct PlayerTransmitCache
13191329
pSlot.bIsNew = false;
13201330
}
13211331

1332+
pSlot.bAlwaysNetwork = g_pForceWeaponTransmitIndexes.IsBitSet(pWeapon->edict()->m_EdictIndex);
1333+
13221334
nHighestWeaponSlot = i;
13231335
} else {
13241336
pSlot.bIsValid = false;
13251337
pSlot.bIsNew = false;
1338+
pSlot.bAlwaysNetwork = false;
13261339
}
13271340
}
13281341

@@ -1366,6 +1379,9 @@ struct PlayerTransmitCache
13661379
{
13671380
bool bIsNew = false; // Exists for quick checking to not have to compare numbers
13681381
bool bIsValid = false;
1382+
// Transmit state - in case an offhand weapon insists on being an ass requesting to be networked
1383+
// NOTE: For this to take effect, a weapon must return TRANSMIT_ALWAYS inside Entity:UpdateTransmitState
1384+
bool bAlwaysNetwork = false;
13691385
int nCreationTick = 0; // For how many ticks a weapon is considered new
13701386
CBaseEntity* pWeapon = NULL; // in case a weapon is removed/given onto the same slot in a tick
13711387
};
@@ -1580,9 +1596,9 @@ static void hook_CBaseCombatCharacter_SetTransmit(CBaseCombatCharacter* pCharact
15801596
}
15811597
}
15821598

1599+
const PlayerTransmitCache& pCache = g_pPlayerTransmitCache[pCharacterEdict->m_EdictIndex-1];
15831600
if (bLocalPlayer)
15841601
{
1585-
const PlayerTransmitCache& pCache = g_pPlayerTransmitCache[pCharacterEdict->m_EdictIndex-1];
15861602
if (networking_transmit_onfullupdate.GetBool() && pCache.InFullUpdate())
15871603
{
15881604
// DevMsg(PROJECT_NAME " - networking: Doing full weapon transmit for %i...\n", pCharacterEdict->m_EdictIndex);
@@ -1607,6 +1623,15 @@ static void hook_CBaseCombatCharacter_SetTransmit(CBaseCombatCharacter* pCharact
16071623
}
16081624
}
16091625
}
1626+
1627+
// In some cases offhand weapons may want to be transmitted!
1628+
// This normally is shit! Why would anyone need offhand weapons? Idk, some do!
1629+
for (int i=0; i < MAX_WEAPONS; ++i)
1630+
{
1631+
const PlayerTransmitCache::WeaponSlot& pWeaponSlot = pCache.pWeapons[i];
1632+
if (pWeaponSlot.bAlwaysNetwork)
1633+
pWeaponSlot.pWeapon->SetTransmit(pInfo, bAlways);
1634+
}
16101635
}
16111636
}
16121637

@@ -2226,32 +2251,6 @@ void PackEntities_Normal(int clientCount, CGameClient **clients, CFrameSnapshot
22262251
func_InvalidateSharedEdictChangeInfos();
22272252
}
22282253

2229-
/*void SV_ComputeClientPacks(
2230-
int clientCount,
2231-
CGameClient **clients,
2232-
CFrameSnapshot *snapshot )
2233-
{
2234-
MDLCACHE_CRITICAL_SECTION_(g_pMDLCache);
2235-
2236-
{
2237-
VPROF_BUDGET_FLAGS( "SV_ComputeClientPacks", "CheckTransmit", BUDGETFLAG_SERVER );
2238-
2239-
for (int iClient = 0; iClient < clientCount; ++iClient)
2240-
{
2241-
CCheckTransmitInfo *pInfo = &clients[iClient]->m_PackInfo;
2242-
clients[iClient]->SetupPackInfo( snapshot );
2243-
Util::servergameents->CheckTransmit( pInfo, snapshot->m_pValidEntities, snapshot->m_nValidEntities );
2244-
clients[iClient]->SetupPrevPackInfo();
2245-
}
2246-
}
2247-
2248-
VPROF_BUDGET_FLAGS( "SV_ComputeClientPacks", "ComputeClientPacks", BUDGETFLAG_SERVER );
2249-
2250-
// Fk local network backdoor, we expect holylib to rarely run on a local server so it's not worth to implement.
2251-
2252-
PackEntities_Normal( clientCount, clients, snapshot );
2253-
}*/
2254-
22552254
void CNetworkingModule::OnEntityDeleted(CBaseEntity* pEntity)
22562255
{
22572256
edict_t* pEdict = pEntity->edict();
@@ -2261,12 +2260,11 @@ void CNetworkingModule::OnEntityDeleted(CBaseEntity* pEntity)
22612260
g_nEntityTransmitCache.EntityRemoved(pEntity, pEdict);
22622261
CleaupSetPreventTransmit(pEntity);
22632262
g_pEntityCache[pEdict->m_EdictIndex] = NULL;
2263+
g_pForceWeaponTransmitIndexes.Clear(pEdict->m_EdictIndex);
22642264
}
22652265

22662266
void CNetworkingModule::OnEntityCreated(CBaseEntity* pEntity)
22672267
{
2268-
//auto mod = GetOrCreateEntityModule<SendpropOverrideModule>(pEntity, "sendpropoverride");
2269-
//mod->AddOverride(CallbackPluginCall, precalcIndex, prop, callbacks.size() - 1);
22702268
const edict_t* pEdict = pEntity->edict();
22712269
if (pEdict)
22722270
g_pEntityCache[pEdict->m_EdictIndex] = pEntity;

source/modules/pvs.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,24 @@ LUA_FUNCTION_STATIC(pvs_GetEntitiesFromTransmit)
869869
return 1;
870870
}
871871

872+
LUA_FUNCTION_STATIC(pvs_ForceWeaponTransmit)
873+
{
874+
CBaseEntity* pWeapon = Util::Get_Entity(LUA, 1, true);
875+
bool bForceTransmit = LUA->GetBool(2);
876+
877+
// If it isn't a weapon - we don't care.
878+
// Why? Because then it simply has no effect!
879+
880+
#if MODULE_EXISTS_NETWORKING
881+
extern void Networking_ForceWeaponTransmit(int entIndex, bool bForceTransmit);
882+
Networking_ForceWeaponTransmit(pWeapon->edict()->m_EdictIndex, bForceTransmit);
883+
#else
884+
LUA->ThrowError("Networking module does not exist! This function has no purpose!");
885+
#endif
886+
return 0;
887+
}
888+
889+
872890
LUA_FUNCTION_STATIC(pvs_EnablePreTransmitHook)
873891
{
874892
g_bEnableLuaPreTransmitHook = LUA->GetBool(1);
@@ -914,6 +932,7 @@ void CPVSModule::LuaInit(GarrysMod::Lua::ILuaInterface* pLua, bool bServerInit)
914932
Util::AddFunc(pLua, pvs_TestPVS, "TestPVS");
915933
Util::AddFunc(pLua, pvs_ForceFullUpdate, "ForceFullUpdate");
916934
Util::AddFunc(pLua, pvs_GetEntitiesFromTransmit, "GetEntitiesFromTransmit");
935+
Util::AddFunc(pLua, pvs_ForceWeaponTransmit, "ForceWeaponTransmit");
917936

918937
// Use the functions below only inside the HolyLib:[Pre/Post]CheckTransmit hook.
919938
Util::AddFunc(pLua, pvs_RemoveEntityFromTransmit, "RemoveEntityFromTransmit");

0 commit comments

Comments
 (0)