Fix crash in TFCX module when Infection weapon is used

This commit is contained in:
Arkshine 2015-03-28 16:43:24 +01:00
parent bebe9f8e2e
commit db9421d0be
2 changed files with 84 additions and 30 deletions

View File

@ -19,25 +19,27 @@
#include "CRank.h"
#if defined(_WIN32)
#define LINUXOFFSET 0
#define CLIP_LINUXOFFSET 0
#define LINUXOFFSET 0
#define PLAYER_LINUXOFFSET 0
#define CLIP_LINUXOFFSET 0
#else
#define LINUXOFFSET 4
#define CLIP_LINUXOFFSET 4
#define LINUXOFFSET 4
#define PLAYER_LINUXOFFSET 5
#define CLIP_LINUXOFFSET 4
#endif
#define TFCMAX_CUSTOMWPNS 5
#define TFCMAX_WEAPONS MAX_WEAPONS + TFCMAX_CUSTOMWPNS
#define TFCMAX_CUSTOMWPNS 5
#define TFCMAX_WEAPONS MAX_WEAPONS + TFCMAX_CUSTOMWPNS
#define PD_HAS_GOALITEM 26 + LINUXOFFSET
#define PD_GOALITEM_TEAM 36 + LINUXOFFSET
#define PD_SENTRY_OWNER 83 + LINUXOFFSET
#define PD_TIMER_OWNER 932 + LINUXOFFSET
#define PD_HAS_GOALITEM 26 + LINUXOFFSET
#define PD_GOALITEM_TEAM 36 + LINUXOFFSET
#define PD_SENTRY_OWNER 83 + LINUXOFFSET
#define PD_TIMER_OWNER 932 + PLAYER_LINUXOFFSET
// If somehow TFC updates, the following two offsets can be updated by
// disassembling CBaseEntity::KeyValuePartThree(KeyValueData_s *)
#define PD_REPLACE_MODEL 170 + LINUXOFFSET
#define PD_REPLACE_SKIN 172 + LINUXOFFSET
#define PD_REPLACE_MODEL 170 + LINUXOFFSET
#define PD_REPLACE_SKIN 172 + LINUXOFFSET
#define MAX_TRACE 13
@ -194,12 +196,12 @@ class Grenades
{
struct Obj
{
CPlayer* player;
edict_t* grenade;
float time;
int type;
Obj* next;
Obj* prev;
CPlayer* player;
edict_t* grenade;
float time;
int type;
Obj* next;
Obj* prev;
} *head;

View File

@ -62,6 +62,49 @@ void Client_WeaponList(void* mValue){
}
*/
int get_pdata_ehandle(edict_t* pEntity, int offset)
{
if (FNullEnt(pEntity) || !pEntity->pvPrivateData)
{
return 0;
}
edict_t* pEdict = *(edict_t **)((char *)(pEntity->pvPrivateData) + offset);
if (!pEdict)
{
return 0;
}
static edict_t* pWorld = nullptr;
if (!pWorld)
{
pWorld = INDEXENT(0);
}
int index = pEdict - pWorld;
if (index < 0 || index > gpGlobals->maxEntities)
{
return 0;
}
if (pEdict->free || !pEdict->pvPrivateData)
{
return 0;
}
int serialnumber = *(int *)((char *)pEntity->pvPrivateData + offset + 4);
if (pEdict->serialnumber != serialnumber)
{
return 0;
}
return index;
}
void Client_Damage(void* mValue){
switch (mState++) {
case 1:
@ -144,14 +187,19 @@ void Client_Damage(void* mValue){
case 'e':
weapon = TFC_WPN_TIMER; // TFC_WPN_MEDKIT ??
tempInt = *( (int*)mPlayer->pEdict->pvPrivateData + pdTimerOwner );
if (!tempInt)
break;
tempEnt = (edict_t*)tempInt;
pAttacker = GET_PLAYER_POINTER(tempEnt);
tempInt = get_pdata_ehandle(mPlayer->pEdict, pdTimerOwner * 4); // function is char-based.
if ( pAttacker->teamId == mPlayer->teamId ) // ???
if (tempInt < 1 || tempInt > gpGlobals->maxClients)
{
break;
}
pAttacker = GET_PLAYER_POINTER_I(tempInt);
if (pAttacker->teamId == mPlayer->teamId) // ???
{
ignoreDamage = true;
}
pAttacker->saveShot(weapon); // ??? save shot too
break;
@ -174,12 +222,16 @@ void Client_Damage(void* mValue){
}
}
else { // nailgrenade , mirvgrenade , normalgrenade , rockets
if ( strstr("sentrygun",STRING(enemy->v.classname)) ){
tempInt = *( (int*)enemy->pvPrivateData + pdSentryGunOwner );
if ( !tempInt )
if ( strstr("sentrygun",STRING(enemy->v.classname)) )
{
tempInt = get_pdata_ehandle(mPlayer->pEdict, pdSentryGunOwner * 4); // function is char-based.
if (tempInt < 1 || tempInt > gpGlobals->maxClients)
{
break;
tempEnt = (edict_t*)tempInt;
pAttacker = GET_PLAYER_POINTER(tempEnt);
}
pAttacker = GET_PLAYER_POINTER_I(tempInt);
weapon = TFC_WPN_SENTRYGUN;
pAttacker->saveShot(weapon); // save shot too
pAttacker->saveHit( mPlayer , weapon , damage, aim );