Fix crash in TFCX module when Infection weapon is used
This commit is contained in:
		@@ -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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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 );
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user