diff --git a/modules/tfcx/CMisc.h b/modules/tfcx/CMisc.h index 2b1e9b0a..eeb80730 100644 --- a/modules/tfcx/CMisc.h +++ b/modules/tfcx/CMisc.h @@ -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; diff --git a/modules/tfcx/usermsg.cpp b/modules/tfcx/usermsg.cpp index e3d84571..81d8cde9 100644 --- a/modules/tfcx/usermsg.cpp +++ b/modules/tfcx/usermsg.cpp @@ -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,15 +187,20 @@ void Client_Damage(void* mValue){ case 'e': weapon = TFC_WPN_TIMER; // TFC_WPN_MEDKIT ?? - tempInt = *( (int*)mPlayer->pEdict->pvPrivateData + pdTimerOwner ); - if (!tempInt) + tempInt = get_pdata_ehandle(mPlayer->pEdict, pdTimerOwner * 4); // function is char-based. + + if (tempInt < 1 || tempInt > gpGlobals->maxClients) + { break; - tempEnt = (edict_t*)tempInt; - pAttacker = GET_PLAYER_POINTER(tempEnt); - - if ( pAttacker->teamId == mPlayer->teamId ) // ??? + } + + pAttacker = GET_PLAYER_POINTER_I(tempInt); + + if (pAttacker->teamId == mPlayer->teamId) // ??? + { ignoreDamage = true; - + } + pAttacker->saveShot(weapon); // ??? save shot too break; case 'f': @@ -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 );