Skip to content
This repository has been archived by the owner on Jun 21, 2024. It is now read-only.

Commit

Permalink
feat: add parallel support
Browse files Browse the repository at this point in the history
  • Loading branch information
Kxnrl committed Aug 24, 2023
1 parent dda50a2 commit 5afc76e
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 4 deletions.
17 changes: 16 additions & 1 deletion include/TransmitManager.inc
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
#endif
#define _TransmitManager_included

native void TransmitManager_AddEntityHooks(int entity);
native void TransmitManager_AddEntityHooks(int entity, bool defaultState = true);
native bool TransmitManager_SetEntityOwner(int entity, int target);
native bool TransmitManager_SetEntityState(int entity, int client, bool can);
native bool TransmitManager_GetEntityState(int entity, int client);
native bool TransmitManager_SetEntityBlock(int entity, bool can);
native bool TransmitManager_GetEntityBlock(int entity);
native bool TransmitManager_IsEntityHooked(int entity);

/**
Expand All @@ -27,3 +29,16 @@ public Extension __ext_transmit =
required = 0,
#endif
};

#if !defined REQUIRE_EXTENSIONS
public void __ext_TransmitManager_SetNTVOptional()
{
MarkNativeAsOptional("TransmitManager_AddEntityHooks");
MarkNativeAsOptional("TransmitManager_SetEntityOwner");
MarkNativeAsOptional("TransmitManager_SetEntityState");
MarkNativeAsOptional("TransmitManager_GetEntityState");
MarkNativeAsOptional("TransmitManager_SetEntityBlock");
MarkNativeAsOptional("TransmitManager_GetEntityBlock");
MarkNativeAsOptional("TransmitManager_IsEntityHooked");
}
#endif
11 changes: 11 additions & 0 deletions store.sp
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,8 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max
MarkNativeAsOptional("TransmitManager_SetEntityOwner");
MarkNativeAsOptional("TransmitManager_SetEntityState");
MarkNativeAsOptional("TransmitManager_GetEntityState");
MarkNativeAsOptional("TransmitManager_SetEntityBlock");
MarkNativeAsOptional("TransmitManager_GetEntityBlock");
MarkNativeAsOptional("TransmitManager_IsEntityHooked");

// g_bLateLoad = late;
Expand Down Expand Up @@ -4630,6 +4632,15 @@ static void InterMissionLock(ConVar convar, const char[] oldValue, const char[]
LogMessage("Lock Convar [mp_match_restart_delay] to 20.0, from [%s] to [%s].", oldValue, newValue);
}

stock bool IsParallelMode()
{
ConVar sv_parallel_send = FindConVar("sv_parallel_send");
if (sv_parallel_send == null)
return false;

return sv_parallel_send.BoolValue;
}

/*
void InterMissionConVars()
{
Expand Down
53 changes: 51 additions & 2 deletions store/modules/hats.sp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ void Hats_OnMapStart()
AddFileToDownloadsTable(g_eHats[i].szModel);
}

CreateTimer(0.1, Timer_Hats_Adjust, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
if (g_iHats)
CreateTimer(0.1, Timer_Hats_Adjust, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
}

static Action Timer_Hats_Adjust(Handle timer)
Expand All @@ -87,6 +88,44 @@ static Action Timer_Hats_Adjust(Handle timer)
g_iSpecTarget[client] = client;
}

if (g_pTransmit)
{
ArrayList m_Entities = new ArrayList();

for (int client = 1; client <= MaxClients; ++client)
{
for (int i = 0; i < STORE_MAX_SLOTS; ++i)
{
if (g_iClientHats[client][i] != INVALID_ENT_REFERENCE)
{
int entity = EntRefToEntIndex(g_iClientHats[client][i]);
if (entity > MaxClients && TransmitManager_IsEntityHooked(entity))
{
m_Entities.Push(entity);
}
}
}
}

for (int i = 0; i < m_Entities.Length; i++)
{
int entity = m_Entities.Get(i);
for (int target = 1; target <= MaxClients; ++target)
{
if (IsClientInGame(target))
{
bool can = true;
if (target == g_iHatsOwners[entity])
can = IsPlayerTP(target);
if (g_iSpecTarget[target] == g_iHatsOwners[entity])
can = false;

TransmitManager_SetEntityState(entity, target, can);
}
}
}
}

return Plugin_Continue;
}

Expand Down Expand Up @@ -192,7 +231,17 @@ static void CreateHat(int client, int itemid = -1, int slot = 0)
if (g_eHats[m_iData].bHide)
{
// hook transmit
SDKHook(m_iEnt, SDKHook_SetTransmit, Hook_SetTransmit_Hat);
if (g_pTransmit)
{
TransmitManager_AddEntityHooks(m_iEnt);
TransmitManager_SetEntityOwner(m_iEnt, client);
TransmitManager_SetEntityState(m_iEnt, client, false);
}
else if (!IsParallelMode())
{
// SDKHooks crashes in parallel mode
SDKHook(m_iEnt, SDKHook_SetTransmit, Hook_SetTransmit_Hat);
}
}

TeleportEntity(m_iEnt, m_fHatOrigin, m_fHatAngles, NULL_VECTOR);
Expand Down
55 changes: 54 additions & 1 deletion store/modules/skin.sp
Original file line number Diff line number Diff line change
Expand Up @@ -574,13 +574,66 @@ void Skin_PreviewSkin(int client, int itemid)
g_iPreviewTimes[client] = GetTime() + 18;
g_iPreviewModel[client] = EntIndexToEntRef(m_iViewModel);

SDKHook(m_iViewModel, SDKHook_SetTransmit, Hook_SetTransmit_Preview);
if (g_pTransmit)
{
if (GetFeatureStatus(FeatureType_Native, "TransmitManager_SetEntityBlock") == FeatureStatus_Available)
{
TransmitManager_AddEntityHooks(m_iViewModel, false);
TransmitManager_SetEntityBlock(m_iViewModel, true);
PrintToServer("[Store] Spawn preview model<%d> in block mode.", m_iViewModel);
}
// TODO switch to old mode
else
{
TransmitManager_AddEntityHooks(m_iViewModel);

SetEntPropEnt(m_iViewModel, Prop_Send, "m_hOwnerEntity", client);
CreateTimer(0.1, UpdatePreviewTransmitState, EntIndexToEntRef(m_iViewModel), TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
PrintToServer("[Store] Spawn preview model<%d> in normal mode.", m_iViewModel);
}

TransmitManager_SetEntityOwner(m_iViewModel, client);
TransmitManager_SetEntityState(m_iViewModel, client, true);
}
else if (!IsParallelMode())
{
// SDKHooks crashes in parallel mode
SDKHook(m_iViewModel, SDKHook_SetTransmit, Hook_SetTransmit_Preview);
}

g_tKillPreview[client] = CreateTimer(15.0, Timer_KillPreview, client);

tPrintToChat(client, "%T", "Chat Preview", client);
}

static Action UpdatePreviewTransmitState(Handle timer, int ref)
{
int entity = EntRefToEntIndex(ref);
if (entity < MaxClients)
return Plugin_Stop;

int client = GetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity");
if (client == INVALID_ENT_REFERENCE)
{
RemoveEntity(entity);
return Plugin_Stop;
}

PrintToServer("[Store] Update preview model<%d> in normal mode.", entity);

for (int target = 1; target <= MaxClients; ++target)
{
if (client != target && IsClientInGame(target))
{
TransmitManager_SetEntityState(entity, client, false);
}
}

TransmitManager_SetEntityState(entity, client, true);

return Plugin_Continue;
}

static Action Hook_SetTransmit_Preview(int entity, int client)
{
if (g_iPreviewModel[client] == INVALID_ENT_REFERENCE)
Expand Down

0 comments on commit 5afc76e

Please sign in to comment.