From 1b9fb906e27ab78cda768ed3ce58612fc41156f5 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Thu, 13 Oct 2011 13:17:29 -0400 Subject: [PATCH] Added CS_GetClanTag and CS_SetClanTag natives to cstrike ext (bug 5122, r=fyren). --- extensions/cstrike/natives.cpp | 80 ++++++++++++++++++++++++++++++++++ gamedata/sm-cstrike.games.txt | 14 ++++++ plugins/include/cstrike.inc | 27 +++++++++++- 3 files changed, 119 insertions(+), 2 deletions(-) diff --git a/extensions/cstrike/natives.cpp b/extensions/cstrike/natives.cpp index 92e9a07e..4834ffac 100644 --- a/extensions/cstrike/natives.cpp +++ b/extensions/cstrike/natives.cpp @@ -325,6 +325,7 @@ static cell_t CS_GetTranslatedWeaponAlias(IPluginContext *pContext, const cell_t return 1; } + static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params) { //Hard code return values for weapons that dont call GetWeaponPrice and always use default value. @@ -388,6 +389,83 @@ static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params) return CallPriceForward(params[1], weapon_name, price); } +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[2]; \ + pass[0].flags = PASSFLAG_BYVAL; \ + pass[0].type = PassType_Basic; \ + pass[0].size = sizeof(CBaseEntity *); \ + pass[1].flags = PASSFLAG_BYVAL; \ + pass[1].type = PassType_Basic; \ + pass[1].size = sizeof(char *); \ + pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 2)) + } + + 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; +} + sp_nativeinfo_t g_CSNatives[] = { {"CS_RespawnPlayer", CS_RespawnPlayer}, @@ -396,6 +474,8 @@ sp_nativeinfo_t g_CSNatives[] = {"CS_TerminateRound", CS_TerminateRound}, {"CS_GetTranslatedWeaponAlias", CS_GetTranslatedWeaponAlias}, {"CS_GetWeaponPrice", CS_GetWeaponPrice}, + {"CS_GetClientClanTag", CS_GetClientClanTag}, + {"CS_SetClientClanTag", CS_SetClientClanTag}, {NULL, NULL} }; diff --git a/gamedata/sm-cstrike.games.txt b/gamedata/sm-cstrike.games.txt index 7ad9b480..c1d1a9ac 100644 --- a/gamedata/sm-cstrike.games.txt +++ b/gamedata/sm-cstrike.games.txt @@ -28,6 +28,13 @@ "linux" "2308" "mac" "2308" } + //Offset into SetClanTag to find clan tag's offset from player + "ClanTagOffset" + { + "windows" "24" + "linux" "41" + "mac" "29" + } } "Signatures" { @@ -87,6 +94,13 @@ "linux" "@_Z13GetWeaponInfo10CSWeaponID" "mac" "@_Z13GetWeaponInfo10CSWeaponID" } + "SetClanTag" + { + "library" "server" + "windows" "\x55\x8B\xEC\x51\x89\x2A\x2A\x83\x2A\x2A\x2A\x74\x2A\x6A\x2A\x8B\x2A\x2A\x50" + "linux" "@_ZN9CCSPlayer10SetClanTagEPKc" + "mac" "@_ZN9CCSPlayer10SetClanTagEPKc" + } } } } diff --git a/plugins/include/cstrike.inc b/plugins/include/cstrike.inc index 8af04afb..bc7c5fe9 100644 --- a/plugins/include/cstrike.inc +++ b/plugins/include/cstrike.inc @@ -191,7 +191,7 @@ native CS_DropWeapon(client, weaponIndex, bool:toss, bool:blockhook = false); */ native CS_TerminateRound(Float:delay, CSRoundEndReason:reason, bool:blockhook = false); - /** +/** * Gets a weapon name from a weapon alias * * @param alias Weapons alias to get weapon name for. @@ -203,7 +203,7 @@ native CS_DropWeapon(client, weaponIndex, bool:toss, bool:blockhook = false); */ native CS_GetTranslatedWeaponAlias(const String:alias[], String:weapon[], size); - /** +/** * Gets a weapon's price * * @param client Client to check weapon price for. @@ -216,6 +216,27 @@ native CS_DropWeapon(client, weaponIndex, bool:toss, bool:blockhook = false); */ native CS_GetWeaponPrice(client, CSWeaponID:id, bool:defaultprice = false); +/** + * Gets a clients clan tag + * @param client Client index to get clan tag for. + * @param buffer Buffer to store clients clan tag in. + * @param size Size of the buffer. + * @return Number of non-null bytes written. + * + * @error Invalid client. + */ + native CS_GetClientClanTag(client, String:buffer[], size); + +/** + * Sets a clients clan tag + * @param client Client index to set clan tag for. + * @param tag Tag to set clients clan tag as. + * @noreturn + * + * @error Invalid client. + */ + native CS_SetClientClanTag(client, const String:tag[]); + /** * Do not edit below this line! */ @@ -240,6 +261,8 @@ public __ext_cstrike_SetNTVOptional() MarkNativeAsOptional("CS_TerminateRound"); MarkNativeAsOptional("CS_GetTranslatedWeaponAlias"); MarkNativeAsOptional("CS_GetWeaponPrice"); + MarkNativeAsOptional("CS_GetClientClanTag"); + MarkNativeAsOptional("CS_SetClientClanTag"); } #endif