Raised This Month: $51 Target: $400
 12% 

Solved Is IsClientInGame() really includes IsClientConnected check?


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
HarryPotter
Veteran Member
Join Date: Sep 2017
Location: Taiwan, Asia
Old 12-19-2022 , 21:19   Is IsClientInGame() really includes IsClientConnected check?
Reply With Quote #1

Hello, guys, I have a question.

If IsClientInGame(client) return true, IsClientConnected(client) also definitely 100% true ?

All this time I thought when IsClientInGame(client) is true, then IsClientConnected(client) is definitely 100% true until today I saw an error.

Code:
L 12/19/2022 - 00:18:20: [SM] Exception reported: Client 6 is not connected
L 12/19/2022 - 00:18:20: [SM] Blaming: AI_HardSI.smx
L 12/19/2022 - 00:18:20: [SM] Call stack trace:
L 12/19/2022 - 00:18:20: [SM] [0] SetUserFlagBits
But when I checked source code, it does check "IsClientInGame(client)" , so it is making me confused at the moment.

PHP Code:
if ( IsValidClient(commandDummy) ) {
    
int originalUserFlags GetUserFlagBits(commandDummy);
    
int originalCommandFlags GetCommandFlags(commandName);            
    
SetUserFlagBits(commandDummyADMFLAG_ROOT); 
    
SetCommandFlags(commandNameoriginalCommandFlags FCVAR_CHEAT);               
    
FakeClientCommand(commandDummy"%s %s %s"commandNameargument1argument2);
    
SetCommandFlags(commandNameoriginalCommandFlags);
    
SetUserFlagBits(commandDummyoriginalUserFlags);            
}


