From 2928c622f99ba0cf1a3bc67f0dc8fdf43a95fbf0 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Mon, 23 Nov 2015 14:06:02 +0100 Subject: [PATCH] Add cs_set_ent_class native --- gamedata/modules.games/game.cstrike.txt | 16 ++++++++++++ modules/cstrike/cstrike/CstrikeHacks.cpp | 12 +++++++++ modules/cstrike/cstrike/CstrikeHacks.h | 9 +++++++ modules/cstrike/cstrike/CstrikeNatives.cpp | 29 ++++++++++++++++++++++ plugins/include/cstrike.inc | 18 ++++++++++++-- 5 files changed, 82 insertions(+), 2 deletions(-) diff --git a/gamedata/modules.games/game.cstrike.txt b/gamedata/modules.games/game.cstrike.txt index dbf6578c..01b7aba5 100644 --- a/gamedata/modules.games/game.cstrike.txt +++ b/gamedata/modules.games/game.cstrike.txt @@ -79,6 +79,22 @@ "mac" "@_Z23UTIL_FindEntityByStringP11CBaseEntityPKcS2_" } + "AddEntityHashValue" // void AddEntityHashValue(struct entvars_s *pev, const char *value, hash_types_e fieldType) + { + "library" "server" + "windows" "\x8B\x2A\x2A\x2A\x83\x2A\x2A\x85\x2A\x53\x55\x56\x57\x0F" + "linux" "@_Z18AddEntityHashValueP9entvars_sPKc12hash_types_e" + "mac" "@_Z18AddEntityHashValueP9entvars_sPKc12hash_types_e" + } + + "RemoveEntityHashValue" // void RemoveEntityHashValue(struct entvars_s *pev, const char *value, hash_types_e fieldType) + { + "library" "server" + "windows" "\x8B\x2A\x2A\x2A\x53\x8B\x2A\x55\x8A\x2A\x33" + "linux" "@_Z21RemoveEntityHashValueP9entvars_sPKc12hash_types_e" + "mac" "@_Z21RemoveEntityHashValueP9entvars_sPKc12hash_types_e" + } + "GetWeaponInfo" // WeaponInfoStruct *GetWeaponInfo(int id); { "library" "server" diff --git a/modules/cstrike/cstrike/CstrikeHacks.cpp b/modules/cstrike/cstrike/CstrikeHacks.cpp index 9230c4c2..a633a248 100644 --- a/modules/cstrike/cstrike/CstrikeHacks.cpp +++ b/modules/cstrike/cstrike/CstrikeHacks.cpp @@ -39,6 +39,8 @@ CDetour *BuyGunAmmoDetour; CreateNamedEntityFunc CS_CreateNamedEntity; UTIL_FindEntityByStringFunc CS_UTIL_FindEntityByString; GetWeaponInfoFunc GetWeaponInfo; +AddEntityHashValueFunc AddEntityHashValue; +RemoveEntityHashValueFunc RemoveEntityHashValue; int CurrentItemId; bool TriggeredFromCommand; @@ -537,6 +539,16 @@ void InitFuncsAddresses() GetWeaponInfo = reinterpret_cast(address); } + if (MainConfig->GetMemSig("AddEntityHashValue", &address)) // cs_set_ent_class() + { + AddEntityHashValue = reinterpret_cast(address); + } + + if (MainConfig->GetMemSig("RemoveEntityHashValue", &address)) // cs_set_ent_class() + { + RemoveEntityHashValue = reinterpret_cast(address); + } + if (!CS_CreateNamedEntity) { diff --git a/modules/cstrike/cstrike/CstrikeHacks.h b/modules/cstrike/cstrike/CstrikeHacks.h index 743a7cb9..26ca7e76 100644 --- a/modules/cstrike/cstrike/CstrikeHacks.h +++ b/modules/cstrike/cstrike/CstrikeHacks.h @@ -54,13 +54,22 @@ extern CDetour *CanBuyThisDetour; extern CDetour *GiveDefaultItemsDetour; extern CDetour *BuyGunAmmoDetour; +enum class HashType +{ + Classname +}; + typedef edict_t* (*CreateNamedEntityFunc)(string_t iszClassname); typedef void* (*UTIL_FindEntityByStringFunc)(void* pStartEntity, const char *szKeyword, const char *szValue); typedef WeaponInfoStruct* (*GetWeaponInfoFunc)(int id); +typedef void (*AddEntityHashValueFunc)(struct entvars_s *pev, const char *value, HashType fieldType); +typedef void (*RemoveEntityHashValueFunc)(struct entvars_s *pev, const char *value, HashType fieldType); extern CreateNamedEntityFunc CS_CreateNamedEntity; extern UTIL_FindEntityByStringFunc CS_UTIL_FindEntityByString; extern GetWeaponInfoFunc GetWeaponInfo; +extern AddEntityHashValueFunc AddEntityHashValue; +extern RemoveEntityHashValueFunc RemoveEntityHashValue; extern CDetour *GiveDefaultItemsDetour; extern enginefuncs_t *g_pengfuncsTable; diff --git a/modules/cstrike/cstrike/CstrikeNatives.cpp b/modules/cstrike/cstrike/CstrikeNatives.cpp index 92594e56..f61b2e8c 100644 --- a/modules/cstrike/cstrike/CstrikeNatives.cpp +++ b/modules/cstrike/cstrike/CstrikeNatives.cpp @@ -1782,6 +1782,34 @@ static cell AMX_NATIVE_CALL cs_find_ent_by_owner(AMX* amx, cell* params) return 0; } +// cs_set_ent_class(index, const classname[]) +static cell AMX_NATIVE_CALL cs_set_ent_class(AMX* amx, cell* params) +{ + if (AddEntityHashValue <= 0 || RemoveEntityHashValue <= 0) + { + MF_LogError(amx, AMX_ERR_NATIVE, "Native cs_set_ent_class() is disabled. Check your amxx logs."); + return 0; + } + + auto entity = params[1]; + CHECK_ENTITY_SIMPLE(entity); + + auto pev = TypeConversion.id_to_entvars(entity); + + if (pev->classname) + { + RemoveEntityHashValue(pev, STRING(pev->classname), HashType::Classname); + } + + int length; + auto new_classname = MF_GetAmxString(amx, params[2], 0, &length); + + pev->classname = ALLOC_STRING(new_classname); + AddEntityHashValue(pev, STRING(pev->classname), HashType::Classname); + + return 1; +} + // native any:cs_get_item_id(const name[], &CsWeaponClassType:classid = CS_WEAPONCLASS_NONE); static cell AMX_NATIVE_CALL cs_get_item_id(AMX* amx, cell* params) { @@ -2004,6 +2032,7 @@ AMX_NATIVE_INFO CstrikeNatives[] = {"cs_create_entity", cs_create_entity }, {"cs_find_ent_by_class", cs_find_ent_by_class}, {"cs_find_ent_by_owner", cs_find_ent_by_owner}, + {"cs_set_ent_class", cs_set_ent_class }, {"cs_get_item_id", cs_get_item_id}, {"cs_get_translated_item_alias",cs_get_translated_item_alias}, {"cs_get_weapon_info", cs_get_weapon_info}, diff --git a/plugins/include/cstrike.inc b/plugins/include/cstrike.inc index 73e58628..4976e191 100755 --- a/plugins/include/cstrike.inc +++ b/plugins/include/cstrike.inc @@ -1015,7 +1015,7 @@ native cs_create_entity(const classname[]); * classname lookup compared to the default FindEntityByString (used by * find_ent_by_class() for example). * @note This exclusively considers entities in the hashtable, created by the - * game itself or using cs_create_entity(). + * game itself, using cs_create_entity(), or added via cs_set_ent_class(). * * @param start_index Entity index to start searching from. -1 to start from * the first entity @@ -1034,7 +1034,7 @@ native cs_find_ent_by_class(start_index, const classname[]); * classname lookup compared to the default FindEntityByString (used by * find_ent_by_owner() for example). * @note This exclusively considers entities in the hashtable, created by the - * game itself or using cs_create_entity(). + * game itself, using cs_create_entity(), or added via cs_set_ent_class(). * * @param start_index Entity index to start searching from. -1 to start from * the first entity @@ -1045,6 +1045,20 @@ native cs_find_ent_by_class(start_index, const classname[]); */ native cs_find_ent_by_owner(start_index, const classname[], owner); +/** + * Sets a custom classname of an entity. + * + * @note Unlike other mods CS keeps track of entities using a custom hashtable. + * This function adds or updates the classname in the hasthable as well. + * This is useful for use with cs_find_ent_by_class() and cs_find_ent_by_owner(). + * + * @param index Entity index + * @param classname Classname to update for + * + * @noreturn + */ +native cs_set_ent_class(index, const classname[]); + /** * Returns the item id associated with an item name and its aliases. *