Add client_remove() forward and fix a bug with client not internally disconnected (#414)
* Rename client_disconnected to client_disconnecting * Add client_disconnected as post forward * Fix client not properly disconnected internally Introduced in #264. Edict is reset once SV_DropClient is called, so that second check would be always false. * Reflect changes on the concerned plugins * Revert renaming, let's add only client_remove as post forward
This commit is contained in:
		@@ -136,6 +136,7 @@ int FF_ClientCommand = -1;
 | 
				
			|||||||
int FF_ClientConnect = -1;
 | 
					int FF_ClientConnect = -1;
 | 
				
			||||||
int FF_ClientDisconnect = -1;
 | 
					int FF_ClientDisconnect = -1;
 | 
				
			||||||
int FF_ClientDisconnected = -1;
 | 
					int FF_ClientDisconnected = -1;
 | 
				
			||||||
 | 
					int FF_ClientRemove = -1;
 | 
				
			||||||
int FF_ClientInfoChanged = -1;
 | 
					int FF_ClientInfoChanged = -1;
 | 
				
			||||||
int FF_ClientPutInServer = -1;
 | 
					int FF_ClientPutInServer = -1;
 | 
				
			||||||
int FF_PluginInit = -1;
 | 
					int FF_PluginInit = -1;
 | 
				
			||||||
@@ -498,6 +499,7 @@ int	C_Spawn(edict_t *pent)
 | 
				
			|||||||
	FF_ClientConnect = registerForward("client_connect", ET_IGNORE, FP_CELL, FP_DONE);
 | 
						FF_ClientConnect = registerForward("client_connect", ET_IGNORE, FP_CELL, FP_DONE);
 | 
				
			||||||
	FF_ClientDisconnect = registerForward("client_disconnect", ET_IGNORE, FP_CELL, FP_DONE);
 | 
						FF_ClientDisconnect = registerForward("client_disconnect", ET_IGNORE, FP_CELL, FP_DONE);
 | 
				
			||||||
	FF_ClientDisconnected = registerForward("client_disconnected", ET_IGNORE, FP_CELL, FP_CELL, FP_ARRAY, FP_CELL, FP_DONE);
 | 
						FF_ClientDisconnected = registerForward("client_disconnected", ET_IGNORE, FP_CELL, FP_CELL, FP_ARRAY, FP_CELL, FP_DONE);
 | 
				
			||||||
 | 
						FF_ClientRemove = registerForward("client_remove", ET_IGNORE, FP_CELL, FP_CELL, FP_STRING, FP_DONE);
 | 
				
			||||||
	FF_ClientInfoChanged = registerForward("client_infochanged", ET_IGNORE, FP_CELL, FP_DONE);
 | 
						FF_ClientInfoChanged = registerForward("client_infochanged", ET_IGNORE, FP_CELL, FP_DONE);
 | 
				
			||||||
	FF_ClientPutInServer = registerForward("client_putinserver", ET_IGNORE, FP_CELL, FP_DONE);
 | 
						FF_ClientPutInServer = registerForward("client_putinserver", ET_IGNORE, FP_CELL, FP_DONE);
 | 
				
			||||||
	FF_PluginCfg = registerForward("plugin_cfg", ET_IGNORE, FP_DONE);
 | 
						FF_PluginCfg = registerForward("plugin_cfg", ET_IGNORE, FP_DONE);
 | 
				
			||||||
@@ -688,8 +690,15 @@ void C_ServerDeactivate()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		if (pPlayer->ingame)
 | 
							if (pPlayer->ingame)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								auto wasDisconnecting = pPlayer->disconnecting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pPlayer->Disconnect();
 | 
								pPlayer->Disconnect();
 | 
				
			||||||
			--g_players_num;
 | 
								--g_players_num;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (!wasDisconnecting && DropClientDetour)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									executeForwards(FF_ClientRemove, static_cast<cell>(pPlayer->index), FALSE, const_cast<char*>(""));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -881,8 +890,15 @@ void C_ClientDisconnect(edict_t *pEntity)
 | 
				
			|||||||
		--g_players_num;
 | 
							--g_players_num;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto wasDisconnecting = pPlayer->disconnecting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pPlayer->Disconnect();
 | 
						pPlayer->Disconnect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!wasDisconnecting && DropClientDetour)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							executeForwards(FF_ClientRemove, static_cast<cell>(pPlayer->index), FALSE, const_cast<char*>(""));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RETURN_META(MRES_IGNORED);
 | 
						RETURN_META(MRES_IGNORED);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -896,12 +912,10 @@ DETOUR_DECL_STATIC3_VAR(SV_DropClient, void, client_t*, cl, qboolean, crash, con
 | 
				
			|||||||
	ke::SafeVsprintf(buffer, sizeof(buffer) - 1, format, ap);
 | 
						ke::SafeVsprintf(buffer, sizeof(buffer) - 1, format, ap);
 | 
				
			||||||
	va_end(ap);
 | 
						va_end(ap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	CPlayer *pPlayer;
 | 
						auto pPlayer = cl->edict ? GET_PLAYER_POINTER(cl->edict) : nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (cl->edict)
 | 
						if (pPlayer)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		pPlayer = GET_PLAYER_POINTER(cl->edict);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (pPlayer->initialized)
 | 
							if (pPlayer->initialized)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			pPlayer->disconnecting = true;
 | 
								pPlayer->disconnecting = true;
 | 
				
			||||||
@@ -911,9 +925,10 @@ DETOUR_DECL_STATIC3_VAR(SV_DropClient, void, client_t*, cl, qboolean, crash, con
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	DETOUR_STATIC_CALL(SV_DropClient)(cl, crash, "%s", buffer);
 | 
						DETOUR_STATIC_CALL(SV_DropClient)(cl, crash, "%s", buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (cl->edict)
 | 
						if (pPlayer)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		pPlayer->Disconnect();
 | 
							pPlayer->Disconnect();
 | 
				
			||||||
 | 
							executeForwards(FF_ClientRemove, pPlayer->index, TRUE, buffer);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1597,7 +1612,7 @@ C_DLLEXPORT	int	Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		AMXXLOG_Log("client_disconnected forward has been disabled - check your gamedata files.");
 | 
							AMXXLOG_Log("client_disconnected and client_remove forwards have been disabled - check your gamedata files.");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GET_IFACE<IFileSystem>("filesystem_stdio", g_FileSystem, FILESYSTEM_INTERFACE_VERSION);
 | 
						GET_IFACE<IFileSystem>("filesystem_stdio", g_FileSystem, FILESYSTEM_INTERFACE_VERSION);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,11 +56,11 @@ public client_authorized(id)
 | 
				
			|||||||
 	server_cmd("kick #%d ^"%L^"", get_user_userid(id), id, "DROPPED_RES")
 | 
					 	server_cmd("kick #%d ^"%L^"", get_user_userid(id), id, "DROPPED_RES")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public client_disconnected(id)
 | 
					public client_remove(id)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (get_pcvar_num(g_HidePtr))
 | 
						if (get_pcvar_num(g_HidePtr))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		setVisibleSlots(get_playersnum(1) - 1, MaxClients - get_pcvar_num(g_ResPtr))
 | 
							setVisibleSlots(get_playersnum(1), MaxClients - get_pcvar_num(g_ResPtr))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -184,18 +184,33 @@ forward client_disconnect(id);
 | 
				
			|||||||
 * @note This will be called in some additional cases that client_disconnect doesn't cover, 
 | 
					 * @note This will be called in some additional cases that client_disconnect doesn't cover, 
 | 
				
			||||||
 *       most notably when a client aborts the connection process. It is guaranteed to pair 
 | 
					 *       most notably when a client aborts the connection process. It is guaranteed to pair 
 | 
				
			||||||
 *       with the client_connect() forward.
 | 
					 *       with the client_connect() forward.
 | 
				
			||||||
 * @note By this point it is already too late to do anything that directly
 | 
					 * @note When this fires the player entity is still valid (e.g. is_user_connected(id) will 
 | 
				
			||||||
 *       affects the client.
 | 
					 *       return true), but no networked commands will reach the client.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @param id         Client index
 | 
					 * @param id         Client index
 | 
				
			||||||
 * @param drop       If true, client has been explicitly dropped by game
 | 
					 * @param drop       If true, the game has explicitly dropped the client
 | 
				
			||||||
 * @param message    If drop is true, a disconnected message or buffer to copy a new message to
 | 
					 * @param message    If drop is true, a writable buffer containing the disconnect info message
 | 
				
			||||||
 * @param maxlen     Maximum size of buffer
 | 
					 * @param maxlen     Maximum size of buffer
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @noreturn
 | 
					 * @noreturn
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
forward client_disconnected(id, bool:drop, message[], maxlen);
 | 
					forward client_disconnected(id, bool:drop, message[], maxlen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Called when a client entity has been removed from the server.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @note This fires after the client_disconnected() forward, when the player entity has been
 | 
				
			||||||
 | 
					 *       removed (e.g. is_user_connected(id) will return false).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param id         Client index
 | 
				
			||||||
 | 
					 * @param drop       If true, the game has explicitly dropped the client
 | 
				
			||||||
 | 
					 * @param message    If drop is true, contains the disconnect info message
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @noreturn
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					forward client_remove(id, bool:drop, const message[]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Called when a client attempts to execute a command.
 | 
					 * Called when a client attempts to execute a command.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user