From 0d90a958ae5039fb82672fc7f56960129cb36e15 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 29 Jul 2005 20:15:08 +0000 Subject: [PATCH] Added request at16475 Fixed crash bug from bad allocation in construction --- dlls/engine/amxxmodule.h | 126 ++++++++++++++++++++++---------------- dlls/engine/engine.cpp | 128 +++++++++++++++++++++++++++++++++++++++ dlls/engine/messages.cpp | 21 ++++++- dlls/engine/messages.h | 2 + 4 files changed, 224 insertions(+), 53 deletions(-) diff --git a/dlls/engine/amxxmodule.h b/dlls/engine/amxxmodule.h index 74cc5f72..bbaec2f5 100755 --- a/dlls/engine/amxxmodule.h +++ b/dlls/engine/amxxmodule.h @@ -31,8 +31,10 @@ // ***** AMXX stuff ***** -// module interface version is 1 -#define AMXX_INTERFACE_VERSION 2 +// module interface version was 1 +// 2 - added logtag to struct (amxx1.1-rc1) +// 3 - added new tagAMX structure (amxx1.5) +#define AMXX_INTERFACE_VERSION 3 // amxx module info struct amxx_module_info_s @@ -54,38 +56,55 @@ struct amxx_module_info_s // *** Small stuff *** // The next section is copied from the amx.h file -// Copyright (c) ITB CompuPhase, 1997-2004 +// Copyright (c) ITB CompuPhase, 1997-2005 -#if defined __LCC__ || defined __DMC__ || defined __linux__ || defined __GNUC__ +#if defined HAVE_STDINT_H #include -#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L - /* The ISO C99 defines the int16_t and int_32t types. If the compiler got - * here, these types are probably undefined. - */ - #if defined __FreeBSD__ - #include - #else - typedef short int int16_t; - typedef unsigned short int uint16_t; - #if defined SN_TARGET_PS2 - typedef int int32_t; - typedef unsigned int uint32_t; +#else + #if defined __LCC__ || defined __DMC__ || defined LINUX + #if defined HAVE_INTTYPES_H + #include #else - typedef long int int32_t; - typedef unsigned long int uint32_t; + #include #endif - #if defined __WIN32__ || defined _WIN32 || defined WIN32 - typedef __int64 int64_t; - typedef unsigned __int64 uint64_t; - #define HAVE_I64 - #elif defined __GNUC__ - typedef long long int64_t; - typedef unsigned long long uint64_t; - #define HAVE_I64 + #elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L + /* The ISO C99 defines the int16_t and int_32t types. If the compiler got + * here, these types are probably undefined. + */ + #if defined __MACH__ + #include + typedef unsigned short int uint16_t; + typedef unsigned long int uint32_t; + #elif defined __FreeBSD__ + #include + #else + typedef short int int16_t; + typedef unsigned short int uint16_t; + #if defined SN_TARGET_PS2 + typedef int int32_t; + typedef unsigned int uint32_t; + #else + typedef long int int32_t; + typedef unsigned long int uint32_t; + #endif + #if defined __WIN32__ || defined _WIN32 || defined WIN32 + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; + #define HAVE_I64 + #elif defined __GNUC__ + typedef long long int64_t; + typedef unsigned long long uint64_t; + #define HAVE_I64 + #endif #endif #endif + #define HAVE_STDINT_H +#endif +#if defined _LP64 || defined WIN64 || defined _WIN64 + #if !defined __64BIT__ + #define __64BIT__ + #endif #endif - /* calling convention for native functions */ #if !defined AMX_NATIVE_CALL @@ -105,24 +124,26 @@ struct amxx_module_info_s #define AMXEXPORT #endif - - -#if !defined SMALL_CELL_SIZE - #define SMALL_CELL_SIZE 32 /* by default, use 32-bit cells */ +#if !defined PAWN_CELL_SIZE + #define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */ #endif -#if SMALL_CELL_SIZE==32 +#if PAWN_CELL_SIZE==16 + typedef uint16_t ucell; + typedef int16_t cell; +#elif PAWN_CELL_SIZE==32 typedef uint32_t ucell; typedef int32_t cell; - typedef float REAL; -#elif SMALL_CELL_SIZE==64 +#define REAL float +#elif PAWN_CELL_SIZE==64 typedef uint64_t ucell; typedef int64_t cell; - typedef double REAL; +#define REAL double #else - #error Unsupported cell size (SMALL_CELL_SIZE) + #error Unsupported cell size (PAWN_CELL_SIZE) #endif #define UNPACKEDMAX ((1 << (sizeof(cell)-1)*8) - 1) +#define UNLIMITED (~1u >> 1) struct tagAMX; typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params); @@ -140,21 +161,24 @@ typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx); #endif -#if defined SN_TARGET_PS2 || defined __GNUC__ +/* Some compilers do not support the #pragma align, which should be fine. Some + * compilers give a warning on unknown #pragmas, which is not so fine... + */ +#if (defined SN_TARGET_PS2 || defined __GNUC__) && !defined AMX_NO_ALIGN #define AMX_NO_ALIGN #endif - #if defined __GNUC__ #define PACKED __attribute__((packed)) #else #define PACKED #endif - #if !defined AMX_NO_ALIGN - #if defined __linux__ + #if defined LINUX || defined __FreeBSD__ #pragma pack(1) /* structures must be packed (byte-aligned) */ + #elif defined MACOS && defined __MWERKS__ + #pragma options align=mac68k #else #pragma pack(push) #pragma pack(1) /* structures must be packed (byte-aligned) */ @@ -175,7 +199,7 @@ typedef struct { * fields are valid at all times; many fields are cached in local variables. */ typedef struct tagAMX { - unsigned char _FAR *base PACKED; /* points to the AMX header ("amxhdr") plus the code, optionally also the data */ + unsigned char _FAR *base PACKED; /* points to the AMX header plus the code, optionally also the data */ unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */ AMX_CALLBACK callback PACKED; AMX_DEBUG debug PACKED; /* debug callback */ @@ -187,28 +211,25 @@ typedef struct tagAMX { cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */ cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */ int flags PACKED; /* current status, see amx_Flags() */ - /* for assertions and debug hook */ - cell curline PACKED; - cell curfile PACKED; - int dbgcode PACKED; - cell dbgaddr PACKED; - cell dbgparam PACKED; - char _FAR *dbgname PACKED; /* user data */ 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 void _FAR *userdata[AMX_USERNUM] PACKED; /* native functions can raise an error */ int error PACKED; + /* passing parameters requires a "count" field */ + int paramcount; /* the sleep opcode needs to store the full AMX status */ cell pri PACKED; cell alt PACKED; cell reset_stk PACKED; cell reset_hea PACKED; cell sysreq_d PACKED; /* relocated address/value for the SYSREQ.D opcode */ - /* support variables for the JIT */ - int reloc_size PACKED; /* required temporary buffer for relocations */ - long code_size PACKED; /* estimated memory footprint of the native code */ -} AMX; + /* support variables for the JIT */ + int reloc_size PACKED; /* required temporary buffer for relocations */ + long code_size PACKED; /* estimated memory footprint of the native code */ +} PACKED AMX; enum { AMX_ERR_NONE, @@ -225,6 +246,7 @@ enum { AMX_ERR_NATIVE, /* native function failed */ AMX_ERR_DIVIDE, /* divide by zero */ AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */ + AMX_ERR_INVSTATE, /* invalid state for this access */ AMX_ERR_MEMORY = 16, /* out of memory */ AMX_ERR_FORMAT, /* invalid file format */ diff --git a/dlls/engine/engine.cpp b/dlls/engine/engine.cpp index e36cc9b0..3ba2c1a4 100755 --- a/dlls/engine/engine.cpp +++ b/dlls/engine/engine.cpp @@ -956,6 +956,133 @@ static cell AMX_NATIVE_CALL get_string(AMX *amx, cell *params) // (string, retur return MF_SetAmxString(amx, params[2], g_buffer, params[3]); } +//contributed by twistedeuphoria +static cell AMX_NATIVE_CALL trace_forward(AMX *amx, cell *params) +//native trace_forward(Float:start[3], Float:angle, Float:give, ignoreEnt, &Float:hitX, &Float:hitY, &Float:shortestDistance, &Float:shortestDistLow, &Float:shortestDistHigh) +{ + cell *cStart = MF_GetAmxAddr(amx, params[1]); + REAL fAngle = amx_ctof(params[2]); + REAL fGive = amx_ctof(params[3]); + int iIgnoreEnt = params[4]; + cell *hitX = MF_GetAmxAddr(amx, params[5]); + cell *hitY = MF_GetAmxAddr(amx, params[6]); + cell *shortestDistance = MF_GetAmxAddr(amx, params[7]); + cell *shortestDistLow = MF_GetAmxAddr(amx, params[8]); + cell *shortestDistHigh = MF_GetAmxAddr(amx, params[9]); + + if(fGive < 0.0) + fGive = 20.0; + fAngle -= 90.0; + if(fAngle < 0.0) + fAngle += 360.0; + + REAL fRadians = M_PI * fAngle; + fRadians /= 180.0; + REAL fTanResult = tan(fRadians); + REAL fStartX = amx_ctof(cStart[0]); + REAL fStartY = amx_ctof(cStart[1]); + REAL fStartZ = amx_ctof(cStart[2]); + REAL fEndX = -1.0; + REAL fEndY = -1.0; + if((fAngle == 0.0) || (fAngle == 360.0)) + { + fEndX = fStartX; + fEndY = 4000; + } + else if(fAngle == 90.0) + { + fEndX = 4000; + fEndY = fStartY; + } + else if(fAngle == 180.0) + { + fEndX = -4000; + fEndY = fStartY; + } + else if(fAngle == 270.0) + { + fEndX = fStartX; + fEndY = -4000; + } + if((fAngle > 0.0) && (fAngle < 180.0) && (fEndX == -1.0)) + fEndX = fStartX - 4000; + else if(fEndX == -1.0) + fEndX = fStartX + 4000; + if(fEndY == -1.0) + fEndY = fStartY + (4000.0 * fTanResult); + if((fAngle > 0.0) && (fAngle < 90.0)) + { + REAL tempSlot = fEndX; + fEndX = fEndY * -1.0; + fEndY = tempSlot * -1.0; + } + if((fAngle > 90.0) && (fAngle < 180.0)) + { + REAL tempSlot = fEndX; + fEndX = fEndY * -1.0; + fEndY = tempSlot; + } + if((fAngle > 180.0) && (fAngle < 270.0)) + { + REAL tempSlot = fEndX; + fEndX = fEndY; + fEndY = tempSlot; + fEndY *= -1.0; + } + if((fAngle > 270.0) && (fAngle < 360.0)) + { + REAL tempSlot = fEndX; + fEndX = fEndY; + fEndY = tempSlot; + } + REAL fClosestDist = 999999.9; + REAL fClosestLow = 0.0; + REAL fClosestHigh = 0.0; + REAL fClosestX = 0.0; + REAL fClosestY = 0.0; + TraceResult tr; + REAL fRetX; + REAL fRetY; + REAL fRetZ; + + for(int inum=-36;inum<=36;inum++) + { + REAL fUseZ = fStartZ + (REAL)inum; + Vector vStart = Vector(fStartX, fStartY, fUseZ); + Vector vEnd = Vector(fEndX, fEndY, fUseZ); + if(iIgnoreEnt == -1) + TRACE_LINE(vStart, vEnd, ignore_monsters, NULL, &tr); + else + TRACE_LINE(vStart, vEnd, dont_ignore_monsters, INDEXENT2(iIgnoreEnt), &tr); + fRetX = tr.vecEndPos.x; + fRetY = tr.vecEndPos.y; + fRetZ = tr.vecEndPos.z; + Vector vHit = Vector(fRetX, fRetY, fRetZ); + + REAL fLength = (vStart - vHit).Length(); + if(fLength < 20.0) continue; + if(fabs(fLength - fClosestDist) < fGive) + fClosestHigh = fUseZ - fStartZ; + else if(fLength < fClosestDist) + { + fClosestDist = fLength; + fClosestLow = fUseZ - fStartZ; + fClosestHigh = fUseZ - fStartZ; + fClosestX = fRetX; + fClosestY = fRetY; + } + } + fClosestLow += 36.0; + fClosestHigh += 36.0; + + *hitX = amx_ftoc(fClosestX); + *hitY = amx_ftoc(fClosestY); + *shortestDistance = amx_ftoc(fClosestDist); + *shortestDistLow = amx_ftoc(fClosestLow); + *shortestDistHigh = amx_ftoc(fClosestHigh); + return 1; +} + AMX_NATIVE_INFO engine_Natives[] = { {"halflife_time", halflife_time}, @@ -999,6 +1126,7 @@ AMX_NATIVE_INFO engine_Natives[] = { {"get_string", get_string}, {"in_view_cone", in_view_cone}, {"is_visible", is_visible}, + {"trace_forward", trace_forward}, {NULL, NULL}, /////////////////// diff --git a/dlls/engine/messages.cpp b/dlls/engine/messages.cpp index 355e339a..730b7eb9 100755 --- a/dlls/engine/messages.cpp +++ b/dlls/engine/messages.cpp @@ -12,6 +12,20 @@ bool inblock = false; Message::Message() { + m_CurParam = 0; +} + +bool Message::Ready() +{ + if (!m_Params.size()) + return false; + return true; +} + +void Message::Init() +{ + if (Ready()) + return; msgparam *p = new msgparam; m_Params.push_back(p); m_CurParam = 0; @@ -317,7 +331,12 @@ static cell AMX_NATIVE_CALL register_message(AMX *amx, cell *params) { int len; char *name = MF_GetAmxString(amx, params[2], 0, &len); - if (params[1]>0 && params[1] < 256) { + + if (!Msg.Ready()) + Msg.Init(); + + if (params[1]>0 && params[1] < 256) + { int id = MF_RegisterSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE); if (id != -1) { diff --git a/dlls/engine/messages.h b/dlls/engine/messages.h index 2e6fd113..37d4852b 100755 --- a/dlls/engine/messages.h +++ b/dlls/engine/messages.h @@ -45,6 +45,8 @@ public: void SetParam(size_t index, const char *data); const char *GetParamString(size_t index); float GetParamFloat(size_t index); + bool Ready(); + void Init(); int GetParamInt(size_t index); msgtype GetParamType(size_t index); void Reset();