[BUG]: Blocking RH_SV_DropClient results in unintended behavior
👉👈 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
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