Added SetUserInfo command to sdktools.
authorMatt Woodrow <pred@alliedmods.net>
Mon Jun 09 07:12:32 2008 +0000 (2008-06-09)
changeset 21075e6c815d7ed9
parent 2106 b051de4afc41
child 2108 cb79854cf137
Added SetUserInfo command to sdktools.
extensions/sdktools/vnatives.cpp
gamedata/sdktools.games.ep2.txt
gamedata/sdktools.games.txt
plugins/include/sdktools_functions.inc
     1.1 --- a/extensions/sdktools/vnatives.cpp	Fri Jun 06 04:55:27 2008 +0000
     1.2 +++ b/extensions/sdktools/vnatives.cpp	Mon Jun 09 07:12:32 2008 +0000
     1.3 @@ -37,6 +37,8 @@
     1.4  #include "vhelpers.h"
     1.5  #include "vglobals.h"
     1.6  #include "CellRecipientFilter.h"
     1.7 +#include <inetchannel.h>
     1.8 +#include <iclient.h>
     1.9  
    1.10  SourceHook::List<ValveCall *> g_RegCalls;
    1.11  SourceHook::List<ICallWrapper *> g_CallWraps;
    1.12 @@ -916,6 +918,64 @@
    1.13  	return 1;
    1.14  }
    1.15  
    1.16 +static cell_t SetClientInfo(IPluginContext *pContext, const cell_t *params)
    1.17 +{
    1.18 +	IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]);
    1.19 +	if (player == NULL)
    1.20 +	{
    1.21 +		return pContext->ThrowNativeError("Invalid client index %d", params[1]);
    1.22 +	}
    1.23 +	if (!player->IsConnected())
    1.24 +	{
    1.25 +		return pContext->ThrowNativeError("Client %d is not connected", params[1]);
    1.26 +	}
    1.27 +
    1.28 +	static ValveCall *pCall = NULL;
    1.29 +	if (!pCall)
    1.30 +	{
    1.31 +		ValvePassInfo params[2];
    1.32 +		InitPass(params[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
    1.33 +		InitPass(params[1], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
    1.34 +
    1.35 +		if (!CreateBaseCall("SetUserCvar", ValveCall_Entity, NULL, params, 2, &pCall))
    1.36 +		{
    1.37 +			return pContext->ThrowNativeError("\"SetUserCvar\" not supported by this mod");
    1.38 +		}
    1.39 +		else if (!pCall)
    1.40 +		{
    1.41 +			return pContext->ThrowNativeError("\"SetUserCvar\" wrapper failed to initialized");
    1.42 +		}
    1.43 +	}
    1.44 +
    1.45 +	static int changedOffset = -1;
    1.46 +
    1.47 +	if (changedOffset == -1)
    1.48 +	{	
    1.49 +		if (!g_pGameConf->GetOffset("InfoChanged", &changedOffset))
    1.50 +		{
    1.51 +			return pContext->ThrowNativeError("\"SetUserCvar\" not supported by this mod");
    1.52 +		}
    1.53 +	}
    1.54 +
    1.55 +	INetChannel *pNetChan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(params[1]));
    1.56 +	IClient *pClient = static_cast<IClient *>(pNetChan->GetMsgHandler());
    1.57 +
    1.58 +	unsigned char *CGameClient = (unsigned char *)pClient - 4;
    1.59 +
    1.60 +	START_CALL();
    1.61 +	/* Not really a CBaseEntity* but this works */
    1.62 +	CBaseEntity **ebuf = (CBaseEntity **)vptr;
    1.63 +	*ebuf = (CBaseEntity *)CGameClient;
    1.64 +	DECODE_VALVE_PARAM(2, vparams, 0);
    1.65 +	DECODE_VALVE_PARAM(3, vparams, 1);
    1.66 +	FINISH_CALL_SIMPLE(NULL);
    1.67 +
    1.68 +	uint8_t* changed = (uint8_t *)(CGameClient + changedOffset);
    1.69 +	*changed = 1;
    1.70 +
    1.71 +	return 1;
    1.72 +}
    1.73 +
    1.74  sp_nativeinfo_t g_Natives[] = 
    1.75  {
    1.76  	{"ExtinguishEntity",		ExtinguishEntity},
    1.77 @@ -942,5 +1002,6 @@
    1.78  	{"GetServerNetStats",		GetServerNetStats},
    1.79  	{"EquipPlayerWeapon",		WeaponEquip},
    1.80  	{"ActivateEntity",			ActivateEntity},
    1.81 +	{"SetClientInfo",			SetClientInfo},
    1.82  	{NULL,						NULL},
    1.83  };
     2.1 --- a/gamedata/sdktools.games.ep2.txt	Fri Jun 06 04:55:27 2008 +0000
     2.2 +++ b/gamedata/sdktools.games.ep2.txt	Mon Jun 09 07:12:32 2008 +0000
     2.3 @@ -411,4 +411,34 @@
     2.4  			}
     2.5  		}
     2.6  	}
     2.7 +
     2.8 +	/* SetUserInfo data */
     2.9 +	"#default"
    2.10 +	{
    2.11 +		"Offsets"
    2.12 +		{
    2.13 +			/**
    2.14 +			 * CBaseClient::SetUserCVar(char  const*,char  const*);
    2.15 +			 * Linux offset straight from VTable dump.
    2.16 +			 * Windows offset is crazy. Found the windows 'SetName' function using string "(%d)%-0.*s"
    2.17 +			 * Cross referenced back to the vtable and counted manually (SetUserCvar is 1 higher, offsets start from 1)
    2.18 +			 */
    2.19 +			"SetUserCvar"
    2.20 +			{
    2.21 +				"windows"	"17"
    2.22 +				"linux"		"55"
    2.23 +			}
    2.24 +			/**
    2.25 +			 * Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
    2.26 +			 * Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end.
    2.27 +			 * Linux: 	mov     byte ptr [esi+98h], 0
    2.28 +			 * Win:	mov     byte ptr [esi+0A4h], 0
    2.29 +			 */
    2.30 +			"InfoChanged"
    2.31 +			{
    2.32 +				"windows"	"164"
    2.33 +				"linux"		"152"
    2.34 +			}
    2.35 +		}
    2.36 +	}
    2.37  }
     3.1 --- a/gamedata/sdktools.games.txt	Fri Jun 06 04:55:27 2008 +0000
     3.2 +++ b/gamedata/sdktools.games.txt	Mon Jun 09 07:12:32 2008 +0000
     3.3 @@ -1858,5 +1858,35 @@
     3.4  			}
     3.5  		}
     3.6  	}
     3.7 +
     3.8 +	/* SetUserInfo data */
     3.9 +	"#default"
    3.10 +	{
    3.11 +		"Offsets"
    3.12 +		{
    3.13 +			/**
    3.14 +			 * CBaseClient::SetUserCVar(char  const*,char  const*);
    3.15 +			 * Linux offset straight from VTable dump.
    3.16 +			 * Windows offset is crazy. Found the windows 'SetName' function using string "(%d)%-0.*s"
    3.17 +			 * Cross referenced back to the vtable and counted manually (SetUserCvar is 1 higher, offsets start from 1)
    3.18 +			 */
    3.19 +			"SetUserCvar"
    3.20 +			{
    3.21 +				"windows"	"17"
    3.22 +				"linux"		"53"
    3.23 +			}
    3.24 +			/**
    3.25 +			 * Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
    3.26 +			 * Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end.
    3.27 +			 * Linux: 	mov     byte ptr [esi+98h], 0
    3.28 +			 * Win:	mov     byte ptr [esi+0A4h], 0
    3.29 +			 */
    3.30 +			"InfoChanged"
    3.31 +			{
    3.32 +				"windows"	"164"
    3.33 +				"linux"		"152"
    3.34 +			}
    3.35 +		}
    3.36 +	}
    3.37  }
    3.38  
     4.1 --- a/plugins/include/sdktools_functions.inc	Fri Jun 06 04:55:27 2008 +0000
     4.2 +++ b/plugins/include/sdktools_functions.inc	Mon Jun 09 07:12:32 2008 +0000
     4.3 @@ -308,3 +308,15 @@
     4.4   * @error				Invalid entity or lack of mod support.
     4.5   */
     4.6  native ActivateEntity(entity);
     4.7 +
     4.8 +/**
     4.9 + * Sets values to client info buffer keys and notifies the engine of the change.
    4.10 + * The change does not get propogated to mods until the next frame.
    4.11 + *
    4.12 + * @param client		Player's index.
    4.13 + * @param key			Key string.
    4.14 + * @param value			Value string.
    4.15 + * @noreturn
    4.16 + * @error				Invalid client index, or client not connected.
    4.17 + */
    4.18 +native SetClientInfo(client, const String:key[], const String:value[]);