Skip to content

NormalSHook erroring on non-IsInGame clients#1450

Merged
KyleSanderson merged 1 commit intoalliedmodders:masterfrom
rtldg:normalsoundhook-thing
Jun 24, 2021
Merged

NormalSHook erroring on non-IsInGame clients#1450
KyleSanderson merged 1 commit intoalliedmodders:masterfrom
rtldg:normalsoundhook-thing

Conversation

@rtldg
Copy link
Contributor

@rtldg rtldg commented Mar 20, 2021

IEngineSound::EmitSound seems to be called with clients in the filter that might not be IsInGame() which can throw an error when using a NormalSHook and returning Plugin_Changed since all the clients will will be checked if IsInGame().

Using CBroadcastRecipientFilter would add all players than can be grabbed with UTIL_PlayerByIndex and is probably cause of EmitSound having clients that are not IsInGame().

This PR has been changed to remove clients from the players array that are not IsInGame(). Also a check for the callback-provided size variable has been added

previously Removing the `IsInGame()` check should be fine since `EmitSound` eventually uses `CGameClient::IsActive()` to only send to active clients.

EmitSound -> EmitSoundInternal -> SV_StartSound ->sv.BroadcastSound

CGameClient *pClient = Client( index - 1 );

// client must be fully connect to hear sounds
if ( !pClient->IsActive() )
{
	continue;
}

pClient->SendSound( sound, filter.IsReliable() );

CGameClient -> CBaseClient
virtual bool IsActive( void ) const { return m_nSignonState == SIGNONSTATE_FULL; };

@rtldg rtldg changed the title Normalsoundhook thing NormalSHook erroring on non-IsInGame clients Mar 20, 2021
@Fyren
Copy link
Contributor

Fyren commented Mar 23, 2021

Removing the IsInGame() check should be fine since EmitSound eventually uses CGameClient::IsActive() to only send to active clients.

Did you check if this is true for all engine versions SM supports? Did you actually test it on any?

@rtldg
Copy link
Contributor Author

rtldg commented Mar 24, 2021

Removing the IsInGame() check should be fine since EmitSound eventually uses CGameClient::IsActive() to only send to active clients.

Did you check if this is true for all engine versions SM supports? Did you actually test it on any?

It looks like it has always checked if the client is active in both older and newer engine versions.
Also it was a CSGO server that was throwing these sourcemod errors about players not being ingame after returning Plugin_Changed in NormalSHook.

@KyleSanderson
Copy link
Member

I really don't remember why this was added, I think I hit a filter or something that crashed on a mid-connecting client. That's the reason this one hasn't been merged yet, I know it's painful but the only path to merge this one would be to test every game presently.

@rtldg
Copy link
Contributor Author

rtldg commented May 21, 2021

Alternatively, how about removing the client from the players array if not IsInGame()?

@KyleSanderson
Copy link
Member

Alternatively, how about removing the client from the players array if not IsInGame()?

I think that's a fine idea

@rtldg
Copy link
Contributor Author

rtldg commented May 27, 2021

I force pushed a commit to remove clients from the players array if not IsInGame and also to check if the size variable is valid.

edit:
also instead of

memmove(&players[i], &players[i+1], (size-i-1) * sizeof(int));
--i;
--size;

this would be funny

memmove(&players[i], &players[i+1], (size-- - --i) * sizeof(int));

Copy link
Member

@asherkin asherkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I think this looks sane to me, but I'd like a 2nd ack for merge.

@asherkin asherkin requested a review from KyleSanderson June 24, 2021 14:46
@KyleSanderson KyleSanderson merged commit 3b2fa89 into alliedmodders:master Jun 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants