reapi icon indicating copy to clipboard operation
reapi copied to clipboard

[BUG]: Blocking RH_SV_DropClient results in unintended behavior

Open szGabu opened this issue 2 months ago • 1 comments

👉👈 Contact Details (optional)

No response

🤔 What happened?

Hooking and blocking RH_SV_DropClient will result in unintended behavior, such as the server's plugins believing the player is not connected.

Test Plugin:

#include <amxmodx>
#include <reapi>

#define PLUGIN_NAME     "Test"
#define PLUGIN_VERSION  "1.0.0"
#define PLUGIN_AUTHOR   "-----"

public plugin_init()
{
    register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR);
    
    RegisterHookChain(RH_SV_DropClient, "ReAPI_HC_DropClient_Pre");
}

public ReAPI_HC_DropClient_Pre(iClient, bool:bCrash, const szReason[])
{
    if(containi(szReason, "Kicked") > -1)
    {
        server_print("[WARNING] %s::ReAPI_HC_DropClient_Pre() - Prevented kick of %n.", __BINARY__, iClient);
        RequestFrame("DebugConnection", iClient);
        return HC_BREAK;
    }

    return HC_CONTINUE;
}  

public DebugConnection(iClient)
{
    server_print("[DEBUG] %s::DebugConnection() - Is player %d connected? %d", __BINARY__, iClient, is_user_connected(iClient));
}

After preventing the disconnection, any plugin that relies on asking if the user is connected will return 0.

This is not ideal, as this can help some servers of kicking some Steam players due to a No-steam logon error due to a faulty connection to Valve's servers.

Is this not blocking AMXX's own hooks?

⚠️ Meta-information

Protocol version 48
Exe version 1.1.2.2/Stdio (valve)
ReHLDS version: 3.14.0.857-dev
Build date: 19:52:21 Mar 27 2025 (4002)
Build from: https://github.com/rehlds/ReHLDS/commit/89958d3
Metamod-r v1.3.0.149, API (5:13)
Metamod-r build: 11:31:17 Apr 23 2024
Metamod-r from: https://github.com/theAsmodai/metamod-r/commit/603a257
Currently loaded plugins:
      description              stat pend  file                      vers                            src  load  unload
 [ 1] AMX Mod X                RUN   -    amxmodx_mm_i386.so        v1.10.0.5467                    ini  Start ANY  
 [16] ReAPI                    RUN   -    reapi_amxx_i386.so        v5.26.0.338-dev                 pl1  ANY   Never

Linux Server, Testing on HL Bugfixed

📄 Relevant log output

kick Gab
[WARNING] test.amx::ReAPI_HC_DropClient_Pre() - Prevented kick of Gab.
[DEBUG] test.amx::DebugConnection() - Is player 1 connected? 0

szGabu avatar Oct 02 '25 17:10 szGabu

You're requesting the is_user_connected function the state of the player before actually returning your actual value of the hook.

#include <amxmodx>
#include <reapi>

#define PLUGIN_NAME     "Test"
#define PLUGIN_VERSION  "1.0.0"
#define PLUGIN_AUTHOR   "-----"

public plugin_init()
{
    register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR);
    
    RegisterHookChain(RH_SV_DropClient, "ReAPI_HC_DropClient_Pre");
    RegisterHookChain(RH_SV_DropClient, "ReAPI_HC_DropClient_Pre2");
}

public ReAPI_HC_DropClient_Pre(iClient, bool:bCrash, const szReason[])
{
    if(containi(szReason, "Kicked") > -1)
    {
        server_print("[WARNING] %s::ReAPI_HC_DropClient_Pre() - Prevented kick of %n.", __BINARY__, iClient);
        return HC_SUPERCEDE;
    }

    return HC_CONTINUE;
}  

public DebugConnection(iClient, bool:bCrash, const szReason[])
{
    server_print("[DEBUG] %s::DebugConnection() - Is player %d connected? %d", __BINARY__, iClient, is_user_connected(iClient));
}

This code works fine as it does what is intended to do, not kick the player.

enum
{
	HC_CONTINUE = 0, // Plugin didn't take any action
	HC_SUPERCEDE,    // Skip real function, use my return value
	HC_BREAK,        // Skip all forwards and real function, use my return value
                     // @note Warning: Be very careful, using this type of return will skip calls for all following AMXX plugins

	HC_BYPASS        // Skip calls for all following AMXX plugins, but call the original function
                     // @note Warning: In PRE skips all forwards including POST forwards
};

Also, if you're using HC_BREAK it will not call the hook for other plugins. You should use the HC_SUPERCEDE if you still want to call the hook using your passed values within it.

Debug:

kick CirA-
[WARNING] test.amx::ReAPI_HC_DropClient_Pre() - Prevented kick of CirA-.
[DEBUG] test.amx::DebugConnection() - Is player 2 connected? 1

ShadowsAdi avatar Nov 15 '25 10:11 ShadowsAdi