Skip to content

Commit

Permalink
Switch CS:GO Clantag set/get to use netprops + offset over sig + offs…
Browse files Browse the repository at this point in the history
…et. (#922)

* Switch CS:GO Clantag set/get to use netprops + offset over sig+offset.

* Make sure the new functions are defined before using them...

* Fix offset name

* Fix incorrectly dereferencing.
  • Loading branch information
Drifter321 authored and psychonic committed Nov 9, 2018
1 parent cb8d92e commit d79c5e0
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 89 deletions.
204 changes: 130 additions & 74 deletions extensions/cstrike/natives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -521,80 +521,6 @@ static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
}
#endif

static cell_t CS_GetClientClanTag(IPluginContext *pContext, const cell_t *params)
{
static void *addr;
if (!addr)
{
if (!g_pGameConf->GetMemSig("SetClanTag", &addr) || !addr)
{
return pContext->ThrowNativeError("Failed to locate function");
}
}

CBaseEntity *pEntity;
if (!(pEntity = GetCBaseEntity(params[1], true)))
{
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
}

static int tagOffsetOffset = -1;
static int tagOffset;

if (tagOffsetOffset == -1)
{
if (!g_pGameConf->GetOffset("ClanTagOffset", &tagOffsetOffset))
{
tagOffsetOffset = -1;
return pContext->ThrowNativeError("Unable to find ClanTagOffset gamedata");
}

tagOffset = *(int *)((intptr_t)addr + tagOffsetOffset);
}

size_t len;

const char *src = (char *)((intptr_t)pEntity + tagOffset);
pContext->StringToLocalUTF8(params[2], params[3], src, &len);

return len;
}

static cell_t CS_SetClientClanTag(IPluginContext *pContext, const cell_t *params)
{
static ICallWrapper *pWrapper = NULL;

if (!pWrapper)
{
REGISTER_NATIVE_ADDR("SetClanTag",
PassInfo pass[1]; \
pass[0].flags = PASSFLAG_BYVAL; \
pass[0].type = PassType_Basic; \
pass[0].size = sizeof(char *); \
pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 1))
}

CBaseEntity *pEntity;
if (!(pEntity = GetCBaseEntity(params[1], true)))
{
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
}

char *szNewTag;
pContext->LocalToString(params[2], &szNewTag);

unsigned char vstk[sizeof(CBaseEntity *) + sizeof(char *)];
unsigned char *vptr = vstk;

*(CBaseEntity **)vptr = pEntity;
vptr += sizeof(CBaseEntity *);
*(char **)vptr = szNewTag;

pWrapper->Execute(vstk, NULL);

return 1;
}

static cell_t CS_AliasToWeaponID(IPluginContext *pContext, const cell_t *params)
{
#if SOURCE_ENGINE == SE_CSGO
Expand Down Expand Up @@ -838,6 +764,136 @@ static inline cell_t SetPlayerVar(IPluginContext *pContext, const cell_t *params
return 0;
}

static inline cell_t GetPlayerStringVar(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]);
}

char *pVar = GetPlayerVarAddressOrError<char>(varName, pContext, pPlayer);
if (pVar)
{
size_t len;
pContext->StringToLocalUTF8(params[2], params[3], pVar, &len);
return len;
}

return 0;
}

static inline cell_t SetPlayerStringVar(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]);
}

char szSizeName[128];
g_pSM->Format(szSizeName, sizeof(szSizeName), "%sSize", varName);

int maxlen = 0;
if(!g_pGameConf->GetOffset(szSizeName, &maxlen))
{
return pContext->ThrowNativeError("Failed to locate %s offset in gamedata", szSizeName);
}

char *pVar = GetPlayerVarAddressOrError<char>(varName, pContext, pPlayer);

if (pVar)
{
char *newValue;
pContext->LocalToString(params[2], &newValue);
Q_strncpy(pVar, newValue, maxlen);
}

return 1;
}

static cell_t CS_GetClientClanTag(IPluginContext *pContext, const cell_t *params)
{
#if SOURCE_ENGINE == SE_CSGO
return GetPlayerStringVar(pContext, params, "ClanTag");
#else
static void *addr;
if (!addr)
{
if (!g_pGameConf->GetMemSig("SetClanTag", &addr) || !addr)
{
return pContext->ThrowNativeError("Failed to locate function");
}
}

CBaseEntity *pEntity;
if (!(pEntity = GetCBaseEntity(params[1], true)))
{
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
}

static int tagOffsetOffset = -1;
static int tagOffset;

if (tagOffsetOffset == -1)
{
if (!g_pGameConf->GetOffset("ClanTagOffset", &tagOffsetOffset))
{
tagOffsetOffset = -1;
return pContext->ThrowNativeError("Unable to find ClanTagOffset gamedata");
}

tagOffset = *(int *)((intptr_t)addr + tagOffsetOffset);
}

size_t len;

const char *src = (char *)((intptr_t)pEntity + tagOffset);
pContext->StringToLocalUTF8(params[2], params[3], src, &len);

return len;
#endif
}

static cell_t CS_SetClientClanTag(IPluginContext *pContext, const cell_t *params)
{
#if SOURCE_ENGINE == SE_CSGO
return SetPlayerStringVar(pContext, params, "ClanTag");
#else
static ICallWrapper *pWrapper = NULL;

if (!pWrapper)
{
REGISTER_NATIVE_ADDR("SetClanTag",
PassInfo pass[1]; \
pass[0].flags = PASSFLAG_BYVAL; \
pass[0].type = PassType_Basic; \
pass[0].size = sizeof(char *); \
pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 1))
}

CBaseEntity *pEntity;
if (!(pEntity = GetCBaseEntity(params[1], true)))
{
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
}

char *szNewTag;
pContext->LocalToString(params[2], &szNewTag);

unsigned char vstk[sizeof(CBaseEntity *) + sizeof(char *)];
unsigned char *vptr = vstk;

*(CBaseEntity **)vptr = pEntity;
vptr += sizeof(CBaseEntity *);
*(char **)vptr = szNewTag;

pWrapper->Execute(vstk, NULL);

return 1;
#endif
}

static cell_t CS_SetMVPCount(IPluginContext *pContext, const cell_t *params)
{
return SetPlayerVar<int>(pContext, params, "MVPs");
Expand Down
49 changes: 34 additions & 15 deletions gamedata/sm-cstrike.games/game.csgo.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,6 @@
"linux64" "174"
"mac64" "177"
}
"ClanTagOffset"
{
"windows" "12"
"linux" "29"
"linux64" "13"
"mac64" "12"
}
//Offset into HandleCommand_Buy_Internal
"CCSPlayerInventoryOffset"
{
Expand Down Expand Up @@ -168,14 +161,6 @@
"linux64" "\x55\x48\x89\xE5\x41\x57\x41\x56\x41\x55\x41\x54\x53\x48\x89\xFB\x48\x83\xEC\x58\x64\x48\x8B\x04\x25\x28\x00\x00\x00\x48\x89\x45\xC8\x31\xC0\x4C\x8B\x2D\x46\xD3\xBB\x00"
"mac64" "\x55\x48\x89\xE5\x41\x57\x41\x56\x41\x55\x41\x54\x53\x48\x83\xEC\x58\x49\x89\xFD\x48\x8B\x1D\x85\x76\x60\x00"
}
"SetClanTag"
{
"library" "server"
"windows" "\x55\x8B\xEC\x8B\x55\x08\x85\xD2\x74\x2A\x8D\x81\x5C\x25\x00\x00"
"linux" "\x55\x89\xE5\x83\xEC\x18\x8B\x45\x0C\x85\xC0\x74\x2A\x89\x44\x24\x04\x8B\x45\x08\xC7\x44\x24\x08\x10\x00\x00\x00"
"linux64" "\x55\x48\x85\xF6\x48\x89\xE5\x74\x2A\x5D\x48\x81\xC7\x90\x28\x00\x00"
"mac64" "\x55\x48\x89\xE5\x48\x85\xF6\x74\x2A\x48\x81\xC7\x88\x28\x00\x00"
}
"SetModelFromClass"
{
"library" "server"
Expand Down Expand Up @@ -253,4 +238,38 @@
}
}
}

// Used for SetClanTag and GetClanTag
// to find the ClanTag offset start with the string "ClanTagChanged". Inside the function there is 2 KeyValues::GetString, one for "tag", and one for "name"
// The respective function underneath each are SetClanTag and SetClanName.
// To get the offset of the base (m_flGroundAccelLinearFracLastTime) unqiue string is "------- accelspeed = %f, flGoalSpeed = %f, flStoredAccel = %f\n"
// Inside that function right above the debug message is an if with a call to CBaseEntity::NetworkStateChanged and a member set with the same offset.
// Do math.
// Note: Second offset can be skipped by simply dumping the netprops instead on each os although the distance will probably be the same on all.

"#default"
{
"Keys"
{
"ClanTagBase" "m_flGroundAccelLinearFracLastTime"
}

"Offsets"
{
"ClanTagSize"
{
"windows" "16"
"linux" "16"
"linux64" "16"
"mac64" "16"
}
"ClanTag"
{
"windows" "140"
"linux" "140"
"linux64" "140"
"mac64" "140"
}
}
}
}

0 comments on commit d79c5e0

Please sign in to comment.