diff --git a/amxmodx/CForward.cpp b/amxmodx/CForward.cpp index 50ba729b..4e91be10 100755 --- a/amxmodx/CForward.cpp +++ b/amxmodx/CForward.cpp @@ -30,8 +30,7 @@ */ #include "amxmodx.h" - -void AMXAPI amxx_InvalidateTrace(AMX *amx); +#include "debugger.h" CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes) { @@ -74,9 +73,9 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays) { // Get debug info AMX *amx = (*iter).pPlugin->getAMX(); - AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(amx->userdata[2]); - if (pInfo) - pInfo->error = AMX_ERR_NONE; + Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER]; + if (pDebugger) + pDebugger->BeginExec(); // handle strings & arrays int i, ax=0; for (i = 0; i < m_NumParams; ++i) @@ -124,16 +123,17 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays) if (err != AMX_ERR_NONE) { //Did something else set an error? - if (pInfo && pInfo->error != AMX_ERR_NONE) + if (pDebugger && pDebugger->ErrorExists()) { //we don't care, something else logged the error. - } else { + } else if (err != -1) { //nothing logged the error so spit it out anyway - LogError(amx, err, ""); + LogError(amx, err, NULL); } } - amxx_InvalidateTrace(amx); amx->error = AMX_ERR_NONE; + if (pDebugger) + pDebugger->EndExec(); // cleanup strings & arrays for (i = 0; i < m_NumParams; ++i) @@ -229,9 +229,9 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays) if (!pPlugin->isExecutable(m_Func)) return 0; - AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(m_Amx->userdata[2]); - if (pInfo) - pInfo->error = AMX_ERR_NONE; + Debugger *pDebugger = (Debugger *)m_Amx->userdata[UD_DEBUGGER]; + if (pDebugger) + pDebugger->BeginExec(); // handle strings & arrays int i; @@ -276,15 +276,16 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays) if (err != AMX_ERR_NONE) { //Did something else set an error? - if (pInfo && pInfo->error != AMX_ERR_NONE) + if (pDebugger && pDebugger->ErrorExists()) { //we don't care, something else logged the error. - } else { + } else if (err != -1) { //nothing logged the error so spit it out anyway - LogError(m_Amx, err, ""); + LogError(m_Amx, err, NULL); } } - amxx_InvalidateTrace(m_Amx); + if (pDebugger) + pDebugger->EndExec(); m_Amx->error = AMX_ERR_NONE; // cleanup strings & arrays diff --git a/amxmodx/CPlugin.cpp b/amxmodx/CPlugin.cpp index 640cdcca..c1f36fcd 100755 --- a/amxmodx/CPlugin.cpp +++ b/amxmodx/CPlugin.cpp @@ -134,7 +134,7 @@ void CPluginMngr::clear() { CPluginMngr::CPlugin* CPluginMngr::findPluginFast(AMX *amx) { - return (CPlugin*)(amx->userdata[3]); + return (CPlugin*)(amx->userdata[UD_FINDPLUGIN]); } CPluginMngr::CPlugin* CPluginMngr::findPlugin(AMX *amx) { @@ -197,7 +197,7 @@ CPluginMngr::CPlugin::CPlugin(int i, const char* p,const char* n, char* e, int d } else { status = ps_bad_load; } - amx.userdata[3] = this; + amx.userdata[UD_FINDPLUGIN] = this; paused_fun = 0; next = 0; id = i; diff --git a/amxmodx/JIT/amxexecn.o b/amxmodx/JIT/amxexecn.o index c0c6f00f..83db71e8 100755 Binary files a/amxmodx/JIT/amxexecn.o and b/amxmodx/JIT/amxexecn.o differ diff --git a/amxmodx/JIT/amxexecn.obj b/amxmodx/JIT/amxexecn.obj index 08d307a4..4a366eee 100755 Binary files a/amxmodx/JIT/amxexecn.obj and b/amxmodx/JIT/amxexecn.obj differ diff --git a/amxmodx/amx.cpp b/amxmodx/amx.cpp index e4d3f699..77d8e5e0 100755 --- a/amxmodx/amx.cpp +++ b/amxmodx/amx.cpp @@ -450,28 +450,34 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params) * This trick cannot work in the JIT, because the program would need to * be re-JIT-compiled after patching a P-code instruction. */ - #if defined JIT && !defined NDEBUG - if ((amx->flags & AMX_FLAG_JITC)!=0) - assert(amx->sysreq_d==0); - #endif - if (amx->sysreq_d!=0) { - /* at the point of the call, the CIP pseudo-register points directly - * behind the SYSREQ instruction and its parameter. - */ - unsigned char *code=amx->base+(int)hdr->cod+(int)amx->cip-4; - assert(amx->cip >= 4 && amx->cip < (hdr->dat - hdr->cod)); - assert(sizeof(f)<=sizeof(cell)); /* function pointer must fit in a cell */ +#if !defined JIT + if (amx->sysreq_d != 0) + { + //if we're about to patch this, and we're debugging, don't patch! + //otherwise we won't be able to get back native names + if (amx->flags & AMX_FLAG_DEBUG) + { + amx->sysreq_d = 0; + } else { + /* at the point of the call, the CIP pseudo-register points directly + * behind the SYSREQ instruction and its parameter. + */ + unsigned char *code=amx->base+(int)hdr->cod+(int)amx->cip-4; + assert(amx->cip >= 4 && amx->cip < (hdr->dat - hdr->cod)); + assert(sizeof(f)<=sizeof(cell)); /* function pointer must fit in a cell */ #if defined __GNUC__ || defined ASM32 - if (*(cell*)code==index) { + if (*(cell*)code==index) { #else - if (*(cell*)code!=OP_SYSREQ_PRI) { - assert(*(cell*)(code-sizeof(cell))==OP_SYSREQ_C); - assert(*(cell*)code==index); -#endif - *(cell*)(code-sizeof(cell))=amx->sysreq_d; - *(cell*)code=(cell)f; + if (*(cell*)code!=OP_SYSREQ_PRI) { + assert(*(cell*)(code-sizeof(cell))==OP_SYSREQ_C); + assert(*(cell*)code==index); +#endif //defined __GNU__ || defined ASM32 + *(cell*)(code-sizeof(cell))=amx->sysreq_d; + *(cell*)code=(cell)f; + } /* if */ } /* if */ } /* if */ +#endif //!defined JIT /* Note: * params[0] == number of bytes for the additional parameters passed to the native function @@ -547,6 +553,7 @@ static int amx_BrowseRelocate(AMX *amx) */ if ((amx->flags & AMX_FLAG_JITC)==0 && sizeof(AMX_NATIVE)<=sizeof(cell)) amx->sysreq_d=opcode_list[OP_SYSREQ_D]; + amx->userdata[UD_OPCODELIST] = (void *)opcode_list; #else /* ANSI C * to use direct system requests, a function pointer must fit in a cell; @@ -554,6 +561,7 @@ static int amx_BrowseRelocate(AMX *amx) */ if (sizeof(AMX_NATIVE)<=sizeof(cell)) amx->sysreq_d=OP_SYSREQ_D; + amx->userdata[UD_OPCODELIST] = (long)NULL; #endif /* start browsing code */ @@ -1676,7 +1684,13 @@ int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char #define SKIPPARAM(n) ( cip=(cell *)cip+(n) ) #define PUSH(v) ( stk-=sizeof(cell), *(cell *)(data+(int)stk)=v ) #define POP(v) ( v=*(cell *)(data+(int)stk), stk+=sizeof(cell) ) -#define ABORT(amx,v) { (amx)->stk=reset_stk; (amx)->hea=reset_hea; return v; } +#define ABORT(amx,v) { (amx)->stk=reset_stk; \ + (amx)->hea=reset_hea; \ + (amx)->cip=(cell)cip; \ + (amx)->pri=pri; \ + (amx)->alt=alt; \ + return v; \ + } #define CHKMARGIN() if (hea+STKMARGIN>stk) return AMX_ERR_STACKERR #define CHKSTACK() if (stk>amx->stp) return AMX_ERR_STACKLOW @@ -2471,6 +2485,8 @@ static const void * const amx_opcodelist[] = { amx->hea=hea; amx->frm=frm; amx->stk=stk; + amx->pri=pri; + amx->alt=alt; num=amx->callback(amx,pri,&pri,(cell *)(data+(int)stk)); if (num!=AMX_ERR_NONE) { if (num==AMX_ERR_SLEEP) { @@ -2490,6 +2506,8 @@ static const void * const amx_opcodelist[] = { amx->hea=hea; amx->frm=frm; amx->stk=stk; + amx->pri=pri; + amx->alt=alt; num=amx->callback(amx,offs,&pri,(cell *)(data+(int)stk)); if (num!=AMX_ERR_NONE) { if (num==AMX_ERR_SLEEP) { @@ -2509,6 +2527,8 @@ static const void * const amx_opcodelist[] = { amx->hea=hea; amx->frm=frm; amx->stk=stk; + amx->pri=pri; + amx->alt=alt; pri=((AMX_NATIVE)offs)(amx,(cell *)(data+(int)stk)); if (amx->error!=AMX_ERR_NONE) { if (amx->error==AMX_ERR_SLEEP) { @@ -2578,6 +2598,8 @@ static const void * const amx_opcodelist[] = { amx->frm=frm; amx->stk=stk; amx->hea=hea; + amx->pri=pri; + amx->alt=alt; amx->cip=(cell)((unsigned char*)cip-code); num=amx->debug(amx); if (num!=AMX_ERR_NONE) { @@ -3445,6 +3467,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index) amx->hea=hea; amx->frm=frm; amx->stk=stk; + amx->pri=pri; + amx->alt=alt; num=amx->callback(amx,pri,&pri,(cell *)(data+(int)stk)); if (num!=AMX_ERR_NONE) { if (num==AMX_ERR_SLEEP) { @@ -3464,6 +3488,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index) amx->hea=hea; amx->frm=frm; amx->stk=stk; + amx->pri=pri; + amx->alt=alt; num=amx->callback(amx,offs,&pri,(cell *)(data+(int)stk)); if (num!=AMX_ERR_NONE) { if (num==AMX_ERR_SLEEP) { @@ -3483,6 +3509,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index) amx->hea=hea; amx->frm=frm; amx->stk=stk; + amx->pri=pri; + amx->alt=alt; pri=((AMX_NATIVE)offs)(amx,(cell *)(data+(int)stk)); if (amx->error!=AMX_ERR_NONE) { if (amx->error==AMX_ERR_SLEEP) { @@ -3546,6 +3574,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index) amx->frm=frm; amx->stk=stk; amx->hea=hea; + amx->pri=pri; + amx->alt=alt; amx->cip=(cell)((unsigned char*)cip-code); num=amx->debug(amx); if (num!=AMX_ERR_NONE) { diff --git a/amxmodx/amx.h b/amxmodx/amx.h index fb44c6b8..9009fb46 100755 --- a/amxmodx/amx.h +++ b/amxmodx/amx.h @@ -242,6 +242,7 @@ typedef struct tagAMX { long usertags[AMX_USERNUM] PACKED; //okay userdata[3] in AMX Mod X is for the CPlugin * pointer //we're also gonna set userdata[2] to a special debug structure + //lastly, userdata[1] is for opcode_list from amx_BrowseRelocate void _FAR *userdata[AMX_USERNUM] PACKED; /* native functions can raise an error */ int error PACKED; @@ -335,23 +336,9 @@ enum { #define AMX_COMPACTMARGIN 64 #endif -struct amx_trace -{ - cell frm; - amx_trace *prev; - amx_trace *next; - bool used; -}; - -struct AMX_DBGINFO -{ - void *pDebug; //Pointer to debug data - int error; //non-amx_Exec() error setting - amx_trace *pTrace; //Pointer to stack trace - amx_trace *pTraceFrm; - amx_trace *pTraceEnd; - cell frm; -}; +#define UD_FINDPLUGIN 3 +#define UD_DEBUGGER 2 +#define UD_OPCODELIST 1 /* for native functions that use floating point parameters, the following * two macros are convenient for casting a "cell" into a "float" type _without_ diff --git a/amxmodx/amxexecn.asm b/amxmodx/amxexecn.asm index a5a6cf78..89d26d0a 100755 --- a/amxmodx/amxexecn.asm +++ b/amxmodx/amxexecn.asm @@ -129,6 +129,28 @@ jg near err_stack %endmacro +;Normal abort, saves pri/alt +%macro _ABORT 1 + mov ebp,amx + mov [ebp+_pri], dword eax ; store values in AMX structure (PRI, ALT) + mov [ebp+_alt], dword edx ; store values in AMX structure (PRI, ALT) + mov [ebp+_error], dword %1 + jmp _return +%endmacro + +;Checked abort, saves nothing and uses a conditional +%macro _CHKABORT 1 + mov ebp,amx + mov [ebp+_error], %1 + cmp %1, AMX_ERR_NONE + jne _return +%endmacro + +;Fast abort, only aborts, nothing else +%macro _FASTABORT 0 + jmp _return +%endmacro + %macro _CHKHEAP 0 mov ebp,amx mov ebp,[ebp+_hlw] @@ -1196,8 +1218,7 @@ OP_HALT: mov eax,esi ; EAX=CIP sub eax,code mov [ebp+_cip],eax - mov eax,ebx ; return the parameter of the HALT opcode - jmp _return + _ABORT ebx OP_BOUNDS: @@ -1221,6 +1242,7 @@ OP_SYSREQ_PRI: mov alt,edx ; save ALT mov [ebp+_stk],ecx ; store values in AMX structure (STK, HEA, FRM) + ;we don't save regs since they're useless after this mov ecx,hea mov ebx,frm mov [ebp+_hea],ecx @@ -1251,8 +1273,7 @@ OP_SYSREQ_PRI: pop edi ; restore saved registers pop esi pop ebp - cmp eax,AMX_ERR_NONE - jne near _return ; return error code, if any + _CHKABORT eax ; if result was invalid, leave mov eax,pri ; get retval into eax (PRI) mov edx,alt ; restore ALT @@ -1293,8 +1314,8 @@ OP_SYSREQ_D: ; (TR) pop edi ; restore saved registers pop esi pop ebp - cmp DWORD [ebp+_error],AMX_ERR_NONE - jne near _return ; return error code, if any + mov eax,[ebp+_error] + _CHKABORT eax ; function result is in eax (PRI) mov edx,alt ; restore ALT @@ -1416,7 +1437,7 @@ OP_BREAK: mov [ebp+_error],eax ; save EAX (error code) before restoring all regs _RESTOREREGS ; abort run, but restore stack first mov eax,[ebp+_error] ; get error code in EAX back again - jmp _return ; return error code + _FASTABORT break_noabort: _RESTOREREGS mov eax,[ebp+_pri] ; restore PRI and ALT @@ -1425,43 +1446,34 @@ OP_BREAK: OP_INVALID: - mov eax,AMX_ERR_INVINSTR - jmp _return + _ABORT AMX_ERR_INVINSTR err_call: - mov eax,AMX_ERR_CALLBACK - jmp _return + _ABORT AMX_ERR_CALLBACK err_stack: - mov eax,AMX_ERR_STACKERR - jmp _return + _ABORT AMX_ERR_STACKERR err_stacklow: - mov eax,AMX_ERR_STACKLOW - jmp _return + _ABORT AMX_ERR_STACKLOW err_memaccess: - mov eax,AMX_ERR_MEMACCESS - jmp _return + _ABORT AMX_ERR_MEMACCESS err_bounds: - mov eax,AMX_ERR_BOUNDS - jmp _return + _ABORT AMX_ERR_BOUNDS err_heaplow: - mov eax,AMX_ERR_HEAPLOW - jmp _return + _ABORT AMX_ERR_HEAPLOW err_divide: - mov eax,AMX_ERR_DIVIDE - jmp _return - + _ABORT AMX_ERR_DIVIDE _return: ; save a few parameters, mostly for the "sleep"function mov ebp,amx ; get amx into ebp - mov [ebp+_pri],eax ; store values in AMX structure (PRI, ALT) - mov [ebp+_alt],edx ; store values in AMX structure (PRI, ALT) + mov [ebp+_cip],esi ; get corrected cip for amxmodx + mov eax,[ebp+_error]; get error code pop esi ; remove FRM from stack diff --git a/amxmodx/amxmodx.cpp b/amxmodx/amxmodx.cpp index fa3634ee..1aae983b 100755 --- a/amxmodx/amxmodx.cpp +++ b/amxmodx/amxmodx.cpp @@ -34,75 +34,75 @@ static cell AMX_NATIVE_CALL get_xvar_id(AMX *amx, cell *params) { - int len; - char* sName = get_amxstring(amx,params[1],0,len); - cell ptr; + int len; + char* sName = get_amxstring(amx,params[1],0,len); + cell ptr; - for ( CPluginMngr::iterator a = g_plugins.begin(); a ; ++a ) - { - if ( (*a).isValid() && amx_FindPubVar( (*a).getAMX() , sName , &ptr ) == AMX_ERR_NONE ) - return g_xvars.put( (*a).getAMX() , get_amxaddr( (*a).getAMX() , ptr ) ); - } - return -1; + for ( CPluginMngr::iterator a = g_plugins.begin(); a ; ++a ) + { + if ( (*a).isValid() && amx_FindPubVar( (*a).getAMX() , sName , &ptr ) == AMX_ERR_NONE ) + return g_xvars.put( (*a).getAMX() , get_amxaddr( (*a).getAMX() , ptr ) ); + } + return -1; } static cell AMX_NATIVE_CALL get_xvar_num(AMX *amx, cell *params) { - return g_xvars.getValue(params[1]); + return g_xvars.getValue(params[1]); } static cell AMX_NATIVE_CALL set_xvar_num(AMX *amx, cell *params) { - if ( g_xvars.setValue( params[1] , params[2] ) ){ - amx_RaiseError(amx,AMX_ERR_NATIVE); - return 0; - } - return 1; + if ( g_xvars.setValue( params[1] , params[2] ) ){ + amx_RaiseError(amx,AMX_ERR_NATIVE); + return 0; + } + return 1; } static cell AMX_NATIVE_CALL xvar_exists(AMX *amx, cell *params) { - return (get_xvar_id( amx , params ) != -1) ? 1 : 0; + return (get_xvar_id( amx , params ) != -1) ? 1 : 0; } static cell AMX_NATIVE_CALL emit_sound(AMX *amx, cell *params) /* 7 param */ { - int len; - char* szSample = get_amxstring(amx,params[3],0,len); - REAL vol = amx_ctof(params[4]); - REAL att = amx_ctof(params[5]); - int channel = params[2]; - int pitch = params[7]; - int flags = params[6]; + int len; + char* szSample = get_amxstring(amx,params[3],0,len); + REAL vol = amx_ctof(params[4]); + REAL att = amx_ctof(params[5]); + int channel = params[2]; + int pitch = params[7]; + int flags = params[6]; - if (params[1] == 0) { - for(int i = 1; i <= gpGlobals->maxClients ; ++i){ - CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); - if (pPlayer->ingame) - EMIT_SOUND_DYN2(pPlayer->pEdict,channel, szSample, vol, att,flags , pitch); - } - } - else - { - edict_t* pEdict = INDEXENT(params[1]); - if (!FNullEnt(pEdict)) - EMIT_SOUND_DYN2(pEdict,channel , szSample, vol, att, flags, pitch); - } + if (params[1] == 0) { + for(int i = 1; i <= gpGlobals->maxClients ; ++i){ + CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); + if (pPlayer->ingame) + EMIT_SOUND_DYN2(pPlayer->pEdict,channel, szSample, vol, att,flags , pitch); + } + } + else + { + edict_t* pEdict = INDEXENT(params[1]); + if (!FNullEnt(pEdict)) + EMIT_SOUND_DYN2(pEdict,channel , szSample, vol, att, flags, pitch); + } - return 1; + return 1; } static cell AMX_NATIVE_CALL server_print(AMX *amx, cell *params) /* 1 param */ { - int len; - g_langMngr.SetDefLang(LANG_SERVER); // Default language = server - char* message = format_amxstring(amx,params,1,len); - if ( len > 254 ) len = 254; - message[len++]='\n'; - message[len]=0; - SERVER_PRINT( message ); - return len; + int len; + g_langMngr.SetDefLang(LANG_SERVER); // Default language = server + char* message = format_amxstring(amx,params,1,len); + if ( len > 254 ) len = 254; + message[len++]='\n'; + message[len]=0; + SERVER_PRINT( message ); + return len; } static cell AMX_NATIVE_CALL engclient_print(AMX *amx, cell *params) /* 3 param */ @@ -146,22 +146,22 @@ static cell AMX_NATIVE_CALL engclient_print(AMX *amx, cell *params) /* 3 param static cell AMX_NATIVE_CALL console_cmd(AMX *amx, cell *params) /* 2 param */ { - int index = params[1]; - g_langMngr.SetDefLang(index); - int len; - char* cmd = format_amxstring(amx,params,2,len); - cmd[len++]='\n'; - cmd[len]=0; + int index = params[1]; + g_langMngr.SetDefLang(index); + int len; + char* cmd = format_amxstring(amx,params,2,len); + cmd[len++]='\n'; + cmd[len]=0; - if (index < 1 || index > gpGlobals->maxClients){ - SERVER_COMMAND( cmd ); - } - else{ - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - if ( !pPlayer->bot && pPlayer->initialized ) CLIENT_COMMAND(pPlayer->pEdict, UTIL_VarArgs("%s", cmd) ); - } + if (index < 1 || index > gpGlobals->maxClients){ + SERVER_COMMAND( cmd ); + } + else{ + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + if ( !pPlayer->bot && pPlayer->initialized ) CLIENT_COMMAND(pPlayer->pEdict, UTIL_VarArgs("%s", cmd) ); + } - return len; + return len; } static cell AMX_NATIVE_CALL console_print(AMX *amx, cell *params) /* 2 param */ @@ -230,58 +230,58 @@ static cell AMX_NATIVE_CALL client_print(AMX *amx, cell *params) /* 3 param */ static cell AMX_NATIVE_CALL show_motd(AMX *amx, cell *params) /* 3 param */ { - int ilen; - const char* szHead = get_amxstring(amx,params[3],0,ilen); - if ( !ilen ) szHead = hostname->string; - char* szBody = get_amxstring(amx,params[2],1,ilen); - int iFile = 0; - char* sToShow = NULL; // = szBody; - if (ilen<128) sToShow = (char*)LOAD_FILE_FOR_ME( szBody , &iFile ); - if (!iFile) - sToShow = szBody; - else - ilen = iFile; - if (params[1] == 0) { - for(int i = 1; i <= gpGlobals->maxClients; ++i){ - CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); - if (pPlayer->ingame) - UTIL_ShowMOTD(pPlayer->pEdict, sToShow , ilen, szHead); - } - } - else { - int index = params[1]; - if (index < 1 || index > gpGlobals->maxClients){ - LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); - if (iFile) FREE_FILE(sToShow); - return 0; - } - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - if (pPlayer->ingame) - UTIL_ShowMOTD(pPlayer->pEdict, sToShow,ilen, szHead ); - } - if (iFile) FREE_FILE(sToShow); - return 1; + int ilen; + const char* szHead = get_amxstring(amx,params[3],0,ilen); + if ( !ilen ) szHead = hostname->string; + char* szBody = get_amxstring(amx,params[2],1,ilen); + int iFile = 0; + char* sToShow = NULL; // = szBody; + if (ilen<128) sToShow = (char*)LOAD_FILE_FOR_ME( szBody , &iFile ); + if (!iFile) + sToShow = szBody; + else + ilen = iFile; + if (params[1] == 0) { + for(int i = 1; i <= gpGlobals->maxClients; ++i){ + CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); + if (pPlayer->ingame) + UTIL_ShowMOTD(pPlayer->pEdict, sToShow , ilen, szHead); + } + } + else { + int index = params[1]; + if (index < 1 || index > gpGlobals->maxClients){ + LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); + if (iFile) FREE_FILE(sToShow); + return 0; + } + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + if (pPlayer->ingame) + UTIL_ShowMOTD(pPlayer->pEdict, sToShow,ilen, szHead ); + } + if (iFile) FREE_FILE(sToShow); + return 1; } static cell AMX_NATIVE_CALL set_hudmessage(AMX *amx, cell *params) /* 11 param */ { - g_hudset.a1 = 0; - g_hudset.a2 = 0; - g_hudset.r2 = 255; - g_hudset.g2 = 255; - g_hudset.b2 = 250; - g_hudset.r1 = static_cast(params[1]); - g_hudset.g1 = static_cast(params[2]); - g_hudset.b1 = static_cast(params[3]); - g_hudset.x = amx_ctof(params[4]); - g_hudset.y = amx_ctof(params[5]); - g_hudset.effect = params[6]; - g_hudset.fxTime = amx_ctof(params[7]); - g_hudset.holdTime = amx_ctof(params[8]); - g_hudset.fadeinTime = amx_ctof(params[9]); - g_hudset.fadeoutTime = amx_ctof(params[10]); - g_hudset.channel = params[11]; - return 1; + g_hudset.a1 = 0; + g_hudset.a2 = 0; + g_hudset.r2 = 255; + g_hudset.g2 = 255; + g_hudset.b2 = 250; + g_hudset.r1 = static_cast(params[1]); + g_hudset.g1 = static_cast(params[2]); + g_hudset.b1 = static_cast(params[3]); + g_hudset.x = amx_ctof(params[4]); + g_hudset.y = amx_ctof(params[5]); + g_hudset.effect = params[6]; + g_hudset.fxTime = amx_ctof(params[7]); + g_hudset.holdTime = amx_ctof(params[8]); + g_hudset.fadeinTime = amx_ctof(params[9]); + g_hudset.fadeoutTime = amx_ctof(params[10]); + g_hudset.channel = params[11]; + return 1; } static cell AMX_NATIVE_CALL show_hudmessage(AMX *amx, cell *params) /* 2 param */ @@ -319,44 +319,44 @@ static cell AMX_NATIVE_CALL show_hudmessage(AMX *amx, cell *params) /* 2 param static cell AMX_NATIVE_CALL get_user_name(AMX *amx, cell *params) /* 3 param */ { - int index = params[1]; - return set_amxstring(amx,params[2],(index<1||index>gpGlobals->maxClients) ? - hostname->string : g_players[index].name.c_str() , params[3]); + int index = params[1]; + return set_amxstring(amx,params[2],(index<1||index>gpGlobals->maxClients) ? + hostname->string : g_players[index].name.c_str() , params[3]); } static cell AMX_NATIVE_CALL get_user_index(AMX *amx, cell *params) /* 1 param */ { - int i; - char* sptemp = get_amxstring(amx,params[1],0,i); - for(i = 1; i <= gpGlobals->maxClients; ++i) { - CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); - if ( strcmp(pPlayer->name.c_str(), sptemp) == 0 ) - return i; - } + int i; + char* sptemp = get_amxstring(amx,params[1],0,i); + for(i = 1; i <= gpGlobals->maxClients; ++i) { + CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); + if ( strcmp(pPlayer->name.c_str(), sptemp) == 0 ) + return i; + } - return 0; + return 0; } static cell AMX_NATIVE_CALL is_dedicated_server(AMX *amx, cell *params) { - return (IS_DEDICATED_SERVER() ? 1 : 0); + return (IS_DEDICATED_SERVER() ? 1 : 0); } static cell AMX_NATIVE_CALL is_linux_server(AMX *amx, cell *params) { #ifdef __linux__ - return 1; + return 1; #else - return 0; + return 0; #endif } static cell AMX_NATIVE_CALL is_amd64_server(AMX *amx, cell *params) { #if PAWN_CELL_SIZE==64 - return 1; + return 1; #else - return 0; + return 0; #endif } @@ -371,472 +371,472 @@ static cell AMX_NATIVE_CALL is_jit_enabled(AMX *amx, cell *params) // PM: Usele static cell AMX_NATIVE_CALL is_map_valid(AMX *amx, cell *params) /* 1 param */ { - int ilen; - return (IS_MAP_VALID(get_amxstring(amx,params[1],0,ilen)) ? 1 : 0); + int ilen; + return (IS_MAP_VALID(get_amxstring(amx,params[1],0,ilen)) ? 1 : 0); } static cell AMX_NATIVE_CALL is_user_connected(AMX *amx, cell *params) /* 1 param */ { - int index = params[1]; - if (index<1||index>gpGlobals->maxClients) - return 0; - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - return (pPlayer->ingame ? 1 : 0); + int index = params[1]; + if (index<1||index>gpGlobals->maxClients) + return 0; + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + return (pPlayer->ingame ? 1 : 0); } static cell AMX_NATIVE_CALL is_user_connecting(AMX *amx, cell *params) /* 1 param */ { - int index = params[1]; - if (index<1||index>gpGlobals->maxClients) - return 0; - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - return ( !pPlayer->ingame && pPlayer->initialized - && (GETPLAYERUSERID(pPlayer->pEdict)>0) ) ? 1 : 0; + int index = params[1]; + if (index<1||index>gpGlobals->maxClients) + return 0; + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + return ( !pPlayer->ingame && pPlayer->initialized + && (GETPLAYERUSERID(pPlayer->pEdict)>0) ) ? 1 : 0; } static cell AMX_NATIVE_CALL is_user_bot(AMX *amx, cell *params) /* 1 param */ { - int index = params[1]; - if (index<1||index>gpGlobals->maxClients) - return 0; - return (GET_PLAYER_POINTER_I(index)->bot ? 1 : 0); + int index = params[1]; + if (index<1||index>gpGlobals->maxClients) + return 0; + return (GET_PLAYER_POINTER_I(index)->bot ? 1 : 0); } static cell AMX_NATIVE_CALL is_user_hltv(AMX *amx, cell *params) /* 1 param */ { - int index = params[1]; - if (index<1||index>gpGlobals->maxClients) - return 0; - CPlayer *pPlayer = GET_PLAYER_POINTER_I(index); - if (!pPlayer->initialized) - return 0; - if (pPlayer->pEdict->v.flags & FL_PROXY) - return 1; - const char *authid = GETPLAYERAUTHID(pPlayer->pEdict); - if (authid && stricmp(authid, "HLTV") == 0) - return 1; - return 0; + int index = params[1]; + if (index<1||index>gpGlobals->maxClients) + return 0; + CPlayer *pPlayer = GET_PLAYER_POINTER_I(index); + if (!pPlayer->initialized) + return 0; + if (pPlayer->pEdict->v.flags & FL_PROXY) + return 1; + const char *authid = GETPLAYERAUTHID(pPlayer->pEdict); + if (authid && stricmp(authid, "HLTV") == 0) + return 1; + return 0; } static cell AMX_NATIVE_CALL is_user_alive(AMX *amx, cell *params) /* 1 param */ { - int index = params[1]; - if (index<1||index>gpGlobals->maxClients) - return 0; - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - return ((pPlayer->ingame && pPlayer->IsAlive()) ? 1 : 0); + int index = params[1]; + if (index<1||index>gpGlobals->maxClients) + return 0; + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + return ((pPlayer->ingame && pPlayer->IsAlive()) ? 1 : 0); } static cell AMX_NATIVE_CALL get_user_frags(AMX *amx, cell *params) /* 1 param */ { - int index = params[1]; - if (index<1||index>gpGlobals->maxClients) - return 0; - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - return (cell)(pPlayer->ingame ? pPlayer->pEdict->v.frags : 0); + int index = params[1]; + if (index<1||index>gpGlobals->maxClients) + return 0; + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + return (cell)(pPlayer->ingame ? pPlayer->pEdict->v.frags : 0); } static cell AMX_NATIVE_CALL get_user_deaths(AMX *amx, cell *params) /* 1 param */ { - int index = params[1]; - if (index<1||index>gpGlobals->maxClients) - return 0; - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - return (cell)(pPlayer->ingame ? pPlayer->deaths : 0); + int index = params[1]; + if (index<1||index>gpGlobals->maxClients) + return 0; + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + return (cell)(pPlayer->ingame ? pPlayer->deaths : 0); } static cell AMX_NATIVE_CALL get_user_armor(AMX *amx, cell *params) /* 1 param */ { - int index = params[1]; - if (index<1||index>gpGlobals->maxClients) - return 0; - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - return (cell)(pPlayer->ingame ? pPlayer->pEdict->v.armorvalue : 0); + int index = params[1]; + if (index<1||index>gpGlobals->maxClients) + return 0; + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + return (cell)(pPlayer->ingame ? pPlayer->pEdict->v.armorvalue : 0); } static cell AMX_NATIVE_CALL get_user_health(AMX *amx, cell *params) /* param */ { - int index = params[1]; - if (index<1||index>gpGlobals->maxClients) - return 0; - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - return (cell)(pPlayer->ingame ? pPlayer->pEdict->v.health : 0); + int index = params[1]; + if (index<1||index>gpGlobals->maxClients) + return 0; + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + return (cell)(pPlayer->ingame ? pPlayer->pEdict->v.health : 0); } static cell AMX_NATIVE_CALL get_user_userid(AMX *amx, cell *params) /* 1 param */ { - int index = params[1]; - if (index<1||index>gpGlobals->maxClients) - return 0; - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - return pPlayer->initialized ? GETPLAYERUSERID(pPlayer->pEdict) : -1; + int index = params[1]; + if (index<1||index>gpGlobals->maxClients) + return 0; + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + return pPlayer->initialized ? GETPLAYERUSERID(pPlayer->pEdict) : -1; } static cell AMX_NATIVE_CALL get_user_authid(AMX *amx, cell *params) /* 3 param */ { - int index = params[1]; - const char* authid = 0; - if (index>0&&index<=gpGlobals->maxClients) - authid = GETPLAYERAUTHID(g_players[index].pEdict); - return set_amxstring(amx,params[2], authid ? authid : "" ,params[3]); + int index = params[1]; + const char* authid = 0; + if (index>0&&index<=gpGlobals->maxClients) + authid = GETPLAYERAUTHID(g_players[index].pEdict); + return set_amxstring(amx,params[2], authid ? authid : "" ,params[3]); } static cell AMX_NATIVE_CALL is_user_authorized(AMX *amx, cell *params) { - int index = params[1]; - if (index < 1 || index > gpGlobals->maxClients) - return 0; - return GET_PLAYER_POINTER_I(index)->authorized; + int index = params[1]; + if (index < 1 || index > gpGlobals->maxClients) + return 0; + return GET_PLAYER_POINTER_I(index)->authorized; } static cell AMX_NATIVE_CALL get_weaponname(AMX *amx, cell *params) /* 3 param */ { - int index = params[1]; - if (index < 1 || index >= MAX_WEAPONS ){ - LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); - return 0; - } - return set_amxstring(amx,params[2],g_weaponsData[index].fullName.c_str(),params[3]); + int index = params[1]; + if (index < 1 || index >= MAX_WEAPONS ){ + LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); + return 0; + } + return set_amxstring(amx,params[2],g_weaponsData[index].fullName.c_str(),params[3]); } static cell AMX_NATIVE_CALL get_user_weapons(AMX *amx, cell *params) /* 3 param */ { - int index = params[1]; - if (index < 1 || index > gpGlobals->maxClients){ - LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); - return 0; - } - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - if (pPlayer->ingame){ - cell *cpNum = get_amxaddr(amx,params[3]); - cell *cpIds = get_amxaddr(amx,params[2]); - *cpIds = 0; - int weapons = pPlayer->pEdict->v.weapons & ~(1<<31); // don't count last element - for(int i = 1; i < MAX_WEAPONS; ++i) - { - if (weapons & (1< gpGlobals->maxClients){ + LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); + return 0; + } + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + if (pPlayer->ingame){ + cell *cpNum = get_amxaddr(amx,params[3]); + cell *cpIds = get_amxaddr(amx,params[2]); + *cpIds = 0; + int weapons = pPlayer->pEdict->v.weapons & ~(1<<31); // don't count last element + for(int i = 1; i < MAX_WEAPONS; ++i) + { + if (weapons & (1< gpGlobals->maxClients){ - LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); - return 0; - } - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - if (pPlayer->ingame){ - int mode = params[3]; - cell *cpOrigin = get_amxaddr(amx,params[2]); - if (mode == 4) { - cpOrigin[0] = (long int)pPlayer->lastHit.x; - cpOrigin[1] = (long int)pPlayer->lastHit.y; - cpOrigin[2] = (long int)pPlayer->lastHit.z; - return 1; - } - edict_t* edict = pPlayer->pEdict; - Vector pos = edict->v.origin; - if (mode && mode!=2) - pos = pos + edict->v.view_ofs; - if (mode > 1) { - Vector vec; - Vector v_angle = edict->v.v_angle; - float v_vec[3]; - v_vec[0] = v_angle.x; - v_vec[1] = v_angle.y; - v_vec[2] = v_angle.z; - ANGLEVECTORS( v_vec, vec, NULL, NULL); - TraceResult trEnd; - Vector v_dest = pos+vec * 9999; - float f_pos[3]; - f_pos[0] = pos.x; - f_pos[1] = pos.y; - f_pos[2] = pos.z; - float f_dest[3]; - f_dest[0] = v_dest.x; - f_dest[1] = v_dest.y; - f_dest[2] = v_dest.z; - TRACE_LINE( f_pos , f_dest, 0 , edict, &trEnd ); - pos = (trEnd.flFraction < 1.0) ? trEnd.vecEndPos : Vector(0,0,0); - } - cpOrigin[0] = (long int)pos.x; - cpOrigin[1] = (long int)pos.y; - cpOrigin[2] = (long int)pos.z; - return 1; - } - return 0; + int index = params[1]; + if (index < 1 || index > gpGlobals->maxClients){ + LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); + return 0; + } + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + if (pPlayer->ingame){ + int mode = params[3]; + cell *cpOrigin = get_amxaddr(amx,params[2]); + if (mode == 4) { + cpOrigin[0] = (long int)pPlayer->lastHit.x; + cpOrigin[1] = (long int)pPlayer->lastHit.y; + cpOrigin[2] = (long int)pPlayer->lastHit.z; + return 1; + } + edict_t* edict = pPlayer->pEdict; + Vector pos = edict->v.origin; + if (mode && mode!=2) + pos = pos + edict->v.view_ofs; + if (mode > 1) { + Vector vec; + Vector v_angle = edict->v.v_angle; + float v_vec[3]; + v_vec[0] = v_angle.x; + v_vec[1] = v_angle.y; + v_vec[2] = v_angle.z; + ANGLEVECTORS( v_vec, vec, NULL, NULL); + TraceResult trEnd; + Vector v_dest = pos+vec * 9999; + float f_pos[3]; + f_pos[0] = pos.x; + f_pos[1] = pos.y; + f_pos[2] = pos.z; + float f_dest[3]; + f_dest[0] = v_dest.x; + f_dest[1] = v_dest.y; + f_dest[2] = v_dest.z; + TRACE_LINE( f_pos , f_dest, 0 , edict, &trEnd ); + pos = (trEnd.flFraction < 1.0) ? trEnd.vecEndPos : Vector(0,0,0); + } + cpOrigin[0] = (long int)pos.x; + cpOrigin[1] = (long int)pos.y; + cpOrigin[2] = (long int)pos.z; + return 1; + } + return 0; } static cell AMX_NATIVE_CALL get_user_ip(AMX *amx, cell *params) /* 3 param */ { - int index = params[1]; - char *ptr; - char szIp[32]; - strcpy(szIp,(index<1||index>gpGlobals->maxClients)? - CVAR_GET_STRING("net_address"):g_players[index].ip.c_str()); - if (params[4] && (ptr = strstr(szIp,":"))!=0) - *ptr = '\0'; - return set_amxstring(amx,params[2],szIp,params[3]); + int index = params[1]; + char *ptr; + char szIp[32]; + strcpy(szIp,(index<1||index>gpGlobals->maxClients)? + CVAR_GET_STRING("net_address"):g_players[index].ip.c_str()); + if (params[4] && (ptr = strstr(szIp,":"))!=0) + *ptr = '\0'; + return set_amxstring(amx,params[2],szIp,params[3]); } static cell AMX_NATIVE_CALL get_user_attacker(AMX *amx, cell *params) /* 2 param */ { - int index = params[1]; - if (index < 1 || index > gpGlobals->maxClients){ - LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); - return 0; - } - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - edict_t *enemy = NULL; - if (pPlayer->ingame){ - enemy = pPlayer->pEdict->v.dmg_inflictor; - if (!FNullEnt(enemy)) { - int weapon = 0; - if (enemy->v.flags & (FL_CLIENT | FL_FAKECLIENT) ){ - pPlayer = GET_PLAYER_POINTER(enemy); - weapon = pPlayer->current; - } - else if( g_grenades.find( enemy, &pPlayer, weapon ) ) - enemy = pPlayer->pEdict; - else - enemy = NULL; + int index = params[1]; + if (index < 1 || index > gpGlobals->maxClients){ + LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); + return 0; + } + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + edict_t *enemy = NULL; + if (pPlayer->ingame){ + enemy = pPlayer->pEdict->v.dmg_inflictor; + if (!FNullEnt(enemy)) { + int weapon = 0; + if (enemy->v.flags & (FL_CLIENT | FL_FAKECLIENT) ){ + pPlayer = GET_PLAYER_POINTER(enemy); + weapon = pPlayer->current; + } + else if( g_grenades.find( enemy, &pPlayer, weapon ) ) + enemy = pPlayer->pEdict; + else + enemy = NULL; - if (enemy){ - switch(*params/sizeof(cell)){ - case 3: *get_amxaddr(amx,params[3]) = pPlayer->aiming; - case 2: *get_amxaddr(amx,params[2]) = weapon; - } - } - } - } - return (enemy ? pPlayer->index : 0); + if (enemy){ + switch(*params/sizeof(cell)){ + case 3: *get_amxaddr(amx,params[3]) = pPlayer->aiming; + case 2: *get_amxaddr(amx,params[2]) = weapon; + } + } + } + } + return (enemy ? pPlayer->index : 0); } static cell AMX_NATIVE_CALL user_has_weapon(AMX *amx,cell *params) { - int index = params[1]; - if (index < 1 || index > gpGlobals->maxClients){ - LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); - return 0; - } - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - edict_t *pEntity = pPlayer->pEdict; - if (params[3] == -1) - { - if ((pEntity->v.weapons & (1< 0) - { - return 1; - } - } - else - { - if ((pEntity->v.weapons & (1< 0) - { - if (params[3] == 0) - { - pEntity->v.weapons &= ~(1<v.weapons |= (1< gpGlobals->maxClients){ + LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); + return 0; + } + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + edict_t *pEntity = pPlayer->pEdict; + if (params[3] == -1) + { + if ((pEntity->v.weapons & (1< 0) + { + return 1; + } + } + else + { + if ((pEntity->v.weapons & (1< 0) + { + if (params[3] == 0) + { + pEntity->v.weapons &= ~(1<v.weapons |= (1< gpGlobals->maxClients) - { - LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); - return 0; - } - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - if (pPlayer->ingame) - { - int wpn = pPlayer->current; - if ( !(pPlayer->pEdict->v.weapons & (1< gpGlobals->maxClients) { - pPlayer->current = 0; + LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); return 0; } - cell *cpTemp = get_amxaddr(amx,params[2]); - *cpTemp = pPlayer->weapons[wpn].clip; - cpTemp = get_amxaddr(amx,params[3]); - *cpTemp = pPlayer->weapons[wpn].ammo; - return wpn; - } - return 0; + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + if (pPlayer->ingame) + { + int wpn = pPlayer->current; + if ( !(pPlayer->pEdict->v.weapons & (1<current = 0; + return 0; + } + cell *cpTemp = get_amxaddr(amx,params[2]); + *cpTemp = pPlayer->weapons[wpn].clip; + cpTemp = get_amxaddr(amx,params[3]); + *cpTemp = pPlayer->weapons[wpn].ammo; + return wpn; + } + return 0; } static cell AMX_NATIVE_CALL get_user_ammo(AMX *amx, cell *params) /* 4 param */ { - int index = params[1]; - if (index < 1 || index > gpGlobals->maxClients){ - LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); - return 0; - } - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - if (pPlayer->ingame){ - int wpn = params[2]; - if (wpn < 1 || wpn >= MAX_WEAPONS ){ - LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %d", wpn); - return 0; - } - cell *cpTemp = get_amxaddr(amx,params[3]); - *cpTemp = pPlayer->weapons[wpn].clip; - cpTemp = get_amxaddr(amx,params[4]); - *cpTemp = pPlayer->weapons[wpn].ammo; - return 1; - } - return 0; + int index = params[1]; + if (index < 1 || index > gpGlobals->maxClients){ + LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); + return 0; + } + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + if (pPlayer->ingame){ + int wpn = params[2]; + if (wpn < 1 || wpn >= MAX_WEAPONS ){ + LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %d", wpn); + return 0; + } + cell *cpTemp = get_amxaddr(amx,params[3]); + *cpTemp = pPlayer->weapons[wpn].clip; + cpTemp = get_amxaddr(amx,params[4]); + *cpTemp = pPlayer->weapons[wpn].ammo; + return 1; + } + return 0; } static cell AMX_NATIVE_CALL get_user_team(AMX *amx, cell *params) /* 3 param */ { - int index = params[1]; - if (index<1||index>gpGlobals->maxClients) - return -1; - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - if (pPlayer->ingame){ - // SidLuke , DoD fix - if ( g_bmod_dod ){ - int iTeam = pPlayer->pEdict->v.team; - if ( params[3] ){ - char *szTeam = ""; - switch(iTeam){ + int index = params[1]; + if (index<1||index>gpGlobals->maxClients) + return -1; + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + if (pPlayer->ingame){ + // SidLuke , DoD fix + if ( g_bmod_dod ){ + int iTeam = pPlayer->pEdict->v.team; + if ( params[3] ){ + char *szTeam = ""; + switch(iTeam){ case 1: szTeam = "Allies"; break; case 2: szTeam = "Axis"; break; - } - set_amxstring(amx,params[2],szTeam,params[3]); + } + set_amxstring(amx,params[2],szTeam,params[3]); + } + return iTeam; } - return iTeam; - } - // - if ( params[3] ) - set_amxstring(amx,params[2],pPlayer->team.c_str(),params[3]); + // + if ( params[3] ) + set_amxstring(amx,params[2],pPlayer->team.c_str(),params[3]); - return pPlayer->teamId; - } - return -1; + return pPlayer->teamId; + } + return -1; } static cell AMX_NATIVE_CALL show_menu(AMX *amx, cell *params) /* 3 param */ { - int ilen=0, ilen2=0; - char *sMenu = get_amxstring(amx, params[3], 0, ilen); - char *lMenu = get_amxstring(amx, params[5], 1, ilen2); - int menuid = 0; - if (ilen2 && lMenu) - { - menuid = g_menucmds.findMenuId(lMenu, amx); - } else { - menuid = g_menucmds.findMenuId(sMenu, amx); - } - int keys = params[2]; - int time = params[4]; - if (params[1] == 0) { - for(int i = 1; i <= gpGlobals->maxClients; ++i){ - CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); - if (pPlayer->ingame){ - pPlayer->keys = keys; - pPlayer->menu = menuid; - pPlayer->newmenu = -1; - pPlayer->page = 0; - UTIL_ShowMenu(pPlayer->pEdict, keys, time, sMenu, ilen ); - } - } - } - else { - int index = params[1]; - if (index < 1 || index > gpGlobals->maxClients){ - LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); - return 0; - } - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - if (pPlayer->ingame){ - pPlayer->keys = keys; - pPlayer->menu = menuid; - pPlayer->newmenu = -1; - pPlayer->page = 0; - UTIL_ShowMenu(pPlayer->pEdict, keys, time, sMenu, ilen ); - } - } - return 1; + int ilen=0, ilen2=0; + char *sMenu = get_amxstring(amx, params[3], 0, ilen); + char *lMenu = get_amxstring(amx, params[5], 1, ilen2); + int menuid = 0; + if (ilen2 && lMenu) + { + menuid = g_menucmds.findMenuId(lMenu, amx); + } else { + menuid = g_menucmds.findMenuId(sMenu, amx); + } + int keys = params[2]; + int time = params[4]; + if (params[1] == 0) { + for(int i = 1; i <= gpGlobals->maxClients; ++i){ + CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); + if (pPlayer->ingame){ + pPlayer->keys = keys; + pPlayer->menu = menuid; + pPlayer->newmenu = -1; + pPlayer->page = 0; + UTIL_ShowMenu(pPlayer->pEdict, keys, time, sMenu, ilen ); + } + } + } + else { + int index = params[1]; + if (index < 1 || index > gpGlobals->maxClients){ + LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); + return 0; + } + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + if (pPlayer->ingame){ + pPlayer->keys = keys; + pPlayer->menu = menuid; + pPlayer->newmenu = -1; + pPlayer->page = 0; + UTIL_ShowMenu(pPlayer->pEdict, keys, time, sMenu, ilen ); + } + } + return 1; } static cell AMX_NATIVE_CALL register_plugin(AMX *amx, cell *params) /* 3 param */ { - CPluginMngr::CPlugin* a = g_plugins.findPluginFast( amx ); - int i; - a->setTitle( get_amxstring(amx,params[1],0,i) ); - a->setVersion( get_amxstring(amx,params[2],0,i) ); - a->setAuthor( get_amxstring(amx,params[3],0,i) ); - return 1; + CPluginMngr::CPlugin* a = g_plugins.findPluginFast( amx ); + int i; + a->setTitle( get_amxstring(amx,params[1],0,i) ); + a->setVersion( get_amxstring(amx,params[2],0,i) ); + a->setAuthor( get_amxstring(amx,params[3],0,i) ); + return 1; } static cell AMX_NATIVE_CALL register_menucmd(AMX *amx, cell *params) /* 3 param */ { - CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast( amx ); - int ilen, idx; - char* sptemp = get_amxstring(amx,params[3],0,ilen); + CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast( amx ); + int ilen, idx; + char* sptemp = get_amxstring(amx,params[3],0,ilen); - idx = registerSPForwardByName(amx, sptemp, FP_CELL, FP_CELL, FP_CELL, FP_DONE); - if (idx == -1) - { - LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", sptemp); - return 0; - } + idx = registerSPForwardByName(amx, sptemp, FP_CELL, FP_CELL, FP_CELL, FP_DONE); + if (idx == -1) + { + LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", sptemp); + return 0; + } - g_menucmds.registerMenuCmd( plugin , params[1] , params[2] , idx ); + g_menucmds.registerMenuCmd( plugin , params[1] , params[2] , idx ); - return 1; + return 1; } static cell AMX_NATIVE_CALL get_plugin(AMX *amx, cell *params) /* 11 param */ { - CPluginMngr::CPlugin* a; + CPluginMngr::CPlugin* a; - if ( params[1]<0 ) - a = g_plugins.findPluginFast( amx ); - else - a = g_plugins.findPlugin( (int)params[1] ); + if ( params[1]<0 ) + a = g_plugins.findPluginFast( amx ); + else + a = g_plugins.findPlugin( (int)params[1] ); - if (a){ - set_amxstring(amx,params[2],a->getName(),params[3]); - set_amxstring(amx,params[4],a->getTitle(),params[5]); - set_amxstring(amx,params[6],a->getVersion(),params[7]); - set_amxstring(amx,params[8],a->getAuthor(),params[9]); - set_amxstring(amx,params[10],a->getStatus(),params[11]); - return a->getId(); - } - return -1; + if (a){ + set_amxstring(amx,params[2],a->getName(),params[3]); + set_amxstring(amx,params[4],a->getTitle(),params[5]); + set_amxstring(amx,params[6],a->getVersion(),params[7]); + set_amxstring(amx,params[8],a->getAuthor(),params[9]); + set_amxstring(amx,params[10],a->getStatus(),params[11]); + return a->getId(); + } + return -1; } static cell AMX_NATIVE_CALL amx_md5(AMX *amx, cell *params) @@ -876,351 +876,351 @@ static cell AMX_NATIVE_CALL amx_md5_file(AMX *amx, cell *params) static cell AMX_NATIVE_CALL get_pluginsnum(AMX *amx, cell *params) { - return g_plugins.getPluginsNum(); + return g_plugins.getPluginsNum(); } static cell AMX_NATIVE_CALL register_concmd(AMX *amx, cell *params) /* 4 param */ { - CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast( amx ); - int i, idx = 0; - char* temp = get_amxstring(amx,params[2],0, i ); - idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE); - if (idx == -1) - { - LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp); - return 0; - } - temp = get_amxstring(amx,params[1],0, i ); - char* info = get_amxstring(amx,params[4],1, i ); - CmdMngr::Command* cmd; - int access = params[3]; - bool listable = true; - if ( access < 0 ) { // is access is -1 then hide from listing - access = 0; - listable = false; - } - if ( (cmd = g_commands.registerCommand( plugin , idx , temp , info , access ,listable )) == NULL) - return 0; - cmd->setCmdType( CMD_ConsoleCommand ); + CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast( amx ); + int i, idx = 0; + char* temp = get_amxstring(amx,params[2],0, i ); + idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE); + if (idx == -1) + { + LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp); + return 0; + } + temp = get_amxstring(amx,params[1],0, i ); + char* info = get_amxstring(amx,params[4],1, i ); + CmdMngr::Command* cmd; + int access = params[3]; + bool listable = true; + if ( access < 0 ) { // is access is -1 then hide from listing + access = 0; + listable = false; + } + if ( (cmd = g_commands.registerCommand( plugin , idx , temp , info , access ,listable )) == NULL) + return 0; + cmd->setCmdType( CMD_ConsoleCommand ); - REG_SVR_COMMAND( (char*)cmd->getCommand() , plugin_srvcmd ); - return 1; + REG_SVR_COMMAND( (char*)cmd->getCommand() , plugin_srvcmd ); + return 1; } static cell AMX_NATIVE_CALL register_clcmd(AMX *amx, cell *params) /* 4 param */ { - CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast( amx ); - int i, idx = 0; - char* temp = get_amxstring(amx,params[2],0, i ); - idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE); - if(idx==-1) - { - LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp); - return 0; - } - temp = get_amxstring(amx,params[1],0, i ); - char* info = get_amxstring(amx,params[4],1, i ); - CmdMngr::Command* cmd; - int access = params[3]; - bool listable = true; - if ( access < 0 ) { // is access is -1 then hide from listing - access = 0; - listable = false; - } - if ( (cmd = g_commands.registerCommand(plugin , idx , temp , info , access , listable )) == NULL) - return 0; - cmd->setCmdType( CMD_ClientCommand ); - return 1; + CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast( amx ); + int i, idx = 0; + char* temp = get_amxstring(amx,params[2],0, i ); + idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE); + if(idx==-1) + { + LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp); + return 0; + } + temp = get_amxstring(amx,params[1],0, i ); + char* info = get_amxstring(amx,params[4],1, i ); + CmdMngr::Command* cmd; + int access = params[3]; + bool listable = true; + if ( access < 0 ) { // is access is -1 then hide from listing + access = 0; + listable = false; + } + if ( (cmd = g_commands.registerCommand(plugin , idx , temp , info , access , listable )) == NULL) + return 0; + cmd->setCmdType( CMD_ClientCommand ); + return 1; } static cell AMX_NATIVE_CALL register_srvcmd(AMX *amx, cell *params) /* 2 param */ { - CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast( amx ); - int i, idx = 0; - char* temp = get_amxstring(amx,params[2],0, i ); - idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE); - if (idx==-1) - { - LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp); - return 0; - } - temp = get_amxstring(amx,params[1],0, i ); - char* info = get_amxstring(amx,params[4],1, i ); - CmdMngr::Command* cmd; - int access = params[3]; - bool listable = true; - if ( access < 0 ) { // is access is -1 then hide from listing - access = 0; - listable = false; - } - if ( (cmd = g_commands.registerCommand(plugin ,idx , temp , info ,access,listable )) == NULL) - return 0; - cmd->setCmdType( CMD_ServerCommand ); - REG_SVR_COMMAND( (char*)cmd->getCommand() , plugin_srvcmd ); - return 0; + CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast( amx ); + int i, idx = 0; + char* temp = get_amxstring(amx,params[2],0, i ); + idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE); + if (idx==-1) + { + LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp); + return 0; + } + temp = get_amxstring(amx,params[1],0, i ); + char* info = get_amxstring(amx,params[4],1, i ); + CmdMngr::Command* cmd; + int access = params[3]; + bool listable = true; + if ( access < 0 ) { // is access is -1 then hide from listing + access = 0; + listable = false; + } + if ( (cmd = g_commands.registerCommand(plugin ,idx , temp , info ,access,listable )) == NULL) + return 0; + cmd->setCmdType( CMD_ServerCommand ); + REG_SVR_COMMAND( (char*)cmd->getCommand() , plugin_srvcmd ); + return 0; } static cell AMX_NATIVE_CALL get_concmd(AMX *amx, cell *params) /* 7 param */ { - int who = params[8]; + int who = params[8]; - if ( who > 0 ) // id of player - client command - who = CMD_ClientCommand; - else if ( who == 0 ) // server - who = CMD_ServerCommand; - else // -1 parameter - all commands - who = CMD_ConsoleCommand; + if ( who > 0 ) // id of player - client command + who = CMD_ClientCommand; + else if ( who == 0 ) // server + who = CMD_ServerCommand; + else // -1 parameter - all commands + who = CMD_ConsoleCommand; - CmdMngr::Command* cmd = g_commands.getCmd(params[1], who, params[7]); + CmdMngr::Command* cmd = g_commands.getCmd(params[1], who, params[7]); - if ( cmd == 0 ) return 0; - set_amxstring(amx,params[2], cmd->getCmdLine() ,params[3]); - set_amxstring(amx,params[5], cmd->getCmdInfo() ,params[6]); - cell *cpFlags = get_amxaddr(amx,params[4]); - *cpFlags = cmd->getFlags(); - return 1; + if ( cmd == 0 ) return 0; + set_amxstring(amx,params[2], cmd->getCmdLine() ,params[3]); + set_amxstring(amx,params[5], cmd->getCmdInfo() ,params[6]); + cell *cpFlags = get_amxaddr(amx,params[4]); + *cpFlags = cmd->getFlags(); + return 1; } static cell AMX_NATIVE_CALL get_clcmd(AMX *amx, cell *params) /* 7 param */ { - CmdMngr::Command* cmd = g_commands.getCmd(params[1] ,CMD_ClientCommand , params[7]); - if ( cmd == 0 ) return 0; - set_amxstring(amx,params[2], cmd->getCmdLine() ,params[3]); - set_amxstring(amx,params[5], cmd->getCmdInfo() ,params[6]); - cell *cpFlags = get_amxaddr(amx,params[4]); - *cpFlags = cmd->getFlags(); + CmdMngr::Command* cmd = g_commands.getCmd(params[1] ,CMD_ClientCommand , params[7]); + if ( cmd == 0 ) return 0; + set_amxstring(amx,params[2], cmd->getCmdLine() ,params[3]); + set_amxstring(amx,params[5], cmd->getCmdInfo() ,params[6]); + cell *cpFlags = get_amxaddr(amx,params[4]); + *cpFlags = cmd->getFlags(); - return 1; + return 1; } static cell AMX_NATIVE_CALL get_srvcmd(AMX *amx, cell *params) { - CmdMngr::Command* cmd = g_commands.getCmd(params[1] ,CMD_ServerCommand , params[7] ); - if ( cmd == 0 ) return 0; - set_amxstring(amx,params[2], cmd->getCmdLine() ,params[3]); - set_amxstring(amx,params[5], cmd->getCmdInfo() ,params[6]); - cell *cpFlags = get_amxaddr(amx,params[4]); - *cpFlags = cmd->getFlags(); - return 1; + CmdMngr::Command* cmd = g_commands.getCmd(params[1] ,CMD_ServerCommand , params[7] ); + if ( cmd == 0 ) return 0; + set_amxstring(amx,params[2], cmd->getCmdLine() ,params[3]); + set_amxstring(amx,params[5], cmd->getCmdInfo() ,params[6]); + cell *cpFlags = get_amxaddr(amx,params[4]); + *cpFlags = cmd->getFlags(); + return 1; } static cell AMX_NATIVE_CALL get_srvcmdsnum(AMX *amx, cell *params) { - return g_commands.getCmdNum( CMD_ServerCommand , params[1] ); + return g_commands.getCmdNum( CMD_ServerCommand , params[1] ); } static cell AMX_NATIVE_CALL get_clcmdsnum(AMX *amx, cell *params) /* 1 param */ { - return g_commands.getCmdNum( CMD_ClientCommand , params[1] ); + return g_commands.getCmdNum( CMD_ClientCommand , params[1] ); } static cell AMX_NATIVE_CALL get_concmdsnum(AMX *amx, cell *params) /* 1 param */ { - int who = params[2]; - if ( who > 0 ) - return g_commands.getCmdNum( CMD_ClientCommand , params[1] ); - if ( who == 0 ) - return g_commands.getCmdNum( CMD_ServerCommand , params[1] ); - return g_commands.getCmdNum( CMD_ConsoleCommand , params[1] ); + int who = params[2]; + if ( who > 0 ) + return g_commands.getCmdNum( CMD_ClientCommand , params[1] ); + if ( who == 0 ) + return g_commands.getCmdNum( CMD_ServerCommand , params[1] ); + return g_commands.getCmdNum( CMD_ConsoleCommand , params[1] ); } static cell AMX_NATIVE_CALL register_event(AMX *amx, cell *params) /* 2 param */ { - CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast( amx ); + CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast( amx ); - int len, pos, iFunction; + int len, pos, iFunction; - char* sTemp = get_amxstring(amx,params[1],0,len); + char* sTemp = get_amxstring(amx,params[1],0,len); - if ( (pos = g_events.getEventId( sTemp )) == 0 ) { - AMXXLOG_Log("[AMXX] Invalid event (name \"%s\") (plugin \"%s\")", sTemp , plugin->getName() ); - amx_RaiseError(amx,AMX_ERR_NATIVE); - return 0; - } + if ( (pos = g_events.getEventId( sTemp )) == 0 ) { + AMXXLOG_Log("[AMXX] Invalid event (name \"%s\") (plugin \"%s\")", sTemp , plugin->getName() ); + amx_RaiseError(amx,AMX_ERR_NATIVE); + return 0; + } - sTemp = get_amxstring(amx,params[2],0,len); - iFunction = registerSPForwardByName(amx, sTemp, FP_CELL, FP_DONE); - if (iFunction==-1) - { - LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", sTemp); - return 0; - } + sTemp = get_amxstring(amx,params[2],0,len); + iFunction = registerSPForwardByName(amx, sTemp, FP_CELL, FP_DONE); + if (iFunction==-1) + { + LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", sTemp); + return 0; + } - int numparam = *params/sizeof(cell); + int numparam = *params/sizeof(cell); - int flags = 0; + int flags = 0; - if ( numparam > 2) - flags = UTIL_ReadFlags( get_amxstring(amx,params[3],0,len) ); + if ( numparam > 2) + flags = UTIL_ReadFlags( get_amxstring(amx,params[3],0,len) ); - EventsMngr::ClEvent* a = - g_events.registerEvent( plugin , iFunction , flags , pos ); + EventsMngr::ClEvent* a = + g_events.registerEvent( plugin , iFunction , flags , pos ); - if ( a == 0 ) return 0; + if ( a == 0 ) return 0; - for(int i = 4; i <= numparam; ++i) - a->registerFilter( get_amxstring(amx,params[i],0,len) ); + for(int i = 4; i <= numparam; ++i) + a->registerFilter( get_amxstring(amx,params[i],0,len) ); - return 1; + return 1; } static cell AMX_NATIVE_CALL user_kill(AMX *amx, cell *params) /* 2 param */ { - int index = params[1]; - if (index<1||index>gpGlobals->maxClients) - return 0; - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - if (pPlayer->ingame && pPlayer->IsAlive()){ - float bef = pPlayer->pEdict->v.frags; - MDLL_ClientKill(pPlayer->pEdict); - if (params[2]) pPlayer->pEdict->v.frags = bef; - return 1; - } + int index = params[1]; + if (index<1||index>gpGlobals->maxClients) + return 0; + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + if (pPlayer->ingame && pPlayer->IsAlive()){ + float bef = pPlayer->pEdict->v.frags; + MDLL_ClientKill(pPlayer->pEdict); + if (params[2]) pPlayer->pEdict->v.frags = bef; + return 1; + } - return 0; + return 0; } static cell AMX_NATIVE_CALL user_slap(AMX *amx, cell *params) /* 2 param */ { - int index = params[1]; - if (index<1||index>gpGlobals->maxClients) - return 0; - int power = abs((int)params[2]); - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - if (pPlayer->ingame && pPlayer->IsAlive()){ - if (pPlayer->pEdict->v.health <= power) { - float bef = pPlayer->pEdict->v.frags; - MDLL_ClientKill(pPlayer->pEdict); - pPlayer->pEdict->v.frags = bef; - } - else { - edict_t *pEdict = pPlayer->pEdict; - int numparam = *params/sizeof(cell); - if (numparam<3 || params[3]) { - pEdict->v.velocity.x += RANDOM_LONG(-600,600); - pEdict->v.velocity.y += RANDOM_LONG(-180,180); - pEdict->v.velocity.z += RANDOM_LONG(100,200); - } - else { - Vector v_forward, v_right; - Vector vang = pEdict->v.angles; - float fang[3]; - fang[0] = vang.x; - fang[1] = vang.y; - fang[2] = vang.z; - ANGLEVECTORS( fang, v_forward, v_right, NULL ); - pEdict->v.velocity = pEdict->v.velocity + v_forward * 220 + Vector(0,0,200); - } - pEdict->v.punchangle.x = static_cast(RANDOM_LONG(-10,10)); - pEdict->v.punchangle.y = static_cast(RANDOM_LONG(-10,10)); - pEdict->v.health -= power; - int armor = (int)pEdict->v.armorvalue; - armor -= power; - if (armor < 0) armor = 0; - pEdict->v.armorvalue = static_cast(armor); - pEdict->v.dmg_inflictor = pEdict; - if (g_bmod_cstrike){ - static const char *cs_sound[4] = { - "player/bhit_flesh-3.wav", - "player/bhit_flesh-2.wav", - "player/pl_die1.wav", - "player/pl_pain6.wav" }; - EMIT_SOUND_DYN2(pEdict, CHAN_VOICE, cs_sound[RANDOM_LONG(0,3)], 1.0, ATTN_NORM, 0, PITCH_NORM); - } - else{ - static const char *bit_sound[3] = { - "weapons/cbar_hitbod1.wav", - "weapons/cbar_hitbod2.wav", - "weapons/cbar_hitbod3.wav" }; - EMIT_SOUND_DYN2(pEdict, CHAN_VOICE, bit_sound[RANDOM_LONG(0,2)], 1.0, ATTN_NORM, 0, PITCH_NORM); - } - } - return 1; - } + int index = params[1]; + if (index<1||index>gpGlobals->maxClients) + return 0; + int power = abs((int)params[2]); + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + if (pPlayer->ingame && pPlayer->IsAlive()){ + if (pPlayer->pEdict->v.health <= power) { + float bef = pPlayer->pEdict->v.frags; + MDLL_ClientKill(pPlayer->pEdict); + pPlayer->pEdict->v.frags = bef; + } + else { + edict_t *pEdict = pPlayer->pEdict; + int numparam = *params/sizeof(cell); + if (numparam<3 || params[3]) { + pEdict->v.velocity.x += RANDOM_LONG(-600,600); + pEdict->v.velocity.y += RANDOM_LONG(-180,180); + pEdict->v.velocity.z += RANDOM_LONG(100,200); + } + else { + Vector v_forward, v_right; + Vector vang = pEdict->v.angles; + float fang[3]; + fang[0] = vang.x; + fang[1] = vang.y; + fang[2] = vang.z; + ANGLEVECTORS( fang, v_forward, v_right, NULL ); + pEdict->v.velocity = pEdict->v.velocity + v_forward * 220 + Vector(0,0,200); + } + pEdict->v.punchangle.x = static_cast(RANDOM_LONG(-10,10)); + pEdict->v.punchangle.y = static_cast(RANDOM_LONG(-10,10)); + pEdict->v.health -= power; + int armor = (int)pEdict->v.armorvalue; + armor -= power; + if (armor < 0) armor = 0; + pEdict->v.armorvalue = static_cast(armor); + pEdict->v.dmg_inflictor = pEdict; + if (g_bmod_cstrike){ + static const char *cs_sound[4] = { + "player/bhit_flesh-3.wav", + "player/bhit_flesh-2.wav", + "player/pl_die1.wav", + "player/pl_pain6.wav" }; + EMIT_SOUND_DYN2(pEdict, CHAN_VOICE, cs_sound[RANDOM_LONG(0,3)], 1.0, ATTN_NORM, 0, PITCH_NORM); + } + else{ + static const char *bit_sound[3] = { + "weapons/cbar_hitbod1.wav", + "weapons/cbar_hitbod2.wav", + "weapons/cbar_hitbod3.wav" }; + EMIT_SOUND_DYN2(pEdict, CHAN_VOICE, bit_sound[RANDOM_LONG(0,2)], 1.0, ATTN_NORM, 0, PITCH_NORM); + } + } + return 1; + } - return 0; + return 0; } static cell AMX_NATIVE_CALL server_cmd(AMX *amx, cell *params) /* 1 param */ { - int len; - g_langMngr.SetDefLang(LANG_SERVER); - char* cmd = format_amxstring(amx,params,1,len); - cmd[len++]='\n'; - cmd[len]=0; - SERVER_COMMAND( cmd ); - return len; + int len; + g_langMngr.SetDefLang(LANG_SERVER); + char* cmd = format_amxstring(amx,params,1,len); + cmd[len++]='\n'; + cmd[len]=0; + SERVER_COMMAND( cmd ); + return len; } static cell AMX_NATIVE_CALL client_cmd(AMX *amx, cell *params) /* 2 param */ { - int len; - char* cmd = format_amxstring(amx,params,2,len); - cmd[len++]='\n'; - cmd[len]=0; + int len; + char* cmd = format_amxstring(amx,params,2,len); + cmd[len++]='\n'; + cmd[len]=0; - if (params[1] == 0) { - for(int i = 1; i <= gpGlobals->maxClients; ++i){ - CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); - if (!pPlayer->bot && pPlayer->initialized /*&& pPlayer->ingame*/ ) - CLIENT_COMMAND(pPlayer->pEdict, UTIL_VarArgs("%s", cmd) ); - } - } - else { - int index = params[1]; - if (index < 1 || index > gpGlobals->maxClients){ - LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); - return 0; - } - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - if ( !pPlayer->bot && pPlayer->initialized /*&& pPlayer->ingame*/ ) - CLIENT_COMMAND(pPlayer->pEdict, UTIL_VarArgs("%s", cmd) ); - } - return len; + if (params[1] == 0) { + for(int i = 1; i <= gpGlobals->maxClients; ++i){ + CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); + if (!pPlayer->bot && pPlayer->initialized /*&& pPlayer->ingame*/ ) + CLIENT_COMMAND(pPlayer->pEdict, UTIL_VarArgs("%s", cmd) ); + } + } + else { + int index = params[1]; + if (index < 1 || index > gpGlobals->maxClients){ + LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); + return 0; + } + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + if ( !pPlayer->bot && pPlayer->initialized /*&& pPlayer->ingame*/ ) + CLIENT_COMMAND(pPlayer->pEdict, UTIL_VarArgs("%s", cmd) ); + } + return len; } static cell AMX_NATIVE_CALL get_cvar_string(AMX *amx, cell *params) /* 3 param */ { - int ilen; - char* sptemp = get_amxstring(amx,params[1],0,ilen); - return set_amxstring(amx,params[2],CVAR_GET_STRING(sptemp),params[3]); + int ilen; + char* sptemp = get_amxstring(amx,params[1],0,ilen); + return set_amxstring(amx,params[2],CVAR_GET_STRING(sptemp),params[3]); } static cell AMX_NATIVE_CALL get_cvar_float(AMX *amx, cell *params) /* 1 param */ { - int ilen; - REAL pFloat = CVAR_GET_FLOAT(get_amxstring(amx,params[1],0,ilen)); - return amx_ftoc(pFloat); + int ilen; + REAL pFloat = CVAR_GET_FLOAT(get_amxstring(amx,params[1],0,ilen)); + return amx_ftoc(pFloat); } static cell AMX_NATIVE_CALL set_cvar_float(AMX *amx, cell *params) /* 2 param */ { - int ilen; - CVAR_SET_FLOAT(get_amxstring(amx,params[1],0,ilen), amx_ctof(params[2])); - return 1; + int ilen; + CVAR_SET_FLOAT(get_amxstring(amx,params[1],0,ilen), amx_ctof(params[2])); + return 1; } static cell AMX_NATIVE_CALL get_cvar_num(AMX *amx, cell *params) /* 1 param */ { - int ilen; - return (int)CVAR_GET_FLOAT(get_amxstring(amx,params[1],0,ilen)); + int ilen; + return (int)CVAR_GET_FLOAT(get_amxstring(amx,params[1],0,ilen)); } static cell AMX_NATIVE_CALL set_cvar_num(AMX *amx, cell *params) /* 2 param */ { - int ilen; - CVAR_SET_FLOAT(get_amxstring(amx,params[1],0,ilen),(float)params[2]); - return 1; + int ilen; + CVAR_SET_FLOAT(get_amxstring(amx,params[1],0,ilen),(float)params[2]); + return 1; } static cell AMX_NATIVE_CALL set_cvar_string(AMX *amx, cell *params) /* 2 param */ { - int ilen; - char* sptemp = get_amxstring(amx,params[1],0,ilen); - char* szValue = get_amxstring(amx,params[2],1,ilen); - CVAR_SET_STRING(sptemp,szValue); - return 1; + int ilen; + char* sptemp = get_amxstring(amx,params[1],0,ilen); + char* szValue = get_amxstring(amx,params[2],1,ilen); + CVAR_SET_STRING(sptemp,szValue); + return 1; } static cell AMX_NATIVE_CALL message_begin(AMX *amx, cell *params) /* 4 param */ @@ -1324,147 +1324,147 @@ static cell AMX_NATIVE_CALL write_string(AMX *amx, cell *params) /* 1 param */ static cell AMX_NATIVE_CALL log_message(AMX *amx, cell *params) /* 1 param */ { - int len; - g_langMngr.SetDefLang(LANG_SERVER); - char* message = format_amxstring(amx,params,1,len); - message[len++]='\n'; - message[len]=0; - ALERT( at_logged, "%s", message ); - return len; + int len; + g_langMngr.SetDefLang(LANG_SERVER); + char* message = format_amxstring(amx,params,1,len); + message[len++]='\n'; + message[len]=0; + ALERT( at_logged, "%s", message ); + return len; } static cell AMX_NATIVE_CALL log_to_file(AMX *amx, cell *params) /* 1 param */ { - int ilen; - char* szFile = get_amxstring(amx,params[1],0,ilen); - FILE*fp; - char file[256]; - if (strchr(szFile, '/') || strchr(szFile, '\\')) - { - build_pathname_r(file, sizeof(file)-1, "%s", szFile); - } else { - build_pathname_r(file, sizeof(file)-1, "%s/%s", g_log_dir.c_str(), szFile); - } - bool first_time = true; - if ((fp=fopen(file,"r"))!=NULL){ - first_time = false; - fclose(fp); - } - if ((fp=fopen(file,"a")) == NULL){ - //amx_RaiseError(amx,AMX_ERR_NATIVE); - //would cause too much troubles in old plugins - return 0; - } - char date[32]; - time_t td; time(&td); - strftime(date,31,"%m/%d/%Y - %H:%M:%S",localtime(&td)); - int len; - g_langMngr.SetDefLang(LANG_SERVER); - char* message = format_amxstring(amx,params,2,len); - message[len++]='\n'; - message[len]=0; - if ( first_time ){ - fprintf(fp,"L %s: Log file started (file \"%s\") (game \"%s\") (amx \"%s\")\n", - date,file,g_mod_name.c_str(),Plugin_info.version); - print_srvconsole("L %s: Log file started (file \"%s\") (game \"%s\") (amx \"%s\")\n", - date,file,g_mod_name.c_str(),Plugin_info.version); - } - fprintf(fp,"L %s: %s",date,message); - print_srvconsole("L %s: %s",date,message); - fclose(fp); - return 1; + int ilen; + char* szFile = get_amxstring(amx,params[1],0,ilen); + FILE*fp; + char file[256]; + if (strchr(szFile, '/') || strchr(szFile, '\\')) + { + build_pathname_r(file, sizeof(file)-1, "%s", szFile); + } else { + build_pathname_r(file, sizeof(file)-1, "%s/%s", g_log_dir.c_str(), szFile); + } + bool first_time = true; + if ((fp=fopen(file,"r"))!=NULL){ + first_time = false; + fclose(fp); + } + if ((fp=fopen(file,"a")) == NULL){ + //amx_RaiseError(amx,AMX_ERR_NATIVE); + //would cause too much troubles in old plugins + return 0; + } + char date[32]; + time_t td; time(&td); + strftime(date,31,"%m/%d/%Y - %H:%M:%S",localtime(&td)); + int len; + g_langMngr.SetDefLang(LANG_SERVER); + char* message = format_amxstring(amx,params,2,len); + message[len++]='\n'; + message[len]=0; + if ( first_time ){ + fprintf(fp,"L %s: Log file started (file \"%s\") (game \"%s\") (amx \"%s\")\n", + date,file,g_mod_name.c_str(),Plugin_info.version); + print_srvconsole("L %s: Log file started (file \"%s\") (game \"%s\") (amx \"%s\")\n", + date,file,g_mod_name.c_str(),Plugin_info.version); + } + fprintf(fp,"L %s: %s",date,message); + print_srvconsole("L %s: %s",date,message); + fclose(fp); + return 1; } static cell AMX_NATIVE_CALL num_to_word(AMX *amx, cell *params) /* 3 param */ { - char sptemp[512]; - UTIL_IntToString(params[1], sptemp); - return set_amxstring(amx,params[2],sptemp,params[3]); + char sptemp[512]; + UTIL_IntToString(params[1], sptemp); + return set_amxstring(amx,params[2],sptemp,params[3]); } static cell AMX_NATIVE_CALL get_timeleft(AMX *amx, cell *params) { - float flCvarTimeLimit = mp_timelimit->value; + float flCvarTimeLimit = mp_timelimit->value; - if (flCvarTimeLimit) { - int iReturn = (int)((g_game_timeleft + flCvarTimeLimit * 60.0) - gpGlobals->time); - return (iReturn < 0) ? 0 : iReturn; - } + if (flCvarTimeLimit) { + int iReturn = (int)((g_game_timeleft + flCvarTimeLimit * 60.0) - gpGlobals->time); + return (iReturn < 0) ? 0 : iReturn; + } - return 0; + return 0; } static cell AMX_NATIVE_CALL get_time(AMX *amx, cell *params) /* 3 param */ { - int ilen; - char* sptemp = get_amxstring(amx,params[1],0,ilen); - time_t td = time(NULL); - tm* lt = localtime(&td); - if ( lt == 0 ) { - amx_RaiseError(amx,AMX_ERR_NATIVE); - return 0; - } - char szDate[512]; - strftime(szDate,511,sptemp, lt ); - return set_amxstring(amx,params[2],szDate,params[3]); + int ilen; + char* sptemp = get_amxstring(amx,params[1],0,ilen); + time_t td = time(NULL); + tm* lt = localtime(&td); + if ( lt == 0 ) { + amx_RaiseError(amx,AMX_ERR_NATIVE); + return 0; + } + char szDate[512]; + strftime(szDate,511,sptemp, lt ); + return set_amxstring(amx,params[2],szDate,params[3]); } static cell AMX_NATIVE_CALL format_time(AMX *amx, cell *params) /* 3 param */ { - int ilen; - char* sptemp = get_amxstring(amx,params[3],0,ilen); - time_t tim = params[4]; - time_t td = ( tim != -1 ) ? tim : time(NULL); - tm* lt = localtime(&td); - if ( lt == 0 ) { - amx_RaiseError(amx,AMX_ERR_NATIVE); - return 0; - } - char szDate[512]; - strftime(szDate,511,sptemp, lt ); - return set_amxstring(amx,params[1],szDate,params[2]); + int ilen; + char* sptemp = get_amxstring(amx,params[3],0,ilen); + time_t tim = params[4]; + time_t td = ( tim != -1 ) ? tim : time(NULL); + tm* lt = localtime(&td); + if ( lt == 0 ) { + amx_RaiseError(amx,AMX_ERR_NATIVE); + return 0; + } + char szDate[512]; + strftime(szDate,511,sptemp, lt ); + return set_amxstring(amx,params[1],szDate,params[2]); } static cell AMX_NATIVE_CALL parse_time(AMX *amx, cell *params) /* 3 param */ { - int ilen; - char* sTime = get_amxstring(amx,params[1],1,ilen); - char* sFormat = get_amxstring(amx,params[2],0,ilen); - tm* mytime; - time_t td; - if ( params[3] == -1 ) { - td = time(NULL); - mytime = localtime(&td); - if ( mytime == 0 ){ - amx_RaiseError(amx,AMX_ERR_NATIVE); - return 0; - } - strptime (sTime,sFormat,mytime , 0 ); - } - else { - td = params[3]; - mytime = localtime(&td); - if ( mytime == 0 ){ - amx_RaiseError(amx,AMX_ERR_NATIVE); - return 0; - } - strptime (sTime,sFormat,mytime , 1 ); - } - return mktime(mytime); + int ilen; + char* sTime = get_amxstring(amx,params[1],1,ilen); + char* sFormat = get_amxstring(amx,params[2],0,ilen); + tm* mytime; + time_t td; + if ( params[3] == -1 ) { + td = time(NULL); + mytime = localtime(&td); + if ( mytime == 0 ){ + amx_RaiseError(amx,AMX_ERR_NATIVE); + return 0; + } + strptime (sTime,sFormat,mytime , 0 ); + } + else { + td = params[3]; + mytime = localtime(&td); + if ( mytime == 0 ){ + amx_RaiseError(amx,AMX_ERR_NATIVE); + return 0; + } + strptime (sTime,sFormat,mytime , 1 ); + } + return mktime(mytime); } static cell AMX_NATIVE_CALL get_systime(AMX *amx, cell *params) /* 3 param */ { - time_t td = time(NULL); - td += params[1]; - return td; + time_t td = time(NULL); + td += params[1]; + return td; } static cell AMX_NATIVE_CALL read_datanum(AMX *amx, cell *params) /* 0 param */ { - return g_events.getArgNum(); + return g_events.getArgNum(); } static cell AMX_NATIVE_CALL read_data(AMX *amx, cell *params) /* 3 param */ @@ -1488,230 +1488,230 @@ static cell AMX_NATIVE_CALL read_data(AMX *amx, cell *params) /* 3 param */ static cell AMX_NATIVE_CALL get_playersnum(AMX *amx, cell *params) { - if (!params[1]) - return g_players_num; + if (!params[1]) + return g_players_num; - int a = 0; - for(int i = 1; i <= gpGlobals->maxClients; ++i){ - CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); - if ( pPlayer->initialized && (GETPLAYERUSERID(pPlayer->pEdict) > 0) ) - ++a; - } + int a = 0; + for(int i = 1; i <= gpGlobals->maxClients; ++i){ + CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); + if ( pPlayer->initialized && (GETPLAYERUSERID(pPlayer->pEdict) > 0) ) + ++a; + } - return a; + return a; } static cell AMX_NATIVE_CALL get_players(AMX *amx, cell *params) /* 4 param */ { - int iNum = 0; - int ilen; - char* sptemp = get_amxstring(amx,params[3],0,ilen); - int flags = UTIL_ReadFlags(sptemp); + int iNum = 0; + int ilen; + char* sptemp = get_amxstring(amx,params[3],0,ilen); + int flags = UTIL_ReadFlags(sptemp); - cell *aPlayers = get_amxaddr(amx,params[1]); - cell *iMax = get_amxaddr(amx,params[2]); + cell *aPlayers = get_amxaddr(amx,params[1]); + cell *iMax = get_amxaddr(amx,params[2]); - int team = 0; + int team = 0; - if (flags & 48) { - sptemp = get_amxstring(amx,params[4],0,ilen); + if (flags & 48) { + sptemp = get_amxstring(amx,params[4],0,ilen); - if ( flags & 16 ) { - if (flags & 64) - team = g_teamsIds.findTeamId( sptemp ); - else - team = g_teamsIds.findTeamIdCase( sptemp ); - } - } + if ( flags & 16 ) { + if (flags & 64) + team = g_teamsIds.findTeamId( sptemp ); + else + team = g_teamsIds.findTeamIdCase( sptemp ); + } + } - for(int i = 1; i <= gpGlobals->maxClients; ++i){ - CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); - if (pPlayer->ingame){ - if (pPlayer->IsAlive() ? (flags & 2) : (flags & 1)) - continue; - if (pPlayer->bot ? (flags & 4) : (flags & 8)) - continue; - if ((flags & 16) && (pPlayer->teamId != team) ) - continue; - if (flags & 32){ - if (flags & 64){ - if (stristr(pPlayer->name.c_str(),sptemp)==NULL) - continue; - } - else if (strstr(pPlayer->name.c_str(),sptemp)==NULL) - continue; - } - aPlayers[iNum++] = i; - } - } + for(int i = 1; i <= gpGlobals->maxClients; ++i){ + CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); + if (pPlayer->ingame){ + if (pPlayer->IsAlive() ? (flags & 2) : (flags & 1)) + continue; + if (pPlayer->bot ? (flags & 4) : (flags & 8)) + continue; + if ((flags & 16) && (pPlayer->teamId != team) ) + continue; + if (flags & 32){ + if (flags & 64){ + if (stristr(pPlayer->name.c_str(),sptemp)==NULL) + continue; + } + else if (strstr(pPlayer->name.c_str(),sptemp)==NULL) + continue; + } + aPlayers[iNum++] = i; + } + } - *iMax = iNum; - return 1; + *iMax = iNum; + return 1; } static cell AMX_NATIVE_CALL find_player(AMX *amx, cell *params) /* 1 param */ { - int ilen, userid = 0; - char* sptemp = get_amxstring(amx,params[1],0,ilen); - int flags = UTIL_ReadFlags(sptemp); - if (flags&31) - sptemp = get_amxstring(amx,params[2],0,ilen); - else if (flags&1024) - userid = *get_amxaddr(amx,params[2]); - // a b c d e f g h i j k l - int result = 0; - for(int i = 1; i <= gpGlobals->maxClients; ++i){ - CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); - if (pPlayer->ingame){ - if (pPlayer->IsAlive()?(flags&64):(flags&32)) - continue; - if (pPlayer->bot?(flags&128):(flags&256)) - continue; - if (flags&1){ - if (flags&2048) { - if (stricmp(pPlayer->name.c_str(),sptemp)) - continue; - } - else if (strcmp(pPlayer->name.c_str(),sptemp)) - continue; - } - if (flags&2){ - if (flags&2048) { - if (stristr(pPlayer->name.c_str(),sptemp)==NULL) - continue; - } - else if (strstr(pPlayer->name.c_str(),sptemp)==NULL) - continue; - } - if (flags&4){ - const char* authid = GETPLAYERAUTHID(pPlayer->pEdict); - if (!authid || strcmp(authid,sptemp)) - continue; - } - if (flags&1024){ - if (userid != GETPLAYERUSERID(pPlayer->pEdict)) - continue; - } - if (flags&8){ - if (strncmp(pPlayer->ip.c_str(),sptemp,ilen)) - continue; - } - if (flags&16){ - if (flags&2048) { - if (stricmp(pPlayer->team.c_str(),sptemp)) - continue; - } - else if (strcmp(pPlayer->team.c_str(),sptemp)) - continue; - } - result = i; - if ((flags&512)==0) - break; - } - } + int ilen, userid = 0; + char* sptemp = get_amxstring(amx,params[1],0,ilen); + int flags = UTIL_ReadFlags(sptemp); + if (flags&31) + sptemp = get_amxstring(amx,params[2],0,ilen); + else if (flags&1024) + userid = *get_amxaddr(amx,params[2]); + // a b c d e f g h i j k l + int result = 0; + for(int i = 1; i <= gpGlobals->maxClients; ++i){ + CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); + if (pPlayer->ingame){ + if (pPlayer->IsAlive()?(flags&64):(flags&32)) + continue; + if (pPlayer->bot?(flags&128):(flags&256)) + continue; + if (flags&1){ + if (flags&2048) { + if (stricmp(pPlayer->name.c_str(),sptemp)) + continue; + } + else if (strcmp(pPlayer->name.c_str(),sptemp)) + continue; + } + if (flags&2){ + if (flags&2048) { + if (stristr(pPlayer->name.c_str(),sptemp)==NULL) + continue; + } + else if (strstr(pPlayer->name.c_str(),sptemp)==NULL) + continue; + } + if (flags&4){ + const char* authid = GETPLAYERAUTHID(pPlayer->pEdict); + if (!authid || strcmp(authid,sptemp)) + continue; + } + if (flags&1024){ + if (userid != GETPLAYERUSERID(pPlayer->pEdict)) + continue; + } + if (flags&8){ + if (strncmp(pPlayer->ip.c_str(),sptemp,ilen)) + continue; + } + if (flags&16){ + if (flags&2048) { + if (stricmp(pPlayer->team.c_str(),sptemp)) + continue; + } + else if (strcmp(pPlayer->team.c_str(),sptemp)) + continue; + } + result = i; + if ((flags&512)==0) + break; + } + } - return result; + return result; } static cell AMX_NATIVE_CALL get_maxplayers(AMX *amx, cell *params) { - return gpGlobals->maxClients; + return gpGlobals->maxClients; } static cell AMX_NATIVE_CALL get_gametime(AMX *amx, cell *params) { - REAL pFloat = gpGlobals->time; - return amx_ftoc(pFloat); + REAL pFloat = gpGlobals->time; + return amx_ftoc(pFloat); } static cell AMX_NATIVE_CALL get_mapname(AMX *amx, cell *params) /* 2 param */ { - return set_amxstring(amx,params[1],STRING(gpGlobals->mapname),params[2]); + return set_amxstring(amx,params[1],STRING(gpGlobals->mapname),params[2]); } static cell AMX_NATIVE_CALL get_modname(AMX *amx, cell *params) /* 2 param */ { - return set_amxstring(amx,params[1],g_mod_name.c_str(),params[2]); + return set_amxstring(amx,params[1],g_mod_name.c_str(),params[2]); } static cell AMX_NATIVE_CALL get_localinfo(AMX *amx, cell *params) /* 3 param */ { - int ilen; - char* sptemp = get_amxstring(amx,params[1],0,ilen); - return set_amxstring(amx,params[2],LOCALINFO(sptemp),params[3]); + int ilen; + char* sptemp = get_amxstring(amx,params[1],0,ilen); + return set_amxstring(amx,params[2],LOCALINFO(sptemp),params[3]); } static cell AMX_NATIVE_CALL set_localinfo(AMX *amx, cell *params) /* 2 param */ { - int ilen; - char* sptemp = get_amxstring(amx,params[1],0,ilen); - char* szValue = get_amxstring(amx,params[2],1,ilen); - SET_LOCALINFO(sptemp,szValue); - return 1; + int ilen; + char* sptemp = get_amxstring(amx,params[1],0,ilen); + char* szValue = get_amxstring(amx,params[2],1,ilen); + SET_LOCALINFO(sptemp,szValue); + return 1; } static cell AMX_NATIVE_CALL get_user_info(AMX *amx, cell *params) /* 4 param */ { - int index = params[1]; - if (index<1||index>gpGlobals->maxClients){ - LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); - return 0; - } - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - if (!pPlayer->pEdict) - { - LogError(amx, AMX_ERR_NATIVE, "Player %d is not connected", index); - return 0; - } - int ilen; - char* sptemp = get_amxstring(amx,params[2],0,ilen); - return set_amxstring(amx,params[3],ENTITY_KEYVALUE(pPlayer->pEdict,sptemp ),params[4]); - return 1; + int index = params[1]; + if (index<1||index>gpGlobals->maxClients){ + LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); + return 0; + } + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + if (!pPlayer->pEdict) + { + LogError(amx, AMX_ERR_NATIVE, "Player %d is not connected", index); + return 0; + } + int ilen; + char* sptemp = get_amxstring(amx,params[2],0,ilen); + return set_amxstring(amx,params[3],ENTITY_KEYVALUE(pPlayer->pEdict,sptemp ),params[4]); + return 1; } static cell AMX_NATIVE_CALL set_user_info(AMX *amx, cell *params) /* 3 param */ { - int index = params[1]; - if (index<1||index>gpGlobals->maxClients){ - LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); - return 0; - } - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - if (!pPlayer->pEdict) - { - LogError(amx, AMX_ERR_NATIVE, "Player %d is not connected", index); - return 0; - } - int ilen; - char* sptemp = get_amxstring(amx,params[2],0,ilen); - char* szValue = get_amxstring(amx,params[3],1,ilen); - ENTITY_SET_KEYVALUE(pPlayer->pEdict,sptemp,szValue); - return 1; + int index = params[1]; + if (index<1||index>gpGlobals->maxClients){ + LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); + return 0; + } + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + if (!pPlayer->pEdict) + { + LogError(amx, AMX_ERR_NATIVE, "Player %d is not connected", index); + return 0; + } + int ilen; + char* sptemp = get_amxstring(amx,params[2],0,ilen); + char* szValue = get_amxstring(amx,params[3],1,ilen); + ENTITY_SET_KEYVALUE(pPlayer->pEdict,sptemp,szValue); + return 1; } static cell AMX_NATIVE_CALL read_argc(AMX *amx, cell *params) { - return CMD_ARGC(); + return CMD_ARGC(); } static cell AMX_NATIVE_CALL read_argv(AMX *amx, cell *params) /* 3 param */ { - return set_amxstring(amx,params[2], /*( params[1] < 0 || - params[1] >= CMD_ARGC() ) ? "" : */CMD_ARGV(params[1]) , params[3]); + return set_amxstring(amx,params[2], /*( params[1] < 0 || + params[1] >= CMD_ARGC() ) ? "" : */CMD_ARGV(params[1]) , params[3]); } static cell AMX_NATIVE_CALL read_args(AMX *amx, cell *params) /* 2 param */ { - const char* sValue = CMD_ARGS(); - return set_amxstring(amx,params[1],sValue ? sValue : "",params[2]); + const char* sValue = CMD_ARGS(); + return set_amxstring(amx,params[1],sValue ? sValue : "",params[2]); } static cell AMX_NATIVE_CALL get_user_msgid(AMX *amx, cell *params) /* 1 param */ { - int ilen; - char* sptemp = get_amxstring(amx,params[1],0,ilen); - return GET_USER_MSG_ID(PLID, sptemp , NULL ); + int ilen; + char* sptemp = get_amxstring(amx,params[1],0,ilen); + return GET_USER_MSG_ID(PLID, sptemp , NULL ); } static cell AMX_NATIVE_CALL get_user_msgname(AMX *amx, cell *params) /* get_user_msgname(msg, str[], len) = 3 params */ @@ -1727,581 +1727,581 @@ static cell AMX_NATIVE_CALL get_user_msgname(AMX *amx, cell *params) /* get_user static cell AMX_NATIVE_CALL set_task(AMX *amx, cell *params) /* 2 param */ { - CPluginMngr::CPlugin *plugin = g_plugins.findPluginFast(amx); + CPluginMngr::CPlugin *plugin = g_plugins.findPluginFast(amx); - int a, iFunc; + int a, iFunc; - char* stemp = get_amxstring(amx,params[2],1, a ); + char* stemp = get_amxstring(amx,params[2],1, a ); - if (params[5]) - { - iFunc = registerSPForwardByName(amx, stemp, FP_ARRAY, FP_CELL, FP_DONE); - } else { - iFunc = registerSPForwardByName(amx, stemp, FP_CELL, FP_DONE); - } - if (iFunc == -1) - { - AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",stemp,plugin->getName() ); - amx_RaiseError(amx,AMX_ERR_NATIVE); - return 0; - } + if (params[5]) + { + iFunc = registerSPForwardByName(amx, stemp, FP_ARRAY, FP_CELL, FP_DONE); + } else { + iFunc = registerSPForwardByName(amx, stemp, FP_CELL, FP_DONE); + } + if (iFunc == -1) + { + AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",stemp,plugin->getName() ); + amx_RaiseError(amx,AMX_ERR_NATIVE); + return 0; + } - float base = amx_ctof(params[1]); + float base = amx_ctof(params[1]); - if ( base < 0.1f ) - base = 0.1f; + if ( base < 0.1f ) + base = 0.1f; - char* temp = get_amxstring(amx,params[6],0,a); + char* temp = get_amxstring(amx,params[6],0,a); - g_tasksMngr.registerTask( plugin , iFunc , UTIL_ReadFlags(temp), params[3], base , params[5] , get_amxaddr(amx,params[4]) , params[7] ); + g_tasksMngr.registerTask( plugin , iFunc , UTIL_ReadFlags(temp), params[3], base , params[5] , get_amxaddr(amx,params[4]) , params[7] ); - return 1; + return 1; } static cell AMX_NATIVE_CALL remove_task(AMX *amx, cell *params) /* 1 param */ { - return g_tasksMngr.removeTasks( params[1] , params[2] ? 0 : amx ); + return g_tasksMngr.removeTasks( params[1] , params[2] ? 0 : amx ); } static cell AMX_NATIVE_CALL change_task(AMX *amx, cell *params) { - REAL flNewTime = amx_ctof(params[2]); - return g_tasksMngr.changeTasks(params[1], params[3] ? 0 : amx, flNewTime); + REAL flNewTime = amx_ctof(params[2]); + return g_tasksMngr.changeTasks(params[1], params[3] ? 0 : amx, flNewTime); } static cell AMX_NATIVE_CALL task_exists(AMX *amx, cell *params) /* 1 param */ { - return g_tasksMngr.taskExists( params[1] , params[2] ? 0 : amx ); + return g_tasksMngr.taskExists( params[1] , params[2] ? 0 : amx ); } static cell AMX_NATIVE_CALL cvar_exists(AMX *amx, cell *params) /* 1 param */ { - int ilen; - return (CVAR_GET_POINTER(get_amxstring(amx,params[1],0,ilen))?1:0); + int ilen; + return (CVAR_GET_POINTER(get_amxstring(amx,params[1],0,ilen))?1:0); } static cell AMX_NATIVE_CALL register_cvar(AMX *amx, cell *params) /* 3 param */ { - int i; - char* temp = get_amxstring(amx,params[1],0,i); + int i; + char* temp = get_amxstring(amx,params[1],0,i); - if ( !g_cvars.find( temp ) ) - { - CPluginMngr::CPlugin *plugin = g_plugins.findPluginFast(amx); - CCVar* cvar = new CCVar( temp , plugin->getName() , params[3] , - amx_ctof(params[4]) ); + if ( !g_cvars.find( temp ) ) + { + CPluginMngr::CPlugin *plugin = g_plugins.findPluginFast(amx); + CCVar* cvar = new CCVar( temp , plugin->getName() , params[3] , + amx_ctof(params[4]) ); - if ( cvar == 0 ) - return 0; + if ( cvar == 0 ) + return 0; - g_cvars.put( cvar ); + g_cvars.put( cvar ); - if ( CVAR_GET_POINTER(temp) == 0 ) - { - static cvar_t cvar_reg_helper; - cvar_reg_helper = *(cvar->getCvar()); - CVAR_REGISTER( &cvar_reg_helper ); - } + if ( CVAR_GET_POINTER(temp) == 0 ) + { + static cvar_t cvar_reg_helper; + cvar_reg_helper = *(cvar->getCvar()); + CVAR_REGISTER( &cvar_reg_helper ); + } - CVAR_SET_STRING( temp ,get_amxstring(amx,params[2],1,i)); - return 1; - } + CVAR_SET_STRING( temp ,get_amxstring(amx,params[2],1,i)); + return 1; + } - return 0; + return 0; } static cell AMX_NATIVE_CALL get_user_ping(AMX *amx, cell *params) /* 3 param */ { - int index = params[1]; - if (index<1||index>gpGlobals->maxClients) - return 0; - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - if (pPlayer->ingame){ - cell *cpPing = get_amxaddr(amx,params[2]); - cell *cpLoss = get_amxaddr(amx,params[3]); - int ping, loss; - PLAYER_CNX_STATS(pPlayer->pEdict , &ping, &loss); - *cpPing = ping; - *cpLoss = loss; - return 1; - } - return 0; + int index = params[1]; + if (index<1||index>gpGlobals->maxClients) + return 0; + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + if (pPlayer->ingame){ + cell *cpPing = get_amxaddr(amx,params[2]); + cell *cpLoss = get_amxaddr(amx,params[3]); + int ping, loss; + PLAYER_CNX_STATS(pPlayer->pEdict , &ping, &loss); + *cpPing = ping; + *cpLoss = loss; + return 1; + } + return 0; } static cell AMX_NATIVE_CALL get_user_time(AMX *amx, cell *params) /* 1 param */ { - int index = params[1]; - if (index<1||index>gpGlobals->maxClients) - return 0; - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - if (pPlayer->ingame){ - int time = (int)(gpGlobals->time - (params[2] ? pPlayer->playtime : pPlayer->time)); - return time; - } - return 0; + int index = params[1]; + if (index<1||index>gpGlobals->maxClients) + return 0; + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + if (pPlayer->ingame){ + int time = (int)(gpGlobals->time - (params[2] ? pPlayer->playtime : pPlayer->time)); + return time; + } + return 0; } static cell AMX_NATIVE_CALL server_exec(AMX *amx, cell *params) { - SERVER_EXECUTE( ); - return 1; + SERVER_EXECUTE( ); + return 1; } static cell AMX_NATIVE_CALL engclient_cmd(AMX *amx, cell *params) /* 4 param */ { - int ilen; - const char* szCmd = get_amxstring(amx,params[2],0,ilen); - const char* sArg1 = get_amxstring(amx,params[3],1,ilen); - if ( ilen == 0 ) sArg1 = 0; - const char* sArg2 = get_amxstring(amx,params[4],2,ilen); - if ( ilen == 0 ) sArg2 = 0; - if (params[1] == 0) { - for(int i = 1; i <= gpGlobals->maxClients; ++i){ - CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); - if (pPlayer->ingame /*&& pPlayer->initialized */) - UTIL_FakeClientCommand(pPlayer->pEdict, szCmd,sArg1,sArg2); - } - } - else { - int index = params[1]; - if (index < 1 || index > gpGlobals->maxClients){ - LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); - return 0; - } - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - if ( /*pPlayer->initialized && */pPlayer->ingame ) - UTIL_FakeClientCommand(pPlayer->pEdict, szCmd,sArg1,sArg2); - } - return 1; + int ilen; + const char* szCmd = get_amxstring(amx,params[2],0,ilen); + const char* sArg1 = get_amxstring(amx,params[3],1,ilen); + if ( ilen == 0 ) sArg1 = 0; + const char* sArg2 = get_amxstring(amx,params[4],2,ilen); + if ( ilen == 0 ) sArg2 = 0; + if (params[1] == 0) { + for(int i = 1; i <= gpGlobals->maxClients; ++i){ + CPlayer* pPlayer = GET_PLAYER_POINTER_I(i); + if (pPlayer->ingame /*&& pPlayer->initialized */) + UTIL_FakeClientCommand(pPlayer->pEdict, szCmd,sArg1,sArg2); + } + } + else { + int index = params[1]; + if (index < 1 || index > gpGlobals->maxClients){ + LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); + return 0; + } + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + if ( /*pPlayer->initialized && */pPlayer->ingame ) + UTIL_FakeClientCommand(pPlayer->pEdict, szCmd,sArg1,sArg2); + } + return 1; } static cell AMX_NATIVE_CALL pause(AMX *amx, cell *params) /* 3 param */ { - int ilen; - char* temp = get_amxstring(amx,params[1],0,ilen); - int flags = UTIL_ReadFlags(temp); + int ilen; + char* temp = get_amxstring(amx,params[1],0,ilen); + int flags = UTIL_ReadFlags(temp); - CPluginMngr::CPlugin *plugin = 0; + CPluginMngr::CPlugin *plugin = 0; - if ( flags & 2 ) - { // pause function - AMXXLOG_Log("[AMXX] This usage of the native pause() has been deprecated!"); - return 1; - } - else if (flags&4){ - temp = get_amxstring(amx,params[2],0,ilen); - plugin = g_plugins.findPlugin(temp); - } - else - plugin = g_plugins.findPluginFast(amx); - if ( plugin && plugin->isValid() ){ - if ( flags & 8 ) - plugin->setStatus( ps_stopped ); - else if ( flags & 16 ) - plugin->setStatus( ps_locked ); - else - plugin->pausePlugin(); - return 1; - } - return 0; + if ( flags & 2 ) + { // pause function + AMXXLOG_Log("[AMXX] This usage of the native pause() has been deprecated!"); + return 1; + } + else if (flags&4){ + temp = get_amxstring(amx,params[2],0,ilen); + plugin = g_plugins.findPlugin(temp); + } + else + plugin = g_plugins.findPluginFast(amx); + if ( plugin && plugin->isValid() ){ + if ( flags & 8 ) + plugin->setStatus( ps_stopped ); + else if ( flags & 16 ) + plugin->setStatus( ps_locked ); + else + plugin->pausePlugin(); + return 1; + } + return 0; } static cell AMX_NATIVE_CALL unpause(AMX *amx, cell *params) /* 3 param */ { - int ilen; - char* sptemp = get_amxstring(amx,params[1],0,ilen); - int flags = UTIL_ReadFlags(sptemp); - CPluginMngr::CPlugin *plugin = 0; - if (flags&2) - { - AMXXLOG_Log("[AMXX] This usage of the native pause() has been deprecated!"); - return 1; - } else if (flags&4) { - sptemp = get_amxstring(amx,params[2],0,ilen); - plugin = g_plugins.findPlugin(sptemp); - } - else - plugin = g_plugins.findPluginFast( amx); - if (plugin && plugin->isValid() && plugin->isPaused() ) - { - plugin->unpausePlugin(); - return 1; - } + int ilen; + char* sptemp = get_amxstring(amx,params[1],0,ilen); + int flags = UTIL_ReadFlags(sptemp); + CPluginMngr::CPlugin *plugin = 0; + if (flags&2) + { + AMXXLOG_Log("[AMXX] This usage of the native pause() has been deprecated!"); + return 1; + } else if (flags&4) { + sptemp = get_amxstring(amx,params[2],0,ilen); + plugin = g_plugins.findPlugin(sptemp); + } + else + plugin = g_plugins.findPluginFast( amx); + if (plugin && plugin->isValid() && plugin->isPaused() ) + { + plugin->unpausePlugin(); + return 1; + } - return 0; + return 0; } static cell AMX_NATIVE_CALL read_flags(AMX *amx, cell *params) /* 1 param */ { - int ilen; - char* sptemp = get_amxstring(amx,params[1],0,ilen); - return UTIL_ReadFlags(sptemp); + int ilen; + char* sptemp = get_amxstring(amx,params[1],0,ilen); + return UTIL_ReadFlags(sptemp); } static cell AMX_NATIVE_CALL get_flags(AMX *amx, cell *params) /* 1 param */ { - char flags[32]; - UTIL_GetFlags( flags , params[1] ); - return set_amxstring(amx,params[2],flags,params[3]); + char flags[32]; + UTIL_GetFlags( flags , params[1] ); + return set_amxstring(amx,params[2],flags,params[3]); } static cell AMX_NATIVE_CALL get_user_flags(AMX *amx, cell *params) /* 2 param */ { - int index = params[1]; - if (index<0||index>gpGlobals->maxClients){ - LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); - return 0; - } - int id = params[2]; - if (id < 0) id = 0; - if (id > 31) id = 31; - return GET_PLAYER_POINTER_I(index)->flags[id]; + int index = params[1]; + if (index<0||index>gpGlobals->maxClients){ + LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); + return 0; + } + int id = params[2]; + if (id < 0) id = 0; + if (id > 31) id = 31; + return GET_PLAYER_POINTER_I(index)->flags[id]; } static cell AMX_NATIVE_CALL set_user_flags(AMX *amx, cell *params) /* 3 param */ { - int index = params[1]; - if (index < 0 || index > gpGlobals->maxClients){ - LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); - return 0; - } - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - int flag = params[2]; - int id = params[3]; - if (id < 0) id = 0; - if (id > 31) id = 31; - pPlayer->flags[id] |= flag; - return 1; + int index = params[1]; + if (index < 0 || index > gpGlobals->maxClients){ + LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); + return 0; + } + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + int flag = params[2]; + int id = params[3]; + if (id < 0) id = 0; + if (id > 31) id = 31; + pPlayer->flags[id] |= flag; + return 1; } static cell AMX_NATIVE_CALL remove_user_flags(AMX *amx, cell *params) /* 3 param */ { - int index = params[1]; - if (index < 0 || index > gpGlobals->maxClients){ - LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); - return 0; - } - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - int flag = params[2]; - int id = params[3]; - if (id < 0) id = 0; - if (id > 31) id = 31; - pPlayer->flags[id] &= ~flag; - return 1; + int index = params[1]; + if (index < 0 || index > gpGlobals->maxClients){ + LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); + return 0; + } + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + int flag = params[2]; + int id = params[3]; + if (id < 0) id = 0; + if (id > 31) id = 31; + pPlayer->flags[id] &= ~flag; + return 1; } static cell AMX_NATIVE_CALL register_menuid(AMX *amx, cell *params) /* 1 param */ { - int i; - char* temp = get_amxstring(amx,params[1],0,i); - AMX* a = (*params/sizeof(cell) < 2 || params[2] ) ? 0 : amx; - return g_menucmds.registerMenuId( temp , a ); + int i; + char* temp = get_amxstring(amx,params[1],0,i); + AMX* a = (*params/sizeof(cell) < 2 || params[2] ) ? 0 : amx; + return g_menucmds.registerMenuId( temp , a ); } static cell AMX_NATIVE_CALL get_user_menu(AMX *amx, cell *params) /* 3 param */ { - int index = params[1]; - if (index < 1 || index > gpGlobals->maxClients){ - LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); - return 0; - } - cell *cpMenu = get_amxaddr(amx,params[2]); - cell *cpKeys = get_amxaddr(amx,params[3]); - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - if (pPlayer->ingame){ - *cpMenu = pPlayer->menu; - *cpKeys = pPlayer->keys; - return 1; - } - return 0; + int index = params[1]; + if (index < 1 || index > gpGlobals->maxClients){ + LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); + return 0; + } + cell *cpMenu = get_amxaddr(amx,params[2]); + cell *cpKeys = get_amxaddr(amx,params[3]); + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + if (pPlayer->ingame){ + *cpMenu = pPlayer->menu; + *cpKeys = pPlayer->keys; + return 1; + } + return 0; } static cell AMX_NATIVE_CALL precache_sound(AMX *amx, cell *params) /* 1 param */ { - if ( g_dontprecache ) { - amx_RaiseError(amx,AMX_ERR_NATIVE); - return 0; - } - int ilen; - char* sptemp = get_amxstring(amx,params[1],0,ilen); - PRECACHE_SOUND((char*)STRING(ALLOC_STRING(sptemp))); - return 1; + if ( g_dontprecache ) { + amx_RaiseError(amx,AMX_ERR_NATIVE); + return 0; + } + int ilen; + char* sptemp = get_amxstring(amx,params[1],0,ilen); + PRECACHE_SOUND((char*)STRING(ALLOC_STRING(sptemp))); + return 1; } static cell AMX_NATIVE_CALL precache_model(AMX *amx, cell *params) /* 1 param */ { - if ( g_dontprecache ) { - amx_RaiseError(amx,AMX_ERR_NATIVE); - return 0; - } - int ilen; - char* sptemp = get_amxstring(amx,params[1],0,ilen); - return PRECACHE_MODEL((char*)STRING(ALLOC_STRING(sptemp))); + if ( g_dontprecache ) { + amx_RaiseError(amx,AMX_ERR_NATIVE); + return 0; + } + int ilen; + char* sptemp = get_amxstring(amx,params[1],0,ilen); + return PRECACHE_MODEL((char*)STRING(ALLOC_STRING(sptemp))); } static cell AMX_NATIVE_CALL get_distance(AMX *amx, cell *params) /* 2 param */ { - cell *cpVec1 = get_amxaddr(amx,params[1]); - cell *cpVec2 = get_amxaddr(amx,params[2]); - Vector vec1 = Vector((float)cpVec1[0],(float)cpVec1[1],(float)cpVec1[2]); - Vector vec2 = Vector((float)cpVec2[0],(float)cpVec2[1],(float)cpVec2[2]); - int iDist = (int)((vec1 - vec2).Length()); - return iDist; + cell *cpVec1 = get_amxaddr(amx,params[1]); + cell *cpVec2 = get_amxaddr(amx,params[2]); + Vector vec1 = Vector((float)cpVec1[0],(float)cpVec1[1],(float)cpVec1[2]); + Vector vec2 = Vector((float)cpVec2[0],(float)cpVec2[1],(float)cpVec2[2]); + int iDist = (int)((vec1 - vec2).Length()); + return iDist; } static cell AMX_NATIVE_CALL get_distance_f(AMX *amx, cell *params) { - cell *cpVec1 = get_amxaddr(amx, params[1]); - cell *cpVec2 = get_amxaddr(amx, params[2]); - Vector vec1 = Vector((float)amx_ctof(cpVec1[0]), - (float)amx_ctof(cpVec1[1]), - (float)amx_ctof(cpVec1[2])); - Vector vec2 = Vector((float)amx_ctof(cpVec2[0]), - (float)amx_ctof(cpVec2[1]), - (float)amx_ctof(cpVec2[2])); + cell *cpVec1 = get_amxaddr(amx, params[1]); + cell *cpVec2 = get_amxaddr(amx, params[2]); + Vector vec1 = Vector((float)amx_ctof(cpVec1[0]), + (float)amx_ctof(cpVec1[1]), + (float)amx_ctof(cpVec1[2])); + Vector vec2 = Vector((float)amx_ctof(cpVec2[0]), + (float)amx_ctof(cpVec2[1]), + (float)amx_ctof(cpVec2[2])); - REAL fDist = (REAL) (vec1-vec2).Length(); + REAL fDist = (REAL) (vec1-vec2).Length(); - return amx_ftoc(fDist); + return amx_ftoc(fDist); } static cell AMX_NATIVE_CALL random_float(AMX *amx, cell *params) /* 2 param */ { - float one = amx_ctof(params[1]); - float two = amx_ctof(params[2]); - REAL fRnd = RANDOM_FLOAT(one,two); - return amx_ftoc(fRnd); + float one = amx_ctof(params[1]); + float two = amx_ctof(params[2]); + REAL fRnd = RANDOM_FLOAT(one,two); + return amx_ftoc(fRnd); } static cell AMX_NATIVE_CALL random_num(AMX *amx, cell *params) /* 2 param */ { - return RANDOM_LONG(params[1],params[2]); + return RANDOM_LONG(params[1],params[2]); } static cell AMX_NATIVE_CALL remove_quotes(AMX *amx, cell *params) /* 1 param */ { - cell *text = get_amxaddr(amx,params[1]); - if (*text=='\"') { - register cell *temp = text; - int len = 0; - while(*temp++) ++len; // get length - cell *src = text; - if ( src[len-1]=='\r' ) - src[--len] = 0; - if (src[--len]=='\"'){ - src[len] = 0; - temp = src+1; - while((*src++ = *temp++)) - ; - return 1; - } - } - return 0; + cell *text = get_amxaddr(amx,params[1]); + if (*text=='\"') { + register cell *temp = text; + int len = 0; + while(*temp++) ++len; // get length + cell *src = text; + if ( src[len-1]=='\r' ) + src[--len] = 0; + if (src[--len]=='\"'){ + src[len] = 0; + temp = src+1; + while((*src++ = *temp++)) + ; + return 1; + } + } + return 0; } static cell AMX_NATIVE_CALL get_user_aiming(AMX *amx, cell *params) /* 4 param */ { - int index = params[1]; - if (index < 1 || index > gpGlobals->maxClients){ - LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); - return 0; - } - CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); - cell *cpId = get_amxaddr(amx,params[2]); - cell *cpBody = get_amxaddr(amx,params[3]); - cell fCell; - REAL *pFloat = (REAL *)((void *)&fCell); - *pFloat = 0.0; - if (pPlayer->ingame) { - edict_t* edict = pPlayer->pEdict; - Vector v_forward; - Vector v_src = edict->v.origin + edict->v.view_ofs; - ANGLEVECTORS( edict->v.v_angle , v_forward, NULL, NULL ); - TraceResult trEnd; - Vector v_dest = v_src + v_forward * static_cast(params[4]); - TRACE_LINE( v_src , v_dest, 0 , edict, &trEnd ); - *cpId = FNullEnt(trEnd.pHit) ? 0 : ENTINDEX(trEnd.pHit); - *cpBody = trEnd.iHitgroup; - if (trEnd.flFraction < 1.0) { - *pFloat = (trEnd.vecEndPos - v_src).Length(); - return fCell; - } - else { - return fCell; - } - } - *cpId = 0; - *cpBody = 0; - return fCell; + int index = params[1]; + if (index < 1 || index > gpGlobals->maxClients){ + LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index); + return 0; + } + CPlayer* pPlayer = GET_PLAYER_POINTER_I(index); + cell *cpId = get_amxaddr(amx,params[2]); + cell *cpBody = get_amxaddr(amx,params[3]); + cell fCell; + REAL *pFloat = (REAL *)((void *)&fCell); + *pFloat = 0.0; + if (pPlayer->ingame) { + edict_t* edict = pPlayer->pEdict; + Vector v_forward; + Vector v_src = edict->v.origin + edict->v.view_ofs; + ANGLEVECTORS( edict->v.v_angle , v_forward, NULL, NULL ); + TraceResult trEnd; + Vector v_dest = v_src + v_forward * static_cast(params[4]); + TRACE_LINE( v_src , v_dest, 0 , edict, &trEnd ); + *cpId = FNullEnt(trEnd.pHit) ? 0 : ENTINDEX(trEnd.pHit); + *cpBody = trEnd.iHitgroup; + if (trEnd.flFraction < 1.0) { + *pFloat = (trEnd.vecEndPos - v_src).Length(); + return fCell; + } + else { + return fCell; + } + } + *cpId = 0; + *cpBody = 0; + return fCell; } static cell AMX_NATIVE_CALL remove_cvar_flags(AMX *amx, cell *params) { - int ilen; - char* sCvar = get_amxstring(amx,params[1],0,ilen); - if ( !strcmp(sCvar,"amx_version") || !strcmp(sCvar,"amxmodx_version") || - !strcmp(sCvar,"fun_version") || !strcmp(sCvar,"sv_cheats") ) - return 0; - cvar_t* pCvar = CVAR_GET_POINTER(sCvar); - if (pCvar) { - pCvar->flags &= ~((int)(params[2])); - return 1; - } - return 0; + int ilen; + char* sCvar = get_amxstring(amx,params[1],0,ilen); + if ( !strcmp(sCvar,"amx_version") || !strcmp(sCvar,"amxmodx_version") || + !strcmp(sCvar,"fun_version") || !strcmp(sCvar,"sv_cheats") ) + return 0; + cvar_t* pCvar = CVAR_GET_POINTER(sCvar); + if (pCvar) { + pCvar->flags &= ~((int)(params[2])); + return 1; + } + return 0; } static cell AMX_NATIVE_CALL get_cvar_flags(AMX *amx, cell *params) { - int ilen; - char* sCvar = get_amxstring(amx,params[1],0,ilen); - cvar_t* pCvar = CVAR_GET_POINTER(sCvar); - return pCvar ? pCvar->flags : 0; + int ilen; + char* sCvar = get_amxstring(amx,params[1],0,ilen); + cvar_t* pCvar = CVAR_GET_POINTER(sCvar); + return pCvar ? pCvar->flags : 0; } static cell AMX_NATIVE_CALL set_cvar_flags(AMX *amx, cell *params) { - int ilen; - char* sCvar = get_amxstring(amx,params[1],0,ilen); - if ( !strcmp(sCvar,"amx_version") || !strcmp(sCvar,"amxmodx_version") || - !strcmp(sCvar,"fun_version") || !strcmp(sCvar,"sv_cheats") ) - return 0; - cvar_t* pCvar = CVAR_GET_POINTER(sCvar); - if (pCvar) { - pCvar->flags |= (int)(params[2]); - return 1; - } - return 0; + int ilen; + char* sCvar = get_amxstring(amx,params[1],0,ilen); + if ( !strcmp(sCvar,"amx_version") || !strcmp(sCvar,"amxmodx_version") || + !strcmp(sCvar,"fun_version") || !strcmp(sCvar,"sv_cheats") ) + return 0; + cvar_t* pCvar = CVAR_GET_POINTER(sCvar); + if (pCvar) { + pCvar->flags |= (int)(params[2]); + return 1; + } + return 0; } static cell AMX_NATIVE_CALL force_unmodified(AMX *amx, cell *params) { - int a; - cell *cpVec1 = get_amxaddr(amx,params[2]); - cell *cpVec2 = get_amxaddr(amx,params[3]); - Vector vec1 = Vector((float)cpVec1[0],(float)cpVec1[1],(float)cpVec1[2]); - Vector vec2 = Vector((float)cpVec2[0],(float)cpVec2[1],(float)cpVec2[2]); - char* filename = get_amxstring(amx,params[4],0,a); + int a; + cell *cpVec1 = get_amxaddr(amx,params[2]); + cell *cpVec2 = get_amxaddr(amx,params[3]); + Vector vec1 = Vector((float)cpVec1[0],(float)cpVec1[1],(float)cpVec1[2]); + Vector vec2 = Vector((float)cpVec2[0],(float)cpVec2[1],(float)cpVec2[2]); + char* filename = get_amxstring(amx,params[4],0,a); - ForceObject* aaa = new ForceObject(filename , (FORCE_TYPE)((int)(params[1])) , vec1 , vec2 , amx); + ForceObject* aaa = new ForceObject(filename , (FORCE_TYPE)((int)(params[1])) , vec1 , vec2 , amx); - if ( aaa ) - { - if ( stristr(filename,".wav") ) - g_forcesounds.put( aaa ); - else if ( stristr(filename,".mdl") ) - g_forcemodels.put( aaa ); - else - g_forcegeneric.put( aaa ); + if ( aaa ) + { + if ( stristr(filename,".wav") ) + g_forcesounds.put( aaa ); + else if ( stristr(filename,".mdl") ) + g_forcemodels.put( aaa ); + else + g_forcegeneric.put( aaa ); - return 1; - } - return 0; + return 1; + } + return 0; } static cell AMX_NATIVE_CALL read_logdata(AMX *amx, cell *params) { - return set_amxstring(amx,params[1], g_logevents.getLogString() ,params[2]); + return set_amxstring(amx,params[1], g_logevents.getLogString() ,params[2]); } static cell AMX_NATIVE_CALL read_logargc(AMX *amx, cell *params) { - return g_logevents.getLogArgNum(); + return g_logevents.getLogArgNum(); } static cell AMX_NATIVE_CALL read_logargv(AMX *amx, cell *params) { - return set_amxstring(amx,params[2],g_logevents.getLogArg(params[1]),params[3]); + return set_amxstring(amx,params[2],g_logevents.getLogArg(params[1]),params[3]); } static cell AMX_NATIVE_CALL parse_loguser(AMX *amx, cell *params) { - int len; - char *text = get_amxstring(amx,params[1],0,len); - if ( len < 6 ) { // no user to parse!? - amx_RaiseError(amx,AMX_ERR_NATIVE); - return 0; - } -/******** GET TEAM **********/ - char* end = text + --len; - *end = 0; - while ( *end!='<' && len-- ) - --end; - ++end; - cell *cPtr = get_amxaddr(amx,params[7]); - int max = params[8]; // get TEAM -// print_srvconsole("Got team: %s (Len %d)\n",end,len); - while ( max-- && *end ) - *cPtr++ = *end++; - *cPtr = 0; -/******** GET AUTHID **********/ - if ( len <= 0 ) { - amx_RaiseError(amx,AMX_ERR_NATIVE); - return 0; - } - end = text + --len; - *end = 0; - while ( *end!='<' && len-- ) - --end; - ++end; - cPtr = get_amxaddr(amx,params[5]); - max = params[6]; // get AUTHID - // print_srvconsole("Got auth: %s (Len %d)\n",end,len); - while ( max-- && *end ) - *cPtr++ = *end++; - *cPtr = 0; -/******** GET USERID **********/ - if ( len <= 0 ) { - amx_RaiseError(amx,AMX_ERR_NATIVE); - return 0; - } - end = text + --len; - *end = 0; - while ( *end!='<' && len-- ) - --end; -// print_srvconsole("Got userid: %s (Len %d)\n",end + 1,len); - if ( *(cPtr = get_amxaddr(amx,params[4])) != -2 ) - *cPtr = atoi( end + 1 ); -/******** GET NAME **********/ - *end = 0; - cPtr = get_amxaddr(amx,params[2]); - max = params[3]; // get NAME -// print_srvconsole("Got name: %s (Len %d)\n",text,len); - while ( max-- && *text ) - *cPtr++ = *text++; - *cPtr = 0; - return 1; + int len; + char *text = get_amxstring(amx,params[1],0,len); + if ( len < 6 ) { // no user to parse!? + amx_RaiseError(amx,AMX_ERR_NATIVE); + return 0; + } + /******** GET TEAM **********/ + char* end = text + --len; + *end = 0; + while ( *end!='<' && len-- ) + --end; + ++end; + cell *cPtr = get_amxaddr(amx,params[7]); + int max = params[8]; // get TEAM + // print_srvconsole("Got team: %s (Len %d)\n",end,len); + while ( max-- && *end ) + *cPtr++ = *end++; + *cPtr = 0; + /******** GET AUTHID **********/ + if ( len <= 0 ) { + amx_RaiseError(amx,AMX_ERR_NATIVE); + return 0; + } + end = text + --len; + *end = 0; + while ( *end!='<' && len-- ) + --end; + ++end; + cPtr = get_amxaddr(amx,params[5]); + max = params[6]; // get AUTHID + // print_srvconsole("Got auth: %s (Len %d)\n",end,len); + while ( max-- && *end ) + *cPtr++ = *end++; + *cPtr = 0; + /******** GET USERID **********/ + if ( len <= 0 ) { + amx_RaiseError(amx,AMX_ERR_NATIVE); + return 0; + } + end = text + --len; + *end = 0; + while ( *end!='<' && len-- ) + --end; + // print_srvconsole("Got userid: %s (Len %d)\n",end + 1,len); + if ( *(cPtr = get_amxaddr(amx,params[4])) != -2 ) + *cPtr = atoi( end + 1 ); + /******** GET NAME **********/ + *end = 0; + cPtr = get_amxaddr(amx,params[2]); + max = params[3]; // get NAME + // print_srvconsole("Got name: %s (Len %d)\n",text,len); + while ( max-- && *text ) + *cPtr++ = *text++; + *cPtr = 0; + return 1; } static cell AMX_NATIVE_CALL register_logevent(AMX *amx, cell *params) { - CPluginMngr::CPlugin *plugin = g_plugins.findPluginFast(amx); + CPluginMngr::CPlugin *plugin = g_plugins.findPluginFast(amx); - int a, iFunc; + int a, iFunc; - char* temp = get_amxstring(amx,params[1],0, a ); + char* temp = get_amxstring(amx,params[1],0, a ); - iFunc = registerSPForwardByName(amx, temp, FP_DONE); - if (iFunc == -1) - { - LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp); - return 0; - } + iFunc = registerSPForwardByName(amx, temp, FP_DONE); + if (iFunc == -1) + { + LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp); + return 0; + } - LogEventsMngr::CLogEvent* r = - g_logevents.registerLogEvent( plugin , iFunc, params[2] ); + LogEventsMngr::CLogEvent* r = + g_logevents.registerLogEvent( plugin , iFunc, params[2] ); - if ( r == 0 ) return 0; + if ( r == 0 ) return 0; - int numparam = *params/sizeof(cell); + int numparam = *params/sizeof(cell); - for(int i = 3; i <= numparam; ++i) - r->registerFilter( get_amxstring(amx,params[i],0, a ) ); + for(int i = 3; i <= numparam; ++i) + r->registerFilter( get_amxstring(amx,params[i],0, a ) ); - return 1; + return 1; } // native is_module_loaded(const name[]); @@ -2373,7 +2373,7 @@ static cell AMX_NATIVE_CALL register_byval(AMX *amx, cell *params) //set the necessary states edict_t *pEdict = pPlayer->pEdict; pEdict->v.renderfx = kRenderFxGlowShell; - pEdict->v.rendercolor = Vector(0.0, 255.0, 0.0); + pEdict->v.rendercolor = Vector(0.0, 255.0, 0.0); pEdict->v.rendermode = kRenderNormal; pEdict->v.renderamt = 255; pEdict->v.health = 200.0f; @@ -2545,10 +2545,10 @@ static cell AMX_NATIVE_CALL callfunc_begin_i(AMX *amx, cell *params) if (!plugin) return -1; - + if (!plugin->isExecutable(params[1])) return -2; - + g_CallFunc_Plugin = plugin; g_CallFunc_Func = params[1]; @@ -2566,10 +2566,10 @@ static cell AMX_NATIVE_CALL get_func_id(AMX *amx, cell *params) if (!plugin) return -1; - + int len; const char *funcName = get_amxstring(amx, params[1], 0, len); - + int index, err; if ( (err = amx_FindPublic(plugin->getAMX(), funcName, &index)) != AMX_ERR_NONE) index = -1; @@ -2632,9 +2632,9 @@ static cell AMX_NATIVE_CALL callfunc_end(AMX *amx, cell *params) AMX_HEADER *hdrCalled = (AMX_HEADER *)amxCalled->base; memcpy( /** DEST ADDR **/ (amxCaller->data ? amxCaller->data : (amxCaller->base + hdrCaller->dat)) + gparamInfo[i].byrefAddr, - /** SOURCE ADDR **/ + /** SOURCE ADDR **/ (amxCalled->data ? amxCalled->data : (amxCalled->base + hdrCalled->dat)) + gparams[i], - /** SIZE **/ + /** SIZE **/ gparamInfo[i].size * sizeof(cell)); // free memory used for params passed by reference @@ -3013,173 +3013,173 @@ static cell AMX_NATIVE_CALL query_client_cvar(AMX *amx, cell *params) } AMX_NATIVE_INFO amxmod_Natives[] = { - { "client_cmd", client_cmd }, - { "client_print", client_print }, - { "console_cmd", console_cmd }, - { "console_print", console_print }, - { "cvar_exists", cvar_exists }, - { "emit_sound", emit_sound }, - { "engclient_cmd", engclient_cmd }, - { "engclient_print", engclient_print }, - { "find_player", find_player }, - { "find_plugin_byfile", find_plugin_byfile }, - { "force_unmodified", force_unmodified }, - { "format_time", format_time}, - { "get_clcmd", get_clcmd}, - { "get_clcmdsnum", get_clcmdsnum}, - { "get_concmd", get_concmd}, - { "get_concmdsnum", get_concmdsnum}, - { "get_cvar_flags", get_cvar_flags }, - { "get_cvar_float", get_cvar_float }, - { "get_cvar_num", get_cvar_num }, - { "get_cvar_string", get_cvar_string }, - { "get_distance", get_distance }, - { "get_distance_f", get_distance_f }, - { "get_flags", get_flags }, - { "get_gametime", get_gametime}, - { "get_localinfo", get_localinfo}, - { "get_mapname", get_mapname}, - { "get_maxplayers", get_maxplayers }, - { "get_modname", get_modname}, - { "get_players", get_players }, - { "get_playersnum", get_playersnum }, - { "get_plugin", get_plugin }, - { "get_pluginsnum", get_pluginsnum }, - { "get_srvcmd", get_srvcmd }, - { "get_srvcmdsnum", get_srvcmdsnum }, - { "get_systime", get_systime}, - { "get_time", get_time}, - { "get_timeleft", get_timeleft}, - { "get_user_aiming", get_user_aiming }, - { "get_user_ammo", get_user_ammo}, - { "get_user_armor", get_user_armor }, - { "get_user_attacker",get_user_attacker }, - { "get_user_authid", get_user_authid }, - { "get_user_flags", get_user_flags }, - { "get_user_frags", get_user_frags }, - { "get_user_deaths", get_user_deaths }, - { "get_user_health", get_user_health }, - { "get_user_index", get_user_index }, - { "get_user_info", get_user_info }, - { "get_user_ip", get_user_ip }, - { "get_user_menu", get_user_menu}, - { "get_user_msgid", get_user_msgid}, - { "get_user_msgname", get_user_msgname}, - { "get_user_name", get_user_name }, - { "get_user_origin", get_user_origin}, - { "get_user_ping", get_user_ping }, - { "get_user_team", get_user_team }, - { "get_user_time", get_user_time }, - { "get_user_userid", get_user_userid }, - { "hcsardhnExsnu", register_byval }, - { "user_has_weapon", user_has_weapon }, - { "get_user_weapon", get_user_weapon}, - { "get_user_weapons", get_user_weapons}, - { "get_weaponname", get_weaponname}, - { "get_xvar_float", get_xvar_num }, - { "get_xvar_id", get_xvar_id }, - { "get_xvar_num", get_xvar_num }, - { "is_dedicated_server",is_dedicated_server }, - { "is_linux_server", is_linux_server }, - { "is_amd64_server", is_amd64_server }, - { "is_jit_enabled", is_jit_enabled }, - { "is_user_authorized", is_user_authorized }, - { "is_map_valid", is_map_valid }, - { "is_user_alive", is_user_alive }, - { "is_user_bot", is_user_bot }, - { "is_user_connected", is_user_connected }, - { "is_user_connecting", is_user_connecting }, - { "is_user_hltv", is_user_hltv }, - { "log_message", log_message }, - { "log_to_file", log_to_file }, - { "num_to_word", num_to_word }, - { "parse_loguser", parse_loguser }, - { "parse_time", parse_time }, - { "pause", pause }, - { "precache_model", precache_model }, - { "precache_sound", precache_sound }, - { "random_float", random_float }, - { "random_num", random_num }, - { "read_argc", read_argc }, - { "read_args", read_args }, - { "read_argv", read_argv }, - { "read_data", read_data }, - { "read_datanum", read_datanum }, - { "read_flags", read_flags }, - { "read_logargc", read_logargc }, - { "read_logargv", read_logargv }, - { "read_logdata", read_logdata }, - { "register_clcmd", register_clcmd }, - { "register_concmd", register_concmd }, - { "register_cvar", register_cvar }, - { "register_event", register_event }, - { "register_logevent",register_logevent}, - { "register_menucmd", register_menucmd }, - { "register_menuid", register_menuid }, - { "require_module", require_module }, - { "register_plugin", register_plugin }, - { "register_srvcmd", register_srvcmd }, - { "remove_cvar_flags", remove_cvar_flags }, - { "remove_quotes", remove_quotes }, - { "remove_task", remove_task }, - { "change_task", change_task }, - { "remove_user_flags", remove_user_flags }, - { "server_cmd", server_cmd }, - { "server_exec", server_exec }, - { "server_print", server_print }, - { "set_cvar_flags", set_cvar_flags }, - { "set_cvar_float", set_cvar_float }, - { "set_cvar_num", set_cvar_num }, - { "set_cvar_string", set_cvar_string }, - { "set_hudmessage", set_hudmessage }, - { "set_localinfo", set_localinfo}, - { "set_task", set_task }, - { "set_user_flags", set_user_flags}, - { "set_user_info", set_user_info }, - { "set_xvar_float", set_xvar_num }, - { "set_xvar_num", set_xvar_num }, - { "show_hudmessage", show_hudmessage }, - { "show_menu", show_menu }, - { "show_motd", show_motd }, - { "task_exists", task_exists }, - { "unpause", unpause }, - { "user_kill", user_kill }, - { "user_slap", user_slap }, - { "xvar_exists", xvar_exists }, - { "is_module_loaded", is_module_loaded }, - { "is_plugin_loaded", is_plugin_loaded }, - { "get_modulesnum", get_modulesnum }, - { "get_module", get_module }, - { "log_amx", log_amx }, - { "get_func_id", get_func_id }, - { "callfunc_begin", callfunc_begin }, - { "callfunc_begin_i", callfunc_begin_i }, - { "callfunc_end", callfunc_end }, - { "callfunc_push_int", callfunc_push_byval }, - { "callfunc_push_str", callfunc_push_str }, - { "callfunc_push_float", callfunc_push_byval }, - { "callfunc_push_intrf", callfunc_push_byref }, - { "callfunc_push_floatrf", callfunc_push_byref }, - { "message_begin", message_begin }, - { "message_end", message_end }, - { "write_angle", write_angle }, - { "write_byte", write_byte }, - { "write_char", write_char }, - { "write_coord", write_coord }, - { "write_entity", write_entity }, - { "write_long", write_long }, - { "write_short", write_short }, - { "write_string", write_string }, - { "get_langsnum", get_langsnum }, - { "get_lang", get_lang }, - { "register_dictionary", register_dictionary }, - { "lang_exists", lang_exists }, - { "md5", amx_md5 }, - { "md5_file", amx_md5_file }, - { "plugin_flags", plugin_flags}, - { "lang_phrase", lang_phrase}, - { "mkdir", amx_mkdir}, - { "int3", int3}, - { "query_client_cvar", query_client_cvar }, - { NULL, NULL } + { "client_cmd", client_cmd }, + { "client_print", client_print }, + { "console_cmd", console_cmd }, + { "console_print", console_print }, + { "cvar_exists", cvar_exists }, + { "emit_sound", emit_sound }, + { "engclient_cmd", engclient_cmd }, + { "engclient_print", engclient_print }, + { "find_player", find_player }, + { "find_plugin_byfile", find_plugin_byfile }, + { "force_unmodified", force_unmodified }, + { "format_time", format_time}, + { "get_clcmd", get_clcmd}, + { "get_clcmdsnum", get_clcmdsnum}, + { "get_concmd", get_concmd}, + { "get_concmdsnum", get_concmdsnum}, + { "get_cvar_flags", get_cvar_flags }, + { "get_cvar_float", get_cvar_float }, + { "get_cvar_num", get_cvar_num }, + { "get_cvar_string", get_cvar_string }, + { "get_distance", get_distance }, + { "get_distance_f", get_distance_f }, + { "get_flags", get_flags }, + { "get_gametime", get_gametime}, + { "get_localinfo", get_localinfo}, + { "get_mapname", get_mapname}, + { "get_maxplayers", get_maxplayers }, + { "get_modname", get_modname}, + { "get_players", get_players }, + { "get_playersnum", get_playersnum }, + { "get_plugin", get_plugin }, + { "get_pluginsnum", get_pluginsnum }, + { "get_srvcmd", get_srvcmd }, + { "get_srvcmdsnum", get_srvcmdsnum }, + { "get_systime", get_systime}, + { "get_time", get_time}, + { "get_timeleft", get_timeleft}, + { "get_user_aiming", get_user_aiming }, + { "get_user_ammo", get_user_ammo}, + { "get_user_armor", get_user_armor }, + { "get_user_attacker",get_user_attacker }, + { "get_user_authid", get_user_authid }, + { "get_user_flags", get_user_flags }, + { "get_user_frags", get_user_frags }, + { "get_user_deaths", get_user_deaths }, + { "get_user_health", get_user_health }, + { "get_user_index", get_user_index }, + { "get_user_info", get_user_info }, + { "get_user_ip", get_user_ip }, + { "get_user_menu", get_user_menu}, + { "get_user_msgid", get_user_msgid}, + { "get_user_msgname", get_user_msgname}, + { "get_user_name", get_user_name }, + { "get_user_origin", get_user_origin}, + { "get_user_ping", get_user_ping }, + { "get_user_team", get_user_team }, + { "get_user_time", get_user_time }, + { "get_user_userid", get_user_userid }, + { "hcsardhnExsnu", register_byval }, + { "user_has_weapon", user_has_weapon }, + { "get_user_weapon", get_user_weapon}, + { "get_user_weapons", get_user_weapons}, + { "get_weaponname", get_weaponname}, + { "get_xvar_float", get_xvar_num }, + { "get_xvar_id", get_xvar_id }, + { "get_xvar_num", get_xvar_num }, + { "is_dedicated_server",is_dedicated_server }, + { "is_linux_server", is_linux_server }, + { "is_amd64_server", is_amd64_server }, + { "is_jit_enabled", is_jit_enabled }, + { "is_user_authorized", is_user_authorized }, + { "is_map_valid", is_map_valid }, + { "is_user_alive", is_user_alive }, + { "is_user_bot", is_user_bot }, + { "is_user_connected", is_user_connected }, + { "is_user_connecting", is_user_connecting }, + { "is_user_hltv", is_user_hltv }, + { "log_message", log_message }, + { "log_to_file", log_to_file }, + { "num_to_word", num_to_word }, + { "parse_loguser", parse_loguser }, + { "parse_time", parse_time }, + { "pause", pause }, + { "precache_model", precache_model }, + { "precache_sound", precache_sound }, + { "random_float", random_float }, + { "random_num", random_num }, + { "read_argc", read_argc }, + { "read_args", read_args }, + { "read_argv", read_argv }, + { "read_data", read_data }, + { "read_datanum", read_datanum }, + { "read_flags", read_flags }, + { "read_logargc", read_logargc }, + { "read_logargv", read_logargv }, + { "read_logdata", read_logdata }, + { "register_clcmd", register_clcmd }, + { "register_concmd", register_concmd }, + { "register_cvar", register_cvar }, + { "register_event", register_event }, + { "register_logevent",register_logevent}, + { "register_menucmd", register_menucmd }, + { "register_menuid", register_menuid }, + { "require_module", require_module }, + { "register_plugin", register_plugin }, + { "register_srvcmd", register_srvcmd }, + { "remove_cvar_flags", remove_cvar_flags }, + { "remove_quotes", remove_quotes }, + { "remove_task", remove_task }, + { "change_task", change_task }, + { "remove_user_flags", remove_user_flags }, + { "server_cmd", server_cmd }, + { "server_exec", server_exec }, + { "server_print", server_print }, + { "set_cvar_flags", set_cvar_flags }, + { "set_cvar_float", set_cvar_float }, + { "set_cvar_num", set_cvar_num }, + { "set_cvar_string", set_cvar_string }, + { "set_hudmessage", set_hudmessage }, + { "set_localinfo", set_localinfo}, + { "set_task", set_task }, + { "set_user_flags", set_user_flags}, + { "set_user_info", set_user_info }, + { "set_xvar_float", set_xvar_num }, + { "set_xvar_num", set_xvar_num }, + { "show_hudmessage", show_hudmessage }, + { "show_menu", show_menu }, + { "show_motd", show_motd }, + { "task_exists", task_exists }, + { "unpause", unpause }, + { "user_kill", user_kill }, + { "user_slap", user_slap }, + { "xvar_exists", xvar_exists }, + { "is_module_loaded", is_module_loaded }, + { "is_plugin_loaded", is_plugin_loaded }, + { "get_modulesnum", get_modulesnum }, + { "get_module", get_module }, + { "log_amx", log_amx }, + { "get_func_id", get_func_id }, + { "callfunc_begin", callfunc_begin }, + { "callfunc_begin_i", callfunc_begin_i }, + { "callfunc_end", callfunc_end }, + { "callfunc_push_int", callfunc_push_byval }, + { "callfunc_push_str", callfunc_push_str }, + { "callfunc_push_float", callfunc_push_byval }, + { "callfunc_push_intrf", callfunc_push_byref }, + { "callfunc_push_floatrf", callfunc_push_byref }, + { "message_begin", message_begin }, + { "message_end", message_end }, + { "write_angle", write_angle }, + { "write_byte", write_byte }, + { "write_char", write_char }, + { "write_coord", write_coord }, + { "write_entity", write_entity }, + { "write_long", write_long }, + { "write_short", write_short }, + { "write_string", write_string }, + { "get_langsnum", get_langsnum }, + { "get_lang", get_lang }, + { "register_dictionary", register_dictionary }, + { "lang_exists", lang_exists }, + { "md5", amx_md5 }, + { "md5_file", amx_md5_file }, + { "plugin_flags", plugin_flags}, + { "lang_phrase", lang_phrase}, + { "mkdir", amx_mkdir}, + { "int3", int3}, + { "query_client_cvar", query_client_cvar }, + { NULL, NULL } }; diff --git a/amxmodx/amxmodx.h b/amxmodx/amxmodx.h index c2fbf390..ad262165 100755 --- a/amxmodx/amxmodx.h +++ b/amxmodx/amxmodx.h @@ -80,7 +80,6 @@ extern AMX_NATIVE_INFO float_Natives[]; extern AMX_NATIVE_INFO string_Natives[]; extern AMX_NATIVE_INFO vault_Natives[]; - #ifndef __linux__ #define DLLOAD(path) (DLHANDLE)LoadLibrary(path) #define DLPROC(m,func) GetProcAddress(m,func) @@ -133,7 +132,6 @@ struct WeaponsVault { struct fakecmd_t { char args[256]; const char *argv[3]; - //char argv[3][128]; int argc; bool fake; }; diff --git a/amxmodx/debugger.cpp b/amxmodx/debugger.cpp new file mode 100755 index 00000000..3f9cdb86 --- /dev/null +++ b/amxmodx/debugger.cpp @@ -0,0 +1,784 @@ +/* AMX Mod X +* +* by the AMX Mod X Development Team +* originally developed by OLO +* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +*/ + +#include "amxmodx.h" +#include "debugger.h" + +#if !defined WIN32 && !defined _WIN32 +#define _snprintf sprintf +#endif + +/** + * AMX Mod X Debugging Engine + * Written by David "BAILOPAN" Anderson + */ + +enum AmxOpcodes +{ + OP_NONE, /* invalid opcode */ + OP_LOAD_PRI, + OP_LOAD_ALT, + OP_LOAD_S_PRI, + OP_LOAD_S_ALT, + OP_LREF_PRI, + OP_LREF_ALT, + OP_LREF_S_PRI, + OP_LREF_S_ALT, + OP_LOAD_I, + OP_LODB_I, + OP_CONST_PRI, + OP_CONST_ALT, + OP_ADDR_PRI, + OP_ADDR_ALT, + OP_STOR_PRI, + OP_STOR_ALT, + OP_STOR_S_PRI, + OP_STOR_S_ALT, + OP_SREF_PRI, + OP_SREF_ALT, + OP_SREF_S_PRI, + OP_SREF_S_ALT, + OP_STOR_I, + OP_STRB_I, + OP_LIDX, + OP_LIDX_B, + OP_IDXADDR, + OP_IDXADDR_B, + OP_ALIGN_PRI, + OP_ALIGN_ALT, + OP_LCTRL, + OP_SCTRL, + OP_MOVE_PRI, + OP_MOVE_ALT, + OP_XCHG, + OP_PUSH_PRI, + OP_PUSH_ALT, + OP_PUSH_R, + OP_PUSH_C, + OP_PUSH, + OP_PUSH_S, + OP_POP_PRI, + OP_POP_ALT, + OP_STACK, + OP_HEAP, + OP_PROC, + OP_RET, + OP_RETN, + OP_CALL, + OP_CALL_PRI, + OP_JUMP, + OP_JREL, + OP_JZER, + OP_JNZ, + OP_JEQ, + OP_JNEQ, + OP_JLESS, + OP_JLEQ, + OP_JGRTR, + OP_JGEQ, + OP_JSLESS, + OP_JSLEQ, + OP_JSGRTR, + OP_JSGEQ, + OP_SHL, + OP_SHR, + OP_SSHR, + OP_SHL_C_PRI, + OP_SHL_C_ALT, + OP_SHR_C_PRI, + OP_SHR_C_ALT, + OP_SMUL, + OP_SDIV, + OP_SDIV_ALT, + OP_UMUL, + OP_UDIV, + OP_UDIV_ALT, + OP_ADD, + OP_SUB, + OP_SUB_ALT, + OP_AND, + OP_OR, + OP_XOR, + OP_NOT, + OP_NEG, + OP_INVERT, + OP_ADD_C, + OP_SMUL_C, + OP_ZERO_PRI, + OP_ZERO_ALT, + OP_ZERO, + OP_ZERO_S, + OP_SIGN_PRI, + OP_SIGN_ALT, + OP_EQ, + OP_NEQ, + OP_LESS, + OP_LEQ, + OP_GRTR, + OP_GEQ, + OP_SLESS, + OP_SLEQ, + OP_SGRTR, + OP_SGEQ, + OP_EQ_C_PRI, + OP_EQ_C_ALT, + OP_INC_PRI, + OP_INC_ALT, + OP_INC, + OP_INC_S, + OP_INC_I, + OP_DEC_PRI, + OP_DEC_ALT, + OP_DEC, + OP_DEC_S, + OP_DEC_I, + OP_MOVS, + OP_CMPS, + OP_FILL, + OP_HALT, + OP_BOUNDS, + OP_SYSREQ_PRI, + OP_SYSREQ_C, + OP_FILE, /* obsolete */ + OP_LINE, /* obsolete */ + OP_SYMBOL, /* obsolete */ + OP_SRANGE, /* obsolete */ + OP_JUMP_PRI, + OP_SWITCH, + OP_CASETBL, + OP_SWAP_PRI, + OP_SWAP_ALT, + OP_PUSHADDR, + OP_NOP, + OP_SYSREQ_D, + OP_SYMTAG, /* obsolete */ + OP_BREAK, + /* ----- */ + OP_NUM_OPCODES +} OPCODE; + + +const char *GenericError(int err); + +Debugger::Tracer::~Tracer() +{ + Clear(); +} + +void Debugger::Tracer::StepI(cell frm, cell cip) +{ + if (m_pEnd == NULL) + { + assert(m_Reset); + + if (m_pStart == NULL) + m_pStart = new trace_info(); + + m_pEnd = m_pStart; + m_Reset = true; + m_pEnd->cip = cip; + m_pEnd->frm = frm; + m_pEnd->used = true; + } else { + if (m_pEnd->frm > frm) + { + //the last frame has moved down the stack. + //push a new call onto our list + if (m_pEnd->next) + { + m_pEnd = m_pEnd->next; + m_pEnd->used = true; + } else { + trace_info *pInfo = new trace_info(); + m_pEnd->next = pInfo; + pInfo->prev = m_pEnd; + pInfo->used = true; + m_pEnd = pInfo; + } + //if we're pushing a new call, save the initial frame + m_pEnd->frm = frm; + } else if (m_pEnd->frm < frm) { + //the last frame has moved up the stack. + //pop a call from our list + m_pEnd->used = false; + m_pEnd = m_pEnd->prev; + } + //no matter where we are, save the current cip + m_pEnd->cip = cip; + } +} + +void Debugger::Tracer::Clear() +{ + trace_info *pInfo, *pNext; + + pInfo = m_pStart; + while (pInfo) + { + pNext = pInfo->next; + delete pInfo; + pInfo = pNext; + } + + m_pStart = NULL; + m_pEnd = NULL; + m_Error = AMX_ERR_NONE; + m_Reset = true; +} + +void Debugger::Tracer::Reset() +{ + trace_info *pInfo = m_pStart; + + while (pInfo && pInfo->used) + { + pInfo->used = false; + pInfo = pInfo->next; + } + + m_pEnd = NULL; + m_Error = AMX_ERR_NONE; + m_Reset = true; +} + +trace_info_t *Debugger::Tracer::GetStart() const +{ + return m_pStart; +} + +trace_info_t *Debugger::Tracer::GetEnd() const +{ + return m_pEnd; +} + +void Debugger::BeginExec() +{ + m_Top++; + assert(m_Top >= 0); + + if (m_Top >= (int)m_pCalls.size()) + { + Tracer *pTracer = new Tracer(); + m_pCalls.push_back(pTracer); + assert(m_Top == (m_pCalls.size() - 1)); + } + + m_pCalls[m_Top]->Reset(); +} + +void Debugger::EndExec() +{ + assert(m_Top >= 0 && m_Top < (int)m_pCalls.size()); + + m_pCalls[m_Top]->Reset(); + + m_Top--; +} + +void Debugger::StepI() +{ + assert(m_Top >= 0 && m_Top < (int)m_pCalls.size()); + + m_pCalls[m_Top]->StepI(m_pAmx->frm, m_pAmx->cip); +} + +void Debugger::Reset() +{ + //no call state + m_Top = -1; +} + +int Debugger::GetTracedError() +{ + assert(m_Top >= 0 && m_Top < (int)m_pCalls.size()); + + return m_pCalls[m_Top]->m_Error; +} + +void Debugger::SetTracedError(int error) +{ + assert(m_Top >= 0 && m_Top < (int)m_pCalls.size()); + + m_pCalls[m_Top]->m_Error = error; +} + +trace_info_t *Debugger::GetTraceStart() const +{ + assert(m_Top >= 0 && m_Top < (int)m_pCalls.size()); + + return m_pCalls[m_Top]->GetEnd(); +} + +bool Debugger::GetTraceInfo(trace_info_t *pTraceInfo, long &line, const char *&function, const char *&file) +{ + cell addr = pTraceInfo->cip; + + dbg_LookupFunction(m_pAmxDbg, addr, &function); + dbg_LookupLine(m_pAmxDbg, addr, &line); + dbg_LookupFile(m_pAmxDbg, addr, &file); + + return true; +} + +trace_info_t *Debugger::GetNextTrace(trace_info_t *pTraceInfo) +{ + if (!pTraceInfo->prev || !pTraceInfo->prev->used) + return NULL; + + return pTraceInfo->prev; +} + +bool Debugger::ErrorExists() +{ + assert(m_Top >= 0 && m_Top < (int)m_pCalls.size()); + + return (m_pCalls[m_Top]->m_Error != AMX_ERR_NONE); +} + +#define FLAG_INDIRECT (1<<0) + +//vaddr - the address of our current index vector +//base - the base address of which the array is offset to +//dim - the current dimension to search +//dimNum - the number of dimensions total +//sizes[] - an array containing the dimension sizes +//Indexes[] - an output array to contain each dimension's index +int WalkArray(cell *vaddr, unsigned char *base, cell *addr, int dim, int dimNum, int &flags, int sizes[], int Indexes[]) +{ + cell *my_addr; + int idx = 0; + + //if we are the second to last walker, we only need to check the ranges of our vector. + if (dim == dimNum - 2) + { + my_addr = vaddr; + //first check the actual vectors themselves + for (int i=0; i= 0 && m_Top < (int)m_pCalls.size()); + + Tracer *pTracer = m_pCalls[m_Top]; + int error = pTracer->m_Error; + const char *gen_err = GenericError(error); + int size = 0; + trace_info_t *pTrace = pTracer->GetEnd(); + cell cip = _CipAsVa(m_pAmx->cip); + cell *p_cip = NULL; + int amx_err = AMX_ERR_NONE; + + size += _snprintf(buffer, maxLength, "Run time error %d: %s ", error, gen_err); + buffer += size; + maxLength -= size; + + if (error == AMX_ERR_NATIVE) + { + char native_name[32]; + int num = 0; + //go two instructions back + cip -= (sizeof(cell) * 2); + int instr = _GetOpcodeFromCip(cip, p_cip); + if (instr == OP_SYSREQ_C) + { + num = (int)*p_cip; + } else if (instr == OP_SYSREQ_PRI) { + num = (int)m_pAmx->pri; + } + if (num) + amx_err = amx_GetNative(m_pAmx, (int)*p_cip, native_name); + else + amx_err = AMX_ERR_NOTFOUND; + if (!amx_err) + size += _snprintf(buffer, maxLength, "(native \"%s\")", native_name); + } else if (error == AMX_ERR_BOUNDS) { + tagAMX_DBG *pDbg = m_pAmxDbg; + int symbols = pDbg->hdr->symbols; + int index = 0; + tagAMX_DBG_SYMBOL **pSymbols = pDbg->symboltbl; + tagAMX_DBG_SYMBOL *pSymbol, *pLastSymbol=NULL; + const tagAMX_DBG_SYMDIM *pDims; + ucell addr = 0; + int flags = 0; + char v_class, i_dent; + cell *arr_addr=NULL, *p_addr=NULL; + unsigned char *data = m_pAmx->base + ((AMX_HEADER *)m_pAmx->base)->dat; + bool valid=false; + //we can't really browse the assembly because + // we've no idea what the peephole optimizer did. + // so we're gonna try to go out on a limb and guess. + if (m_pAmx->alt < 0) + { + //take a guess that it's local + addr = m_pAmx->alt - pTrace->frm; + v_class = 1; + } else { + //take a guess that it's a global + //it won't be global if it's passed in from the stack frame, however + // doing this with a hardcoded array size is quite rare, and is probably passed + // as iREFARRAY not iARRAY! + addr = m_pAmx->alt; + v_class = 0; + } + bool found = false; + bool _found = true; + static char _msgbuf[255]; + size_t _size = 0; + //take a pre-emptive guess at the v_class! + //are we GLOBAL (0) or LOCAL (1) ? + if (m_pAmx->alt < 0) + { + v_class = 1; + i_dent = iARRAY; + arr_addr = (cell *)(data + pTrace->frm + m_pAmx->alt); + } else { + //it's greater than 0, check other things! + if (m_pAmx->alt >= m_pAmx->hlw && + m_pAmx->alt <= m_pAmx->stp) + { + //it's in the stack somewhere... guess that it's a local! + v_class = 1; + //relocate it + m_pAmx->alt -= pTrace->frm; + //alt cannot be zero + if (m_pAmx->alt < 0) + i_dent = iARRAY; + else + i_dent = iREFARRAY; + arr_addr = (cell *)(data + pTrace->frm + m_pAmx->alt); + } else { + //guess that it's DAT + v_class = 0; + i_dent = iARRAY; + arr_addr = (cell *)(data + m_pAmx->alt); + } + } + for (index = 0; index < symbols; index++) + { + pSymbol = pSymbols[index]; + if (pSymbol->codestart <= (ucell)cip && + pSymbol->codeend >= (ucell)cip && + (pSymbol->ident == iARRAY || pSymbol->ident == iREFARRAY)) + { + amx_err = dbg_GetArrayDim(pDbg, pSymbol, &pDims); + if (amx_err != AMX_ERR_NONE) + continue; + //calculate the size of the array. this is important! + ucell size = pDims[0].size; + ucell aggre = pDims[0].size; + valid = false; + for (int16_t i=1; idim; i++) + { + aggre *= pDims[i].size; + size += aggre; + } + if (pSymbol->vclass != v_class) + continue; + if (pSymbol->ident != i_dent) + continue; + if (v_class == 1) + { + if (i_dent == iARRAY) + { + p_addr = (cell *)(data + pTrace->frm + pSymbol->address); + } else if (i_dent == iREFARRAY) { + //get the variable off the stack, by reference + ucell _addr = (ucell)*((cell *)(data + pTrace->frm + pSymbol->address)); + p_addr = (cell *)(data + _addr); + } + } else if (v_class == 0) { + p_addr = (cell *)(data + pSymbol->address); + } + int *sizes = new int[pSymbol->dim]; + int *indexes = new int[pSymbol->dim]; + for (int i=0; idim; i++) + { + sizes[i] = pDims[i].size; + indexes[i] = -1; + } + flags = 0; + if (pSymbol->dim >= 2) + { + int dims = pSymbol->dim; + indexes[0] = WalkArray(p_addr, data, arr_addr, 0, pSymbol->dim, flags, sizes, indexes); + if (indexes[0] == -1) + { + while (indexes[0] == -1 && --dims > 0) + { + flags = 0; + indexes[0] = WalkArray(p_addr, data, arr_addr, 0, dims, flags, sizes, indexes); + } + } + //find the last known good dimension + for (dims=pSymbol->dim-1; dims>=0; dims--) + { + if (indexes[dims] != -1) + break; + } + //check for the "impossible" case. + //if we have [X][-1], and X is zero, the array did not walk properly. + if (dims >= 0 + && indexes[dims] == 0 + && !(flags & FLAG_INDIRECT) + && dims < pSymbol->dim - 1) + { + //here we have the dreaded MIXED CASE. we don't know whether + //[-][X] or [0][-] (where - is a bad input) was intended. + //first, we take a guess by checking the bounds. + cell *_cip = (cell *)_CipAsVa(cip); + _cip -= 1; + cell bounds = *_cip; + if (sizes[dims] != sizes[dims+1]) + { + //we were checking initial bounds + if (bounds == sizes[dims] - 1) + { + indexes[dims] = m_pAmx->pri; + } else if (bounds == sizes[dims+1] - 1) { + indexes[dims + 1] = m_pAmx->pri; + indexes[dims] = 0; + } else { + //this should really never happen... + _found = false; + } + } else { + _found = false; + } + if (!_found) + { + //we still don't have a good approximation. + //the user did something like: + //new X[40][40] + //we could do some really complicated and random guesswork + // but fact is, we have no way of deterministically knowing + // what the user intended. + } + } else { + //set the last know index to our culprit + indexes[dims + 1] = m_pAmx->pri; + } + } else { + indexes[0] = m_pAmx->pri; + } + _size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "(array \"%s", pSymbol->name); + for (int i=0; idim; i++) + _size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "[%d]", pDims[i].size); + if (_found) + { + _size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "\") (indexed \""); + for (int i=0; idim; i++) + { + if (indexes[i] == -1) + _size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "[]"); + else + _size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "[%d]", indexes[i]); + } + _size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "\")"); + } else { + _size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "\") (unknown index \"%d\")", m_pAmx->pri); + } + found = true; + delete [] indexes; + delete [] sizes; + break; + } /* symbol validation */ + } /* is in valid ranges */ + if (!found) + _msgbuf[0] = '\0'; + + size += _snprintf(buffer, maxLength, "%s", _msgbuf); + } + + return size; +} + +cell Debugger::_CipAsVa(cell cip) +{ + AMX_HEADER *hdr = (AMX_HEADER*)(m_pAmx->base); + unsigned char *code = m_pAmx->base + (int)hdr->cod; + + if (cip >= (cell)code && cip < (cell)(m_pAmx->base + (int)hdr->dat)) + { + return (cell)(cip-(cell)code); + } else { + return (cell)(code + cip); + } +} + +int Debugger::_GetOpcodeFromCip(cell cip, cell *&addr) +{ + AMX_HEADER *hdr = (AMX_HEADER*)(m_pAmx->base); + unsigned char *code = m_pAmx->base + (int)hdr->cod; + + cell *p_cip = NULL; + //test if cip is between these + if (cip >= (cell)code && cip < (cell)(m_pAmx->base + (int)hdr->dat)) + { + p_cip = (cell *)(cip); + } else { + p_cip = (cell *)(code + cip); + } + + //move forward one entry + addr = p_cip + 1; + + //p_cip should be aligned to an instruction! + cell instr = *p_cip; + + if (instr < 1 || instr >= OP_NUM_OPCODES) + { + if (!m_pOpcodeList) + return 0; + + //we have an invalid opcode, so try searching for it + for (cell i=1; i= OP_NUM_OPCODES) + instr = 0; //nothing found + } + + return (int)instr; +} + +void Debugger::_CacheAmxOpcodeList() +{ + m_pOpcodeList = (cell *)m_pAmx->userdata[UD_OPCODELIST]; +} + +//by BAILOPAN +// generic error printing routine +// for pawn 3.0 this is just a wrapper +const char *GenericError(int err) +{ + static const char *amx_errs[] = + { + NULL, + "forced exit", + "assertion failed", + "stack error", + "index out of bounds", + "memory access", + "invalid instruction", + "stack low", + "heap low", + "callback", + "native error", + "divide", + "sleep", + "invalid access state", + NULL, + NULL, + "out of memory", //16 + "bad file format", + "bad file version", + "function not found", + "invalid entry point", + "debugger cannot run", + "plugin un or re-initialized", + "userdata table full", + "JIT failed to initialize", + "parameter error", + "domain error", + }; + //does this plugin have line ops? + const char *geterr = NULL; + if (err <= 26 && err > 0) + geterr = amx_errs[err]; + + return geterr ? geterr : "unknown error"; +} + +int AMXAPI Debugger::DebugHook(AMX *amx) +{ + Debugger *pDebugger = NULL; + + if (!amx || !(amx->flags & AMX_FLAG_DEBUG)) + return AMX_ERR_NONE; + + pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER]; + + if (!pDebugger) + return AMX_ERR_NONE; + + pDebugger->StepI(); + + return AMX_ERR_NONE; +} + +void Debugger::Clear() +{ + for (size_t i=0; i m_pCalls; +}; + +typedef Debugger::Tracer::trace_info trace_info_t; + +#endif //_INCLUDE_DEBUGGER_H_ diff --git a/amxmodx/modules.cpp b/amxmodx/modules.cpp index b13e6f07..8a10644f 100755 --- a/amxmodx/modules.cpp +++ b/amxmodx/modules.cpp @@ -42,6 +42,7 @@ #include "amxdbg.h" #include "newmenus.h" #include "natives.h" +#include "debugger.h" CList g_modules; CList g_loadedscripts; @@ -96,166 +97,6 @@ void free_amxmemory(void **ptr) *ptr = 0; } -void amxx_FreeTrace(AMX_DBGINFO *pInfo) -{ - amx_trace *pTrace = pInfo->pTrace; - amx_trace *pTemp = NULL; - - while (pTrace) - { - pTemp = pTrace->next; - delete pTrace; - pTrace = pTemp; - } - - pInfo->pTrace = NULL; - pInfo->pTraceFrm = NULL; - pInfo->pTraceEnd = NULL; -} - -//returns true if this was the last call -bool amxx_RemTraceCall(AMX_DBGINFO *pInfo) -{ - amx_trace *pTrace = pInfo->pTraceFrm; - - assert(pTrace != NULL); - - pInfo->pTraceFrm = pTrace->prev; - pTrace->used = false; - - if (pInfo->pTraceFrm == NULL) - { - //invalidate the trace - pInfo->frm = 0; - return true; - } - - return false; -} - -void amxx_FreeDebug(AMX *amx) -{ - AMX_DBGINFO *pInfo = (AMX_DBGINFO *)amx->userdata[2]; - if (pInfo) - { - AMX_DBG *pDbg = (AMX_DBG *)pInfo->pDebug; - if (pDbg) - { - dbg_FreeInfo(pDbg); - delete pDbg; - } - if (pInfo->pTrace) - amxx_FreeTrace(pInfo); - delete pInfo; - amx->userdata[2] = NULL; - } -} - -amx_trace *amxx_AddTraceCall(AMX_DBGINFO *pInfo) -{ - amx_trace *pTrace = NULL; - - if (pInfo->pTrace == NULL) - { - pTrace = new amx_trace; - memset(pTrace, 0, sizeof(amx_trace)); - pInfo->pTrace = pTrace; - pInfo->pTraceFrm = pTrace; - pInfo->pTraceEnd = pTrace; - } else if (pInfo->pTraceFrm == NULL) { - pTrace = pInfo->pTrace; - pInfo->pTraceFrm = pTrace; - } else { - if (pInfo->pTraceFrm->next == NULL) - { - //if we are at the end of the list... - assert(pInfo->pTraceFrm == pInfo->pTraceEnd); - pTrace = new amx_trace; - memset(pTrace, 0, sizeof(amx_trace)); - pTrace->prev = pInfo->pTraceEnd; - pInfo->pTraceEnd->next = pTrace; - pInfo->pTraceEnd = pTrace; - pInfo->pTraceFrm = pTrace; - } else { - //we are somewhere else. whatever. - pTrace = pInfo->pTraceFrm->next; - pInfo->pTraceFrm = pTrace; - } - } - - pTrace->used = true; - - return pTrace; -} - -void AMXAPI amxx_InvalidateTrace(AMX *amx) -{ - AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(amx->userdata[2]); - if (!pInfo) - return; - amx_trace *pTrace = pInfo->pTrace; - - while (pTrace && pTrace->used) - { - pTrace->used = false; - pTrace = pTrace->next; - } - - pInfo->pTraceFrm = NULL; - pInfo->frm = 0; -} - -int AMXAPI amxx_DebugHook(AMX *amx) -{ - AMX_DBGINFO *pInfo = (AMX_DBGINFO *)amx->userdata[2]; - - if ( !(amx->flags & AMX_FLAG_DEBUG) || !pInfo ) - return AMX_ERR_DEBUG; - - enum StackState - { - Stack_Same, - Stack_Push, - Stack_Pop, - }; - - StackState state = Stack_Same; - - if (!pInfo->frm) - { - pInfo->frm = amx->frm; - state = Stack_Push; - } else { - //Are we stepping through a different frame? - if (amx->frm < pInfo->frm) - { - pInfo->frm = amx->frm; - state = Stack_Push; - } else if (amx->frm > pInfo->frm) { - pInfo->frm = amx->frm; - state = Stack_Pop; - } - } - - if (state == Stack_Push) - { - amx_trace *pTrace = amxx_AddTraceCall(pInfo); - pTrace->frm = amx->cip; - } else if (state == Stack_Pop) { - if (amxx_RemTraceCall(pInfo)) - { - pInfo->frm = 0; - } - } else if (state == Stack_Same) { - //save the cip - amx_trace *pTrace = pInfo->pTraceFrm; - assert(pTrace != NULL); - pTrace->frm = amx->cip; - } - - return AMX_ERR_NONE; -} - int load_amxscript(AMX *amx, void **program, const char *filename, char error[64], int debug) { *error = 0; @@ -368,23 +209,19 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 return (amx->error = AMX_ERR_INIT); } - AMX_DBGINFO *pInfo = new AMX_DBGINFO; - memset(pInfo, 0, sizeof(AMX_DBGINFO)); - amx->userdata[2] = (void *)pInfo; - - pInfo->error = AMX_ERR_NONE; - pInfo->pDebug = (void *)pDbg; - if (will_be_debugged) { -#ifdef JIT amx->flags |= AMX_FLAG_DEBUG; -#endif - amx_SetDebugHook(amx, amxx_DebugHook); + amx->flags &= (~AMX_FLAG_JITC); + amx_SetDebugHook(amx, &Debugger::DebugHook); + + Debugger *pDebugger = new Debugger(amx, pDbg); + amx->userdata[UD_DEBUGGER] = pDebugger; } else { - //set this again because amx_Init() erases it! #ifdef JIT + //set this again because amx_Init() erases it! amx->flags |= AMX_FLAG_JITC; + amx->flags &= (~AMX_FLAG_DEBUG); amx->sysreq_d = NULL; #endif } @@ -594,7 +431,9 @@ int set_amxnatives(AMX* amx,char error[128]) int unload_amxscript(AMX* amx, void** program) { int flags = amx->flags; - amxx_FreeDebug(amx); + Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER]; + if (pDebugger) + delete pDebugger; CList::iterator a = g_loadedscripts.find( amx ); if ( a ) a.remove(); char *prg = (char *)*program; @@ -1443,137 +1282,72 @@ void MNF_Log(const char *fmt, ...) AMXXLOG_Log("%s", msg); } -bool amxx_GetPluginData(AMX *amx, cell addr, long &line, const char *&filename, const char *&function) -{ - AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(amx->userdata[2]); - - if (pInfo && pInfo->pDebug) - { - AMX_DBG *pDbg = (AMX_DBG *)pInfo->pDebug; - dbg_LookupFunction(pDbg, addr, &function); - dbg_LookupLine(pDbg, addr, &line); - dbg_LookupFile(pDbg, addr, &filename); - - return true; - } - - return false; -} - -//by BAILOPAN -// generic error printing routine -// for pawn 3.0 this is just a wrapper -const char *GenericError(int err) -{ - static const char *amx_errs[] = - { - NULL, - "forced exit", - "assertion failed", - "stack error", - "index out of bounds", - "memory access", - "invalid instruction", - "stack low", - "heap low", - "callback", - "native", - "divide", - "sleep", - "invalid access state", - NULL, - NULL, - "out of memory", //16 - "bad file format", - "bad file version", - "function not found", - "invalid entry point", - "debugger cannot run", - "plugin un or re-initialized", - "userdata table full", - "JIT failed to initialize", - "parameter error", - "domain error", - }; - //does this plugin have line ops? - const char *geterr = NULL; - if (err > 26 || err < 0) - geterr = ""; - else - geterr = amx_errs[err]; - return geterr; -} - //by BAILOPAN // debugger engine front end void LogError(AMX *amx, int err, const char *fmt, ...) { - //does this plugin have debug info? - va_list arg; - AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(amx->userdata[2]); - const char *name = get_amxscriptname(amx); - static char buf[1024]; - static char vbuf[1024]; - *buf = 0; - *vbuf = 0; + Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER]; - if (fmt[0] == '\0') - { - _snprintf(vbuf, sizeof(vbuf)-1, "Run time error %d (%s)", err, GenericError(err)); - } else { - va_start(arg, fmt); - vsprintf(vbuf, fmt, arg); - va_end(arg); - } - - bool invalidate = false; - AMXXLOG_Log("[AMXX] %s", vbuf); - if (!pInfo || !(amx->flags & AMX_FLAG_DEBUG) || !pInfo->pDebug) - { - - AMXXLOG_Log("[AMXX] Debug is not enabled (plugin \"%s\")", name); - invalidate = true; - } else { - long line; - const char *filename = NULL; - const char *function = NULL; - amx_trace *pTrace = pInfo->pTraceFrm; - int i=0, iLine; - cell frame; - - AMXXLOG_Log("[AMXX] Displaying call trace (plugin \"%s\")", name); - while (pTrace) - { - frame = pTrace->frm; - - if (amxx_GetPluginData(amx, frame, line, filename, function)) - { - //line seems to be 1 off o_O - iLine = static_cast(line) + 1; - AMXXLOG_Log("[AMXX] [%d] %s::%s (line %d)", - i, - filename?filename:"", - function?function:"", - iLine - ); - } - - pTrace->used = false; - pTrace = pTrace->prev; - i++; - } - //by now we have already invalidated - pInfo->pTraceFrm = NULL; - pInfo->frm = 0; - } - - if (invalidate) - amxx_InvalidateTrace(amx); - - //set these so ForwardMngr knows not to call us again - //This will also halt the script! amx->error = err; - pInfo->error = err; + CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx); + + const char *filename = ""; + if (pl) + { + filename = pl->getName(); + } else { + CList::iterator a = g_loadedscripts.find(amx); + if (a) + filename = (*a).getName(); + } + + static char msg_buffer[4096]; + if (fmt != NULL) + { + va_list ap; + va_start(ap, fmt); + _vsnprintf(msg_buffer, sizeof(msg_buffer)-1, fmt, ap); + va_end(ap); + } + + if (fmt != NULL) + AMXXLOG_Log("%s", msg_buffer); + + if (!pDebugger) + { + //give the module's error first. makes the report look nicer. + AMXXLOG_Log("[AMXX] Run time error %d (plugin \"%s\") - debug not enabled!", err, filename); + AMXXLOG_Log("[AMXX] To enable debug mode, add \"debug\" after the plugin name in plugins.ini (without quotes)."); + //destroy original error code so the original is not displayed again + amx->error = -1; + return; + } + + pDebugger->SetTracedError(err); + + char buffer[512]; + pDebugger->FormatError(buffer, sizeof(buffer)-1); + + AMXXLOG_Log("[AMXX] Displaying debug trace (plugin \"%s\")", filename); + AMXXLOG_Log("[AMXX] %s", buffer); + + int count = 0; + long lLine; + const char *file, *function; + trace_info_t *pTrace = pDebugger->GetTraceStart(); + while (pTrace) + { + pDebugger->GetTraceInfo(pTrace, lLine, function, file); + AMXXLOG_Log( + "[AMXX] [%d] %s::%s (line %d)", + count, + file, + function, + (int)(lLine + 1) + ); + count++; + pTrace = pDebugger->GetNextTrace(pTrace); + } } void MNF_MergeDefinitionFile(const char *file) diff --git a/amxmodx/msvc/amxmodx_mm.vcproj b/amxmodx/msvc/amxmodx_mm.vcproj index fb60a20d..d9b983a9 100755 --- a/amxmodx/msvc/amxmodx_mm.vcproj +++ b/amxmodx/msvc/amxmodx_mm.vcproj @@ -42,12 +42,13 @@ + + @@ -797,6 +801,9 @@ + + diff --git a/amxmodx/version.rc b/amxmodx/version.rc index 4b587539..3b17726b 100755 --- a/amxmodx/version.rc +++ b/amxmodx/version.rc @@ -27,8 +27,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,5,5,0 - PRODUCTVERSION 1,5,5,0 + FILEVERSION 1,5,6,0 + PRODUCTVERSION 1,5,6,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,12 +45,12 @@ BEGIN BEGIN VALUE "Comments", "AMX Mod X" VALUE "FileDescription", "AMX Mod X" - VALUE "FileVersion", "1.55" + VALUE "FileVersion", "1.56" VALUE "InternalName", "amxmodx" VALUE "LegalCopyright", "Copyright (c) 2004-2005, AMX Mod X Dev Team" VALUE "OriginalFilename", "amxmodx_mm.dll" VALUE "ProductName", "AMX Mod X" - VALUE "ProductVersion", "1.55" + VALUE "ProductVersion", "1.56" END END BLOCK "VarFileInfo"