Closed JustPlayerDE closed 1 year ago
The SourceTV client is based off the CGameClient and because of this treated as a normal client.
// engine/sv_main.cpp (SV_ActivateServer)
// create new HLTV client
CGameClient *pClient = (CGameClient*)sv.CreateFakeClient( tv_name.GetString() );
hltv->StartMaster( pClient );
One way to solve this would probably be to have something like (CGameClient)pClient->SetBot(true)
to force the client to be treated as a bot. (The function and all its logic CGameClient::IsBot
would need to be implemented)
Or you can let all clients created by CGameServer::CreateFakeClient
be treated as a bot idk.
I've run into this via mod code a while ago, since I don't have access to the engine code the earliest point to fix it was in ClientActivate
(game/server/client.cpp
, or a game specific one) using a simple trick:
void ClientActive( edict_t* pEdict, bool bLoadGame )
{
CBasePlayer* pPlayer = nullptr;
#if _DEBUG
Assert( dynamic_cast<CBasePlayer*>( CBaseEntity::Instance( pEdict ) ) );
#endif
pPlayer = static_cast<CBasePlayer*>( CBaseEntity::Instance( pEdict ) );
if( !pPlayer ) ClientPutInServer( pEdict );
// Note: we have no player name set in rare cases where no proper `ClientPutInServer` was called, like for HLTV
else if( V_strlen( pPlayer->GetPlayerName() ) <= 0 ) pPlayer->SetPlayerName( engine->GetClientConVarValue( pPlayer->entindex(), "name" ) );
// Note: make sure we detect HLTV as a bot early
ConVarRef hHLTVName( "tv_name" );
if( hHLTVName.IsValid() && FStrEq( hHLTVName.GetString(), pPlayer->GetPlayerName() ) ) pPlayer->AddFlag( FL_FAKECLIENT );
FinishClientPutInServer( pPlayer );
}
for gmod it can be properly set inside the hltv class just before ClientActive
is being called
Details
Output (when SourceTV spawns):
As you can see the server thinks it is not a Bot in these hooks when SourceTV spawns the first time, as soon as SourceTV dies and spawns again it will print
IsBot
on PlayerSpawn tho.When i run it in the console it also says its a Bot:
Steps to reproduce