From 81d5b4b6996381c16da96b67837f51a7c5ab71ad Mon Sep 17 00:00:00 2001 From: asmodai Date: Fri, 6 Oct 2017 14:25:43 +0300 Subject: [PATCH] getAmxString refactoring --- reapi/src/amxxmodule.cpp | 2 +- reapi/src/amxxmodule.h | 4 +- reapi/src/natives/natives_common.cpp | 39 +++++++----- reapi/src/natives/natives_helper.h | 26 +++----- reapi/src/natives/natives_hookchains.cpp | 9 ++- reapi/src/natives/natives_members.cpp | 8 ++- reapi/src/natives/natives_misc.cpp | 80 ++++++++++++++---------- reapi/src/natives/natives_rechecker.cpp | 13 ++-- reapi/src/natives/natives_vtc.cpp | 3 +- 9 files changed, 101 insertions(+), 83 deletions(-) diff --git a/reapi/src/amxxmodule.cpp b/reapi/src/amxxmodule.cpp index f21c24b..0d2482b 100644 --- a/reapi/src/amxxmodule.cpp +++ b/reapi/src/amxxmodule.cpp @@ -240,7 +240,7 @@ NOINLINE void AMXX_Error(AMX *amx, const char *fmt, ...) g_amxxapi.Log("[%s] %s", scriptName, msg); } -char* getAmxStringTemp(cell* src, char* dest, size_t max, size_t* len) +char* getAmxString(cell* src, char* dest, size_t max, size_t* len) { char* start = dest; diff --git a/reapi/src/amxxmodule.h b/reapi/src/amxxmodule.h index 1094e7b..f756ecc 100644 --- a/reapi/src/amxxmodule.h +++ b/reapi/src/amxxmodule.h @@ -494,12 +494,12 @@ extern amxxapi_t g_amxxapi; void MF_Log(const char *fmt, ...); void MF_LogError(AMX *amx, int err, const char *fmt, ...); void AMXX_Error(AMX *amx, const char *fmt, ...); -char* getAmxStringTemp(cell* src, char* dest, size_t max, size_t* len = nullptr); +char* getAmxString(cell* src, char* dest, size_t max, size_t* len = nullptr); void setAmxString(cell* dest, const char* string, size_t max); inline cell* getAmxAddr(AMX *amx, cell amx_addr) { - return (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr)); + return (cell *)(amx->base + (size_t)(((AMX_HEADER *)amx->base)->dat + amx_addr)); } #endif // __AMXXMODULE_H__ diff --git a/reapi/src/natives/natives_common.cpp b/reapi/src/natives/natives_common.cpp index bae8c32..931dfc7 100644 --- a/reapi/src/natives/natives_common.cpp +++ b/reapi/src/natives/natives_common.cpp @@ -17,8 +17,10 @@ cell AMX_NATIVE_CALL amx_FClassnameIs(AMX *amx, cell *params) return FALSE; } + char classname[256]; + edict_t *pEdict = edictByIndex(nEntityIndex); - if (pEdict && FClassnameIs(pEdict, getAmxString(amx, params[arg_classname]))) { + if (pEdict && FClassnameIs(pEdict, getAmxString(amx, params[arg_classname], classname))) { return TRUE; } @@ -136,8 +138,8 @@ cell AMX_NATIVE_CALL amx_get_key_value(AMX *amx, cell *params) return FALSE; } - char key[MAX_KV_LEN]; - Q_strlcpy(key, getAmxString(amx, params[arg_key])); + char keybuf[MAX_KV_LEN]; + auto key = getAmxString(amx, params[arg_key], keybuf); return g_amxxapi.SetAmxString(amx, params[arg_value], g_engfuncs.pfnInfoKeyValue(buffer, key), params[arg_maxlen]); } @@ -164,9 +166,9 @@ cell AMX_NATIVE_CALL amx_set_key_value(AMX *amx, cell *params) return FALSE; } - char key[MAX_KV_LEN], value[MAX_KV_LEN]; - Q_strlcpy(key, getAmxString(amx, params[arg_key])); - Q_strlcpy(value, getAmxString(amx, params[arg_value])); + char keybuf[MAX_KV_LEN], valuebuf[MAX_KV_LEN]; + auto key = getAmxString(amx, params[arg_key], keybuf); + auto value = getAmxString(amx, params[arg_value], valuebuf); if (!key[0]) { @@ -282,13 +284,14 @@ cell AMX_NATIVE_CALL amx_SetThink(AMX *amx, cell *params) return FALSE; } - int funcid; - const char *funcname = getAmxString(amx, params[arg_handler]); + char namebuf[256]; + const char *funcname = getAmxString(amx, params[arg_handler], namebuf); if (unlikely(funcname == nullptr || funcname[0] == '\0')) { pEntity->SetThink(nullptr); return TRUE; } + int funcid; if (unlikely(g_amxxapi.amx_FindPublic(amx, funcname, &funcid) != AMX_ERR_NONE)) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: public function \"%s\" not found.", __FUNCTION__, funcname); return FALSE; @@ -325,13 +328,14 @@ cell AMX_NATIVE_CALL amx_SetTouch(AMX *amx, cell *params) return FALSE; } - int funcid; - const char *funcname = getAmxString(amx, params[arg_handler]); + char namebuf[256]; + const char *funcname = getAmxString(amx, params[arg_handler], namebuf); if (unlikely(funcname == nullptr || funcname[0] == '\0')) { pEntity->SetTouch(nullptr); return TRUE; } + int funcid; if (unlikely(g_amxxapi.amx_FindPublic(amx, funcname, &funcid) != AMX_ERR_NONE)) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: public function \"%s\" not found.", __FUNCTION__, funcname); return FALSE; @@ -368,13 +372,14 @@ cell AMX_NATIVE_CALL amx_SetUse(AMX *amx, cell *params) return FALSE; } - int funcid; - const char *funcname = getAmxString(amx, params[arg_handler]); + char namebuf[256]; + const char *funcname = getAmxString(amx, params[arg_handler], namebuf); if (unlikely(funcname == nullptr || funcname[0] == '\0')) { pEntity->SetUse(nullptr); return TRUE; } + int funcid; if (unlikely(g_amxxapi.amx_FindPublic(amx, funcname, &funcid) != AMX_ERR_NONE)) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: public function \"%s\" not found.", __FUNCTION__, funcname); return FALSE; @@ -411,13 +416,14 @@ cell AMX_NATIVE_CALL amx_SetBlocked(AMX *amx, cell *params) return FALSE; } - int funcid; - const char *funcname = getAmxString(amx, params[arg_handler]); + char namebuf[256]; + const char *funcname = getAmxString(amx, params[arg_handler], namebuf); if (unlikely(funcname == nullptr || funcname[0] == '\0')) { pEntity->SetBlocked(nullptr); return TRUE; } + int funcid; if (unlikely(g_amxxapi.amx_FindPublic(amx, funcname, &funcid) != AMX_ERR_NONE)) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: public function \"%s\" not found.", __FUNCTION__, funcname); return FALSE; @@ -455,13 +461,14 @@ cell AMX_NATIVE_CALL amx_SetMoveDone(AMX *amx, cell *params) return FALSE; } - int funcid; - const char *funcname = getAmxString(amx, params[arg_handler]); + char namebuf[256]; + const char *funcname = getAmxString(amx, params[arg_handler], namebuf); if (unlikely(funcname == nullptr || funcname[0] == '\0')) { ((CBaseToggle *)pEntity)->SetMoveDone(nullptr); return TRUE; } + int funcid; if (unlikely(g_amxxapi.amx_FindPublic(amx, funcname, &funcid) != AMX_ERR_NONE)) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: public function \"%s\" not found.", __FUNCTION__, funcname); return FALSE; diff --git a/reapi/src/natives/natives_helper.h b/reapi/src/natives/natives_helper.h index 8f096d3..83d5558 100644 --- a/reapi/src/natives/natives_helper.h +++ b/reapi/src/natives/natives_helper.h @@ -98,25 +98,17 @@ private: cell* m_params; }; -struct getAmxString +template +const char* getAmxString(cell* src, char (&dest)[N], size_t* len = nullptr) { - getAmxString(cell* src, size_t* len = nullptr) - { - getAmxStringTemp(src, temp, sizeof temp - 1, len); - } + return getAmxString(src, dest, N - 1, len); +} - getAmxString(AMX* amx, cell addr, size_t* len = nullptr) - { - getAmxStringTemp(getAmxAddr(amx, addr), temp, sizeof temp - 1, len); - } - - operator char *() - { - return temp; - } - - char temp[1024]; -}; +template +const char* getAmxString(AMX* amx, cell addr, char (&dest)[N], size_t* len = nullptr) +{ + return getAmxString(getAmxAddr(amx, addr), dest, N - 1, len); +} inline void fillNatives(AMX_NATIVE_INFO* table, cell (AMX_NATIVE_CALL with)(AMX *, cell *)) { diff --git a/reapi/src/natives/natives_hookchains.cpp b/reapi/src/natives/natives_hookchains.cpp index b6212eb..24bffd5 100644 --- a/reapi/src/natives/natives_hookchains.cpp +++ b/reapi/src/natives/natives_hookchains.cpp @@ -32,8 +32,10 @@ cell AMX_NATIVE_CALL RegisterHookChain(AMX *amx, cell *params) return INVALID_HOOKCHAIN; } + char namebuf[256]; + const char *funcname = getAmxString(amx, params[arg_handler], namebuf); + int funcid; - const char *funcname = getAmxString(amx, params[arg_handler]); if (unlikely(g_amxxapi.amx_FindPublic(amx, funcname, &funcid) != AMX_ERR_NONE)) { MF_LogError(amx, AMX_ERR_NATIVE, "%s: public function \"%s\" not found.", __FUNCTION__, funcname); @@ -125,6 +127,7 @@ cell AMX_NATIVE_CALL SetHookChainReturn(AMX *amx, cell *params) return FALSE; } + char string[2048]; cell* srcAddr = getAmxAddr(amx, params[arg_value]); switch (retVal.type) @@ -140,7 +143,7 @@ cell AMX_NATIVE_CALL SetHookChainReturn(AMX *amx, cell *params) delete[] retVal._string; size_t len; - const char *dest = getAmxString(srcAddr, &len); + const char *dest = getAmxString(srcAddr, string, &len); retVal._string = strcpy(new char[len + 1], dest); break; } @@ -270,7 +273,7 @@ cell AMX_NATIVE_CALL SetHookChainArg(AMX *amx, cell *params) *(cell *)destAddr = *srcAddr; break; case ATYPE_STRING: - *(char **)destAddr = getAmxStringTemp(srcAddr, g_hookCtx->get_temp_string(amx), CTempStrings::STRING_LEN); + *(char **)destAddr = getAmxString(srcAddr, g_hookCtx->get_temp_string(amx), CTempStrings::STRING_LEN); break; case ATYPE_CLASSPTR: *(CBaseEntity **)destAddr = getPrivate(*srcAddr); diff --git a/reapi/src/natives/natives_members.cpp b/reapi/src/natives/natives_members.cpp index 288c165..c6243e0 100644 --- a/reapi/src/natives/natives_members.cpp +++ b/reapi/src/natives/natives_members.cpp @@ -620,6 +620,8 @@ void RegisterNatives_Members() cell set_member(void* pdata, const member_t *member, cell* value, size_t element) { + char string[2048]; + switch (member->type) { case MEMBER_CLASSPTR: { @@ -655,14 +657,14 @@ cell set_member(void* pdata, const member_t *member, cell* value, size_t element // native set_member(_index, any:_member, const source[]); if (member->max_size > sizeof(char*)) { // char [] - char *source = getAmxString(value); + const char *source = getAmxString(value, string); char *dest = get_member_direct(pdata, member->offset); strncpy(dest, source, member->max_size - 1); dest[member->max_size - 1] = '\0'; } else { // char * - char *source = getAmxString(value); + const char *source = getAmxString(value, string); char *&dest = get_member(pdata, member->offset); g_ReGameFuncs->ChangeString(dest, source); } @@ -671,7 +673,7 @@ cell set_member(void* pdata, const member_t *member, cell* value, size_t element } case MEMBER_QSTRING: { - char *source = getAmxString(value); + const char *source = getAmxString(value, string); string_t newstr = (source && source[0] != '\0') ? ALLOC_STRING(source) : iStringNull; set_member(pdata, member->offset, newstr, element); return (cell)newstr; diff --git a/reapi/src/natives/natives_misc.cpp b/reapi/src/natives/natives_misc.cpp index 409b85f..fce809f 100644 --- a/reapi/src/natives/natives_misc.cpp +++ b/reapi/src/natives/natives_misc.cpp @@ -73,9 +73,10 @@ cell AMX_NATIVE_CALL rg_give_item(AMX *amx, cell *params) CBasePlayer *pPlayer = UTIL_PlayerByIndex(params[arg_index]); CHECK_CONNECTED(pPlayer, arg_index); - GiveType type = static_cast(params[arg_type]); - const char *itemName = getAmxString(amx, params[arg_item]); + char namebuf[256]; + const char *itemName = getAmxString(amx, params[arg_item], namebuf); + GiveType type = static_cast(params[arg_type]); if (type > GT_APPEND) { auto pInfo = g_ReGameApi->GetWeaponSlot(itemName); @@ -118,9 +119,10 @@ cell AMX_NATIVE_CALL rg_give_custom_item(AMX *amx, cell *params) CBasePlayer *pPlayer = UTIL_PlayerByIndex(params[arg_index]); CHECK_CONNECTED(pPlayer, arg_index); - GiveType type = static_cast(params[arg_type]); - const char *itemName = getAmxString(amx, params[arg_item]); + char namebuf[256]; + const char *itemName = getAmxString(amx, params[arg_item], namebuf); + GiveType type = static_cast(params[arg_type]); if (type > GT_APPEND) { auto pInfo = g_ReGameApi->GetWeaponSlot(itemName); @@ -420,29 +422,25 @@ cell AMX_NATIVE_CALL rg_round_end(AMX *amx, cell *params) return FALSE; } + char sentencebuf[190], messagebuf[190]; + const char *sentence = getAmxString(amx, params[arg_sentence], sentencebuf); + const char *message = getAmxString(amx, params[arg_message], messagebuf); + ScenarioEventEndRound event = static_cast(params[arg_event]); - - char sentence[190], message[190]; - Q_strlcpy(sentence, getAmxString(amx, params[arg_sentence])); - Q_strlcpy(message, getAmxString(amx, params[arg_message])); - - const char *_sentence = sentence; - const char *_message = message; - if (event != ROUND_NONE) { auto& lst = msg_sentence_list[event]; - if (strcmp(_sentence, "default") == 0) - _sentence = lst.sentence; + if (strcmp(sentence, "default") == 0) + sentence = lst.sentence; if (strcmp(message, "default") == 0) - _message = lst.msg; + message = lst.msg; } - if (_sentence[0] != '\0') + if (sentence[0] != '\0') { - Broadcast(_sentence); + Broadcast(sentence); } - CSGameRules()->EndRoundMessage(_message, event); + CSGameRules()->EndRoundMessage(message, event); CSGameRules()->TerminateRound(CAmxArg(amx, params[arg_delay]), winstatus); return TRUE; } @@ -486,7 +484,8 @@ cell AMX_NATIVE_CALL rg_create_entity(AMX *amx, cell *params) { enum args_e { arg_count, arg_classname, arg_hashtable }; - string_t iClass = g_engfuncs.pfnAllocString(getAmxString(amx, params[arg_classname])); + char classname[256]; + string_t iClass = g_engfuncs.pfnAllocString(getAmxString(amx, params[arg_classname], classname)); edict_t *pEntity; if (params[arg_hashtable] != 0) @@ -518,7 +517,8 @@ cell AMX_NATIVE_CALL rg_find_ent_by_class(AMX *amx, cell *params) { enum args_e { arg_count, arg_start_index, arg_classname, arg_hashtable }; - const char* value = getAmxString(amx, params[arg_classname]); + char classname[256]; + const char* value = getAmxString(amx, params[arg_classname], classname); if (params[arg_hashtable] != 0) { @@ -556,8 +556,10 @@ cell AMX_NATIVE_CALL rg_find_ent_by_owner(AMX *amx, cell *params) CHECK_ISENTITY(arg_onwer); + char classname[256]; + cell& startIndex = *getAmxAddr(amx, params[arg_start_index]); - const char* value = getAmxString(amx, params[arg_classname]); + const char* value = getAmxString(amx, params[arg_classname], classname); edict_t* pOwner = edictByIndexAmx(params[arg_onwer]); edict_t* pEntity = g_pEdicts + startIndex; @@ -599,7 +601,8 @@ cell AMX_NATIVE_CALL rg_find_weapon_bpack_by_name(AMX *amx, cell *params) CBasePlayer *pPlayer = UTIL_PlayerByIndex(params[arg_index]); CHECK_CONNECTED(pPlayer, arg_index); - const char *pszWeaponName = getAmxString(amx, params[arg_weapon]); + char wname[256]; + const char *pszWeaponName = getAmxString(amx, params[arg_weapon], wname); auto pInfo = g_ReGameApi->GetWeaponSlot(pszWeaponName); if (pInfo != nullptr) { @@ -647,7 +650,8 @@ cell AMX_NATIVE_CALL rg_has_item_by_name(AMX *amx, cell *params) CBasePlayer *pPlayer = UTIL_PlayerByIndex(params[arg_index]); CHECK_CONNECTED(pPlayer, arg_index); - const char *pszItemName = getAmxString(amx, params[arg_item]); + char iname[256]; + const char *pszItemName = getAmxString(amx, params[arg_item], iname); // item_* and weapon_shield for (auto& inf : itemInfoStruct) { if (FStrEq(inf.pszItemName, pszItemName)) { @@ -697,8 +701,9 @@ cell AMX_NATIVE_CALL rg_get_weapon_info(AMX *amx, cell *params) return 0; } + char wname[256]; + const char* szWeaponName = getAmxString(amx, params[arg_weapon_id], wname); WeaponInfoStruct* info = g_ReGameApi->GetWeaponInfo(weaponId); - char* szWeaponName = getAmxString(amx, params[arg_weapon_id]); switch (info_type) { @@ -937,7 +942,8 @@ cell AMX_NATIVE_CALL rg_drop_item(AMX *amx, cell *params) CBasePlayer *pPlayer = UTIL_PlayerByIndex(params[arg_index]); CHECK_CONNECTED(pPlayer, arg_index); - pPlayer->CSPlayer()->DropPlayerItem(getAmxString(amx, params[arg_item_name])); + char item[256]; + pPlayer->CSPlayer()->DropPlayerItem(getAmxString(amx, params[arg_item_name], item)); return TRUE; } @@ -963,9 +969,8 @@ cell AMX_NATIVE_CALL rg_internal_cmd(AMX *amx, cell *params) return FALSE; } - char command[128]; - Q_strlcpy(command, getAmxString(amx, params[arg_cmd])); - pPlayer->CSPlayer()->ClientCommand(command, getAmxString(amx, params[arg_arg])); + char cmd[256], arg[256]; + pPlayer->CSPlayer()->ClientCommand(getAmxString(amx, params[arg_cmd], cmd), getAmxString(amx, params[arg_arg], arg)); return TRUE; } @@ -988,7 +993,8 @@ cell AMX_NATIVE_CALL rg_remove_item(AMX *amx, cell *params) CBasePlayer *pPlayer = UTIL_PlayerByIndex(params[arg_index]); CHECK_CONNECTED(pPlayer, arg_index); - const char* szItemName = getAmxString(amx, params[arg_item_name]); + char iname[256]; + const char* szItemName = getAmxString(amx, params[arg_item_name], iname); if (pPlayer->CSPlayer()->RemovePlayerItem(szItemName)) { return TRUE; } @@ -1173,7 +1179,9 @@ cell AMX_NATIVE_CALL rg_give_defusekit(AMX *amx, cell *params) if (params[arg_def] != 0) { Vector* color = (Vector *)getAmxAddr(amx, params[arg_color]); - const char* icon = getAmxString(amx, params[arg_icon]); + + char iconbuf[256]; + const char* icon = getAmxString(amx, params[arg_icon], iconbuf); MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, nullptr, pPlayer->pev); WRITE_BYTE(params[arg_flash] != 0 ? STATUSICON_FLASH : STATUSICON_SHOW); @@ -1369,7 +1377,8 @@ cell AMX_NATIVE_CALL rg_set_user_model(AMX *amx, cell *params) CBasePlayer *pPlayer = UTIL_PlayerByIndex(params[arg_index]); CHECK_CONNECTED(pPlayer, arg_index); - const char* newModel = getAmxString(amx, params[arg_model]); + char modelbuf[256]; + const char* newModel = getAmxString(amx, params[arg_model], modelbuf); if (*newModel == '\0') { MF_LogError(amx, AMX_ERR_NATIVE, "Model can not be empty"); return FALSE; @@ -1902,7 +1911,8 @@ cell AMX_NATIVE_CALL rg_send_audio(AMX *amx, cell *params) if (nIndex < 0) nIndex = 0; - const char *szSample = getAmxString(amx, params[arg_sample]); + char sample[256]; + const char *szSample = getAmxString(amx, params[arg_sample], sample); auto pEdict = (nIndex == 0) ? nullptr : edictByIndexAmx(nIndex); EMESSAGE_BEGIN(nIndex ? MSG_ONE_UNRELIABLE : MSG_BROADCAST, gmsgSendAudio, nullptr, pEdict); @@ -2005,7 +2015,8 @@ cell AMX_NATIVE_CALL rh_set_mapname(AMX *amx, cell *params) { enum args_e { arg_count, arg_mapname }; - const char *mapname = getAmxString(amx, params[arg_mapname]); + char mapbuf[256]; + const char *mapname = getAmxString(amx, params[arg_mapname], mapbuf); g_RehldsData->SetName(mapname); g_pFunctionTable->pfnResetGlobalState = ResetGlobalState; return TRUE; @@ -2090,7 +2101,8 @@ cell AMX_NATIVE_CALL rh_emit_sound2(AMX *amx, cell *params) } CAmxArgs args(amx, params); - const char *sample = getAmxString(amx, params[arg_sample]); + char samplebuf[256]; + const char *sample = getAmxString(amx, params[arg_sample], samplebuf); return (cell)g_RehldsFuncs->SV_EmitSound2 ( diff --git a/reapi/src/natives/natives_rechecker.cpp b/reapi/src/natives/natives_rechecker.cpp index e3c087e..49cfd9a 100644 --- a/reapi/src/natives/natives_rechecker.cpp +++ b/reapi/src/natives/natives_rechecker.cpp @@ -33,22 +33,23 @@ cell AMX_NATIVE_CALL RegisterQueryFile(AMX *amx, cell *params) } char filename[MAX_PATH]; - const char *file = getAmxString(amx, params[arg_file]); + const char *file = getAmxString(amx, params[arg_file], filename); if (!file || file[0] == '\0') { MF_LogError(amx, AMX_ERR_NATIVE, "%s: file can not be empty.", __FUNCTION__); return FALSE; } - Q_strlcpy(filename, file); + char funcname[256]; + const char *func = getAmxString(amx, params[arg_handler], funcname); + int funcid; - const char *funcname = getAmxString(amx, params[arg_handler]); - if (unlikely(g_amxxapi.amx_FindPublic(amx, funcname, &funcid) != AMX_ERR_NONE)) + if (unlikely(g_amxxapi.amx_FindPublic(amx, func, &funcid) != AMX_ERR_NONE)) { - MF_LogError(amx, AMX_ERR_NATIVE, "%s: public function \"%s\" not found.", __FUNCTION__, funcname); + MF_LogError(amx, AMX_ERR_NATIVE, "%s: public function \"%s\" not found.", __FUNCTION__, func); return FALSE; } - return g_queryFileManager.Add(amx, filename, funcname, flag, params[arg_hash]); + return g_queryFileManager.Add(amx, filename, func, flag, params[arg_hash]); } /* diff --git a/reapi/src/natives/natives_vtc.cpp b/reapi/src/natives/natives_vtc.cpp index f148eee..fa2289b 100644 --- a/reapi/src/natives/natives_vtc.cpp +++ b/reapi/src/natives/natives_vtc.cpp @@ -93,7 +93,8 @@ cell AMX_NATIVE_CALL VTC_PlaySound(AMX *amx, cell *params) CHECK_ISPLAYER(arg_index); - g_pVoiceTranscoderApi->PlaySound((size_t)params[arg_index], getAmxString(amx, params[arg_audio_pathfile])); + char pathfile[MAX_PATH]; + g_pVoiceTranscoderApi->PlaySound((size_t)params[arg_index], getAmxString(amx, params[arg_audio_pathfile], pathfile)); return TRUE; }