bool IsValidClient(int client) {
    if( 
client && client <= MaxClients && IsClientInGame(client) ) {
        return 
true;
    } else {
        return 
false;
    }    

Then I investigate functions and in include/clients.inc, it says


PHP Code:
/**
...
 * @param client        Player index (index does not have to be connected).
...
 */
native bool IsClientInGame(int client);

/** 
 * Sets access flags on a client using bits instead of flags.  If the
 * client is not an admin, and flags not 0, a temporary, anonymous AdminId is given.
 *
 * @param client        Player's index.
 * @param flags         Bitstring of flags to set on client.
 * @error               Invalid client index, or client not connected.
 */
native void SetUserFlagBits(int clientint flags); 

Edit: the client could be kick when executing FakeClientCommand,
add IsClientConnected() check after FakeClientCommand.

PHP Code:
int userflags GetUserFlagBits(client);
int cmdflags GetCommandFlags("give");
SetUserFlagBits(clientADMFLAG_ROOT);
SetCommandFlags("give"cmdflags & ~FCVAR_CHEAT);
FakeClientCommand(client"give health"); //could be kicked (reason: run too many commands or other reason else)
SetCommandFlags("give"cmdflags);
if (
IsClientConnected(client)) SetUserFlagBits(clientuserflags); 
__________________

Last edited by HarryPotter; 12-26-2022 at 14:25.
HarryPotter is offline
LinLinLin
Senior Member
Join Date: Sep 2021
Old 12-20-2022 , 01:50   Re: Is IsClientInGame() really includes IsClientConnected check?
Reply With Quote #2

i don't know this but this is the info i can found
PHP Code:
static cell_t sm_IsClientConnected(IPluginContext *pCtx, const cell_t *params)
{
    
int index params[1];
    if ((
index 1) || (index playerhelpers->GetMaxClients()))
    {
        return 
pCtx->ThrowNativeError("Client index %d is invalid"index);
    }

    return (
playerhelpers->GetGamePlayer(index)->IsConnected()) ? 0;
}

static 
cell_t sm_IsClientInGame(IPluginContext *pCtx, const cell_t *params)
{
    
int index params[1];
    if ((
index 1) || (index playerhelpers->GetMaxClients()))
    {
        return 
pCtx->ThrowNativeError("Client index %d is invalid"index);
    }

    return (
playerhelpers->GetGamePlayer(index)->IsInGame()) ? 0;

PHP Code:
namespace SourceMod
{
    
/**
     * @brief Abstracts some Half-Life 2 and SourceMod properties about clients.
     */
    
class IGamePlayer
    
{
    public:
        
/**
         * @brief Returns whether the player is in game (putinserver).
         *
         * @return        True if in game, false otherwise.
         */
        
virtual bool IsInGame() =0;

        
/**
         * @brief Returns whether the player is connected.
         *
         * Note: If this returns true, all above functions except for
         * GetAuthString() should return non-NULL results.
         *
         * @return        True if connected, false otherwise.
         */
        
virtual bool IsConnected() =0
LinLinLin is offline
little_froy
Senior Member
Join Date: May 2021
Old 12-20-2022 , 02:08   Re: Is IsClientInGame() really includes IsClientConnected check?
Reply With Quote #3

i don't know but i can confirm that, FakeClientCommand() cause player disconnected if it runs too often.


Code:
#pragma tabsize 0
#pragma semicolon 1
#pragma newdecls required
#include <sourcemod>

#define COUNT   (1000)

public Action cmd_test(int client, int args) 
{
    if(client > 0 && client <= MaxClients && IsClientInGame(client) && IsClientConnected(client))
    {
        for(int i = 0; i < COUNT; i++)
        {
            int userflags = GetUserFlagBits(client);
            int cmdflags = GetCommandFlags("give");
            SetUserFlagBits(client, ADMFLAG_ROOT);
            SetCommandFlags("give", cmdflags & ~FCVAR_CHEAT);
            FakeClientCommand(client, "give health");
            SetCommandFlags("give", cmdflags);
            SetUserFlagBits(client, userflags);
        }
    }
    return Plugin_Handled;
}

public void OnPluginStart()
{
    RegConsoleCmd("sm_test", cmd_test);
}

Last edited by little_froy; 12-20-2022 at 02:10.
little_froy is offline
HarryPotter
Veteran Member
Join Date: Sep 2017
Location: Taiwan, Asia
Old 12-20-2022 , 14:41   Re: Is IsClientInGame() really includes IsClientConnected check?
Reply With Quote #4

Quote:
Originally Posted by little_froy View Post
Code:
public Action cmd_test(int client, int args) 
{
    if(client > 0 && client <= MaxClients && IsClientInGame(client) && IsClientConnected(client))
    {
        for(int i = 0; i < COUNT; i++)
        {
            int userflags = GetUserFlagBits(client);
            int cmdflags = GetCommandFlags("give");
            SetUserFlagBits(client, ADMFLAG_ROOT);
            SetCommandFlags("give", cmdflags & ~FCVAR_CHEAT);
            FakeClientCommand(client, "give health");
            SetCommandFlags("give", cmdflags);
            SetUserFlagBits(client, userflags);
        }
    }
    return Plugin_Handled;
}
You might be right, this could be the reason, I test your code, and there is an exactly same error.
Code:
L 12/21/2022 - 03:40:23: SourceMod error session started
L 12/21/2022 - 03:40:23: Info (map "c2m2_fairgrounds") (file "D:\Left 4 Dead 2 Test Server\left4dead2\addons\sourcemod\logs\errors_20221221.log")
L 12/21/2022 - 03:40:23: [SM] Exception reported: Client 1 is not connected
L 12/21/2022 - 03:40:23: [SM] Blaming: test.smx
L 12/21/2022 - 03:40:23: [SM] Call stack trace:
L 12/21/2022 - 03:40:23: [SM]   [0] SetUserFlagBits
L 12/21/2022 - 03:40:23: [SM]   [1] Line 64, d:\Github\Private-Work\L4D2-插件\scripting_1.11\test.sp::Cmd_test
L 12/21/2022 - 03:40:29: Error log file session closed.
__________________

Last edited by HarryPotter; 12-20-2022 at 23:34.
HarryPotter is offline
Bacardi
Veteran Member
Join Date: Jan 2010
Location: mom's basement
Old 12-20-2022 , 15:25   Re: Is IsClientInGame() really includes IsClientConnected check?
Reply With Quote #5

You should also expect, if some "natives" not take action exactly in that time/same frame.
Maybe change itself happen in next frame ?

*edit
...indeed. Try change order of those natives.
FakeClientCommand to last ?

Last edited by Bacardi; 12-20-2022 at 15:27.
Bacardi is offline
HarryPotter
Veteran Member
Join Date: Sep 2017
Location: Taiwan, Asia
Old 12-21-2022 , 11:37   Re: Is IsClientInGame() really includes IsClientConnected check?
Reply With Quote #6

Quote:
Originally Posted by Bacardi View Post
Try change order of those natives.
FakeClientCommand to last ?
Thank you, I add IsClientConnected() check after FakeClientCommand.
PHP Code:
            int userflags GetUserFlagBits(client);
            
int cmdflags GetCommandFlags("give");
            
SetUserFlagBits(clientADMFLAG_ROOT);
            
SetCommandFlags("give"cmdflags & ~FCVAR_CHEAT);
            
FakeClientCommand(client"give health"); //could be kicked (reason: run too many commands)
            
SetCommandFlags("give"cmdflags);
            if (
IsClientConnected(client)) SetUserFlagBits(clientuserflags); 
__________________

Last edited by HarryPotter; 12-26-2022 at 14:25.
HarryPotter is offline
luki1412
Veteran Member
Join Date: Oct 2008
Location: OnPluginStart()
Old 12-23-2022 , 14:06   Re: Is IsClientInGame() really includes IsClientConnected check?
Reply With Quote #7

They are not the same. You connect first, then you enter the game. You just need to check them in the right order.

Quote:
if(client > 0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client))
{

}
In your case you do not need IsClientInGame check at all though.
Check Errors section of each command to see what is needed to be checked.
__________________

Last edited by luki1412; 12-23-2022 at 14:14.
luki1412 is offline
Silvers
SourceMod Plugin Approver
Join Date: Aug 2010
Location: SpaceX
Old 12-23-2022 , 14:25   Re: Is IsClientInGame() really includes IsClientConnected check?
Reply With Quote #8

Quote:
Originally Posted by luki1412 View Post
You just need to check them in the right order.
In a loop like this you don't need IsClientConnected only IsClientInGame since that validates they are connected.
__________________
Silvers is offline
luki1412
Veteran Member
Join Date: Oct 2008
Location: OnPluginStart()
Old 12-23-2022 , 14:46   Re: Is IsClientInGame() really includes IsClientConnected check?
Reply With Quote #9

Quote:
Originally Posted by Silvers View Post
In a loop like this you don't need IsClientConnected only IsClientInGame since that validates they are connected.
What do you mean?

Not sure why that loop was added or why he needs to execute that command 1000 times but those commands require the client to be connected. Assuming they dont execute in one frame, in the next frame the client is not guaranteed to still be connected.
__________________
luki1412 is offline
Silvers
SourceMod Plugin Approver
Join Date: Aug 2010
Location: SpaceX
Old 12-23-2022 , 15:30   Re: Is IsClientInGame() really includes IsClientConnected check?
Reply With Quote #10

The 1000 loop was a test.

What I'm saying is IsClientInGame supersedes IsClientConnected, you don't need to call IsClientConnected if you're calling IsClientInGame.
__________________
Silvers is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 19:25.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode