Added natives to CStrike ext to access assists/score in CSGO (bug 5525, r=asherkin).
This commit is contained in:
parent
c0b91dd107
commit
ba2915ce4e
@ -600,74 +600,136 @@ static cell_t CS_GetTeamScore(IPluginContext *pContext, const cell_t *params)
|
||||
return pContext->ThrowNativeError("Invalid team index passed (%i).", params[1]);
|
||||
}
|
||||
|
||||
static cell_t CS_SetMVPCount(IPluginContext *pContext, const cell_t *params)
|
||||
template <typename T>
|
||||
static inline T *GetPlayerVarAddressOrError(const char *pszGamedataName, IPluginContext *pContext, CBaseEntity *pPlayerEntity)
|
||||
{
|
||||
static void *addr;
|
||||
if (!addr)
|
||||
char szBaseName[128];
|
||||
g_pSM->Format(szBaseName, sizeof(szBaseName), "%sBase", pszGamedataName);
|
||||
|
||||
const char *pszBaseVar = g_pGameConf->GetKeyValue(szBaseName);
|
||||
if (pszBaseVar == NULL)
|
||||
{
|
||||
if (!g_pGameConf->GetMemSig("IncrementNumMVPs", &addr) || !addr)
|
||||
pContext->ThrowNativeError("Failed to locate %s key in gamedata", szBaseName);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int interimOffset = 0;
|
||||
sm_sendprop_info_t info;
|
||||
if (gamehelpers->FindSendPropInfo("CCSPlayer", pszBaseVar, &info))
|
||||
{
|
||||
interimOffset = info.actual_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
datamap_t *pMap = gamehelpers->GetDataMap(pPlayerEntity);
|
||||
typedescription_t *td = gamehelpers->FindInDataMap(pMap, pszBaseVar);
|
||||
if (td)
|
||||
{
|
||||
return pContext->ThrowNativeError("Failed to locate IncrementNumMVPs function");
|
||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD
|
||||
interimOffset = td->fieldOffset;
|
||||
#else
|
||||
interimOffset = td->fieldOffset[TD_OFFSET_NORMAL];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
CBaseEntity *pEntity;
|
||||
if (!(pEntity = GetCBaseEntity(params[1], true)))
|
||||
if (interimOffset == 0)
|
||||
{
|
||||
pContext->ThrowNativeError("Failed to find property \"%s\" on player.", pszBaseVar);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int tempOffset;
|
||||
if (!g_pGameConf->GetOffset(pszGamedataName, &tempOffset))
|
||||
{
|
||||
pContext->ThrowNativeError("Failed to locate %s offset in gamedata", pszGamedataName);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (T *)((intptr_t)pPlayerEntity + interimOffset + tempOffset);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline cell_t GetPlayerVar(IPluginContext *pContext, const cell_t *params, const char *varName)
|
||||
{
|
||||
CBaseEntity *pPlayer = GetCBaseEntity(params[1], true);
|
||||
if (!pPlayer)
|
||||
{
|
||||
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
|
||||
}
|
||||
|
||||
static int mvpOffsetOffset = -1;
|
||||
static int mvpOffset;
|
||||
|
||||
if (mvpOffsetOffset == -1)
|
||||
{
|
||||
if (!g_pGameConf->GetOffset("MVPCountOffset", &mvpOffsetOffset))
|
||||
{
|
||||
mvpOffsetOffset = -1;
|
||||
return pContext->ThrowNativeError("Unable to find MVPCountOffset gamedata");
|
||||
}
|
||||
|
||||
mvpOffset = *(int *)((intptr_t)addr + mvpOffsetOffset);
|
||||
T *pVar = GetPlayerVarAddressOrError<T>(varName, pContext, pPlayer);
|
||||
if (pVar)
|
||||
{
|
||||
return (cell_t)*pVar;
|
||||
}
|
||||
|
||||
*(int *)((intptr_t)pEntity + mvpOffset) = params[2];
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
template <typename T>
|
||||
static inline cell_t SetPlayerVar(IPluginContext *pContext, const cell_t *params, const char *varName)
|
||||
{
|
||||
CBaseEntity *pPlayer = GetCBaseEntity(params[1], true);
|
||||
if (!pPlayer)
|
||||
{
|
||||
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
|
||||
}
|
||||
|
||||
T *pVar = GetPlayerVarAddressOrError<T>(varName, pContext, pPlayer);
|
||||
if (pVar)
|
||||
{
|
||||
*pVar = (T)params[2];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell_t CS_SetMVPCount(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
return SetPlayerVar<int>(pContext, params, "MVPs");
|
||||
}
|
||||
|
||||
static cell_t CS_GetMVPCount(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
static void *addr;
|
||||
if (!addr)
|
||||
{
|
||||
if (!g_pGameConf->GetMemSig("IncrementNumMVPs", &addr) || !addr)
|
||||
{
|
||||
return pContext->ThrowNativeError("Failed to locate IncrementNumMVPs function");
|
||||
}
|
||||
}
|
||||
return GetPlayerVar<int>(pContext, params, "MVPs");
|
||||
}
|
||||
|
||||
CBaseEntity *pEntity;
|
||||
if (!(pEntity = GetCBaseEntity(params[1], true)))
|
||||
{
|
||||
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
|
||||
}
|
||||
static cell_t CS_SetClientContributionScore(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
return SetPlayerVar<int>(pContext, params, "CScore");
|
||||
#else
|
||||
return pContext->ThrowNativeError("SetClientContributionScore is not supported on this game");
|
||||
#endif
|
||||
}
|
||||
|
||||
static int mvpOffsetOffset = -1;
|
||||
static int mvpOffset;
|
||||
static cell_t CS_GetClientContributionScore(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
return GetPlayerVar<int>(pContext, params, "CScore");
|
||||
#else
|
||||
return pContext->ThrowNativeError("GetClientContributionScore is not supported on this game");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (mvpOffsetOffset == -1)
|
||||
{
|
||||
if (!g_pGameConf->GetOffset("MVPCountOffset", &mvpOffsetOffset))
|
||||
{
|
||||
mvpOffsetOffset = -1;
|
||||
return pContext->ThrowNativeError("Unable to find MVPCountOffset gamedata");
|
||||
}
|
||||
static cell_t CS_SetClientAssists(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
return SetPlayerVar<int>(pContext, params, "Assists");
|
||||
#else
|
||||
return pContext->ThrowNativeError("SetClientAssists is not supported on this game");
|
||||
#endif
|
||||
}
|
||||
|
||||
mvpOffset = *(int *)((intptr_t)addr + mvpOffsetOffset);
|
||||
}
|
||||
|
||||
return *(int *)((intptr_t)pEntity + mvpOffset);
|
||||
static cell_t CS_GetClientAssists(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
return GetPlayerVar<int>(pContext, params, "Assists");
|
||||
#else
|
||||
return pContext->ThrowNativeError("GetClientAssists is not supported on this game");
|
||||
#endif
|
||||
}
|
||||
|
||||
sp_nativeinfo_t g_CSNatives[] =
|
||||
@ -686,6 +748,10 @@ sp_nativeinfo_t g_CSNatives[] =
|
||||
{"CS_GetMVPCount", CS_GetMVPCount},
|
||||
{"CS_SetMVPCount", CS_SetMVPCount},
|
||||
{"CS_WeaponIDToAlias", CS_WeaponIDToAlias},
|
||||
{"CS_GetClientContributionScore", CS_GetClientContributionScore},
|
||||
{"CS_SetClientContributionScore", CS_SetClientContributionScore},
|
||||
{"CS_GetClientAssists", CS_GetClientAssists},
|
||||
{"CS_SetClientAssists", CS_SetClientAssists},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -42,13 +42,6 @@
|
||||
"linux" "159"
|
||||
"mac" "185"
|
||||
}
|
||||
//Offset into IncrementNumMVPs to find MVP count offset from player
|
||||
"MVPCountOffset"
|
||||
{
|
||||
"windows" "46"
|
||||
"linux" "47"
|
||||
"mac" "61"
|
||||
}
|
||||
"ClanTagOffset"
|
||||
{
|
||||
"windows" "15"
|
||||
@ -115,13 +108,6 @@
|
||||
"linux" "@_ZN12CCSGameRules17CheckRestartRoundEv"
|
||||
"mac" "@_ZN12CCSGameRules17CheckRestartRoundEv"
|
||||
}
|
||||
"IncrementNumMVPs"
|
||||
{
|
||||
"library" "server"
|
||||
"windows" "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x8B\x50\x34\x81\xEC\x2A\x2A\x2A\x2A\x57\x8B\xF9\xB9\x2A\x2A\x2A\x2A\xFF\xD2\x85\xC0\x74"
|
||||
"linux" "@_ZN9CCSPlayer16IncrementNumMVPsE13CSMvpReason_t"
|
||||
"mac" "@_ZN9CCSPlayer16IncrementNumMVPsE13CSMvpReason_t"
|
||||
}
|
||||
"AliasToWeaponID"
|
||||
{
|
||||
"library" "server"
|
||||
@ -145,4 +131,60 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"csgo"
|
||||
{
|
||||
"Keys"
|
||||
{
|
||||
"AssistsBase" "m_iFrags"
|
||||
}
|
||||
|
||||
"Offsets"
|
||||
{
|
||||
"Assists"
|
||||
{
|
||||
"windows" "4"
|
||||
"linux" "4"
|
||||
"mac" "4"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"csgo"
|
||||
{
|
||||
"Keys"
|
||||
{
|
||||
"CScoreBase" "m_iWeaponPurchasesThisRound"
|
||||
}
|
||||
|
||||
"Offsets"
|
||||
{
|
||||
/* factors in 256 (size of m_iWeaponPurchasesThisRound array (int size * 64 maxplayers)) */
|
||||
"CScore"
|
||||
{
|
||||
"windows" "276"
|
||||
"linux" "276"
|
||||
"mac" "276"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"csgo"
|
||||
{
|
||||
"Keys"
|
||||
{
|
||||
"MVPsBase" "m_iWeaponPurchasesThisRound"
|
||||
}
|
||||
|
||||
"Offsets"
|
||||
{
|
||||
"MVPs"
|
||||
{
|
||||
/* factors in 256 (size of m_iWeaponPurchasesThisRound array (int size * 64 maxplayers)) */
|
||||
"windows" "256"
|
||||
"linux" "256"
|
||||
"mac" "256"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,13 +49,6 @@
|
||||
"linux" "57"
|
||||
"mac" "481"
|
||||
}
|
||||
//Offset into IncrementNumMVPs to find MVP count offset from player
|
||||
"MVPCountOffset"
|
||||
{
|
||||
"windows" "60"
|
||||
"linux" "49"
|
||||
"mac" "62"
|
||||
}
|
||||
}
|
||||
"Signatures"
|
||||
{
|
||||
@ -145,12 +138,25 @@
|
||||
"linux" "@_ZN12CCSGameRules13CheckWinLimitEv"
|
||||
"mac" "@_ZN12CCSGameRules5ThinkEv"
|
||||
}
|
||||
"IncrementNumMVPs"
|
||||
}
|
||||
}
|
||||
|
||||
"cstrike"
|
||||
{
|
||||
"Keys"
|
||||
{
|
||||
"MVPsBase" "m_bPlayerDominatingMe"
|
||||
}
|
||||
|
||||
"Offsets"
|
||||
{
|
||||
"MVPs"
|
||||
{
|
||||
"library" "server"
|
||||
"windows" "\x55\x8B\xEC\x83\xEC\x2A\x89\x2A\x2A\xA1\x2A\x2A\x2A\x2A\x8B\x48\x2A\x89\x2A\x2A\x33\xD2\x83\x7D\x2A\x00\x0F\x95\xC2\x0F\xB6\xC2\x85\xC0\x74\x2A\x68"
|
||||
"linux" "@_ZN9CCSPlayer16IncrementNumMVPsE13CSMvpReason_t"
|
||||
"mac" "@_ZN9CCSPlayer16IncrementNumMVPsE13CSMvpReason_t"
|
||||
/* factors in 66 (size of m_bPlayerDominatingMe array (bool size * (65 maxplayers + 1)))
|
||||
... plus another 3 because alignment(?) lolidk */
|
||||
"windows" "69"
|
||||
"linux" "69"
|
||||
"mac" "69"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -285,8 +285,8 @@ native CS_SetTeamScore(team, value);
|
||||
|
||||
/**
|
||||
* Gets a client's mvp count
|
||||
* @param client Client index to set mvp count for.
|
||||
* @return Returns the clients internal MVP count.
|
||||
* @param client Client index to get mvp count of.
|
||||
* @return Returns the client's internal MVP count.
|
||||
*
|
||||
* @error Invalid client.
|
||||
*/
|
||||
@ -295,13 +295,51 @@ native CS_GetMVPCount(client);
|
||||
/**
|
||||
* Sets a client's mvp count
|
||||
* @param client Client index to set mvp count for.
|
||||
* @param value Value to set clients mvp count as.
|
||||
* @param value Value to set client's mvp count as.
|
||||
* @noreturn
|
||||
*
|
||||
* @error Invalid client.
|
||||
*/
|
||||
native CS_SetMVPCount(client, value);
|
||||
|
||||
/**
|
||||
* Gets a client's contribution score (CS:GO only)
|
||||
* @param client Client index to get score of.
|
||||
* @return Returns the client's score.
|
||||
*
|
||||
* @error Invalid client.
|
||||
*/
|
||||
native CS_GetClientContributionScore(client);
|
||||
|
||||
/**
|
||||
* Sets a client's contribution score (CS:GO only)
|
||||
* @param client Client index to set score for.
|
||||
* @param value Value to set client's score as.
|
||||
* @noreturn
|
||||
*
|
||||
* @error Invalid client.
|
||||
*/
|
||||
native CS_SetClientContributionScore(client, value);
|
||||
|
||||
/**
|
||||
* Gets a client's assists (CS:GO only)
|
||||
* @param client Client index to get assists of.
|
||||
* @return Returns the client's assists.
|
||||
*
|
||||
* @error Invalid client.
|
||||
*/
|
||||
native CS_GetClientAssists(client);
|
||||
|
||||
/**
|
||||
* Sets a client's assists (CS:GO only)
|
||||
* @param client Client index to set assists for.
|
||||
* @param value Value to set client's assists as.
|
||||
* @noreturn
|
||||
*
|
||||
* @error Invalid client.
|
||||
*/
|
||||
native CS_SetClientAssists(client, value);
|
||||
|
||||
/**
|
||||
* Gets a weaponID from a alias
|
||||
* @param alias Weapon alias to attempt to get an id for.
|
||||
@ -350,6 +388,10 @@ public __ext_cstrike_SetNTVOptional()
|
||||
MarkNativeAsOptional("CS_SetTeamScore");
|
||||
MarkNativeAsOptional("CS_GetMVPCount");
|
||||
MarkNativeAsOptional("CS_SetMVPCount");
|
||||
MarkNativeAsOptional("CS_GetClientContributionScore");
|
||||
MarkNativeAsOptional("CS_SetClientContributionScore");
|
||||
MarkNativeAsOptional("CS_GetClientAssists");
|
||||
MarkNativeAsOptional("CS_SetClientAssists");
|
||||
MarkNativeAsOptional("CS_AliasToWeaponID");
|
||||
}
|
||||
#endif
|
||||
|
94
plugins/testsuite/cstrike-test.sp
Normal file
94
plugins/testsuite/cstrike-test.sp
Normal file
@ -0,0 +1,94 @@
|
||||
#include <sourcemod>
|
||||
#include <cstrike>
|
||||
|
||||
stock GET_ARG_INT( arg, maxSize=64 )
|
||||
{
|
||||
decl String:tempvar[maxSize];
|
||||
GetCmdArg( arg, tempvar, maxSize );
|
||||
return StringToInt( tempvar );
|
||||
}
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
RegConsoleCmd( "get_mvps", get_mvps );
|
||||
RegConsoleCmd( "set_mvps", set_mvps );
|
||||
RegConsoleCmd( "get_score", get_score );
|
||||
RegConsoleCmd( "set_score", set_score );
|
||||
RegConsoleCmd( "get_assists", get_assists );
|
||||
RegConsoleCmd( "set_assists", set_assists );
|
||||
}
|
||||
|
||||
public Action:get_mvps( client, argc )
|
||||
{
|
||||
ReplyToCommand( client, "Your MVP count is %d", CS_GetMVPCount( client ) );
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:set_mvps( client, argc )
|
||||
{
|
||||
new count = GET_ARG_INT( 1 );
|
||||
|
||||
CS_SetMVPCount( client, count );
|
||||
ReplyToCommand( client, "Set your MVP count to %d", count );
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:get_score( client, argc )
|
||||
{
|
||||
if( GuessSDKVersion() != SOURCE_SDK_CSGO )
|
||||
{
|
||||
ReplyToCommand( client, "This command is only intended for CS:GO" );
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
ReplyToCommand( client, "Your contribution score is %d", CS_GetClientContributionScore( client ) );
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:set_score( client, argc )
|
||||
{
|
||||
if( GuessSDKVersion() != SOURCE_SDK_CSGO )
|
||||
{
|
||||
ReplyToCommand( client, "This command is only intended for CS:GO" );
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new count = GET_ARG_INT( 1 );
|
||||
|
||||
CS_SetClientContributionScore( client, count );
|
||||
ReplyToCommand( client, "Set your contribution score to %d", count );
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:get_assists( client, argc )
|
||||
{
|
||||
if( GuessSDKVersion() != SOURCE_SDK_CSGO )
|
||||
{
|
||||
ReplyToCommand( client, "This command is only intended for CS:GO" );
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
ReplyToCommand( client, "Your assist count is %d", CS_GetClientAssists( client ) );
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:set_assists( client, argc )
|
||||
{
|
||||
if( GuessSDKVersion() != SOURCE_SDK_CSGO )
|
||||
{
|
||||
ReplyToCommand( client, "This command is only intended for CS:GO" );
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
new count = GET_ARG_INT( 1 );
|
||||
|
||||
CS_SetClientAssists( client, count );
|
||||
ReplyToCommand( client, "Set your assist count to %d", count );
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
Loading…
Reference in New Issue
Block a user